#include #include #include "binaryen-c.h" // globals: address 4 is index // decisions are at address 8+ int main() { BinaryenModuleRef module = BinaryenModuleCreate(); // check() // if the end, halt BinaryenExpressionRef halter = BinaryenIf(module, BinaryenBinary(module, BinaryenGeUInt32(), BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))), BinaryenConst(module, BinaryenLiteralInt32(4 * 27)) // jumps of 4 bytes ), BinaryenUnreachable(module), NULL ); // increment index BinaryenExpressionRef incer = BinaryenStore(module, 4, 0, 0, BinaryenConst(module, BinaryenLiteralInt32(4)), BinaryenBinary(module, BinaryenAddInt32(), BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))), BinaryenConst(module, BinaryenLiteralInt32(4)) ), BinaryenTypeInt32() ); // optionally, print the return value BinaryenExpressionRef args[] = { BinaryenBinary(module, BinaryenSubInt32(), BinaryenConst(module, BinaryenLiteralInt32(0)), BinaryenLoad(module, 4, 0, 4, 0, BinaryenTypeInt32(), BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))) ) ) }; BinaryenExpressionRef debugger; if (1) debugger = BinaryenCall(module, "print", args, 1, BinaryenTypeNone()); else debugger = BinaryenNop(module); // return the decision. need to subtract 4 that we just added, // and add 8 since that's where we start, so overall offset 4 BinaryenExpressionRef returner = BinaryenLoad(module, 4, 0, 4, 0, BinaryenTypeInt32(), BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))) ); BinaryenExpressionRef checkBodyList[] = { halter, incer, debugger, returner }; BinaryenExpressionRef checkBody = BinaryenBlock(module, NULL, checkBodyList, sizeof(checkBodyList) / sizeof(BinaryenExpressionRef), BinaryenTypeInt32() ); BinaryenAddFunction(module, "check", BinaryenTypeNone(), BinaryenTypeInt32(), NULL, 0, checkBody); // contents of main() begin here RelooperRef relooper = RelooperCreate(module); RelooperBlockRef b0; { BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(0)) }; BinaryenExpressionRef list[] = { BinaryenCall(module, "print", args, 1, BinaryenTypeNone()), BinaryenLocalSet(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenTypeInt32())) }; b0 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone())); } RelooperBlockRef b1; { BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(0)) }; BinaryenExpressionRef list[] = { BinaryenCall(module, "print", args, 1, BinaryenTypeNone()), BinaryenLocalSet(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenTypeInt32())) }; b1 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone())); } RelooperBlockRef b2; { BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(0)) }; BinaryenExpressionRef list[] = { BinaryenCall(module, "print", args, 1, BinaryenTypeNone()), BinaryenLocalSet(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenTypeInt32())) }; b2 = RelooperAddBlockWithSwitch(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()), BinaryenBinary(module, BinaryenRemUInt32(), BinaryenLocalGet(module, 0, BinaryenTypeInt32()), BinaryenConst(module, BinaryenLiteralInt32(2)) ) ); } RelooperBlockRef b3; { BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(0)) }; BinaryenExpressionRef list[] = { BinaryenCall(module, "print", args, 1, BinaryenTypeNone()), BinaryenLocalSet(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenTypeInt32())) }; b3 = RelooperAddBlockWithSwitch(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()), BinaryenBinary(module, BinaryenRemUInt32(), BinaryenLocalGet(module, 0, BinaryenTypeInt32()), BinaryenConst(module, BinaryenLiteralInt32(1)) ) ); } RelooperBlockRef b4; { BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(4)) }; BinaryenExpressionRef list[] = { BinaryenCall(module, "print", args, 1, BinaryenTypeNone()), BinaryenLocalSet(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenTypeInt32())) }; b4 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone())); } RelooperBlockRef b5; { BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(0)) }; BinaryenExpressionRef list[] = { BinaryenCall(module, "print", args, 1, BinaryenTypeNone()), BinaryenLocalSet(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenTypeInt32())) }; b5 = RelooperAddBlockWithSwitch(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()), BinaryenBinary(module, BinaryenRemUInt32(), BinaryenLocalGet(module, 0, BinaryenTypeInt32()), BinaryenConst(module, BinaryenLiteralInt32(1)) ) ); } RelooperBlockRef b6; { BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(6)) }; BinaryenExpressionRef list[] = { BinaryenCall(module, "print", args, 1, BinaryenTypeNone()), BinaryenLocalSet(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenTypeInt32())) }; b6 = RelooperAddBlockWithSwitch(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()), BinaryenBinary(module, BinaryenRemUInt32(), BinaryenLocalGet(module, 0, BinaryenTypeInt32()), BinaryenConst(module, BinaryenLiteralInt32(3)) ) ); } RelooperBlockRef b7; { BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(0)) }; BinaryenExpressionRef list[] = { BinaryenCall(module, "print", args, 1, BinaryenTypeNone()), BinaryenLocalSet(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenTypeInt32())) }; b7 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone())); } RelooperBlockRef b8; { BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(0)) }; BinaryenExpressionRef list[] = { BinaryenCall(module, "print", args, 1, BinaryenTypeNone()), BinaryenLocalSet(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenTypeInt32())) }; b8 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone())); } RelooperAddBranch( b0, b1, NULL, BinaryenStore( module, 4, 0, 0, BinaryenConst(module, BinaryenLiteralInt32(4)), BinaryenBinary( module, BinaryenAddInt32(), BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))), BinaryenConst(module, BinaryenLiteralInt32(4 * 4))), BinaryenTypeInt32())); RelooperAddBranch( b1, b1, NULL, BinaryenStore( module, 4, 0, 0, BinaryenConst(module, BinaryenLiteralInt32(4)), BinaryenBinary( module, BinaryenAddInt32(), BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))), BinaryenConst(module, BinaryenLiteralInt32(4 * 4))), BinaryenTypeInt32())); { BinaryenIndex values[] = { 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86 }; RelooperAddBranchForSwitch( b2, b7, values, sizeof(values) / sizeof(BinaryenIndex), BinaryenStore( module, 4, 0, 0, BinaryenConst(module, BinaryenLiteralInt32(4)), BinaryenBinary( module, BinaryenAddInt32(), BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))), BinaryenConst(module, BinaryenLiteralInt32(4 * 6))), BinaryenTypeInt32())); } RelooperAddBranchForSwitch( b2, b4, NULL, 0, BinaryenStore( module, 4, 0, 0, BinaryenConst(module, BinaryenLiteralInt32(4)), BinaryenBinary( module, BinaryenAddInt32(), BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))), BinaryenConst(module, BinaryenLiteralInt32(4 * 4))), BinaryenTypeInt32())); RelooperAddBranchForSwitch( b3, b6, NULL, 0, BinaryenStore( module, 4, 0, 0, BinaryenConst(module, BinaryenLiteralInt32(4)), BinaryenBinary( module, BinaryenAddInt32(), BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))), BinaryenConst(module, BinaryenLiteralInt32(4 * 5))), BinaryenTypeInt32())); RelooperAddBranch( b4, b7, BinaryenBinary( module, BinaryenEqInt32(), BinaryenBinary(module, BinaryenRemUInt32(), BinaryenLocalGet(module, 0, BinaryenTypeInt32()), BinaryenConst(module, BinaryenLiteralInt32(2))), BinaryenConst(module, BinaryenLiteralInt32(0))), BinaryenStore( module, 4, 0, 0, BinaryenConst(module, BinaryenLiteralInt32(4)), BinaryenBinary( module, BinaryenAddInt32(), BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))), BinaryenConst(module, BinaryenLiteralInt32(4 * 5))), BinaryenTypeInt32())); RelooperAddBranch( b4, b3, NULL, BinaryenStore( module, 4, 0, 0, BinaryenConst(module, BinaryenLiteralInt32(4)), BinaryenBinary( module, BinaryenAddInt32(), BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))), BinaryenConst(module, BinaryenLiteralInt32(4 * 3))), BinaryenTypeInt32())); RelooperAddBranchForSwitch( b5, b1, NULL, 0, BinaryenStore( module, 4, 0, 0, BinaryenConst(module, BinaryenLiteralInt32(4)), BinaryenBinary( module, BinaryenAddInt32(), BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))), BinaryenConst(module, BinaryenLiteralInt32(4 * 4))), BinaryenTypeInt32())); { BinaryenIndex values[] = { 0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93,96,99,102,105,108 }; RelooperAddBranchForSwitch( b6, b1, values, sizeof(values) / sizeof(BinaryenIndex), BinaryenStore( module, 4, 0, 0, BinaryenConst(module, BinaryenLiteralInt32(4)), BinaryenBinary( module, BinaryenAddInt32(), BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))), BinaryenConst(module, BinaryenLiteralInt32(4 * 2))), BinaryenTypeInt32())); } { BinaryenIndex values[] = { 1,4,7,10,13,16,19,22,25,28,31,34,37,40,43,46,49,52,55,58,61,64,67,70,73,76,79,82,85,88,91,94,97,100,103,106,109,112,115,118,121,124,127,130,133,136,139,142,145,148,151,154,157,160 }; RelooperAddBranchForSwitch( b6, b7, values, sizeof(values) / sizeof(BinaryenIndex), BinaryenStore( module, 4, 0, 0, BinaryenConst(module, BinaryenLiteralInt32(4)), BinaryenBinary( module, BinaryenAddInt32(), BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))), BinaryenConst(module, BinaryenLiteralInt32(4 * 3))), BinaryenTypeInt32())); } RelooperAddBranchForSwitch( b6, b2, NULL, 0, BinaryenStore( module, 4, 0, 0, BinaryenConst(module, BinaryenLiteralInt32(4)), BinaryenBinary( module, BinaryenAddInt32(), BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))), BinaryenConst(module, BinaryenLiteralInt32(4 * 3))), BinaryenTypeInt32())); RelooperAddBranch( b7, b5, BinaryenBinary( module, BinaryenEqInt32(), BinaryenBinary(module, BinaryenRemUInt32(), BinaryenLocalGet(module, 0, BinaryenTypeInt32()), BinaryenConst(module, BinaryenLiteralInt32(2))), BinaryenConst(module, BinaryenLiteralInt32(0))), BinaryenStore( module, 4, 0, 0, BinaryenConst(module, BinaryenLiteralInt32(4)), BinaryenBinary( module, BinaryenAddInt32(), BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))), BinaryenConst(module, BinaryenLiteralInt32(4 * 1))), BinaryenTypeInt32())); RelooperAddBranch( b7, b1, NULL, BinaryenStore( module, 4, 0, 0, BinaryenConst(module, BinaryenLiteralInt32(4)), BinaryenBinary( module, BinaryenAddInt32(), BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))), BinaryenConst(module, BinaryenLiteralInt32(4 * 4))), BinaryenTypeInt32())); RelooperAddBranch( b8, b8, NULL, BinaryenStore( module, 4, 0, 0, BinaryenConst(module, BinaryenLiteralInt32(4)), BinaryenBinary( module, BinaryenAddInt32(), BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))), BinaryenConst(module, BinaryenLiteralInt32(4 * 2))), BinaryenTypeInt32())); BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, b0, 1); int decisions[] = { 5, 111, 119, 17, 179, 41, 32, 3, 171, 126, 13, 95, 70, 91, 9, 140, 99, 161, 38, 87, 153, 117, 140, 11, 157, 48, 4 }; int numDecisions = sizeof(decisions)/sizeof(int); // write out all the decisions, then the body of the function BinaryenExpressionRef full[numDecisions + 1]; { int i; for (i = 0; i < numDecisions; i++) { full[i] = BinaryenStore(module, 4, 0, 0, BinaryenConst(module, BinaryenLiteralInt32(8 + 4 * i)), BinaryenConst(module, BinaryenLiteralInt32(decisions[i])), BinaryenTypeInt32() ); } } full[numDecisions] = body; BinaryenExpressionRef all = BinaryenBlock(module, NULL, full, numDecisions + 1, BinaryenTypeNone()); // locals: state, free-for-label BinaryenType localTypes[] = { BinaryenTypeInt32(), BinaryenTypeInt32() }; BinaryenFunctionRef theMain = BinaryenAddFunction( module, "main", BinaryenTypeNone(), BinaryenTypeNone(), localTypes, 2, all); BinaryenSetStart(module, theMain); // import BinaryenAddFunctionImport(module, "print", "spectest", "print", BinaryenTypeInt32(), BinaryenTypeNone()); // memory BinaryenSetMemory(module, 1, 1, "mem", NULL, NULL, NULL, NULL, 0, 0); // optionally, optimize if (0) BinaryenModuleOptimize(module); assert(BinaryenModuleValidate(module)); // write it out BinaryenModulePrint(module); BinaryenModuleDispose(module); return 0; }