gen_insnbench.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. #
  4. # AWL simulator - Generate instruction benchmark
  5. #
  6. # Copyright 2018 Michael Buesch <m@bues.ch>
  7. #
  8. # This program is free software; you can redistribute it and/or modify
  9. # it under the terms of the GNU General Public License as published by
  10. # the Free Software Foundation; either version 2 of the License, or
  11. # (at your option) any later version.
  12. #
  13. # This program is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. # GNU General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU General Public License along
  19. # with this program; if not, write to the Free Software Foundation, Inc.,
  20. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  21. #
  22. from __future__ import division, absolute_import, print_function, unicode_literals
  23. import sys
  24. import random
  25. import getopt
  26. insnCollection = (
  27. (
  28. ( "U", "BOOL"),
  29. ), (
  30. ( "UN", "BOOL"),
  31. ), (
  32. ( "O", "BOOL"),
  33. ), (
  34. ( "ON", "BOOL"),
  35. ), (
  36. ( "X", "BOOL"),
  37. ), (
  38. ( "XN", "BOOL"),
  39. ), (
  40. ( "U", "RANDOM_BOOL"),
  41. ), (
  42. ( "UN", "RANDOM_BOOL"),
  43. ), (
  44. ( "O", "RANDOM_BOOL"),
  45. ), (
  46. ( "ON", "RANDOM_BOOL"),
  47. ), (
  48. ( "X", "RANDOM_BOOL"),
  49. ), (
  50. ( "XN", "RANDOM_BOOL"),
  51. ), (
  52. ( "U(", ""),
  53. ( ")", ""),
  54. ), (
  55. ( "UN(", ""),
  56. ( ")", ""),
  57. ), (
  58. ( "O(", ""),
  59. ( ")", ""),
  60. ), (
  61. ( "ON(", ""),
  62. ( ")", ""),
  63. ), (
  64. ( "X(", ""),
  65. ( ")", ""),
  66. ), (
  67. ( "XN(", ""),
  68. ( ")", ""),
  69. ), (
  70. ( "=", "BOOL"),
  71. ), (
  72. ( "R", "BOOL"),
  73. ), (
  74. ( "S", "BOOL"),
  75. ), (
  76. ( "NOT", ""),
  77. ), (
  78. ( "SET", ""),
  79. ), (
  80. ( "CLR", ""),
  81. ), (
  82. ( "SAVE", ""),
  83. ), (
  84. ( "FN", "BOOL"),
  85. ), (
  86. ( "FP", "BOOL"),
  87. ), (
  88. ( "==I", ""),
  89. ), (
  90. ( "<>I", ""),
  91. ), (
  92. ( ">I", ""),
  93. ), (
  94. ( "<I", ""),
  95. ), (
  96. ( ">=I", ""),
  97. ), (
  98. ( "<=I", ""),
  99. ), (
  100. ( "==D", ""),
  101. ), (
  102. ( "<>D", ""),
  103. ), (
  104. ( ">D", ""),
  105. ), (
  106. ( "<D", ""),
  107. ), (
  108. ( ">=D", ""),
  109. ), (
  110. ( "<=D", ""),
  111. ), (
  112. ( "==R", ""),
  113. ), (
  114. ( "<>R", ""),
  115. ), (
  116. ( ">R", ""),
  117. ), (
  118. ( "<R", ""),
  119. ), (
  120. ( ">=R", ""),
  121. ), (
  122. ( "<=R", ""),
  123. ), (
  124. ( "L", "0"),
  125. ( "BTI", ""),
  126. ), (
  127. ( "ITB", ""),
  128. ), (
  129. ( "L", "0"),
  130. ( "BTD", ""),
  131. ), (
  132. ( "ITD", ""),
  133. ), (
  134. ( "DTB", ""),
  135. ), (
  136. ( "DTR", ""),
  137. ), (
  138. ( "INVI", ""),
  139. ), (
  140. ( "INVD", ""),
  141. ), (
  142. ( "NEGI", ""),
  143. ), (
  144. ( "NEGD", ""),
  145. ), (
  146. ( "NEGR", ""),
  147. ), (
  148. ( "TAW", ""),
  149. ), (
  150. ( "TAD", ""),
  151. ), (
  152. ( "RND", ""),
  153. ), (
  154. ( "TRUNC", ""),
  155. ), (
  156. ( "RND+", ""),
  157. ), (
  158. ( "RND-", ""),
  159. ), (
  160. ( "FR", "COUNTER"),
  161. ), (
  162. ( "L", "RANDOM_DWORD"),
  163. ), (
  164. ( "LC", "WORD"),
  165. ), (
  166. ( "ZV", "COUNTER"),
  167. ), (
  168. ( "ZR", "COUNTER"),
  169. ), (
  170. ( "AUF", "DB"),
  171. ), (
  172. ( "TDB", ""),
  173. ), (
  174. ( "SPA", "LABEL"),
  175. ), (
  176. ( "L", "0"),
  177. ( "SPL", "LABEL"),
  178. ), (
  179. ( "SPB", "LABEL"),
  180. ), (
  181. ( "SPBN", "LABEL"),
  182. ), (
  183. ( "SPBB", "LABEL"),
  184. ), (
  185. ( "SPBNB", "LABEL"),
  186. ), (
  187. ( "SPBI", "LABEL"),
  188. ), (
  189. ( "SPBIN", "LABEL"),
  190. ), (
  191. ( "SPO", "LABEL"),
  192. ), (
  193. ( "SPS", "LABEL"),
  194. ), (
  195. ( "SPZ", "LABEL"),
  196. ), (
  197. ( "SPN", "LABEL"),
  198. ), (
  199. ( "SPP", "LABEL"),
  200. ), (
  201. ( "SPM", "LABEL"),
  202. ), (
  203. ( "SPPZ", "LABEL"),
  204. ), (
  205. ( "SPMZ", "LABEL"),
  206. ), (
  207. ( "SPU", "LABEL"),
  208. ), (
  209. ( "LOOP", "LABEL"),
  210. ), (
  211. ( "+I", ""),
  212. ), (
  213. ( "-I", ""),
  214. ), (
  215. ( "*I", ""),
  216. ), (
  217. ( "/I", ""),
  218. ), (
  219. ( "+", "0"),
  220. ), (
  221. ( "+D", ""),
  222. ), (
  223. ( "-D", ""),
  224. ), (
  225. ( "*D", ""),
  226. ), (
  227. ( "/D", ""),
  228. ), (
  229. ( "MOD", ""),
  230. ), (
  231. ( "+R", ""),
  232. ), (
  233. ( "-R", ""),
  234. ), (
  235. ( "*R", ""),
  236. ), (
  237. ( "/R", ""),
  238. ), (
  239. ( "ABS", ""),
  240. ), (
  241. ( "SQR", ""),
  242. ), (
  243. ( "SQRT", ""),
  244. ), (
  245. ( "EXP", ""),
  246. ), (
  247. ( "LN", ""),
  248. ), (
  249. ( "SIN", ""),
  250. ), (
  251. ( "COS", ""),
  252. ), (
  253. ( "TAN", ""),
  254. ), (
  255. ( "ASIN", ""),
  256. ), (
  257. ( "ACOS", ""),
  258. ), (
  259. ( "ATAN", ""),
  260. ), (
  261. ( "LAR1", ""),
  262. ), (
  263. ( "LAR2", ""),
  264. ), (
  265. ( "T", "DWORD"),
  266. ), (
  267. ( "TAR", ""),
  268. ), (
  269. ( "TAR1", ""),
  270. ), (
  271. ( "TAR2", ""),
  272. ), (
  273. ( "MCR(", ""),
  274. ( "MCRA", ""),
  275. ( "MCRD", ""),
  276. ( ")MCR", ""),
  277. ), (
  278. ( "SSI", ""),
  279. ), (
  280. ( "SSD", ""),
  281. ), (
  282. ( "SLW", ""),
  283. ), (
  284. ( "SRW", ""),
  285. ), (
  286. ( "SLD", ""),
  287. ), (
  288. ( "SRD", ""),
  289. ), (
  290. ( "RLD", ""),
  291. ), (
  292. ( "RRD", ""),
  293. ), (
  294. ( "RLDA", ""),
  295. ), (
  296. ( "RRDA", ""),
  297. ), (
  298. ( "L", "0"),
  299. ( "SI", "TIMER"),
  300. ), (
  301. ( "L", "0"),
  302. ( "SV", "TIMER"),
  303. ), (
  304. ( "L", "0"),
  305. ( "SE", "TIMER"),
  306. ), (
  307. ( "L", "0"),
  308. ( "SS", "TIMER"),
  309. ), (
  310. ( "L", "0"),
  311. ( "SA", "TIMER"),
  312. ), (
  313. ( "UW", ""),
  314. ), (
  315. ( "OW", ""),
  316. ), (
  317. ( "XOW", ""),
  318. ), (
  319. ( "UD", ""),
  320. ), (
  321. ( "OD", ""),
  322. ), (
  323. ( "XOD", ""),
  324. ), (
  325. ( "TAK", ""),
  326. ), (
  327. ( "PUSH", ""),
  328. ), (
  329. ( "POP", ""),
  330. ), (
  331. ( "ENT", ""),
  332. ), (
  333. ( "LEAVE", ""),
  334. ), (
  335. ( "INC", "0"),
  336. ), (
  337. ( "DEC", "0"),
  338. ), (
  339. ( "+AR1", ""),
  340. ), (
  341. ( "+AR2", ""),
  342. ), (
  343. ( "BLD", "0"),
  344. ), (
  345. ( "NOP", "0"),
  346. ), (
  347. ( "CALL", "FC 42"),
  348. ), (
  349. ( "CALL", "FB 45, DB 45"),
  350. ), (
  351. ( "SET", ""),
  352. ), (
  353. ( "CC", "FC 43"),
  354. ), (
  355. ( "UC", "FC 44"),
  356. )
  357. )
  358. def out(data):
  359. print(data, end="\r\n")
  360. def error(msg):
  361. print(msg, file=sys.stderr)
  362. sys.exit(1)
  363. def usage(f=sys.stdout):
  364. print("gen_insnbench.py [OPTIONS]", file=f)
  365. print("", file=f)
  366. print(" -s|--seed SEED Set the randomizer seed. Default: 42", file=f)
  367. print(" -i|--iterations COUNT Set the number of iterations. Default: 10000", file=f)
  368. print(" -o|--one-cycle Generate CALL SFC 46 at the end of OB 1.", file=f)
  369. def getLabelName(index):
  370. if index < 0 or index >= 26 ** 4:
  371. raise ValueError("Label index out of range.")
  372. labelChars = [None] * 4
  373. for i in range(3, -1, -1):
  374. labelChars[i] = chr(ord("A") + (index % 26))
  375. index //= 26
  376. return "".join(labelChars)
  377. def main():
  378. opt_nrIterations = 10000
  379. opt_rngSeed = 42
  380. opt_oneCycle = False
  381. try:
  382. (opts, args) = getopt.getopt(sys.argv[1:],
  383. "hs:i:o",
  384. [ "help", "seed=", "iterations=", "one-cycle", ])
  385. except getopt.GetoptError as e:
  386. error(str(e))
  387. for (o, v) in opts:
  388. if o in ("-h", "--help"):
  389. usage()
  390. return 0
  391. if o in ("-s", "--seed"):
  392. try:
  393. opt_rngSeed = int(v)
  394. if opt_rngSeed < 0 or opt_rngSeed > 0xFFFFFFFF:
  395. raise ValueError
  396. except ValueError:
  397. error("Invalid RNG seed.")
  398. if o in ("-i", "--iterations"):
  399. try:
  400. opt_nrIterations = int(v)
  401. if opt_nrIterations < 0:
  402. raise ValueError
  403. except ValueError:
  404. error("Invalid number of iterations.")
  405. if o in ("-o", "--one-cycle"):
  406. opt_oneCycle = True
  407. if args:
  408. usage(f=sys.stderr)
  409. return 1
  410. rng = random.Random()
  411. rng.seed(opt_rngSeed)
  412. labelIndex = 0
  413. out("// iterations=%d" % opt_nrIterations)
  414. out("// seed=%d" % opt_rngSeed)
  415. out("ORGANIZATION_BLOCK OB 1")
  416. out("BEGIN")
  417. for i in range(opt_nrIterations):
  418. for insn, args in rng.choice(insnCollection):
  419. prefixStr = suffixStr = None
  420. if args == "":
  421. argsStr = ""
  422. elif args == "BOOL":
  423. argsStr = "M 0.4"
  424. elif args == "WORD":
  425. argsStr = "MW 0"
  426. elif args == "DWORD":
  427. argsStr = "MD 0"
  428. elif args == "TIMER":
  429. argsStr = "T 42"
  430. elif args == "COUNTER":
  431. argsStr = "Z 42"
  432. elif args == "DB":
  433. argsStr = "DB 42"
  434. elif args == "LABEL":
  435. try:
  436. labelName = getLabelName(labelIndex)
  437. except ValueError as e:
  438. error("Failed to generate jump label: %s\n"
  439. "The generated program is too big." % str(e))
  440. prefixStr = "\tL 0;\r\n\tCLR;"
  441. argsStr = labelName
  442. suffixStr = "%s:\tNOP 0;" % labelName
  443. labelIndex += 1
  444. elif args == "RANDOM_BOOL":
  445. argsStr = "TRUE" if rng.randint(0, 1) else "FALSE"
  446. elif args == "RANDOM_DWORD":
  447. argsStr = "DW#16#%08X" % rng.randint(0, 0xFFFFFFFF)
  448. else:
  449. argsStr = args
  450. if prefixStr:
  451. out(prefixStr)
  452. if argsStr:
  453. argsStr = " " + argsStr
  454. out("\t%s%s;" % (insn, argsStr))
  455. if suffixStr:
  456. out(suffixStr)
  457. if opt_oneCycle:
  458. out("\tCALL SFC 46 // STOP CPU")
  459. out("END_ORGANIZATION_BLOCK")
  460. out("\r\nDATA_BLOCK DB 42")
  461. out("\tSTRUCT")
  462. out("\t\tVAR : INT;")
  463. out("\tEND_STRUCT")
  464. out("BEGIN")
  465. out("END_DATA_BLOCK")
  466. out("\r\nFUNCTION FC 42 : VOID")
  467. out("BEGIN")
  468. out("\tBE;")
  469. out("END_FUNCTION")
  470. out("\r\nFUNCTION FC 43 : VOID")
  471. out("BEGIN")
  472. out("\tBEA")
  473. out("END_FUNCTION")
  474. out("\r\nFUNCTION FC 44 : VOID")
  475. out("BEGIN")
  476. out("\tSET;")
  477. out("\tBEB;")
  478. out("END_FUNCTION")
  479. out("\r\nFUNCTION_BLOCK FB 45")
  480. out("BEGIN")
  481. out("END_FUNCTION_BLOCK")
  482. out("\r\nDATA_BLOCK DB 45")
  483. out("\tFB 45")
  484. out("BEGIN")
  485. out("END_DATA_BLOCK")
  486. if __name__ == "__main__":
  487. sys.exit(main())