/** * Main display function. This is the place to add more API calls. */ static void Display( void ) { int i; const float v[3] = { 1.0, 0.0, 0.0 }; cycles_t t0; cycles_t t1; glBegin(GL_TRIANGLE_STRIP); DO_FUNC( glColor3fv, (v) ); DO_FUNC( glNormal3fv, (v) ); DO_FUNC( glTexCoord2fv, (v) ); DO_FUNC( glTexCoord3fv, (v) ); DO_FUNC( glMultiTexCoord2fv, (GL_TEXTURE0, v) ); DO_FUNC( glMultiTexCoord2f, (GL_TEXTURE0, 0.0, 0.0) ); DO_FUNC( glFogCoordfv, (v) ); DO_FUNC( glFogCoordf, (0.5) ); glEnd(); exit(0); }
static bool lRunTest(const char *fn) { llvm::LLVMContext *ctx = new llvm::LLVMContext; #ifdef LLVM_2_8 std::string err; llvm::MemoryBuffer *buf = llvm::MemoryBuffer::getFileOrSTDIN(fn, &err); if (!buf) { fprintf(stderr, "Unable to open file \"%s\": %s\n", fn, err.c_str()); delete ctx; return false; } std::string bcErr; llvm::Module *module = llvm::ParseBitcodeFile(buf, *ctx, &bcErr); #else llvm::OwningPtr<llvm::MemoryBuffer> buf; llvm::error_code err = llvm::MemoryBuffer::getFileOrSTDIN(fn, buf); if (err) { fprintf(stderr, "Unable to open file \"%s\": %s\n", fn, err.message().c_str()); delete ctx; return false; } std::string bcErr; llvm::Module *module = llvm::ParseBitcodeFile(buf.get(), *ctx, &bcErr); #endif if (!module) { fprintf(stderr, "Bitcode reader failed for \"%s\": %s\n", fn, bcErr.c_str()); delete ctx; return false; } std::string eeError; llvm::ExecutionEngine *ee = llvm::ExecutionEngine::createJIT(module, &eeError); if (!ee) { fprintf(stderr, "Unable to create ExecutionEngine: %s\n", eeError.c_str()); return false; } llvm::Function *func; #define DO_FUNC(FUNC ,FUNCNAME) \ if ((func = module->getFunction(FUNCNAME)) != NULL) \ ee->addGlobalMapping(func, (void *)FUNC) DO_FUNC(ISPCLaunch, "ISPCLaunch"); DO_FUNC(ISPCSync, "ISPCSync"); #ifdef ISPC_IS_WINDOWS DO_FUNC(ISPCMalloc, "ISPCMalloc"); DO_FUNC(ISPCFree, "ISPCFree"); #endif // ISPC_IS_WINDOWS DO_FUNC(putchar, "putchar"); DO_FUNC(printf, "printf"); DO_FUNC(fflush, "fflush"); DO_FUNC(sinf, "sinf"); DO_FUNC(cosf, "cosf"); DO_FUNC(tanf, "tanf"); DO_FUNC(atanf, "atanf"); DO_FUNC(atan2f, "atan2f"); DO_FUNC(powf, "powf"); DO_FUNC(expf, "expf"); DO_FUNC(logf, "logf"); DO_FUNC(sin, "sin"); DO_FUNC(cos, "cos"); DO_FUNC(tan, "tan"); DO_FUNC(atan, "atan"); DO_FUNC(atan2, "atan2"); DO_FUNC(pow, "pow"); DO_FUNC(exp, "exp"); DO_FUNC(log, "log"); DO_FUNC(memset, "memset"); #ifdef ISPC_IS_APPLE DO_FUNC(memset_pattern4, "memset_pattern4"); DO_FUNC(memset_pattern8, "memset_pattern8"); DO_FUNC(memset_pattern16, "memset_pattern16"); #endif #ifdef ISPC_HAVE_SVML #define DO_SVML(FUNC ,FUNCNAME) \ if ((func = module->getFunction(FUNCNAME)) != NULL) \ ee->addGlobalMapping(func, (void *)FUNC) #else #define DO_SVML(FUNC, FUNCNAME) \ if ((func = module->getFunction(FUNCNAME)) != NULL) \ ee->addGlobalMapping(func, (void *)svml_missing) #endif DO_SVML(__svml_sinf4, "__svml_sinf4"); DO_SVML(__svml_cosf4, "__svml_cosf4"); DO_SVML(__svml_sincosf4, "__svml_sincosf4"); DO_SVML(__svml_tanf4, "__svml_tanf4"); DO_SVML(__svml_atanf4, "__svml_atanf4"); DO_SVML(__svml_atan2f4, "__svml_atan2f4"); DO_SVML(__svml_expf4, "__svml_expf4"); DO_SVML(__svml_logf4, "__svml_logf4"); DO_SVML(__svml_powf4, "__svml_powf4"); // figure out the vector width in the compiled code func = module->getFunction("width"); if (!func) { fprintf(stderr, "No width() function found!\n"); return false; } int width; { typedef int (*PFN)(); PFN pfn = reinterpret_cast<PFN>(ee->getPointerToFunction(func)); width = pfn(); assert(width == 4 || width == 8 || width == 12 || width == 16); } // find the value that returns the desired result func = module->getFunction("result"); bool foundResult = (func != NULL); float result[16]; for (int i = 0; i < 16; ++i) result[i] = 0; bool ok = true; if (foundResult) { typedef void (*PFN)(float *); PFN pfn = reinterpret_cast<PFN>(ee->getPointerToFunction(func)); pfn(result); } else fprintf(stderr, "Warning: no result() function found.\n"); // try to find a function to run float returned[16]; for (int i = 0; i < 16; ++i) returned[i] = 0; float vfloat[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; double vdouble[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; int vint[16] = { 2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32 }; int vint2[16] = { 5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}; if ((func = module->getFunction("f_v")) != NULL) { typedef void (*PFN)(float *); PFN pfn = reinterpret_cast<PFN>(ee->getPointerToFunction(func)); pfn(returned); } else if ((func = module->getFunction("f_f")) != NULL) { typedef void (*PFN)(float *, float *); PFN pfn = reinterpret_cast<PFN>(ee->getPointerToFunction(func)); llvm::verifyFunction(*func); pfn(returned, vfloat); } else if ((func = module->getFunction("f_fu")) != NULL) { typedef void (*PFN)(float *, float *, float fu); PFN pfn = reinterpret_cast<PFN>(ee->getPointerToFunction(func)); llvm::verifyFunction(*func); pfn(returned, vfloat, 5.); } else if ((func = module->getFunction("f_fi")) != NULL) { typedef void (*PFN)(float *, float *, int *); PFN pfn = reinterpret_cast<PFN>(ee->getPointerToFunction(func)); pfn(returned, vfloat, vint); } else if ((func = module->getFunction("f_du")) != NULL) { typedef void (*PFN)(float *, double *, double); PFN pfn = reinterpret_cast<PFN>(ee->getPointerToFunction(func)); pfn(returned, vdouble, 5.); } else if ((func = module->getFunction("f_duf")) != NULL) { typedef void (*PFN)(float *, double *, float); PFN pfn = reinterpret_cast<PFN>(ee->getPointerToFunction(func)); pfn(returned, vdouble, 5.f); } else if ((func = module->getFunction("f_di")) != NULL) { typedef void (*PFN)(float *, double *, int *); PFN pfn = reinterpret_cast<PFN>(ee->getPointerToFunction(func)); pfn(returned, vdouble, vint2); } else { fprintf(stderr, "Unable to find runnable function in file \"%s\"\n", fn); ok = false; } // see if we got the right result if (ok) { if (foundResult) { for (int i = 0; i < width; ++i) if (returned[i] != result[i]) { ok = false; fprintf(stderr, "Test \"%s\" RETURNED %d: %g / %a EXPECTED %g / %a\n", fn, i, returned[i], returned[i], result[i], result[i]); } } else { for (int i = 0; i < width; ++i) fprintf(stderr, "Test \"%s\" returned %d: %g / %a\n", fn, i, returned[i], returned[i]); } } delete ee; delete ctx; return ok && foundResult; }