diff --git a/Makefile b/Makefile index f9d0cbab..4fc142a2 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,7 @@ # ARCH_OS = $(shell uname) +ARCH_OS2 = $(shell uname -o) ARCH_TYPE = $(shell arch) ifeq ($(shell llvm-config --version), 3.1svn) @@ -26,7 +27,15 @@ CLANG_LIBS = -lclangFrontend -lclangDriver \ -lclangAnalysis -lclangAST -lclangLex -lclangBasic ISPC_LIBS=$(shell llvm-config --ldflags) $(CLANG_LIBS) $(LLVM_LIBS) \ - -lpthread -ldl + -lpthread + +ifeq ($(ARCH_OS),Linux) + ISPC_LIBS += -ldl +endif + +ifeq ($(ARCH_OS2),Msys) + ISPC_LIBS += -lshlwapi -limagehlp -lpsapi +endif LLVM_CXXFLAGS=$(shell llvm-config --cppflags) LLVM_VERSION=LLVM_$(shell llvm-config --version | sed s/\\./_/) @@ -133,22 +142,22 @@ objs/lex.o: objs/lex.cpp $(HEADERS) objs/parse.cc objs/builtins-%.cpp: builtins/%.ll builtins/util.m4 $(wildcard builtins/*common.ll) @echo Creating C++ source from builtins definition file $< - @m4 -Ibuiltins/ -DLLVM_VERSION=$(LLVM_VERSION) $< | ./bitcode2cpp.py $< > $@ + @m4 -Ibuiltins/ -DLLVM_VERSION=$(LLVM_VERSION) $< | python bitcode2cpp.py $< > $@ objs/builtins-c-32.cpp: builtins/builtins.c @echo Creating C++ source from builtins definition file $< - @$(CLANG) -m32 -emit-llvm -c $< -o - | llvm-dis - | ./bitcode2cpp.py c-32 > $@ + @$(CLANG) -m32 -emit-llvm -c $< -o - | llvm-dis - | python bitcode2cpp.py c-32 > $@ objs/builtins-c-64.cpp: builtins/builtins.c @echo Creating C++ source from builtins definition file $< - @$(CLANG) -m64 -emit-llvm -c $< -o - | llvm-dis - | ./bitcode2cpp.py c-64 > $@ + @$(CLANG) -m64 -emit-llvm -c $< -o - | llvm-dis - | python bitcode2cpp.py c-64 > $@ objs/stdlib_generic_ispc.cpp: stdlib.ispc @echo Creating C++ source from $< for generic @$(CLANG) -E -x c -DISPC_TARGET_GENERIC=1 -DISPC=1 -DPI=3.1415926536 $< -o - | \ - ./stdlib2cpp.py generic > $@ + python stdlib2cpp.py generic > $@ objs/stdlib_x86_ispc.cpp: stdlib.ispc @echo Creating C++ source from $< for x86 @$(CLANG) -E -x c -DISPC=1 -DPI=3.1415926536 $< -o - | \ - ./stdlib2cpp.py x86 > $@ + python stdlib2cpp.py x86 > $@ diff --git a/builtins/builtins.c b/builtins/builtins.c index f1cb35dd..36498e1a 100644 --- a/builtins/builtins.c +++ b/builtins/builtins.c @@ -149,7 +149,7 @@ void __do_print(const char *format, const char *types, int width, int mask, int __num_cores() { -#ifdef _MSC_VER +#if defined(_MSC_VER) || defined(__MINGW32__) // This is quite a hack. Including all of windows.h to get this definition // pulls in a bunch of stuff that leads to undefined symbols at link time. // So we don't #include but instead have the equivalent declarations diff --git a/cbackend.cpp b/cbackend.cpp index 2eb853e3..5fe87264 100644 --- a/cbackend.cpp +++ b/cbackend.cpp @@ -16,6 +16,11 @@ #warning "The C++ backend isn't supported when building with LLVM 2.9" #else +#include +#ifndef PRIx64 +#define PRIx64 "llx" +#endif + #include "llvm/CallingConv.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" @@ -1280,7 +1285,7 @@ void CWriter::printConstant(Constant *CPV, bool Static) { char Buffer[100]; uint64_t ll = DoubleToBits(V); - sprintf(Buffer, "0x%llx", static_cast(ll)); + sprintf(Buffer, "0x%"PRIx64, static_cast(ll)); std::string Num(&Buffer[0], &Buffer[6]); unsigned long Val = strtoul(Num.c_str(), 0, 16); diff --git a/expr.cpp b/expr.cpp index 1bcfa70d..f94245d5 100644 --- a/expr.cpp +++ b/expr.cpp @@ -43,6 +43,13 @@ #include "module.h" #include "util.h" #include "llvmutil.h" +#include +#ifndef PRId64 +#define PRId64 "lld" +#endif +#ifndef PRIu64 +#define PRIu64 "llu" +#endif #include #include @@ -4540,18 +4547,10 @@ ConstExpr::Print() const { printf("%f", floatVal[i]); break; case AtomicType::TYPE_INT64: -#ifdef ISPC_IS_LINUX - printf("%ld", int64Val[i]); -#else - printf("%lld", int64Val[i]); -#endif + printf("%"PRId64, int64Val[i]); break; case AtomicType::TYPE_UINT64: -#ifdef ISPC_IS_LINUX - printf("%lu", uint64Val[i]); -#else - printf("%llu", uint64Val[i]); -#endif + printf("%"PRIu64, uint64Val[i]); break; case AtomicType::TYPE_DOUBLE: printf("%f", doubleVal[i]); diff --git a/lex.ll b/lex.ll index 39194767..1b6d382b 100644 --- a/lex.ll +++ b/lex.ll @@ -155,7 +155,7 @@ L?\"(\\.|[^\\"])*\" { lStringConst(yylval, yylloc); return TOKEN_STRING_LITERAL; if (yytext[0] == '0' && yytext[1] == 'b') yylval->intVal = lParseBinary(yytext+2, *yylloc, &endPtr); else { -#ifdef ISPC_IS_WINDOWS +#if defined(ISPC_IS_WINDOWS) && !defined(__MINGW32__) yylval->intVal = _strtoi64(yytext, &endPtr, 0); #else // FIXME: should use strtouq and then issue an error if we can't diff --git a/main.cpp b/main.cpp index 84c5c142..d004815b 100644 --- a/main.cpp +++ b/main.cpp @@ -54,7 +54,9 @@ #ifdef ISPC_IS_WINDOWS #define strcasecmp stricmp +#ifndef BUILD_DATE #define BUILD_DATE __DATE__ +#endif #define BUILD_VERSION "" #endif // ISPC_IS_WINDOWS diff --git a/opt.cpp b/opt.cpp index c50f5f06..c66c69b1 100644 --- a/opt.cpp +++ b/opt.cpp @@ -79,7 +79,9 @@ #include #elif defined(ISPC_IS_WINDOWS) #include - #define alloca _alloca + #ifndef __MINGW32__ + #define alloca _alloca + #endif #endif // ISPC_IS_WINDOWS static llvm::Pass *CreateIntrinsicsOptPass(); diff --git a/stmt.cpp b/stmt.cpp index 043f6fa2..079919b2 100644 --- a/stmt.cpp +++ b/stmt.cpp @@ -2299,16 +2299,6 @@ AssertStmt::EmitCode(FunctionEmitContext *ctx) const { m->module->getFunction("__do_assert_varying"); Assert(assertFunc != NULL); -#ifdef ISPC_IS_WINDOWS - char errorString[2048]; - if (sprintf_s(errorString, sizeof(errorString), - "%s(%d): Assertion failed: %s\n", pos.name, - pos.first_line, message.c_str()) == -1) { - Error(pos, "Fatal error in sprintf_s() call when generating assert " - "string."); - return; - } -#else char *errorString; if (asprintf(&errorString, "%s:%d:%d: Assertion failed: %s\n", pos.name, pos.first_line, pos.first_column, @@ -2317,7 +2307,6 @@ AssertStmt::EmitCode(FunctionEmitContext *ctx) const { "unable to allocate memory!"); return; } -#endif std::vector args; args.push_back(ctx->GetStringPtr(errorString)); @@ -2325,9 +2314,7 @@ AssertStmt::EmitCode(FunctionEmitContext *ctx) const { args.push_back(ctx->GetFullMask()); ctx->CallInst(assertFunc, NULL, args, ""); -#ifndef ISPC_IS_WINDOWS free(errorString); -#endif // !ISPC_IS_WINDOWS } diff --git a/util.cpp b/util.cpp index 008fc5a3..9c802f19 100644 --- a/util.cpp +++ b/util.cpp @@ -39,6 +39,9 @@ #include "module.h" #ifdef ISPC_IS_WINDOWS #include +#ifdef __MINGW32__ +#include // for alloca() +#endif #else #include #endif @@ -75,7 +78,7 @@ lTerminalWidth() { HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); if (h == INVALID_HANDLE_VALUE || h == NULL) return 80; - CONSOLE_SCREEN_BUFFER_INFO bufferInfo = { 0 }; + CONSOLE_SCREEN_BUFFER_INFO bufferInfo = { {0} }; GetConsoleScreenBufferInfo(h, &bufferInfo); return bufferInfo.dwSize.X; #else @@ -187,6 +190,32 @@ lPrintWithWordBreaks(const char *buf, int columnWidth, FILE *out) { } +#ifdef ISPC_IS_WINDOWS +// we cover for the lack vasprintf and asprintf on windows (also covers mingw) +int +vasprintf(char **sptr, const char *fmt, va_list argv) +{ + int wanted = vsnprintf(*sptr = NULL, 0, fmt, argv); + if((wanted < 0) || ((*sptr = (char*)malloc( 1 + wanted )) == NULL)) + return -1; + + return vsprintf(*sptr, fmt, argv); +} + + +int +asprintf(char **sptr, const char *fmt, ...) +{ + int retval; + va_list argv; + va_start(argv, fmt); + retval = vasprintf(sptr, fmt, argv); + va_end(argv); + return retval; +} +#endif + + /** Helper function for Error(), Warning(), etc. @param type The type of message being printed (e.g. "Warning") @@ -197,30 +226,6 @@ lPrintWithWordBreaks(const char *buf, int columnWidth, FILE *out) { */ static void lPrint(const char *type, SourcePos p, const char *fmt, va_list args) { -#ifdef ISPC_IS_WINDOWS - char errorBuf[2048], formattedBuf[2048]; - if (vsnprintf_s(errorBuf, sizeof(errorBuf), _TRUNCATE, fmt, args) == -1) { - fprintf(stderr, "vsnprintf_s() error!\n"); - return; - } - - if (p.first_line == 0) { - // We don't have a valid SourcePos, so create a message without it - if (sprintf_s(formattedBuf, sizeof(formattedBuf), "%s: %s\n", - type, errorBuf) == -1) { - fprintf(stderr, "vsnprintf_s() error!\n"); - exit(1); - } - } - else { - // Create an error message that includes the file and line number - if (sprintf_s(formattedBuf, sizeof(formattedBuf), "%s(%d): %s: %s\n", - p.name, p.first_line, type, errorBuf) == -1) { - fprintf(stderr, "vsnprintf_s() error!\n"); - exit(1); - } - } -#else char *errorBuf, *formattedBuf; if (vasprintf(&errorBuf, fmt, args) == -1) { fprintf(stderr, "vasprintf() unable to allocate memory!\n"); @@ -241,7 +246,6 @@ lPrint(const char *type, SourcePos p, const char *fmt, va_list args) { exit(1); } } -#endif // Now that we've done all that work, see if we've already printed the // exact same error message. If so, return, so we don't redundantly @@ -254,10 +258,8 @@ lPrint(const char *type, SourcePos p, const char *fmt, va_list args) { lPrintWithWordBreaks(formattedBuf, lTerminalWidth(), stderr); lPrintFileLineContext(p); -#ifndef ISPC_IS_WINDOWS free(errorBuf); free(formattedBuf); -#endif // !ISPC_IS_WINDOWS } diff --git a/util.h b/util.h index 874e5bdb..e7575379 100644 --- a/util.h +++ b/util.h @@ -40,6 +40,9 @@ #define ISPC_UTIL_H #include "ispc.h" +#ifdef ISPC_IS_WINDOWS +#include +#endif struct SourcePos; @@ -62,6 +65,12 @@ inline uint32_t RoundUpPow2(uint32_t v) { #define PRINTF_FUNC #endif // __GNUG__ +// for cross-platform compatibility +#ifdef ISPC_IS_WINDOWS +int vasprintf(char **sptr, const char *fmt, va_list argv); +int asprintf(char **sptr, const char *fmt, ...); +#endif + /** Prints a debugging message. These messages are only printed if g->debugPrint is \c true. In addition to a program source code position to associate with the message, a printf()-style format string