rx2c.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803
  1. import random
  2. import sys
  3. import os
  4. PROGRAM_SIZE = 512
  5. INSTRUCTION_COUNT = 1024 * 1024
  6. def genBytes(count):
  7. return ', '.join(str(random.getrandbits(8)) for i in range(count))
  8. class OperandType:
  9. INT32 = 0
  10. UINT32 = 1
  11. INT64 = 2
  12. UINT64 = 3
  13. FLOAT = 4
  14. SHIFT = 5
  15. def declareType(type):
  16. converters = {
  17. 0: "int32_t",
  18. 1: "uint32_t",
  19. 2: "int64_t",
  20. 3: "uint64_t",
  21. 4: "double",
  22. 5: "int32_t"
  23. }
  24. return converters.get(type)
  25. def toSigned32(x):
  26. return x - ((x & 0x80000000) << 1)
  27. def toSigned64(x):
  28. return x - ((x & 0x8000000000000000) << 1)
  29. def immediateTo(symbol, type):
  30. converters = {
  31. 0: toSigned32(symbol.imm1),
  32. 1: symbol.imm1,
  33. 2: toSigned32(symbol.imm1),
  34. 3: symbol.imm1,
  35. 4: float(toSigned32(symbol.imm1) << 32),
  36. 5: symbol.imm0 & 63
  37. }
  38. return repr(converters.get(type))
  39. def registerTo(expr, type):
  40. converters = {
  41. 0: "(int64_t){0}",
  42. 1: "{0}",
  43. 2: "(int64_t){0}",
  44. 3: "{0}",
  45. 4: "{0}",
  46. 5: "({0} & 63)"
  47. }
  48. return converters.get(type).format(expr)
  49. def registerFrom(num, type):
  50. converters = {
  51. 0: "r{0}",
  52. 1: "r{0}",
  53. 2: "r{0}",
  54. 3: "r{0}",
  55. 4: "((convertible_t)f{0}).u64",
  56. 5: "r{0}"
  57. }
  58. return converters.get(type).format(num)
  59. def convertibleTo(expr, type):
  60. converters = {
  61. 0: "{0}.i32",
  62. 1: "{0}.u32",
  63. 2: "{0}.i64",
  64. 3: "{0}.u64",
  65. 4: "(double){0}.i64",
  66. 5: "({0}.u64 & 63)"
  67. }
  68. return converters.get(type).format(expr)
  69. def convertibleFrom(expr, type):
  70. converters = {
  71. 0: "{0}.i32",
  72. 1: "{0}.u32",
  73. 2: "{0}.i64",
  74. 3: "{0}.u64",
  75. 4: "{0}.f64",
  76. 5: "({0}.u64 & 63)"
  77. }
  78. return converters.get(type).format(expr)
  79. def getRegister(num, type):
  80. registers = {
  81. 0: "r{0}",
  82. 1: "r{0}",
  83. 2: "r{0}",
  84. 3: "r{0}",
  85. 4: "f{0}",
  86. 5: "r{0}"
  87. }
  88. return registers.get(type).format(num)
  89. def writeInitialValues(file):
  90. file.write("#ifdef RAM\n")
  91. file.write("\tmmu.buffer = (char*)_mm_malloc(DRAM_SIZE, 16);\n")
  92. file.write("\tif(!mmu.buffer) {\n")
  93. file.write('\t\tprintf("DRAM buffer allocation failed\\n");\n')
  94. file.write("\t\treturn 1;\n")
  95. file.write("\t}\n")
  96. file.write('\tprintf("Initializing DRAM buffer...\\n");\n')
  97. file.write("\taesInitialize((__m128i*)aesKey, (__m128i*)aesSeed, (__m128i*)mmu.buffer, DRAM_SIZE);\n")
  98. file.write("#endif\n")
  99. file.write("\tclock_t clockStart = clock(), clockEnd;\n")
  100. for i in range(8):
  101. file.write("\tr{0} = *(uint64_t*)(aesSeed + {1});\n".format(i, i * 8))
  102. for i in range(8):
  103. file.write("\tf{0} = *(int64_t*)(aesSeed + {1});\n".format(i, 64 + i * 8))
  104. file.write("\tmmu.m0 = (aesKey[9] << 8) | (aesKey[10] << 16) | (aesKey[11] << 24);\n")
  105. file.write("\taesInitialize((__m128i*)aesKey, (__m128i*)aesSeed, (__m128i*)scratchpad, SCRATCHPAD_SIZE);\n")
  106. file.write("\tmmu.mx = 0;\n")
  107. file.write("\tsp = 0;\n")
  108. file.write("\tic = {0};\n".format(INSTRUCTION_COUNT))
  109. file.write("\tmxcsr = (_mm_getcsr() | _MM_FLUSH_ZERO_ON) & ~_MM_ROUND_MASK; //flush denormals to zero, round to nearest\n")
  110. file.write("\t_mm_setcsr(mxcsr);\n")
  111. def writeEpilog(file):
  112. file.write("\tend:\n")
  113. file.write("\t\tclockEnd = clock();\n")
  114. for i in range(8):
  115. file.write('\t\tprintf("r{0} = %-36lu f{0} = %g\\n", r{0}, f{0});\n'.format(i))
  116. file.write(("\t\tuint64_t spadsum = 0;\n"
  117. "\t\tfor(int i = 0; i < SCRATCHPAD_LENGTH; ++i) {\n"
  118. "\t\t spadsum += scratchpad[i].u64;\n"
  119. "\t\t}\n"
  120. '\t\tprintf("scratchpad sum = %lu\\n", spadsum);\n'
  121. '\t\tprintf("runtime: %f\\n", (clockEnd - clockStart) / (double)CLOCKS_PER_SEC);\n'
  122. "#ifdef RAM\n"
  123. "\t\t_mm_free((void*)mmu.buffer);\n"
  124. "#endif\n"))
  125. file.write("\t\treturn 0;")
  126. file.write("}")
  127. def writeCommon(file, i, symbol, type, name):
  128. file.write("\ti_{0}: {{ //{1}\n".format(i, name))
  129. file.write("\t\tif(0 == ic--) goto end;\n")
  130. file.write("\t\tr{0} ^= {1};\n".format(symbol.rega, symbol.addr0))
  131. file.write("\t\taddr_t addr = r{0};\n".format(symbol.rega))
  132. def readA(symbol, type):
  133. location = {
  134. 0: "readDram(&mmu, addr)",
  135. 1: "readDram(&mmu, addr)",
  136. 2: "readDram(&mmu, addr)",
  137. 3: "readDram(&mmu, addr)",
  138. 4: "SCRATCHPAD_256K(addr)",
  139. 5: "SCRATCHPAD_16K(addr)",
  140. 6: "SCRATCHPAD_16K(addr)",
  141. 7: "SCRATCHPAD_16K(addr)",
  142. }
  143. return convertibleTo(location.get(symbol.loca), type)
  144. def writeC(symbol, type):
  145. location = {
  146. 0: "SCRATCHPAD_256K(r{0} ^ {1})",
  147. 1: "SCRATCHPAD_16K(r{0} ^ {1})",
  148. 2: "SCRATCHPAD_16K(r{0} ^ {1})",
  149. 3: "SCRATCHPAD_16K(r{0} ^ {1})",
  150. 4: "",
  151. 5: "",
  152. 6: "",
  153. 7: ""
  154. }
  155. c = location.get(symbol.locc)
  156. if c == "":
  157. c = getRegister(symbol.regc, type)
  158. else:
  159. c = convertibleFrom(c.format(symbol.regc, symbol.addr1), type)
  160. return c
  161. def readB(symbol, type):
  162. if symbol.locb < 6:
  163. return registerTo(getRegister(symbol.regb, type), type)
  164. else:
  165. return immediateTo(symbol, type)
  166. class CodeSymbol:
  167. def __init__(self, qi):
  168. self.opcode = qi & 255
  169. self.loca = (qi >> 8) & 7
  170. self.rega = (qi >> 16) & 7
  171. self.locb = (qi >> 24) & 7
  172. self.regb = (qi >> 32) & 7
  173. self.locc = (qi >> 40) & 7
  174. self.regc = (qi >> 48) & 7
  175. self.imm0 = (qi >> 56) & 255
  176. self.addr0 = (qi >> 64) & 0xFFFFFFFF
  177. self.addr1 = self.imm1 = qi >> 96
  178. def writeOperation(file, i, symbol, type, name, op):
  179. writeCommon(file, i, symbol, type, name)
  180. file.write("\t\t{0} A = {1};\n".format(declareType(type), readA(symbol, type)))
  181. file.write("\t\t{0} B = {1};\n".format(declareType(type), readB(symbol, type)))
  182. file.write("\t\t{0} = A {1} B; }}\n".format(writeC(symbol, type), op))
  183. def write_ADD_64(file, i, symbol):
  184. writeOperation(file, i, symbol, OperandType.UINT64, 'ADD_64', '+');
  185. def write_ADD_32(file, i, symbol):
  186. writeOperation(file, i, symbol, OperandType.UINT32, 'ADD_32', '+');
  187. def write_SUB_64(file, i, symbol):
  188. writeOperation(file, i, symbol, OperandType.UINT64, 'SUB_64', '-');
  189. def write_SUB_32(file, i, symbol):
  190. writeOperation(file, i, symbol, OperandType.UINT32, 'SUB_32', '-');
  191. def write_MUL_64(file, i, symbol):
  192. writeOperation(file, i, symbol, OperandType.UINT64, 'MUL_64', '*');
  193. def write_MULH_64(file, i, symbol):
  194. type = OperandType.UINT64
  195. writeCommon(file, i, symbol, type, 'MULH_64')
  196. file.write("\t\t{0} A = {1};\n".format(declareType(type), readA(symbol, type)))
  197. file.write("\t\t{0} B = {1};\n".format(declareType(type), readB(symbol, type)))
  198. file.write("\t\t{0} = ((uint128_t)A * B) >> 64; }}\n".format(writeC(symbol, type)))
  199. def write_MUL_32(file, i, symbol):
  200. type = OperandType.UINT32
  201. writeCommon(file, i, symbol, type, 'MUL_32')
  202. file.write("\t\t{0} A = {1};\n".format(declareType(type), readA(symbol, type)))
  203. file.write("\t\t{0} B = {1};\n".format(declareType(type), readB(symbol, type)))
  204. file.write("\t\t{0} = (uint64_t)A * B; }}\n".format(writeC(symbol, OperandType.UINT64)))
  205. def write_IMUL_32(file, i, symbol):
  206. type = OperandType.INT32
  207. writeCommon(file, i, symbol, type, 'IMUL_32')
  208. file.write("\t\t{0} A = {1};\n".format(declareType(type), readA(symbol, type)))
  209. file.write("\t\t{0} B = {1};\n".format(declareType(type), readB(symbol, type)))
  210. file.write("\t\t{0} = (int64_t)A * B; }}\n".format(writeC(symbol, OperandType.INT64)))
  211. def write_IMULH_64(file, i, symbol):
  212. type = OperandType.INT64
  213. writeCommon(file, i, symbol, type, 'IMULH_64')
  214. file.write("\t\t{0} A = {1};\n".format(declareType(type), readA(symbol, type)))
  215. file.write("\t\t{0} B = {1};\n".format(declareType(type), readB(symbol, type)))
  216. file.write("\t\t{0} = ((int128_t)A * B) >> 64; }}\n".format(writeC(symbol, type)))
  217. def write_DIV_64(file, i, symbol):
  218. type = OperandType.UINT64
  219. writeCommon(file, i, symbol, type, 'DIV_64')
  220. file.write("\t\t{0} A = {1};\n".format(declareType(type), readA(symbol, type)))
  221. file.write("\t\t{0} B = {1};\n".format(declareType(OperandType.UINT32), readB(symbol, OperandType.UINT32)))
  222. file.write("\t\tif(B == 0) B = 1;\n".format(declareType(type), readB(symbol, type)))
  223. file.write("\t\t{0} = A / B; }}\n".format(writeC(symbol, type)))
  224. def write_IDIV_64(file, i, symbol):
  225. type = OperandType.INT64
  226. writeCommon(file, i, symbol, type, 'IDIV_64')
  227. file.write("\t\t{0} A = {1};\n".format(declareType(type), readA(symbol, type)))
  228. file.write("\t\t{0} B = {1};\n".format(declareType(OperandType.INT32), readB(symbol, OperandType.INT32)))
  229. file.write("\t\tif(B == 0) B = 1;\n".format(declareType(type), readB(symbol, type)))
  230. file.write("\t\t{0} = A / B; }}\n".format(writeC(symbol, type)))
  231. def write_AND_64(file, i, symbol):
  232. writeOperation(file, i, symbol, OperandType.UINT64, 'AND_64', '&');
  233. def write_AND_32(file, i, symbol):
  234. writeOperation(file, i, symbol, OperandType.UINT32, 'AND_32', '&');
  235. def write_OR_64(file, i, symbol):
  236. writeOperation(file, i, symbol, OperandType.UINT64, 'OR_64', '|');
  237. def write_OR_32(file, i, symbol):
  238. writeOperation(file, i, symbol, OperandType.UINT32, 'OR_32', '|');
  239. def write_XOR_64(file, i, symbol):
  240. writeOperation(file, i, symbol, OperandType.UINT64, 'XOR_64', '^');
  241. def write_XOR_32(file, i, symbol):
  242. writeOperation(file, i, symbol, OperandType.UINT32, 'XOR_32', '^');
  243. def write_SHL_64(file, i, symbol):
  244. type = OperandType.UINT64
  245. writeCommon(file, i, symbol, type, 'SHL_64')
  246. file.write("\t\t{0} A = {1};\n".format(declareType(type), readA(symbol, type)))
  247. file.write("\t\t{0} B = {1};\n".format(declareType(OperandType.SHIFT), readB(symbol, OperandType.SHIFT)))
  248. file.write("\t\t{0} = A << B; }}\n".format(writeC(symbol, type)))
  249. def write_SHR_64(file, i, symbol):
  250. type = OperandType.UINT64
  251. writeCommon(file, i, symbol, type, 'SHR_64')
  252. file.write("\t\t{0} A = {1};\n".format(declareType(type), readA(symbol, type)))
  253. file.write("\t\t{0} B = {1};\n".format(declareType(OperandType.SHIFT), readB(symbol, OperandType.SHIFT)))
  254. file.write("\t\t{0} = A >> B; }}\n".format(writeC(symbol, type)))
  255. def write_SAR_64(file, i, symbol):
  256. type = OperandType.INT64
  257. writeCommon(file, i, symbol, type, 'SAR_64')
  258. file.write("\t\t{0} A = {1};\n".format(declareType(type), readA(symbol, type)))
  259. file.write("\t\t{0} B = {1};\n".format(declareType(OperandType.SHIFT), readB(symbol, OperandType.SHIFT)))
  260. file.write("\t\t{0} = A >> B; }}\n".format(writeC(symbol, type)))
  261. def write_ROL_64(file, i, symbol):
  262. type = OperandType.UINT64
  263. writeCommon(file, i, symbol, type, 'ROL_64')
  264. file.write("\t\t{0} A = {1};\n".format(declareType(type), readA(symbol, type)))
  265. file.write("\t\t{0} B = {1};\n".format(declareType(OperandType.SHIFT), readB(symbol, OperandType.SHIFT)))
  266. file.write("\t\t{0} = __rolq(A, B); }}\n".format(writeC(symbol, type)))
  267. def write_ROR_64(file, i, symbol):
  268. type = OperandType.UINT64
  269. writeCommon(file, i, symbol, type, 'ROR_64')
  270. file.write("\t\t{0} A = {1};\n".format(declareType(type), readA(symbol, type)))
  271. file.write("\t\t{0} B = {1};\n".format(declareType(OperandType.SHIFT), readB(symbol, OperandType.SHIFT)))
  272. file.write("\t\t{0} = __rorq(A, B); }}\n".format(writeC(symbol, type)))
  273. def write_FADD(file, i, symbol):
  274. writeOperation(file, i, symbol, OperandType.FLOAT, 'FADD', '+');
  275. def write_FSUB(file, i, symbol):
  276. writeOperation(file, i, symbol, OperandType.FLOAT, 'FSUB', '-');
  277. def write_FMUL(file, i, symbol):
  278. writeOperation(file, i, symbol, OperandType.FLOAT, 'FMUL', '*');
  279. def write_FDIV(file, i, symbol):
  280. writeOperation(file, i, symbol, OperandType.FLOAT, 'FDIV', '/');
  281. def write_FSQRT(file, i, symbol):
  282. type = OperandType.FLOAT
  283. writeCommon(file, i, symbol, type, 'FSQRT')
  284. file.write("\t\t{0} A = fabs({1});\n".format(declareType(type), readA(symbol, type)))
  285. file.write("\t\t{0} = _mm_cvtsd_f64(_mm_sqrt_sd(_mm_setzero_pd(), _mm_load_pd(&A))); }}\n".format(writeC(symbol, type)))
  286. def write_FROUND(file, i, symbol):
  287. type = OperandType.FLOAT
  288. writeCommon(file, i, symbol, type, 'FROUND')
  289. file.write("\t\t{0} A = {1};\n".format(declareType(OperandType.INT64), readA(symbol, OperandType.INT64)))
  290. file.write("\t\t{0} = A;\n".format(writeC(symbol, type)))
  291. file.write("\t\t_mm_setcsr(mxcsr | ((uint32_t)(A << 13) & _MM_ROUND_MASK)); }\n")
  292. def write_CALL(file, i, symbol):
  293. type = OperandType.UINT64
  294. writeCommon(file, i, symbol, type, 'CALL')
  295. file.write("\t\t{0} A = {1};\n".format(declareType(type), readA(symbol, type)))
  296. if symbol.locb < 6:
  297. file.write("\t\tif((uint32_t)r{0} <= {1}) {{\n".format(symbol.regb, symbol.imm1))
  298. file.write("\t\t\tPUSH_VALUE(A);\n");
  299. file.write("\t\t\tPUSH_ADDRESS(&&i_{0});\n".format((i + 1) & (PROGRAM_SIZE - 1)));
  300. file.write("\t\t\tgoto i_{0};\n".format((i + 1 + (symbol.imm0 & ((PROGRAM_SIZE >> 2) - 1))) & (PROGRAM_SIZE - 1)));
  301. if symbol.locb < 6:
  302. file.write("\t\t}}\n\t\t{0} = A;".format(writeC(symbol, type)))
  303. file.write("\t\t}\n")
  304. def write_RET(file, i, symbol):
  305. type = OperandType.UINT64
  306. writeCommon(file, i, symbol, type, 'RET')
  307. file.write("\t\t{0} A = {1};\n".format(declareType(type), readA(symbol, type)))
  308. file.write("\t\tif(!STACK_IS_EMPTY()")
  309. if symbol.locb < 6:
  310. file.write(" && (uint32_t)r{0} <= {1}".format(symbol.regb, symbol.imm1))
  311. file.write(") {\n")
  312. file.write("\t\t\tvoid* target = POP_ADDRESS();\n")
  313. file.write("\t\t\tuint64_t C = POP_VALUE();\n")
  314. file.write("\t\t\t{0} = A ^ C;\n".format(writeC(symbol, type)))
  315. file.write("\t\t\tgoto *target;\n")
  316. file.write("\t\t}}\n\t\t{0} = A; }}\n".format(writeC(symbol, type)))
  317. opcodeMap = {
  318. 0: write_ADD_64,
  319. 1: write_ADD_64,
  320. 2: write_ADD_64,
  321. 3: write_ADD_64,
  322. 4: write_ADD_64,
  323. 5: write_ADD_64,
  324. 6: write_ADD_64,
  325. 7: write_ADD_64,
  326. 8: write_ADD_64,
  327. 9: write_ADD_64,
  328. 10: write_ADD_64,
  329. 11: write_ADD_64,
  330. 12: write_ADD_64,
  331. 13: write_ADD_64,
  332. 14: write_ADD_32,
  333. 15: write_ADD_32,
  334. 16: write_ADD_32,
  335. 17: write_ADD_32,
  336. 18: write_ADD_32,
  337. 19: write_ADD_32,
  338. 20: write_ADD_32,
  339. 21: write_SUB_64,
  340. 22: write_SUB_64,
  341. 23: write_SUB_64,
  342. 24: write_SUB_64,
  343. 25: write_SUB_64,
  344. 26: write_SUB_64,
  345. 27: write_SUB_64,
  346. 28: write_SUB_64,
  347. 29: write_SUB_64,
  348. 30: write_SUB_64,
  349. 31: write_SUB_64,
  350. 32: write_SUB_64,
  351. 33: write_SUB_64,
  352. 34: write_SUB_64,
  353. 35: write_SUB_32,
  354. 36: write_SUB_32,
  355. 37: write_SUB_32,
  356. 38: write_SUB_32,
  357. 39: write_SUB_32,
  358. 40: write_SUB_32,
  359. 41: write_SUB_32,
  360. 42: write_MUL_64,
  361. 43: write_MUL_64,
  362. 44: write_MUL_64,
  363. 45: write_MUL_64,
  364. 46: write_MULH_64,
  365. 47: write_MULH_64,
  366. 48: write_MULH_64,
  367. 49: write_MULH_64,
  368. 50: write_MUL_32,
  369. 51: write_MUL_32,
  370. 52: write_MUL_32,
  371. 53: write_MUL_32,
  372. 54: write_IMUL_32,
  373. 55: write_IMUL_32,
  374. 56: write_IMUL_32,
  375. 57: write_IMUL_32,
  376. 58: write_IMULH_64,
  377. 59: write_IMULH_64,
  378. 60: write_IMULH_64,
  379. 61: write_IMULH_64,
  380. 62: write_DIV_64,
  381. 63: write_IDIV_64,
  382. 64: write_AND_64,
  383. 65: write_AND_64,
  384. 66: write_AND_64,
  385. 67: write_AND_64,
  386. 68: write_AND_64,
  387. 69: write_AND_64,
  388. 70: write_AND_64,
  389. 71: write_AND_64,
  390. 72: write_AND_64,
  391. 73: write_AND_64,
  392. 74: write_AND_64,
  393. 75: write_AND_64,
  394. 76: write_AND_64,
  395. 77: write_AND_32,
  396. 78: write_AND_32,
  397. 79: write_AND_32,
  398. 80: write_AND_32,
  399. 81: write_AND_32,
  400. 82: write_AND_32,
  401. 83: write_OR_64,
  402. 84: write_OR_64,
  403. 85: write_OR_64,
  404. 86: write_OR_64,
  405. 87: write_OR_64,
  406. 88: write_OR_64,
  407. 89: write_OR_64,
  408. 90: write_OR_64,
  409. 91: write_OR_64,
  410. 92: write_OR_64,
  411. 93: write_OR_64,
  412. 94: write_OR_64,
  413. 95: write_OR_64,
  414. 96: write_OR_32,
  415. 97: write_OR_32,
  416. 98: write_OR_32,
  417. 99: write_OR_32,
  418. 100: write_OR_32,
  419. 101: write_OR_32,
  420. 102: write_XOR_64,
  421. 103: write_XOR_64,
  422. 104: write_XOR_64,
  423. 105: write_XOR_64,
  424. 106: write_XOR_64,
  425. 107: write_XOR_64,
  426. 108: write_XOR_64,
  427. 109: write_XOR_64,
  428. 110: write_XOR_64,
  429. 111: write_XOR_64,
  430. 112: write_XOR_64,
  431. 113: write_XOR_64,
  432. 114: write_XOR_64,
  433. 115: write_XOR_64,
  434. 116: write_XOR_32,
  435. 117: write_XOR_32,
  436. 118: write_XOR_32,
  437. 119: write_XOR_32,
  438. 120: write_XOR_32,
  439. 121: write_XOR_32,
  440. 122: write_SHL_64,
  441. 123: write_SHL_64,
  442. 124: write_SHL_64,
  443. 125: write_SHL_64,
  444. 126: write_SHL_64,
  445. 127: write_SHL_64,
  446. 128: write_SHL_64,
  447. 129: write_SHR_64,
  448. 130: write_SHR_64,
  449. 131: write_SHR_64,
  450. 132: write_SHR_64,
  451. 133: write_SAR_64,
  452. 134: write_SAR_64,
  453. 135: write_SAR_64,
  454. 136: write_ROL_64,
  455. 137: write_ROL_64,
  456. 138: write_ROL_64,
  457. 139: write_ROL_64,
  458. 140: write_ROL_64,
  459. 141: write_ROL_64,
  460. 142: write_ROL_64,
  461. 143: write_ROL_64,
  462. 144: write_ROL_64,
  463. 145: write_ROL_64,
  464. 146: write_ROL_64,
  465. 147: write_ROR_64,
  466. 148: write_ROR_64,
  467. 149: write_ROR_64,
  468. 150: write_ROR_64,
  469. 151: write_ROR_64,
  470. 152: write_ROR_64,
  471. 153: write_ROR_64,
  472. 154: write_ROR_64,
  473. 155: write_ROR_64,
  474. 156: write_ROR_64,
  475. 157: write_ROR_64,
  476. 158: write_FADD,
  477. 159: write_FADD,
  478. 160: write_FADD,
  479. 161: write_FADD,
  480. 162: write_FADD,
  481. 163: write_FADD,
  482. 164: write_FADD,
  483. 165: write_FADD,
  484. 166: write_FADD,
  485. 167: write_FADD,
  486. 168: write_FADD,
  487. 169: write_FADD,
  488. 170: write_FADD,
  489. 171: write_FADD,
  490. 172: write_FADD,
  491. 173: write_FADD,
  492. 174: write_FADD,
  493. 175: write_FADD,
  494. 176: write_FSUB,
  495. 177: write_FSUB,
  496. 178: write_FSUB,
  497. 179: write_FSUB,
  498. 180: write_FSUB,
  499. 181: write_FSUB,
  500. 182: write_FSUB,
  501. 183: write_FSUB,
  502. 184: write_FSUB,
  503. 185: write_FSUB,
  504. 186: write_FSUB,
  505. 187: write_FSUB,
  506. 188: write_FSUB,
  507. 189: write_FSUB,
  508. 190: write_FSUB,
  509. 191: write_FSUB,
  510. 192: write_FSUB,
  511. 193: write_FSUB,
  512. 194: write_FMUL,
  513. 195: write_FMUL,
  514. 196: write_FMUL,
  515. 197: write_FMUL,
  516. 198: write_FMUL,
  517. 199: write_FMUL,
  518. 200: write_FMUL,
  519. 201: write_FMUL,
  520. 202: write_FMUL,
  521. 203: write_FMUL,
  522. 204: write_FMUL,
  523. 205: write_FMUL,
  524. 206: write_FMUL,
  525. 207: write_FMUL,
  526. 208: write_FMUL,
  527. 209: write_FMUL,
  528. 210: write_FMUL,
  529. 211: write_FMUL,
  530. 212: write_FDIV,
  531. 213: write_FDIV,
  532. 214: write_FDIV,
  533. 215: write_FSQRT,
  534. 216: write_FSQRT,
  535. 217: write_FSQRT,
  536. 218: write_FSQRT,
  537. 219: write_FSQRT,
  538. 220: write_FSQRT,
  539. 221: write_FSQRT,
  540. 222: write_FROUND,
  541. 223: write_FROUND,
  542. 224: write_CALL,
  543. 225: write_CALL,
  544. 226: write_CALL,
  545. 227: write_CALL,
  546. 228: write_CALL,
  547. 229: write_CALL,
  548. 230: write_CALL,
  549. 231: write_CALL,
  550. 232: write_CALL,
  551. 233: write_CALL,
  552. 234: write_CALL,
  553. 235: write_CALL,
  554. 236: write_CALL,
  555. 237: write_CALL,
  556. 238: write_CALL,
  557. 239: write_CALL,
  558. 240: write_CALL,
  559. 241: write_RET,
  560. 242: write_RET,
  561. 243: write_RET,
  562. 244: write_RET,
  563. 245: write_RET,
  564. 246: write_RET,
  565. 247: write_RET,
  566. 248: write_RET,
  567. 249: write_RET,
  568. 250: write_RET,
  569. 251: write_RET,
  570. 252: write_RET,
  571. 253: write_RET,
  572. 254: write_RET,
  573. 255: write_RET,
  574. }
  575. def writeCode(file, i, symbol):
  576. opcodeMap.get(symbol.opcode)(file, i, symbol)
  577. def writeMain(file):
  578. file.write(('__attribute__((optimize("Os"))) int main() {\n'
  579. " register uint64_t r0, r1, r2, r3, r4, r5, r6, r7;\n"
  580. " register double f0, f1, f2, f3, f4, f5, f6, f7;\n"
  581. " register uint64_t ic, sp;\n"
  582. " convertible_t scratchpad[SCRATCHPAD_LENGTH] __attribute__ ((aligned (16)));\n"
  583. " stack_t stack[STACK_LENGTH];\n"
  584. " mmu_t mmu;\n"
  585. " uint32_t mxcsr;\n"
  586. ))
  587. def writeProlog(file):
  588. file.write(("#include <stdint.h>\n"
  589. "#include <time.h>\n"
  590. "#include <stdio.h>\n"
  591. "#include <x86intrin.h>\n"
  592. "#include <emmintrin.h>\n"
  593. "#include <wmmintrin.h>\n"
  594. "#include <math.h>\n"
  595. "typedef uint32_t addr_t;\n"
  596. "typedef unsigned __int128 uint128_t;\n"
  597. "typedef __int128 int128_t;\n"
  598. "typedef unsigned char byte;\n"
  599. "typedef union {\n"
  600. " double f64;\n"
  601. " int64_t i64;\n"
  602. " uint64_t u64;\n"
  603. " int32_t i32;\n"
  604. " uint32_t u32;\n"
  605. "} convertible_t;\n"
  606. "typedef union {\n"
  607. " uint64_t value;\n"
  608. " void* address;\n"
  609. "} stack_t;\n"
  610. "typedef struct {\n"
  611. " addr_t m0;\n"
  612. " addr_t m1;\n"
  613. " addr_t mx;\n"
  614. "#ifdef RAM\n"
  615. " const char* buffer;\n"
  616. "#endif\n"
  617. "} mmu_t;\n"
  618. "#define DRAM_SIZE (1UL << 32)\n"
  619. "#define SCRATCHPAD_SIZE (256 * 1024)\n"
  620. "#define SCRATCHPAD_LENGTH (SCRATCHPAD_SIZE / sizeof(convertible_t))\n"
  621. "#define SCRATCHPAD_MASK14 (16 * 1024 / sizeof(convertible_t) - 1)\n"
  622. "#define SCRATCHPAD_MASK18 (SCRATCHPAD_LENGTH - 1)\n"
  623. "#define SCRATCHPAD_16K(x) scratchpad[(x) & SCRATCHPAD_MASK14]\n"
  624. "#define SCRATCHPAD_256K(x) scratchpad[(x) & SCRATCHPAD_MASK18]\n"
  625. "#define STACK_LENGTH (32 * 1024)\n"
  626. "#ifdef RAM\n"
  627. "#define DRAM_READ(mmu) (convertible_t)*(uint64_t*)((mmu)->buffer + (mmu)->m0)\n"
  628. "#define PREFETCH(mmu) _mm_prefetch(((mmu)->buffer + (mmu)->m1), _MM_HINT_T0)\n"
  629. "#else\n"
  630. "#define DRAM_READ(mmu) (convertible_t)(uint64_t)__rolq(6364136223846793005ULL*((mmu)->m0)+1442695040888963407ULL,32)\n"
  631. "#define PREFETCH(x)\n"
  632. "#endif\n"
  633. "#define PUSH_VALUE(x) stack[sp++].value = x\n"
  634. "#define PUSH_ADDRESS(x) stack[sp++].address = x\n"
  635. "#define STACK_IS_EMPTY() (sp == 0)\n"
  636. "#define POP_VALUE() stack[--sp].value\n"
  637. "#define POP_ADDRESS() stack[--sp].address\n"
  638. "static convertible_t readDram(mmu_t* mmu, addr_t addr) {\n"
  639. " convertible_t data;\n"
  640. " data = DRAM_READ(mmu);\n"
  641. " mmu->m0 += 8;\n"
  642. " mmu->mx ^= addr;\n"
  643. " if((mmu->m0 & 255) == 128) {\n"
  644. " mmu->m1 = mmu->mx & 0xFFFFFF00;\n"
  645. " PREFETCH(mmu);\n"
  646. " }\n"
  647. " if((mmu->m0 & 255) == 0)\n"
  648. " mmu->m0 = mmu->m1;\n"
  649. " return data;\n"
  650. "}\n"
  651. "static inline __m128i sl_xor(__m128i tmp1) {\n"
  652. " __m128i tmp4;\n"
  653. " tmp4 = _mm_slli_si128(tmp1, 0x04);\n"
  654. " tmp1 = _mm_xor_si128(tmp1, tmp4);\n"
  655. " tmp4 = _mm_slli_si128(tmp4, 0x04);\n"
  656. " tmp1 = _mm_xor_si128(tmp1, tmp4);\n"
  657. " tmp4 = _mm_slli_si128(tmp4, 0x04);\n"
  658. " tmp1 = _mm_xor_si128(tmp1, tmp4);\n"
  659. " return tmp1;\n"
  660. "}\n"
  661. "#define AES_GENKEY_SUB(rcon) do { \\\n"
  662. " __m128i xout1 = _mm_aeskeygenassist_si128(xout2, rcon); \\\n"
  663. " xout1 = _mm_shuffle_epi32(xout1, 0xFF); \\\n"
  664. " xout0 = sl_xor(xout0); \\\n"
  665. " xout0 = _mm_xor_si128(xout0, xout1); \\\n"
  666. " xout1 = _mm_aeskeygenassist_si128(xout0, 0x00); \\\n"
  667. " xout1 = _mm_shuffle_epi32(xout1, 0xAA); \\\n"
  668. " xout2 = sl_xor(xout2); \\\n"
  669. " xout2 = _mm_xor_si128(xout2, xout1); } while(0)\n"
  670. "static inline void aes_genkey(const __m128i* memory, __m128i* k0, __m128i* k1, __m128i* k2, __m128i* k3, __m128i* k4, __m128i* k5, __m128i* k6, __m128i* k7, __m128i* k8, __m128i* k9) {\n"
  671. " __m128i xout0, xout2;\n"
  672. " xout0 = _mm_load_si128(memory);\n"
  673. " xout2 = _mm_load_si128(memory+1);\n"
  674. " *k0 = xout0;\n"
  675. " *k1 = xout2;\n"
  676. " AES_GENKEY_SUB(0x01);\n"
  677. " *k2 = xout0;\n"
  678. " *k3 = xout2;\n"
  679. " AES_GENKEY_SUB(0x02);\n"
  680. " *k4 = xout0;\n"
  681. " *k5 = xout2;\n"
  682. " AES_GENKEY_SUB(0x04);\n"
  683. " *k6 = xout0;\n"
  684. " *k7 = xout2;\n"
  685. " AES_GENKEY_SUB(0x08);\n"
  686. " *k8 = xout0;\n"
  687. " *k9 = xout2;\n"
  688. "}\n"
  689. "static inline void aes_round(__m128i key, __m128i* x0, __m128i* x1, __m128i* x2, __m128i* x3, __m128i* x4, __m128i* x5, __m128i* x6, __m128i* x7) {\n"
  690. " *x0 = _mm_aesenc_si128(*x0, key);\n"
  691. " *x1 = _mm_aesenc_si128(*x1, key);\n"
  692. " *x2 = _mm_aesenc_si128(*x2, key);\n"
  693. " *x3 = _mm_aesenc_si128(*x3, key);\n"
  694. " *x4 = _mm_aesenc_si128(*x4, key);\n"
  695. " *x5 = _mm_aesenc_si128(*x5, key);\n"
  696. " *x6 = _mm_aesenc_si128(*x6, key);\n"
  697. " *x7 = _mm_aesenc_si128(*x7, key);\n"
  698. "}\n"
  699. "static void aesInitialize(__m128i* key, __m128i* seed, __m128i* output, size_t count) {\n"
  700. " \n"
  701. " __m128i xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7;\n"
  702. " __m128i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9;\n"
  703. " \n"
  704. " aes_genkey(key, &k0, &k1, &k2, &k3, &k4, &k5, &k6, &k7, &k8, &k9);\n"
  705. " \n"
  706. " xin0 = _mm_load_si128(seed + 0);\n"
  707. " xin1 = _mm_load_si128(seed + 1);\n"
  708. " xin2 = _mm_load_si128(seed + 2);\n"
  709. " xin3 = _mm_load_si128(seed + 3);\n"
  710. " xin4 = _mm_load_si128(seed + 4);\n"
  711. " xin5 = _mm_load_si128(seed + 5);\n"
  712. " xin6 = _mm_load_si128(seed + 6);\n"
  713. " xin7 = _mm_load_si128(seed + 7);\n"
  714. " \n"
  715. " for (size_t i = 0; i < count / sizeof(__m128i); i += 8)\n"
  716. " {\n"
  717. " aes_round(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n"
  718. " aes_round(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n"
  719. " aes_round(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n"
  720. " aes_round(k3, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n"
  721. " aes_round(k4, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n"
  722. " aes_round(k5, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n"
  723. " aes_round(k6, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n"
  724. " aes_round(k7, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n"
  725. " aes_round(k8, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n"
  726. " aes_round(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);\n"
  727. " \n"
  728. " _mm_store_si128(output + i + 0, xin0);\n"
  729. " _mm_store_si128(output + i + 1, xin1);\n"
  730. " _mm_store_si128(output + i + 2, xin2);\n"
  731. " _mm_store_si128(output + i + 3, xin3);\n"
  732. " _mm_store_si128(output + i + 4, xin4);\n"
  733. " _mm_store_si128(output + i + 5, xin5);\n"
  734. " _mm_store_si128(output + i + 6, xin6);\n"
  735. " _mm_store_si128(output + i + 7, xin7);\n"
  736. " }\n"
  737. "}\n"))
  738. with sys.stdout as file:
  739. writeProlog(file)
  740. file.write("const byte aesKey[32] = {{ {0} }};\n".format(genBytes(32)))
  741. file.write("const byte aesSeed[128] = {{ {0} }};\n".format(genBytes(128)))
  742. writeMain(file)
  743. writeInitialValues(file)
  744. for i in range(PROGRAM_SIZE):
  745. writeCode(file, i, CodeSymbol(random.getrandbits(128)))
  746. if PROGRAM_SIZE > 0:
  747. file.write("\t\tgoto i_0;\n")
  748. writeEpilog(file)