dasm_ppc.lua 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230
  1. ------------------------------------------------------------------------------
  2. -- DynASM PPC module.
  3. --
  4. -- Copyright (C) 2005-2012 Mike Pall. All rights reserved.
  5. -- See dynasm.lua for full copyright notice.
  6. ------------------------------------------------------------------------------
  7. -- Module information:
  8. local _info = {
  9. arch = "ppc",
  10. description = "DynASM PPC module",
  11. version = "1.3.0",
  12. vernum = 10300,
  13. release = "2011-05-05",
  14. author = "Mike Pall",
  15. license = "MIT",
  16. }
  17. -- Exported glue functions for the arch-specific module.
  18. local _M = { _info = _info }
  19. -- Cache library functions.
  20. local type, tonumber, pairs, ipairs = type, tonumber, pairs, ipairs
  21. local assert, setmetatable = assert, setmetatable
  22. local _s = string
  23. local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
  24. local match, gmatch = _s.match, _s.gmatch
  25. local concat, sort = table.concat, table.sort
  26. -- Inherited tables and callbacks.
  27. local g_opt, g_arch
  28. local wline, werror, wfatal, wwarn
  29. -- Action name list.
  30. -- CHECK: Keep this in sync with the C code!
  31. local action_names = {
  32. "STOP", "SECTION", "ESC", "REL_EXT",
  33. "ALIGN", "REL_LG", "LABEL_LG",
  34. "REL_PC", "LABEL_PC", "IMM",
  35. }
  36. -- Maximum number of section buffer positions for dasm_put().
  37. -- CHECK: Keep this in sync with the C code!
  38. local maxsecpos = 25 -- Keep this low, to avoid excessively long C lines.
  39. -- Action name -> action number.
  40. local map_action = {}
  41. for n,name in ipairs(action_names) do
  42. map_action[name] = n-1
  43. end
  44. -- Action list buffer.
  45. local actlist = {}
  46. -- Argument list for next dasm_put(). Start with offset 0 into action list.
  47. local actargs = { 0 }
  48. -- Current number of section buffer positions for dasm_put().
  49. local secpos = 1
  50. ------------------------------------------------------------------------------
  51. -- Return 8 digit hex number.
  52. local function tohex(x)
  53. return sub(format("%08x", x), -8) -- Avoid 64 bit portability problem in Lua.
  54. end
  55. -- Dump action names and numbers.
  56. local function dumpactions(out)
  57. out:write("DynASM encoding engine action codes:\n")
  58. for n,name in ipairs(action_names) do
  59. local num = map_action[name]
  60. out:write(format(" %-10s %02X %d\n", name, num, num))
  61. end
  62. out:write("\n")
  63. end
  64. -- Write action list buffer as a huge static C array.
  65. local function writeactions(out, name)
  66. local nn = #actlist
  67. if nn == 0 then nn = 1; actlist[0] = map_action.STOP end
  68. out:write("static const unsigned int ", name, "[", nn, "] = {\n")
  69. for i = 1,nn-1 do
  70. assert(out:write("0x", tohex(actlist[i]), ",\n"))
  71. end
  72. assert(out:write("0x", tohex(actlist[nn]), "\n};\n\n"))
  73. end
  74. ------------------------------------------------------------------------------
  75. -- Add word to action list.
  76. local function wputxw(n)
  77. assert(n >= 0 and n <= 0xffffffff and n % 1 == 0, "word out of range")
  78. actlist[#actlist+1] = n
  79. end
  80. -- Add action to list with optional arg. Advance buffer pos, too.
  81. local function waction(action, val, a, num)
  82. local w = assert(map_action[action], "bad action name `"..action.."'")
  83. wputxw(w * 0x10000 + (val or 0))
  84. if a then actargs[#actargs+1] = a end
  85. if a or num then secpos = secpos + (num or 1) end
  86. end
  87. -- Flush action list (intervening C code or buffer pos overflow).
  88. local function wflush(term)
  89. if #actlist == actargs[1] then return end -- Nothing to flush.
  90. if not term then waction("STOP") end -- Terminate action list.
  91. wline(format("dasm_put(Dst, %s);", concat(actargs, ", ")), true)
  92. actargs = { #actlist } -- Actionlist offset is 1st arg to next dasm_put().
  93. secpos = 1 -- The actionlist offset occupies a buffer position, too.
  94. end
  95. -- Put escaped word.
  96. local function wputw(n)
  97. if n <= 0xffffff then waction("ESC") end
  98. wputxw(n)
  99. end
  100. -- Reserve position for word.
  101. local function wpos()
  102. local pos = #actlist+1
  103. actlist[pos] = ""
  104. return pos
  105. end
  106. -- Store word to reserved position.
  107. local function wputpos(pos, n)
  108. assert(n >= 0 and n <= 0xffffffff and n % 1 == 0, "word out of range")
  109. actlist[pos] = n
  110. end
  111. ------------------------------------------------------------------------------
  112. -- Global label name -> global label number. With auto assignment on 1st use.
  113. local next_global = 20
  114. local map_global = setmetatable({}, { __index = function(t, name)
  115. if not match(name, "^[%a_][%w_]*$") then werror("bad global label") end
  116. local n = next_global
  117. if n > 2047 then werror("too many global labels") end
  118. next_global = n + 1
  119. t[name] = n
  120. return n
  121. end})
  122. -- Dump global labels.
  123. local function dumpglobals(out, lvl)
  124. local t = {}
  125. for name, n in pairs(map_global) do t[n] = name end
  126. out:write("Global labels:\n")
  127. for i=20,next_global-1 do
  128. out:write(format(" %s\n", t[i]))
  129. end
  130. out:write("\n")
  131. end
  132. -- Write global label enum.
  133. local function writeglobals(out, prefix)
  134. local t = {}
  135. for name, n in pairs(map_global) do t[n] = name end
  136. out:write("enum {\n")
  137. for i=20,next_global-1 do
  138. out:write(" ", prefix, t[i], ",\n")
  139. end
  140. out:write(" ", prefix, "_MAX\n};\n")
  141. end
  142. -- Write global label names.
  143. local function writeglobalnames(out, name)
  144. local t = {}
  145. for name, n in pairs(map_global) do t[n] = name end
  146. out:write("static const char *const ", name, "[] = {\n")
  147. for i=20,next_global-1 do
  148. out:write(" \"", t[i], "\",\n")
  149. end
  150. out:write(" (const char *)0\n};\n")
  151. end
  152. ------------------------------------------------------------------------------
  153. -- Extern label name -> extern label number. With auto assignment on 1st use.
  154. local next_extern = 0
  155. local map_extern_ = {}
  156. local map_extern = setmetatable({}, { __index = function(t, name)
  157. -- No restrictions on the name for now.
  158. local n = next_extern
  159. if n > 2047 then werror("too many extern labels") end
  160. next_extern = n + 1
  161. t[name] = n
  162. map_extern_[n] = name
  163. return n
  164. end})
  165. -- Dump extern labels.
  166. local function dumpexterns(out, lvl)
  167. out:write("Extern labels:\n")
  168. for i=0,next_extern-1 do
  169. out:write(format(" %s\n", map_extern_[i]))
  170. end
  171. out:write("\n")
  172. end
  173. -- Write extern label names.
  174. local function writeexternnames(out, name)
  175. out:write("static const char *const ", name, "[] = {\n")
  176. for i=0,next_extern-1 do
  177. out:write(" \"", map_extern_[i], "\",\n")
  178. end
  179. out:write(" (const char *)0\n};\n")
  180. end
  181. ------------------------------------------------------------------------------
  182. -- Arch-specific maps.
  183. local map_archdef = { sp = "r1" } -- Ext. register name -> int. name.
  184. local map_type = {} -- Type name -> { ctype, reg }
  185. local ctypenum = 0 -- Type number (for Dt... macros).
  186. -- Reverse defines for registers.
  187. function _M.revdef(s)
  188. if s == "r1" then return "sp" end
  189. return s
  190. end
  191. local map_cond = {
  192. lt = 0, gt = 1, eq = 2, so = 3,
  193. ge = 4, le = 5, ne = 6, ns = 7,
  194. }
  195. ------------------------------------------------------------------------------
  196. -- Template strings for PPC instructions.
  197. local map_op = {
  198. tdi_3 = "08000000ARI",
  199. twi_3 = "0c000000ARI",
  200. mulli_3 = "1c000000RRI",
  201. subfic_3 = "20000000RRI",
  202. cmplwi_3 = "28000000XRU",
  203. cmplwi_2 = "28000000-RU",
  204. cmpldi_3 = "28200000XRU",
  205. cmpldi_2 = "28200000-RU",
  206. cmpwi_3 = "2c000000XRI",
  207. cmpwi_2 = "2c000000-RI",
  208. cmpdi_3 = "2c200000XRI",
  209. cmpdi_2 = "2c200000-RI",
  210. addic_3 = "30000000RRI",
  211. ["addic._3"] = "34000000RRI",
  212. addi_3 = "38000000RR0I",
  213. li_2 = "38000000RI",
  214. la_2 = "38000000RD",
  215. addis_3 = "3c000000RR0I",
  216. lis_2 = "3c000000RI",
  217. lus_2 = "3c000000RU",
  218. bc_3 = "40000000AAK",
  219. bcl_3 = "40000001AAK",
  220. bdnz_1 = "42000000K",
  221. bdz_1 = "42400000K",
  222. sc_0 = "44000000",
  223. b_1 = "48000000J",
  224. bl_1 = "48000001J",
  225. rlwimi_5 = "50000000RR~AAA.",
  226. rlwinm_5 = "54000000RR~AAA.",
  227. rlwnm_5 = "5c000000RR~RAA.",
  228. ori_3 = "60000000RR~U",
  229. nop_0 = "60000000",
  230. oris_3 = "64000000RR~U",
  231. xori_3 = "68000000RR~U",
  232. xoris_3 = "6c000000RR~U",
  233. ["andi._3"] = "70000000RR~U",
  234. ["andis._3"] = "74000000RR~U",
  235. lwz_2 = "80000000RD",
  236. lwzu_2 = "84000000RD",
  237. lbz_2 = "88000000RD",
  238. lbzu_2 = "8c000000RD",
  239. stw_2 = "90000000RD",
  240. stwu_2 = "94000000RD",
  241. stb_2 = "98000000RD",
  242. stbu_2 = "9c000000RD",
  243. lhz_2 = "a0000000RD",
  244. lhzu_2 = "a4000000RD",
  245. lha_2 = "a8000000RD",
  246. lhau_2 = "ac000000RD",
  247. sth_2 = "b0000000RD",
  248. sthu_2 = "b4000000RD",
  249. lmw_2 = "b8000000RD",
  250. stmw_2 = "bc000000RD",
  251. lfs_2 = "c0000000FD",
  252. lfsu_2 = "c4000000FD",
  253. lfd_2 = "c8000000FD",
  254. lfdu_2 = "cc000000FD",
  255. stfs_2 = "d0000000FD",
  256. stfsu_2 = "d4000000FD",
  257. stfd_2 = "d8000000FD",
  258. stfdu_2 = "dc000000FD",
  259. ld_2 = "e8000000RD", -- NYI: displacement must be divisible by 4.
  260. ldu_2 = "e8000001RD",
  261. lwa_2 = "e8000002RD",
  262. std_2 = "f8000000RD",
  263. stdu_2 = "f8000001RD",
  264. -- Primary opcode 19:
  265. mcrf_2 = "4c000000XX",
  266. isync_0 = "4c00012c",
  267. crnor_3 = "4c000042CCC",
  268. crnot_2 = "4c000042CC=",
  269. crandc_3 = "4c000102CCC",
  270. crxor_3 = "4c000182CCC",
  271. crclr_1 = "4c000182C==",
  272. crnand_3 = "4c0001c2CCC",
  273. crand_3 = "4c000202CCC",
  274. creqv_3 = "4c000242CCC",
  275. crset_1 = "4c000242C==",
  276. crorc_3 = "4c000342CCC",
  277. cror_3 = "4c000382CCC",
  278. crmove_2 = "4c000382CC=",
  279. bclr_2 = "4c000020AA",
  280. bclrl_2 = "4c000021AA",
  281. bcctr_2 = "4c000420AA",
  282. bcctrl_2 = "4c000421AA",
  283. blr_0 = "4e800020",
  284. blrl_0 = "4e800021",
  285. bctr_0 = "4e800420",
  286. bctrl_0 = "4e800421",
  287. -- Primary opcode 31:
  288. cmpw_3 = "7c000000XRR",
  289. cmpw_2 = "7c000000-RR",
  290. cmpd_3 = "7c200000XRR",
  291. cmpd_2 = "7c200000-RR",
  292. tw_3 = "7c000008ARR",
  293. subfc_3 = "7c000010RRR.",
  294. subc_3 = "7c000010RRR~.",
  295. mulhdu_3 = "7c000012RRR.",
  296. addc_3 = "7c000014RRR.",
  297. mulhwu_3 = "7c000016RRR.",
  298. isel_4 = "7c00001eRRRC",
  299. isellt_3 = "7c00001eRRR",
  300. iselgt_3 = "7c00005eRRR",
  301. iseleq_3 = "7c00009eRRR",
  302. mfcr_1 = "7c000026R",
  303. mtcrf_2 = "7c000120GR",
  304. -- NYI: mtocrf, mfocrf
  305. lwarx_3 = "7c000028RR0R",
  306. ldx_3 = "7c00002aRR0R",
  307. lwzx_3 = "7c00002eRR0R",
  308. slw_3 = "7c000030RR~R.",
  309. cntlzw_2 = "7c000034RR~",
  310. sld_3 = "7c000036RR~R.",
  311. and_3 = "7c000038RR~R.",
  312. cmplw_3 = "7c000040XRR",
  313. cmplw_2 = "7c000040-RR",
  314. cmpld_3 = "7c200040XRR",
  315. cmpld_2 = "7c200040-RR",
  316. subf_3 = "7c000050RRR.",
  317. sub_3 = "7c000050RRR~.",
  318. ldux_3 = "7c00006aRR0R",
  319. dcbst_2 = "7c00006c-RR",
  320. lwzux_3 = "7c00006eRR0R",
  321. cntlzd_2 = "7c000074RR~",
  322. andc_3 = "7c000078RR~R.",
  323. td_3 = "7c000088ARR",
  324. mulhd_3 = "7c000092RRR.",
  325. mulhw_3 = "7c000096RRR.",
  326. ldarx_3 = "7c0000a8RR0R",
  327. dcbf_2 = "7c0000ac-RR",
  328. lbzx_3 = "7c0000aeRR0R",
  329. neg_2 = "7c0000d0RR.",
  330. lbzux_3 = "7c0000eeRR0R",
  331. popcntb_2 = "7c0000f4RR~",
  332. not_2 = "7c0000f8RR~%.",
  333. nor_3 = "7c0000f8RR~R.",
  334. subfe_3 = "7c000110RRR.",
  335. sube_3 = "7c000110RRR~.",
  336. adde_3 = "7c000114RRR.",
  337. stdx_3 = "7c00012aRR0R",
  338. stwcx_3 = "7c00012cRR0R.",
  339. stwx_3 = "7c00012eRR0R",
  340. prtyw_2 = "7c000134RR~",
  341. stdux_3 = "7c00016aRR0R",
  342. stwux_3 = "7c00016eRR0R",
  343. prtyd_2 = "7c000174RR~",
  344. subfze_2 = "7c000190RR.",
  345. addze_2 = "7c000194RR.",
  346. stdcx_3 = "7c0001acRR0R.",
  347. stbx_3 = "7c0001aeRR0R",
  348. subfme_2 = "7c0001d0RR.",
  349. mulld_3 = "7c0001d2RRR.",
  350. addme_2 = "7c0001d4RR.",
  351. mullw_3 = "7c0001d6RRR.",
  352. dcbtst_2 = "7c0001ec-RR",
  353. stbux_3 = "7c0001eeRR0R",
  354. add_3 = "7c000214RRR.",
  355. dcbt_2 = "7c00022c-RR",
  356. lhzx_3 = "7c00022eRR0R",
  357. eqv_3 = "7c000238RR~R.",
  358. eciwx_3 = "7c00026cRR0R",
  359. lhzux_3 = "7c00026eRR0R",
  360. xor_3 = "7c000278RR~R.",
  361. mfspefscr_1 = "7c0082a6R",
  362. mfxer_1 = "7c0102a6R",
  363. mflr_1 = "7c0802a6R",
  364. mfctr_1 = "7c0902a6R",
  365. lwax_3 = "7c0002aaRR0R",
  366. lhax_3 = "7c0002aeRR0R",
  367. mftb_1 = "7c0c42e6R",
  368. mftbu_1 = "7c0d42e6R",
  369. lwaux_3 = "7c0002eaRR0R",
  370. lhaux_3 = "7c0002eeRR0R",
  371. sthx_3 = "7c00032eRR0R",
  372. orc_3 = "7c000338RR~R.",
  373. ecowx_3 = "7c00036cRR0R",
  374. sthux_3 = "7c00036eRR0R",
  375. or_3 = "7c000378RR~R.",
  376. mr_2 = "7c000378RR~%.",
  377. divdu_3 = "7c000392RRR.",
  378. divwu_3 = "7c000396RRR.",
  379. mtspefscr_1 = "7c0083a6R",
  380. mtxer_1 = "7c0103a6R",
  381. mtlr_1 = "7c0803a6R",
  382. mtctr_1 = "7c0903a6R",
  383. dcbi_2 = "7c0003ac-RR",
  384. nand_3 = "7c0003b8RR~R.",
  385. divd_3 = "7c0003d2RRR.",
  386. divw_3 = "7c0003d6RRR.",
  387. cmpb_3 = "7c0003f8RR~R.",
  388. mcrxr_1 = "7c000400X",
  389. subfco_3 = "7c000410RRR.",
  390. subco_3 = "7c000410RRR~.",
  391. addco_3 = "7c000414RRR.",
  392. ldbrx_3 = "7c000428RR0R",
  393. lswx_3 = "7c00042aRR0R",
  394. lwbrx_3 = "7c00042cRR0R",
  395. lfsx_3 = "7c00042eFR0R",
  396. srw_3 = "7c000430RR~R.",
  397. srd_3 = "7c000436RR~R.",
  398. subfo_3 = "7c000450RRR.",
  399. subo_3 = "7c000450RRR~.",
  400. lfsux_3 = "7c00046eFR0R",
  401. lswi_3 = "7c0004aaRR0A",
  402. sync_0 = "7c0004ac",
  403. lwsync_0 = "7c2004ac",
  404. ptesync_0 = "7c4004ac",
  405. lfdx_3 = "7c0004aeFR0R",
  406. nego_2 = "7c0004d0RR.",
  407. lfdux_3 = "7c0004eeFR0R",
  408. subfeo_3 = "7c000510RRR.",
  409. subeo_3 = "7c000510RRR~.",
  410. addeo_3 = "7c000514RRR.",
  411. stdbrx_3 = "7c000528RR0R",
  412. stswx_3 = "7c00052aRR0R",
  413. stwbrx_3 = "7c00052cRR0R",
  414. stfsx_3 = "7c00052eFR0R",
  415. stfsux_3 = "7c00056eFR0R",
  416. subfzeo_2 = "7c000590RR.",
  417. addzeo_2 = "7c000594RR.",
  418. stswi_3 = "7c0005aaRR0A",
  419. stfdx_3 = "7c0005aeFR0R",
  420. subfmeo_2 = "7c0005d0RR.",
  421. mulldo_3 = "7c0005d2RRR.",
  422. addmeo_2 = "7c0005d4RR.",
  423. mullwo_3 = "7c0005d6RRR.",
  424. dcba_2 = "7c0005ec-RR",
  425. stfdux_3 = "7c0005eeFR0R",
  426. addo_3 = "7c000614RRR.",
  427. lhbrx_3 = "7c00062cRR0R",
  428. sraw_3 = "7c000630RR~R.",
  429. srad_3 = "7c000634RR~R.",
  430. srawi_3 = "7c000670RR~A.",
  431. eieio_0 = "7c0006ac",
  432. lfiwax_3 = "7c0006aeFR0R",
  433. sthbrx_3 = "7c00072cRR0R",
  434. extsh_2 = "7c000734RR~.",
  435. extsb_2 = "7c000774RR~.",
  436. divduo_3 = "7c000792RRR.",
  437. divwou_3 = "7c000796RRR.",
  438. icbi_2 = "7c0007ac-RR",
  439. stfiwx_3 = "7c0007aeFR0R",
  440. extsw_2 = "7c0007b4RR~.",
  441. divdo_3 = "7c0007d2RRR.",
  442. divwo_3 = "7c0007d6RRR.",
  443. dcbz_2 = "7c0007ec-RR",
  444. -- Primary opcode 59:
  445. fdivs_3 = "ec000024FFF.",
  446. fsubs_3 = "ec000028FFF.",
  447. fadds_3 = "ec00002aFFF.",
  448. fsqrts_2 = "ec00002cF-F.",
  449. fres_2 = "ec000030F-F.",
  450. fmuls_3 = "ec000032FF-F.",
  451. frsqrtes_2 = "ec000034F-F.",
  452. fmsubs_4 = "ec000038FFFF~.",
  453. fmadds_4 = "ec00003aFFFF~.",
  454. fnmsubs_4 = "ec00003cFFFF~.",
  455. fnmadds_4 = "ec00003eFFFF~.",
  456. -- Primary opcode 63:
  457. fdiv_3 = "fc000024FFF.",
  458. fsub_3 = "fc000028FFF.",
  459. fadd_3 = "fc00002aFFF.",
  460. fsqrt_2 = "fc00002cF-F.",
  461. fsel_4 = "fc00002eFFFF~.",
  462. fre_2 = "fc000030F-F.",
  463. fmul_3 = "fc000032FF-F.",
  464. frsqrte_2 = "fc000034F-F.",
  465. fmsub_4 = "fc000038FFFF~.",
  466. fmadd_4 = "fc00003aFFFF~.",
  467. fnmsub_4 = "fc00003cFFFF~.",
  468. fnmadd_4 = "fc00003eFFFF~.",
  469. fcmpu_3 = "fc000000XFF",
  470. fcpsgn_3 = "fc000010FFF.",
  471. fcmpo_3 = "fc000040XFF",
  472. mtfsb1_1 = "fc00004cA",
  473. fneg_2 = "fc000050F-F.",
  474. mcrfs_2 = "fc000080XX",
  475. mtfsb0_1 = "fc00008cA",
  476. fmr_2 = "fc000090F-F.",
  477. frsp_2 = "fc000018F-F.",
  478. fctiw_2 = "fc00001cF-F.",
  479. fctiwz_2 = "fc00001eF-F.",
  480. mtfsfi_2 = "fc00010cAA", -- NYI: upshift.
  481. fnabs_2 = "fc000110F-F.",
  482. fabs_2 = "fc000210F-F.",
  483. frin_2 = "fc000310F-F.",
  484. friz_2 = "fc000350F-F.",
  485. frip_2 = "fc000390F-F.",
  486. frim_2 = "fc0003d0F-F.",
  487. mffs_1 = "fc00048eF.",
  488. -- NYI: mtfsf, mtfsb0, mtfsb1.
  489. fctid_2 = "fc00065cF-F.",
  490. fctidz_2 = "fc00065eF-F.",
  491. fcfid_2 = "fc00069cF-F.",
  492. -- Primary opcode 4, SPE APU extension:
  493. evaddw_3 = "10000200RRR",
  494. evaddiw_3 = "10000202RAR~",
  495. evsubw_3 = "10000204RRR~",
  496. evsubiw_3 = "10000206RAR~",
  497. evabs_2 = "10000208RR",
  498. evneg_2 = "10000209RR",
  499. evextsb_2 = "1000020aRR",
  500. evextsh_2 = "1000020bRR",
  501. evrndw_2 = "1000020cRR",
  502. evcntlzw_2 = "1000020dRR",
  503. evcntlsw_2 = "1000020eRR",
  504. brinc_3 = "1000020fRRR",
  505. evand_3 = "10000211RRR",
  506. evandc_3 = "10000212RRR",
  507. evxor_3 = "10000216RRR",
  508. evor_3 = "10000217RRR",
  509. evmr_2 = "10000217RR=",
  510. evnor_3 = "10000218RRR",
  511. evnot_2 = "10000218RR=",
  512. eveqv_3 = "10000219RRR",
  513. evorc_3 = "1000021bRRR",
  514. evnand_3 = "1000021eRRR",
  515. evsrwu_3 = "10000220RRR",
  516. evsrws_3 = "10000221RRR",
  517. evsrwiu_3 = "10000222RRA",
  518. evsrwis_3 = "10000223RRA",
  519. evslw_3 = "10000224RRR",
  520. evslwi_3 = "10000226RRA",
  521. evrlw_3 = "10000228RRR",
  522. evsplati_2 = "10000229RS",
  523. evrlwi_3 = "1000022aRRA",
  524. evsplatfi_2 = "1000022bRS",
  525. evmergehi_3 = "1000022cRRR",
  526. evmergelo_3 = "1000022dRRR",
  527. evcmpgtu_3 = "10000230XRR",
  528. evcmpgtu_2 = "10000230-RR",
  529. evcmpgts_3 = "10000231XRR",
  530. evcmpgts_2 = "10000231-RR",
  531. evcmpltu_3 = "10000232XRR",
  532. evcmpltu_2 = "10000232-RR",
  533. evcmplts_3 = "10000233XRR",
  534. evcmplts_2 = "10000233-RR",
  535. evcmpeq_3 = "10000234XRR",
  536. evcmpeq_2 = "10000234-RR",
  537. evsel_4 = "10000278RRRW",
  538. evsel_3 = "10000278RRR",
  539. evfsadd_3 = "10000280RRR",
  540. evfssub_3 = "10000281RRR",
  541. evfsabs_2 = "10000284RR",
  542. evfsnabs_2 = "10000285RR",
  543. evfsneg_2 = "10000286RR",
  544. evfsmul_3 = "10000288RRR",
  545. evfsdiv_3 = "10000289RRR",
  546. evfscmpgt_3 = "1000028cXRR",
  547. evfscmpgt_2 = "1000028c-RR",
  548. evfscmplt_3 = "1000028dXRR",
  549. evfscmplt_2 = "1000028d-RR",
  550. evfscmpeq_3 = "1000028eXRR",
  551. evfscmpeq_2 = "1000028e-RR",
  552. evfscfui_2 = "10000290R-R",
  553. evfscfsi_2 = "10000291R-R",
  554. evfscfuf_2 = "10000292R-R",
  555. evfscfsf_2 = "10000293R-R",
  556. evfsctui_2 = "10000294R-R",
  557. evfsctsi_2 = "10000295R-R",
  558. evfsctuf_2 = "10000296R-R",
  559. evfsctsf_2 = "10000297R-R",
  560. evfsctuiz_2 = "10000298R-R",
  561. evfsctsiz_2 = "1000029aR-R",
  562. evfststgt_3 = "1000029cXRR",
  563. evfststgt_2 = "1000029c-RR",
  564. evfststlt_3 = "1000029dXRR",
  565. evfststlt_2 = "1000029d-RR",
  566. evfststeq_3 = "1000029eXRR",
  567. evfststeq_2 = "1000029e-RR",
  568. efsadd_3 = "100002c0RRR",
  569. efssub_3 = "100002c1RRR",
  570. efsabs_2 = "100002c4RR",
  571. efsnabs_2 = "100002c5RR",
  572. efsneg_2 = "100002c6RR",
  573. efsmul_3 = "100002c8RRR",
  574. efsdiv_3 = "100002c9RRR",
  575. efscmpgt_3 = "100002ccXRR",
  576. efscmpgt_2 = "100002cc-RR",
  577. efscmplt_3 = "100002cdXRR",
  578. efscmplt_2 = "100002cd-RR",
  579. efscmpeq_3 = "100002ceXRR",
  580. efscmpeq_2 = "100002ce-RR",
  581. efscfd_2 = "100002cfR-R",
  582. efscfui_2 = "100002d0R-R",
  583. efscfsi_2 = "100002d1R-R",
  584. efscfuf_2 = "100002d2R-R",
  585. efscfsf_2 = "100002d3R-R",
  586. efsctui_2 = "100002d4R-R",
  587. efsctsi_2 = "100002d5R-R",
  588. efsctuf_2 = "100002d6R-R",
  589. efsctsf_2 = "100002d7R-R",
  590. efsctuiz_2 = "100002d8R-R",
  591. efsctsiz_2 = "100002daR-R",
  592. efststgt_3 = "100002dcXRR",
  593. efststgt_2 = "100002dc-RR",
  594. efststlt_3 = "100002ddXRR",
  595. efststlt_2 = "100002dd-RR",
  596. efststeq_3 = "100002deXRR",
  597. efststeq_2 = "100002de-RR",
  598. efdadd_3 = "100002e0RRR",
  599. efdsub_3 = "100002e1RRR",
  600. efdcfuid_2 = "100002e2R-R",
  601. efdcfsid_2 = "100002e3R-R",
  602. efdabs_2 = "100002e4RR",
  603. efdnabs_2 = "100002e5RR",
  604. efdneg_2 = "100002e6RR",
  605. efdmul_3 = "100002e8RRR",
  606. efddiv_3 = "100002e9RRR",
  607. efdctuidz_2 = "100002eaR-R",
  608. efdctsidz_2 = "100002ebR-R",
  609. efdcmpgt_3 = "100002ecXRR",
  610. efdcmpgt_2 = "100002ec-RR",
  611. efdcmplt_3 = "100002edXRR",
  612. efdcmplt_2 = "100002ed-RR",
  613. efdcmpeq_3 = "100002eeXRR",
  614. efdcmpeq_2 = "100002ee-RR",
  615. efdcfs_2 = "100002efR-R",
  616. efdcfui_2 = "100002f0R-R",
  617. efdcfsi_2 = "100002f1R-R",
  618. efdcfuf_2 = "100002f2R-R",
  619. efdcfsf_2 = "100002f3R-R",
  620. efdctui_2 = "100002f4R-R",
  621. efdctsi_2 = "100002f5R-R",
  622. efdctuf_2 = "100002f6R-R",
  623. efdctsf_2 = "100002f7R-R",
  624. efdctuiz_2 = "100002f8R-R",
  625. efdctsiz_2 = "100002faR-R",
  626. efdtstgt_3 = "100002fcXRR",
  627. efdtstgt_2 = "100002fc-RR",
  628. efdtstlt_3 = "100002fdXRR",
  629. efdtstlt_2 = "100002fd-RR",
  630. efdtsteq_3 = "100002feXRR",
  631. efdtsteq_2 = "100002fe-RR",
  632. evlddx_3 = "10000300RR0R",
  633. evldd_2 = "10000301R8",
  634. evldwx_3 = "10000302RR0R",
  635. evldw_2 = "10000303R8",
  636. evldhx_3 = "10000304RR0R",
  637. evldh_2 = "10000305R8",
  638. evlwhex_3 = "10000310RR0R",
  639. evlwhe_2 = "10000311R4",
  640. evlwhoux_3 = "10000314RR0R",
  641. evlwhou_2 = "10000315R4",
  642. evlwhosx_3 = "10000316RR0R",
  643. evlwhos_2 = "10000317R4",
  644. evstddx_3 = "10000320RR0R",
  645. evstdd_2 = "10000321R8",
  646. evstdwx_3 = "10000322RR0R",
  647. evstdw_2 = "10000323R8",
  648. evstdhx_3 = "10000324RR0R",
  649. evstdh_2 = "10000325R8",
  650. evstwhex_3 = "10000330RR0R",
  651. evstwhe_2 = "10000331R4",
  652. evstwhox_3 = "10000334RR0R",
  653. evstwho_2 = "10000335R4",
  654. evstwwex_3 = "10000338RR0R",
  655. evstwwe_2 = "10000339R4",
  656. evstwwox_3 = "1000033cRR0R",
  657. evstwwo_2 = "1000033dR4",
  658. evmhessf_3 = "10000403RRR",
  659. evmhossf_3 = "10000407RRR",
  660. evmheumi_3 = "10000408RRR",
  661. evmhesmi_3 = "10000409RRR",
  662. evmhesmf_3 = "1000040bRRR",
  663. evmhoumi_3 = "1000040cRRR",
  664. evmhosmi_3 = "1000040dRRR",
  665. evmhosmf_3 = "1000040fRRR",
  666. evmhessfa_3 = "10000423RRR",
  667. evmhossfa_3 = "10000427RRR",
  668. evmheumia_3 = "10000428RRR",
  669. evmhesmia_3 = "10000429RRR",
  670. evmhesmfa_3 = "1000042bRRR",
  671. evmhoumia_3 = "1000042cRRR",
  672. evmhosmia_3 = "1000042dRRR",
  673. evmhosmfa_3 = "1000042fRRR",
  674. evmwhssf_3 = "10000447RRR",
  675. evmwlumi_3 = "10000448RRR",
  676. evmwhumi_3 = "1000044cRRR",
  677. evmwhsmi_3 = "1000044dRRR",
  678. evmwhsmf_3 = "1000044fRRR",
  679. evmwssf_3 = "10000453RRR",
  680. evmwumi_3 = "10000458RRR",
  681. evmwsmi_3 = "10000459RRR",
  682. evmwsmf_3 = "1000045bRRR",
  683. evmwhssfa_3 = "10000467RRR",
  684. evmwlumia_3 = "10000468RRR",
  685. evmwhumia_3 = "1000046cRRR",
  686. evmwhsmia_3 = "1000046dRRR",
  687. evmwhsmfa_3 = "1000046fRRR",
  688. evmwssfa_3 = "10000473RRR",
  689. evmwumia_3 = "10000478RRR",
  690. evmwsmia_3 = "10000479RRR",
  691. evmwsmfa_3 = "1000047bRRR",
  692. evmra_2 = "100004c4RR",
  693. evdivws_3 = "100004c6RRR",
  694. evdivwu_3 = "100004c7RRR",
  695. evmwssfaa_3 = "10000553RRR",
  696. evmwumiaa_3 = "10000558RRR",
  697. evmwsmiaa_3 = "10000559RRR",
  698. evmwsmfaa_3 = "1000055bRRR",
  699. evmwssfan_3 = "100005d3RRR",
  700. evmwumian_3 = "100005d8RRR",
  701. evmwsmian_3 = "100005d9RRR",
  702. evmwsmfan_3 = "100005dbRRR",
  703. evmergehilo_3 = "1000022eRRR",
  704. evmergelohi_3 = "1000022fRRR",
  705. evlhhesplatx_3 = "10000308RR0R",
  706. evlhhesplat_2 = "10000309R2",
  707. evlhhousplatx_3 = "1000030cRR0R",
  708. evlhhousplat_2 = "1000030dR2",
  709. evlhhossplatx_3 = "1000030eRR0R",
  710. evlhhossplat_2 = "1000030fR2",
  711. evlwwsplatx_3 = "10000318RR0R",
  712. evlwwsplat_2 = "10000319R4",
  713. evlwhsplatx_3 = "1000031cRR0R",
  714. evlwhsplat_2 = "1000031dR4",
  715. evaddusiaaw_2 = "100004c0RR",
  716. evaddssiaaw_2 = "100004c1RR",
  717. evsubfusiaaw_2 = "100004c2RR",
  718. evsubfssiaaw_2 = "100004c3RR",
  719. evaddumiaaw_2 = "100004c8RR",
  720. evaddsmiaaw_2 = "100004c9RR",
  721. evsubfumiaaw_2 = "100004caRR",
  722. evsubfsmiaaw_2 = "100004cbRR",
  723. evmheusiaaw_3 = "10000500RRR",
  724. evmhessiaaw_3 = "10000501RRR",
  725. evmhessfaaw_3 = "10000503RRR",
  726. evmhousiaaw_3 = "10000504RRR",
  727. evmhossiaaw_3 = "10000505RRR",
  728. evmhossfaaw_3 = "10000507RRR",
  729. evmheumiaaw_3 = "10000508RRR",
  730. evmhesmiaaw_3 = "10000509RRR",
  731. evmhesmfaaw_3 = "1000050bRRR",
  732. evmhoumiaaw_3 = "1000050cRRR",
  733. evmhosmiaaw_3 = "1000050dRRR",
  734. evmhosmfaaw_3 = "1000050fRRR",
  735. evmhegumiaa_3 = "10000528RRR",
  736. evmhegsmiaa_3 = "10000529RRR",
  737. evmhegsmfaa_3 = "1000052bRRR",
  738. evmhogumiaa_3 = "1000052cRRR",
  739. evmhogsmiaa_3 = "1000052dRRR",
  740. evmhogsmfaa_3 = "1000052fRRR",
  741. evmwlusiaaw_3 = "10000540RRR",
  742. evmwlssiaaw_3 = "10000541RRR",
  743. evmwlumiaaw_3 = "10000548RRR",
  744. evmwlsmiaaw_3 = "10000549RRR",
  745. evmheusianw_3 = "10000580RRR",
  746. evmhessianw_3 = "10000581RRR",
  747. evmhessfanw_3 = "10000583RRR",
  748. evmhousianw_3 = "10000584RRR",
  749. evmhossianw_3 = "10000585RRR",
  750. evmhossfanw_3 = "10000587RRR",
  751. evmheumianw_3 = "10000588RRR",
  752. evmhesmianw_3 = "10000589RRR",
  753. evmhesmfanw_3 = "1000058bRRR",
  754. evmhoumianw_3 = "1000058cRRR",
  755. evmhosmianw_3 = "1000058dRRR",
  756. evmhosmfanw_3 = "1000058fRRR",
  757. evmhegumian_3 = "100005a8RRR",
  758. evmhegsmian_3 = "100005a9RRR",
  759. evmhegsmfan_3 = "100005abRRR",
  760. evmhogumian_3 = "100005acRRR",
  761. evmhogsmian_3 = "100005adRRR",
  762. evmhogsmfan_3 = "100005afRRR",
  763. evmwlusianw_3 = "100005c0RRR",
  764. evmwlssianw_3 = "100005c1RRR",
  765. evmwlumianw_3 = "100005c8RRR",
  766. evmwlsmianw_3 = "100005c9RRR",
  767. -- NYI: some 64 bit PowerPC and Book E instructions:
  768. -- rldicl, rldicr, rldic, rldimi, rldcl, rldcr, sradi, 64 bit ext. add/sub,
  769. -- extended addressing branches, cache management, loads and stores
  770. }
  771. -- Add mnemonics for "." variants.
  772. do
  773. local t = {}
  774. for k,v in pairs(map_op) do
  775. if sub(v, -1) == "." then
  776. local v2 = sub(v, 1, 7)..char(byte(v, 8)+1)..sub(v, 9, -2)
  777. t[sub(k, 1, -3).."."..sub(k, -2)] = v2
  778. end
  779. end
  780. for k,v in pairs(t) do
  781. map_op[k] = v
  782. end
  783. end
  784. -- Add more branch mnemonics.
  785. for cond,c in pairs(map_cond) do
  786. local b1 = "b"..cond
  787. local c1 = (c%4)*0x00010000 + (c < 4 and 0x01000000 or 0)
  788. -- bX[l]
  789. map_op[b1.."_1"] = tohex(0x40800000 + c1).."K"
  790. map_op[b1.."y_1"] = tohex(0x40a00000 + c1).."K"
  791. map_op[b1.."l_1"] = tohex(0x40800001 + c1).."K"
  792. map_op[b1.."_2"] = tohex(0x40800000 + c1).."-XK"
  793. map_op[b1.."y_2"] = tohex(0x40a00000 + c1).."-XK"
  794. map_op[b1.."l_2"] = tohex(0x40800001 + c1).."-XK"
  795. -- bXlr[l]
  796. map_op[b1.."lr_0"] = tohex(0x4c800020 + c1)
  797. map_op[b1.."lrl_0"] = tohex(0x4c800021 + c1)
  798. map_op[b1.."ctr_0"] = tohex(0x4c800420 + c1)
  799. map_op[b1.."ctrl_0"] = tohex(0x4c800421 + c1)
  800. -- bXctr[l]
  801. map_op[b1.."lr_1"] = tohex(0x4c800020 + c1).."-X"
  802. map_op[b1.."lrl_1"] = tohex(0x4c800021 + c1).."-X"
  803. map_op[b1.."ctr_1"] = tohex(0x4c800420 + c1).."-X"
  804. map_op[b1.."ctrl_1"] = tohex(0x4c800421 + c1).."-X"
  805. end
  806. ------------------------------------------------------------------------------
  807. local function parse_gpr(expr)
  808. local tname, ovreg = match(expr, "^([%w_]+):(r[1-3]?[0-9])$")
  809. local tp = map_type[tname or expr]
  810. if tp then
  811. local reg = ovreg or tp.reg
  812. if not reg then
  813. werror("type `"..(tname or expr).."' needs a register override")
  814. end
  815. expr = reg
  816. end
  817. local r = match(expr, "^r([1-3]?[0-9])$")
  818. if r then
  819. r = tonumber(r)
  820. if r <= 31 then return r, tp end
  821. end
  822. werror("bad register name `"..expr.."'")
  823. end
  824. local function parse_fpr(expr)
  825. local r = match(expr, "^f([1-3]?[0-9])$")
  826. if r then
  827. r = tonumber(r)
  828. if r <= 31 then return r end
  829. end
  830. werror("bad register name `"..expr.."'")
  831. end
  832. local function parse_cr(expr)
  833. local r = match(expr, "^cr([0-7])$")
  834. if r then return tonumber(r) end
  835. werror("bad condition register name `"..expr.."'")
  836. end
  837. local function parse_cond(expr)
  838. local r, cond = match(expr, "^4%*cr([0-7])%+(%w%w)$")
  839. if r then
  840. r = tonumber(r)
  841. local c = map_cond[cond]
  842. if c and c < 4 then return r*4+c end
  843. end
  844. werror("bad condition bit name `"..expr.."'")
  845. end
  846. local function parse_imm(imm, bits, shift, scale, signed)
  847. local n = tonumber(imm)
  848. if n then
  849. if n % 2^scale == 0 then
  850. n = n / 2^scale
  851. if signed then
  852. if n >= 0 then
  853. if n < 2^(bits-1) then return n*2^shift end
  854. else
  855. if n >= -(2^(bits-1))-1 then return (n+2^bits)*2^shift end
  856. end
  857. else
  858. if n >= 0 and n <= 2^bits-1 then return n*2^shift end
  859. end
  860. end
  861. werror("out of range immediate `"..imm.."'")
  862. elseif match(imm, "^r([1-3]?[0-9])$") or
  863. match(imm, "^([%w_]+):(r[1-3]?[0-9])$") then
  864. werror("expected immediate operand, got register")
  865. else
  866. waction("IMM", (signed and 32768 or 0)+scale*1024+bits*32+shift, imm)
  867. return 0
  868. end
  869. end
  870. local function parse_disp(disp)
  871. local imm, reg = match(disp, "^(.*)%(([%w_:]+)%)$")
  872. if imm then
  873. local r = parse_gpr(reg)
  874. if r == 0 then werror("cannot use r0 in displacement") end
  875. return r*65536 + parse_imm(imm, 16, 0, 0, true)
  876. end
  877. local reg, tailr = match(disp, "^([%w_:]+)%s*(.*)$")
  878. if reg and tailr ~= "" then
  879. local r, tp = parse_gpr(reg)
  880. if r == 0 then werror("cannot use r0 in displacement") end
  881. if tp then
  882. waction("IMM", 32768+16*32, format(tp.ctypefmt, tailr))
  883. return r*65536
  884. end
  885. end
  886. werror("bad displacement `"..disp.."'")
  887. end
  888. local function parse_u5disp(disp, scale)
  889. local imm, reg = match(disp, "^(.*)%(([%w_:]+)%)$")
  890. if imm then
  891. local r = parse_gpr(reg)
  892. if r == 0 then werror("cannot use r0 in displacement") end
  893. return r*65536 + parse_imm(imm, 5, 11, scale, false)
  894. end
  895. local reg, tailr = match(disp, "^([%w_:]+)%s*(.*)$")
  896. if reg and tailr ~= "" then
  897. local r, tp = parse_gpr(reg)
  898. if r == 0 then werror("cannot use r0 in displacement") end
  899. if tp then
  900. waction("IMM", scale*1024+5*32+11, format(tp.ctypefmt, tailr))
  901. return r*65536
  902. end
  903. end
  904. werror("bad displacement `"..disp.."'")
  905. end
  906. local function parse_label(label, def)
  907. local prefix = sub(label, 1, 2)
  908. -- =>label (pc label reference)
  909. if prefix == "=>" then
  910. return "PC", 0, sub(label, 3)
  911. end
  912. -- ->name (global label reference)
  913. if prefix == "->" then
  914. return "LG", map_global[sub(label, 3)]
  915. end
  916. if def then
  917. -- [1-9] (local label definition)
  918. if match(label, "^[1-9]$") then
  919. return "LG", 10+tonumber(label)
  920. end
  921. else
  922. -- [<>][1-9] (local label reference)
  923. local dir, lnum = match(label, "^([<>])([1-9])$")
  924. if dir then -- Fwd: 1-9, Bkwd: 11-19.
  925. return "LG", lnum + (dir == ">" and 0 or 10)
  926. end
  927. -- extern label (extern label reference)
  928. local extname = match(label, "^extern%s+(%S+)$")
  929. if extname then
  930. return "EXT", map_extern[extname]
  931. end
  932. end
  933. werror("bad label `"..label.."'")
  934. end
  935. ------------------------------------------------------------------------------
  936. -- Handle opcodes defined with template strings.
  937. map_op[".template__"] = function(params, template, nparams)
  938. if not params then return sub(template, 9) end
  939. local op = tonumber(sub(template, 1, 8), 16)
  940. local n, rs = 1, 26
  941. -- Limit number of section buffer positions used by a single dasm_put().
  942. -- A single opcode needs a maximum of 3 positions (rlwinm).
  943. if secpos+3 > maxsecpos then wflush() end
  944. local pos = wpos()
  945. -- Process each character.
  946. for p in gmatch(sub(template, 9), ".") do
  947. if p == "R" then
  948. rs = rs - 5; op = op + parse_gpr(params[n]) * 2^rs; n = n + 1
  949. elseif p == "F" then
  950. rs = rs - 5; op = op + parse_fpr(params[n]) * 2^rs; n = n + 1
  951. elseif p == "A" then
  952. rs = rs - 5; op = op + parse_imm(params[n], 5, rs, 0, false); n = n + 1
  953. elseif p == "S" then
  954. rs = rs - 5; op = op + parse_imm(params[n], 5, rs, 0, true); n = n + 1
  955. elseif p == "I" then
  956. op = op + parse_imm(params[n], 16, 0, 0, true); n = n + 1
  957. elseif p == "U" then
  958. op = op + parse_imm(params[n], 16, 0, 0, false); n = n + 1
  959. elseif p == "D" then
  960. op = op + parse_disp(params[n]); n = n + 1
  961. elseif p == "2" then
  962. op = op + parse_u5disp(params[n], 1); n = n + 1
  963. elseif p == "4" then
  964. op = op + parse_u5disp(params[n], 2); n = n + 1
  965. elseif p == "8" then
  966. op = op + parse_u5disp(params[n], 3); n = n + 1
  967. elseif p == "C" then
  968. rs = rs - 5; op = op + parse_cond(params[n]) * 2^rs; n = n + 1
  969. elseif p == "X" then
  970. rs = rs - 5; op = op + parse_cr(params[n]) * 2^(rs+2); n = n + 1
  971. elseif p == "W" then
  972. op = op + parse_cr(params[n]); n = n + 1
  973. elseif p == "G" then
  974. op = op + parse_imm(params[n], 8, 12, 0, false); n = n + 1
  975. elseif p == "J" or p == "K" then
  976. local mode, n, s = parse_label(params[n], false)
  977. if p == "K" then n = n + 2048 end
  978. waction("REL_"..mode, n, s, 1)
  979. n = n + 1
  980. elseif p == "0" then
  981. local mm = 2^rs
  982. local t = op % mm
  983. if ((op - t) / mm) % 32 == 0 then werror("cannot use r0") end
  984. elseif p == "=" or p == "%" then
  985. local mm = 2^(rs + (p == "%" and 5 or 0))
  986. local t = ((op - op % mm) / mm) % 32
  987. rs = rs - 5
  988. op = op + t * 2^rs
  989. elseif p == "~" then
  990. local mm = 2^rs
  991. local t1l = op % mm
  992. local t1h = (op - t1l) / mm
  993. local t2l = t1h % 32
  994. local t2h = (t1h - t2l) / 32
  995. local t3l = t2h % 32
  996. op = ((t2h - t3l + t2l)*32 + t3l)*mm + t1l
  997. elseif p == "-" then
  998. rs = rs - 5
  999. elseif p == "." then
  1000. -- Ignored.
  1001. else
  1002. assert(false)
  1003. end
  1004. end
  1005. wputpos(pos, op)
  1006. end
  1007. ------------------------------------------------------------------------------
  1008. -- Pseudo-opcode to mark the position where the action list is to be emitted.
  1009. map_op[".actionlist_1"] = function(params)
  1010. if not params then return "cvar" end
  1011. local name = params[1] -- No syntax check. You get to keep the pieces.
  1012. wline(function(out) writeactions(out, name) end)
  1013. end
  1014. -- Pseudo-opcode to mark the position where the global enum is to be emitted.
  1015. map_op[".globals_1"] = function(params)
  1016. if not params then return "prefix" end
  1017. local prefix = params[1] -- No syntax check. You get to keep the pieces.
  1018. wline(function(out) writeglobals(out, prefix) end)
  1019. end
  1020. -- Pseudo-opcode to mark the position where the global names are to be emitted.
  1021. map_op[".globalnames_1"] = function(params)
  1022. if not params then return "cvar" end
  1023. local name = params[1] -- No syntax check. You get to keep the pieces.
  1024. wline(function(out) writeglobalnames(out, name) end)
  1025. end
  1026. -- Pseudo-opcode to mark the position where the extern names are to be emitted.
  1027. map_op[".externnames_1"] = function(params)
  1028. if not params then return "cvar" end
  1029. local name = params[1] -- No syntax check. You get to keep the pieces.
  1030. wline(function(out) writeexternnames(out, name) end)
  1031. end
  1032. ------------------------------------------------------------------------------
  1033. -- Label pseudo-opcode (converted from trailing colon form).
  1034. map_op[".label_1"] = function(params)
  1035. if not params then return "[1-9] | ->global | =>pcexpr" end
  1036. if secpos+1 > maxsecpos then wflush() end
  1037. local mode, n, s = parse_label(params[1], true)
  1038. if mode == "EXT" then werror("bad label definition") end
  1039. waction("LABEL_"..mode, n, s, 1)
  1040. end
  1041. ------------------------------------------------------------------------------
  1042. -- Pseudo-opcodes for data storage.
  1043. map_op[".long_*"] = function(params)
  1044. if not params then return "imm..." end
  1045. for _,p in ipairs(params) do
  1046. local n = tonumber(p)
  1047. if not n then werror("bad immediate `"..p.."'") end
  1048. if n < 0 then n = n + 2^32 end
  1049. wputw(n)
  1050. if secpos+2 > maxsecpos then wflush() end
  1051. end
  1052. end
  1053. -- Alignment pseudo-opcode.
  1054. map_op[".align_1"] = function(params)
  1055. if not params then return "numpow2" end
  1056. if secpos+1 > maxsecpos then wflush() end
  1057. local align = tonumber(params[1])
  1058. if align then
  1059. local x = align
  1060. -- Must be a power of 2 in the range (2 ... 256).
  1061. for i=1,8 do
  1062. x = x / 2
  1063. if x == 1 then
  1064. waction("ALIGN", align-1, nil, 1) -- Action byte is 2**n-1.
  1065. return
  1066. end
  1067. end
  1068. end
  1069. werror("bad alignment")
  1070. end
  1071. ------------------------------------------------------------------------------
  1072. -- Pseudo-opcode for (primitive) type definitions (map to C types).
  1073. map_op[".type_3"] = function(params, nparams)
  1074. if not params then
  1075. return nparams == 2 and "name, ctype" or "name, ctype, reg"
  1076. end
  1077. local name, ctype, reg = params[1], params[2], params[3]
  1078. if not match(name, "^[%a_][%w_]*$") then
  1079. werror("bad type name `"..name.."'")
  1080. end
  1081. local tp = map_type[name]
  1082. if tp then
  1083. werror("duplicate type `"..name.."'")
  1084. end
  1085. -- Add #type to defines. A bit unclean to put it in map_archdef.
  1086. map_archdef["#"..name] = "sizeof("..ctype..")"
  1087. -- Add new type and emit shortcut define.
  1088. local num = ctypenum + 1
  1089. map_type[name] = {
  1090. ctype = ctype,
  1091. ctypefmt = format("Dt%X(%%s)", num),
  1092. reg = reg,
  1093. }
  1094. wline(format("#define Dt%X(_V) (int)(ptrdiff_t)&(((%s *)0)_V)", num, ctype))
  1095. ctypenum = num
  1096. end
  1097. map_op[".type_2"] = map_op[".type_3"]
  1098. -- Dump type definitions.
  1099. local function dumptypes(out, lvl)
  1100. local t = {}
  1101. for name in pairs(map_type) do t[#t+1] = name end
  1102. sort(t)
  1103. out:write("Type definitions:\n")
  1104. for _,name in ipairs(t) do
  1105. local tp = map_type[name]
  1106. local reg = tp.reg or ""
  1107. out:write(format(" %-20s %-20s %s\n", name, tp.ctype, reg))
  1108. end
  1109. out:write("\n")
  1110. end
  1111. ------------------------------------------------------------------------------
  1112. -- Set the current section.
  1113. function _M.section(num)
  1114. waction("SECTION", num)
  1115. wflush(true) -- SECTION is a terminal action.
  1116. end
  1117. ------------------------------------------------------------------------------
  1118. -- Dump architecture description.
  1119. function _M.dumparch(out)
  1120. out:write(format("DynASM %s version %s, released %s\n\n",
  1121. _info.arch, _info.version, _info.release))
  1122. dumpactions(out)
  1123. end
  1124. -- Dump all user defined elements.
  1125. function _M.dumpdef(out, lvl)
  1126. dumptypes(out, lvl)
  1127. dumpglobals(out, lvl)
  1128. dumpexterns(out, lvl)
  1129. end
  1130. ------------------------------------------------------------------------------
  1131. -- Pass callbacks from/to the DynASM core.
  1132. function _M.passcb(wl, we, wf, ww)
  1133. wline, werror, wfatal, wwarn = wl, we, wf, ww
  1134. return wflush
  1135. end
  1136. -- Setup the arch-specific module.
  1137. function _M.setup(arch, opt)
  1138. g_arch, g_opt = arch, opt
  1139. end
  1140. -- Merge the core maps and the arch-specific maps.
  1141. function _M.mergemaps(map_coreop, map_def)
  1142. setmetatable(map_op, { __index = map_coreop })
  1143. setmetatable(map_def, { __index = map_archdef })
  1144. return map_op, map_def
  1145. end
  1146. return _M
  1147. ------------------------------------------------------------------------------