dasm_mips.lua 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953
  1. ------------------------------------------------------------------------------
  2. -- DynASM MIPS module.
  3. --
  4. -- Copyright (C) 2005-2013 Mike Pall. All rights reserved.
  5. -- See dynasm.lua for full copyright notice.
  6. ------------------------------------------------------------------------------
  7. -- Module information:
  8. local _info = {
  9. arch = "mips",
  10. description = "DynASM MIPS module",
  11. version = "1.3.0",
  12. vernum = 10300,
  13. release = "2012-01-23",
  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. local bit = bit or require("bit")
  27. local band, shl, sar, tohex = bit.band, bit.lshift, bit.arshift, bit.tohex
  28. -- Inherited tables and callbacks.
  29. local g_opt, g_arch
  30. local wline, werror, wfatal, wwarn
  31. -- Action name list.
  32. -- CHECK: Keep this in sync with the C code!
  33. local action_names = {
  34. "STOP", "SECTION", "ESC", "REL_EXT",
  35. "ALIGN", "REL_LG", "LABEL_LG",
  36. "REL_PC", "LABEL_PC", "IMM",
  37. }
  38. -- Maximum number of section buffer positions for dasm_put().
  39. -- CHECK: Keep this in sync with the C code!
  40. local maxsecpos = 25 -- Keep this low, to avoid excessively long C lines.
  41. -- Action name -> action number.
  42. local map_action = {}
  43. for n,name in ipairs(action_names) do
  44. map_action[name] = n-1
  45. end
  46. -- Action list buffer.
  47. local actlist = {}
  48. -- Argument list for next dasm_put(). Start with offset 0 into action list.
  49. local actargs = { 0 }
  50. -- Current number of section buffer positions for dasm_put().
  51. local secpos = 1
  52. ------------------------------------------------------------------------------
  53. -- Dump action names and numbers.
  54. local function dumpactions(out)
  55. out:write("DynASM encoding engine action codes:\n")
  56. for n,name in ipairs(action_names) do
  57. local num = map_action[name]
  58. out:write(format(" %-10s %02X %d\n", name, num, num))
  59. end
  60. out:write("\n")
  61. end
  62. -- Write action list buffer as a huge static C array.
  63. local function writeactions(out, name)
  64. local nn = #actlist
  65. if nn == 0 then nn = 1; actlist[0] = map_action.STOP end
  66. out:write("static const unsigned int ", name, "[", nn, "] = {\n")
  67. for i = 1,nn-1 do
  68. assert(out:write("0x", tohex(actlist[i]), ",\n"))
  69. end
  70. assert(out:write("0x", tohex(actlist[nn]), "\n};\n\n"))
  71. end
  72. ------------------------------------------------------------------------------
  73. -- Add word to action list.
  74. local function wputxw(n)
  75. assert(n >= 0 and n <= 0xffffffff and n % 1 == 0, "word out of range")
  76. actlist[#actlist+1] = n
  77. end
  78. -- Add action to list with optional arg. Advance buffer pos, too.
  79. local function waction(action, val, a, num)
  80. local w = assert(map_action[action], "bad action name `"..action.."'")
  81. wputxw(0xff000000 + w * 0x10000 + (val or 0))
  82. if a then actargs[#actargs+1] = a end
  83. if a or num then secpos = secpos + (num or 1) end
  84. end
  85. -- Flush action list (intervening C code or buffer pos overflow).
  86. local function wflush(term)
  87. if #actlist == actargs[1] then return end -- Nothing to flush.
  88. if not term then waction("STOP") end -- Terminate action list.
  89. wline(format("dasm_put(Dst, %s);", concat(actargs, ", ")), true)
  90. actargs = { #actlist } -- Actionlist offset is 1st arg to next dasm_put().
  91. secpos = 1 -- The actionlist offset occupies a buffer position, too.
  92. end
  93. -- Put escaped word.
  94. local function wputw(n)
  95. if n >= 0xff000000 then waction("ESC") end
  96. wputxw(n)
  97. end
  98. -- Reserve position for word.
  99. local function wpos()
  100. local pos = #actlist+1
  101. actlist[pos] = ""
  102. return pos
  103. end
  104. -- Store word to reserved position.
  105. local function wputpos(pos, n)
  106. assert(n >= 0 and n <= 0xffffffff and n % 1 == 0, "word out of range")
  107. actlist[pos] = n
  108. end
  109. ------------------------------------------------------------------------------
  110. -- Global label name -> global label number. With auto assignment on 1st use.
  111. local next_global = 20
  112. local map_global = setmetatable({}, { __index = function(t, name)
  113. if not match(name, "^[%a_][%w_]*$") then werror("bad global label") end
  114. local n = next_global
  115. if n > 2047 then werror("too many global labels") end
  116. next_global = n + 1
  117. t[name] = n
  118. return n
  119. end})
  120. -- Dump global labels.
  121. local function dumpglobals(out, lvl)
  122. local t = {}
  123. for name, n in pairs(map_global) do t[n] = name end
  124. out:write("Global labels:\n")
  125. for i=20,next_global-1 do
  126. out:write(format(" %s\n", t[i]))
  127. end
  128. out:write("\n")
  129. end
  130. -- Write global label enum.
  131. local function writeglobals(out, prefix)
  132. local t = {}
  133. for name, n in pairs(map_global) do t[n] = name end
  134. out:write("enum {\n")
  135. for i=20,next_global-1 do
  136. out:write(" ", prefix, t[i], ",\n")
  137. end
  138. out:write(" ", prefix, "_MAX\n};\n")
  139. end
  140. -- Write global label names.
  141. local function writeglobalnames(out, name)
  142. local t = {}
  143. for name, n in pairs(map_global) do t[n] = name end
  144. out:write("static const char *const ", name, "[] = {\n")
  145. for i=20,next_global-1 do
  146. out:write(" \"", t[i], "\",\n")
  147. end
  148. out:write(" (const char *)0\n};\n")
  149. end
  150. ------------------------------------------------------------------------------
  151. -- Extern label name -> extern label number. With auto assignment on 1st use.
  152. local next_extern = 0
  153. local map_extern_ = {}
  154. local map_extern = setmetatable({}, { __index = function(t, name)
  155. -- No restrictions on the name for now.
  156. local n = next_extern
  157. if n > 2047 then werror("too many extern labels") end
  158. next_extern = n + 1
  159. t[name] = n
  160. map_extern_[n] = name
  161. return n
  162. end})
  163. -- Dump extern labels.
  164. local function dumpexterns(out, lvl)
  165. out:write("Extern labels:\n")
  166. for i=0,next_extern-1 do
  167. out:write(format(" %s\n", map_extern_[i]))
  168. end
  169. out:write("\n")
  170. end
  171. -- Write extern label names.
  172. local function writeexternnames(out, name)
  173. out:write("static const char *const ", name, "[] = {\n")
  174. for i=0,next_extern-1 do
  175. out:write(" \"", map_extern_[i], "\",\n")
  176. end
  177. out:write(" (const char *)0\n};\n")
  178. end
  179. ------------------------------------------------------------------------------
  180. -- Arch-specific maps.
  181. local map_archdef = { sp="r29", ra="r31" } -- Ext. register name -> int. name.
  182. local map_type = {} -- Type name -> { ctype, reg }
  183. local ctypenum = 0 -- Type number (for Dt... macros).
  184. -- Reverse defines for registers.
  185. function _M.revdef(s)
  186. if s == "r29" then return "sp"
  187. elseif s == "r31" then return "ra" end
  188. return s
  189. end
  190. ------------------------------------------------------------------------------
  191. -- Template strings for MIPS instructions.
  192. local map_op = {
  193. -- First-level opcodes.
  194. j_1 = "08000000J",
  195. jal_1 = "0c000000J",
  196. b_1 = "10000000B",
  197. beqz_2 = "10000000SB",
  198. beq_3 = "10000000STB",
  199. bnez_2 = "14000000SB",
  200. bne_3 = "14000000STB",
  201. blez_2 = "18000000SB",
  202. bgtz_2 = "1c000000SB",
  203. addi_3 = "20000000TSI",
  204. li_2 = "24000000TI",
  205. addiu_3 = "24000000TSI",
  206. slti_3 = "28000000TSI",
  207. sltiu_3 = "2c000000TSI",
  208. andi_3 = "30000000TSU",
  209. lu_2 = "34000000TU",
  210. ori_3 = "34000000TSU",
  211. xori_3 = "38000000TSU",
  212. lui_2 = "3c000000TU",
  213. beqzl_2 = "50000000SB",
  214. beql_3 = "50000000STB",
  215. bnezl_2 = "54000000SB",
  216. bnel_3 = "54000000STB",
  217. blezl_2 = "58000000SB",
  218. bgtzl_2 = "5c000000SB",
  219. lb_2 = "80000000TO",
  220. lh_2 = "84000000TO",
  221. lwl_2 = "88000000TO",
  222. lw_2 = "8c000000TO",
  223. lbu_2 = "90000000TO",
  224. lhu_2 = "94000000TO",
  225. lwr_2 = "98000000TO",
  226. sb_2 = "a0000000TO",
  227. sh_2 = "a4000000TO",
  228. swl_2 = "a8000000TO",
  229. sw_2 = "ac000000TO",
  230. swr_2 = "b8000000TO",
  231. cache_2 = "bc000000NO",
  232. ll_2 = "c0000000TO",
  233. lwc1_2 = "c4000000HO",
  234. pref_2 = "cc000000NO",
  235. ldc1_2 = "d4000000HO",
  236. sc_2 = "e0000000TO",
  237. swc1_2 = "e4000000HO",
  238. sdc1_2 = "f4000000HO",
  239. -- Opcode SPECIAL.
  240. nop_0 = "00000000",
  241. sll_3 = "00000000DTA",
  242. movf_2 = "00000001DS",
  243. movf_3 = "00000001DSC",
  244. movt_2 = "00010001DS",
  245. movt_3 = "00010001DSC",
  246. srl_3 = "00000002DTA",
  247. rotr_3 = "00200002DTA",
  248. sra_3 = "00000003DTA",
  249. sllv_3 = "00000004DTS",
  250. srlv_3 = "00000006DTS",
  251. rotrv_3 = "00000046DTS",
  252. srav_3 = "00000007DTS",
  253. jr_1 = "00000008S",
  254. jalr_1 = "0000f809S",
  255. jalr_2 = "00000009DS",
  256. movz_3 = "0000000aDST",
  257. movn_3 = "0000000bDST",
  258. syscall_0 = "0000000c",
  259. syscall_1 = "0000000cY",
  260. break_0 = "0000000d",
  261. break_1 = "0000000dY",
  262. sync_0 = "0000000f",
  263. mfhi_1 = "00000010D",
  264. mthi_1 = "00000011S",
  265. mflo_1 = "00000012D",
  266. mtlo_1 = "00000013S",
  267. mult_2 = "00000018ST",
  268. multu_2 = "00000019ST",
  269. div_2 = "0000001aST",
  270. divu_2 = "0000001bST",
  271. add_3 = "00000020DST",
  272. move_2 = "00000021DS",
  273. addu_3 = "00000021DST",
  274. sub_3 = "00000022DST",
  275. negu_2 = "00000023DT",
  276. subu_3 = "00000023DST",
  277. and_3 = "00000024DST",
  278. or_3 = "00000025DST",
  279. xor_3 = "00000026DST",
  280. not_2 = "00000027DS",
  281. nor_3 = "00000027DST",
  282. slt_3 = "0000002aDST",
  283. sltu_3 = "0000002bDST",
  284. tge_2 = "00000030ST",
  285. tge_3 = "00000030STZ",
  286. tgeu_2 = "00000031ST",
  287. tgeu_3 = "00000031STZ",
  288. tlt_2 = "00000032ST",
  289. tlt_3 = "00000032STZ",
  290. tltu_2 = "00000033ST",
  291. tltu_3 = "00000033STZ",
  292. teq_2 = "00000034ST",
  293. teq_3 = "00000034STZ",
  294. tne_2 = "00000036ST",
  295. tne_3 = "00000036STZ",
  296. -- Opcode REGIMM.
  297. bltz_2 = "04000000SB",
  298. bgez_2 = "04010000SB",
  299. bltzl_2 = "04020000SB",
  300. bgezl_2 = "04030000SB",
  301. tgei_2 = "04080000SI",
  302. tgeiu_2 = "04090000SI",
  303. tlti_2 = "040a0000SI",
  304. tltiu_2 = "040b0000SI",
  305. teqi_2 = "040c0000SI",
  306. tnei_2 = "040e0000SI",
  307. bltzal_2 = "04100000SB",
  308. bal_1 = "04110000B",
  309. bgezal_2 = "04110000SB",
  310. bltzall_2 = "04120000SB",
  311. bgezall_2 = "04130000SB",
  312. synci_1 = "041f0000O",
  313. -- Opcode SPECIAL2.
  314. madd_2 = "70000000ST",
  315. maddu_2 = "70000001ST",
  316. mul_3 = "70000002DST",
  317. msub_2 = "70000004ST",
  318. msubu_2 = "70000005ST",
  319. clz_2 = "70000020DS=",
  320. clo_2 = "70000021DS=",
  321. sdbbp_0 = "7000003f",
  322. sdbbp_1 = "7000003fY",
  323. -- Opcode SPECIAL3.
  324. ext_4 = "7c000000TSAM", -- Note: last arg is msbd = size-1
  325. ins_4 = "7c000004TSAM", -- Note: last arg is msb = pos+size-1
  326. wsbh_2 = "7c0000a0DT",
  327. seb_2 = "7c000420DT",
  328. seh_2 = "7c000620DT",
  329. rdhwr_2 = "7c00003bTD",
  330. -- Opcode COP0.
  331. mfc0_2 = "40000000TD",
  332. mfc0_3 = "40000000TDW",
  333. mtc0_2 = "40800000TD",
  334. mtc0_3 = "40800000TDW",
  335. rdpgpr_2 = "41400000DT",
  336. di_0 = "41606000",
  337. di_1 = "41606000T",
  338. ei_0 = "41606020",
  339. ei_1 = "41606020T",
  340. wrpgpr_2 = "41c00000DT",
  341. tlbr_0 = "42000001",
  342. tlbwi_0 = "42000002",
  343. tlbwr_0 = "42000006",
  344. tlbp_0 = "42000008",
  345. eret_0 = "42000018",
  346. deret_0 = "4200001f",
  347. wait_0 = "42000020",
  348. -- Opcode COP1.
  349. mfc1_2 = "44000000TG",
  350. cfc1_2 = "44400000TG",
  351. mfhc1_2 = "44600000TG",
  352. mtc1_2 = "44800000TG",
  353. ctc1_2 = "44c00000TG",
  354. mthc1_2 = "44e00000TG",
  355. bc1f_1 = "45000000B",
  356. bc1f_2 = "45000000CB",
  357. bc1t_1 = "45010000B",
  358. bc1t_2 = "45010000CB",
  359. bc1fl_1 = "45020000B",
  360. bc1fl_2 = "45020000CB",
  361. bc1tl_1 = "45030000B",
  362. bc1tl_2 = "45030000CB",
  363. ["add.s_3"] = "46000000FGH",
  364. ["sub.s_3"] = "46000001FGH",
  365. ["mul.s_3"] = "46000002FGH",
  366. ["div.s_3"] = "46000003FGH",
  367. ["sqrt.s_2"] = "46000004FG",
  368. ["abs.s_2"] = "46000005FG",
  369. ["mov.s_2"] = "46000006FG",
  370. ["neg.s_2"] = "46000007FG",
  371. ["round.l.s_2"] = "46000008FG",
  372. ["trunc.l.s_2"] = "46000009FG",
  373. ["ceil.l.s_2"] = "4600000aFG",
  374. ["floor.l.s_2"] = "4600000bFG",
  375. ["round.w.s_2"] = "4600000cFG",
  376. ["trunc.w.s_2"] = "4600000dFG",
  377. ["ceil.w.s_2"] = "4600000eFG",
  378. ["floor.w.s_2"] = "4600000fFG",
  379. ["movf.s_2"] = "46000011FG",
  380. ["movf.s_3"] = "46000011FGC",
  381. ["movt.s_2"] = "46010011FG",
  382. ["movt.s_3"] = "46010011FGC",
  383. ["movz.s_3"] = "46000012FGT",
  384. ["movn.s_3"] = "46000013FGT",
  385. ["recip.s_2"] = "46000015FG",
  386. ["rsqrt.s_2"] = "46000016FG",
  387. ["cvt.d.s_2"] = "46000021FG",
  388. ["cvt.w.s_2"] = "46000024FG",
  389. ["cvt.l.s_2"] = "46000025FG",
  390. ["cvt.ps.s_3"] = "46000026FGH",
  391. ["c.f.s_2"] = "46000030GH",
  392. ["c.f.s_3"] = "46000030VGH",
  393. ["c.un.s_2"] = "46000031GH",
  394. ["c.un.s_3"] = "46000031VGH",
  395. ["c.eq.s_2"] = "46000032GH",
  396. ["c.eq.s_3"] = "46000032VGH",
  397. ["c.ueq.s_2"] = "46000033GH",
  398. ["c.ueq.s_3"] = "46000033VGH",
  399. ["c.olt.s_2"] = "46000034GH",
  400. ["c.olt.s_3"] = "46000034VGH",
  401. ["c.ult.s_2"] = "46000035GH",
  402. ["c.ult.s_3"] = "46000035VGH",
  403. ["c.ole.s_2"] = "46000036GH",
  404. ["c.ole.s_3"] = "46000036VGH",
  405. ["c.ule.s_2"] = "46000037GH",
  406. ["c.ule.s_3"] = "46000037VGH",
  407. ["c.sf.s_2"] = "46000038GH",
  408. ["c.sf.s_3"] = "46000038VGH",
  409. ["c.ngle.s_2"] = "46000039GH",
  410. ["c.ngle.s_3"] = "46000039VGH",
  411. ["c.seq.s_2"] = "4600003aGH",
  412. ["c.seq.s_3"] = "4600003aVGH",
  413. ["c.ngl.s_2"] = "4600003bGH",
  414. ["c.ngl.s_3"] = "4600003bVGH",
  415. ["c.lt.s_2"] = "4600003cGH",
  416. ["c.lt.s_3"] = "4600003cVGH",
  417. ["c.nge.s_2"] = "4600003dGH",
  418. ["c.nge.s_3"] = "4600003dVGH",
  419. ["c.le.s_2"] = "4600003eGH",
  420. ["c.le.s_3"] = "4600003eVGH",
  421. ["c.ngt.s_2"] = "4600003fGH",
  422. ["c.ngt.s_3"] = "4600003fVGH",
  423. ["add.d_3"] = "46200000FGH",
  424. ["sub.d_3"] = "46200001FGH",
  425. ["mul.d_3"] = "46200002FGH",
  426. ["div.d_3"] = "46200003FGH",
  427. ["sqrt.d_2"] = "46200004FG",
  428. ["abs.d_2"] = "46200005FG",
  429. ["mov.d_2"] = "46200006FG",
  430. ["neg.d_2"] = "46200007FG",
  431. ["round.l.d_2"] = "46200008FG",
  432. ["trunc.l.d_2"] = "46200009FG",
  433. ["ceil.l.d_2"] = "4620000aFG",
  434. ["floor.l.d_2"] = "4620000bFG",
  435. ["round.w.d_2"] = "4620000cFG",
  436. ["trunc.w.d_2"] = "4620000dFG",
  437. ["ceil.w.d_2"] = "4620000eFG",
  438. ["floor.w.d_2"] = "4620000fFG",
  439. ["movf.d_2"] = "46200011FG",
  440. ["movf.d_3"] = "46200011FGC",
  441. ["movt.d_2"] = "46210011FG",
  442. ["movt.d_3"] = "46210011FGC",
  443. ["movz.d_3"] = "46200012FGT",
  444. ["movn.d_3"] = "46200013FGT",
  445. ["recip.d_2"] = "46200015FG",
  446. ["rsqrt.d_2"] = "46200016FG",
  447. ["cvt.s.d_2"] = "46200020FG",
  448. ["cvt.w.d_2"] = "46200024FG",
  449. ["cvt.l.d_2"] = "46200025FG",
  450. ["c.f.d_2"] = "46200030GH",
  451. ["c.f.d_3"] = "46200030VGH",
  452. ["c.un.d_2"] = "46200031GH",
  453. ["c.un.d_3"] = "46200031VGH",
  454. ["c.eq.d_2"] = "46200032GH",
  455. ["c.eq.d_3"] = "46200032VGH",
  456. ["c.ueq.d_2"] = "46200033GH",
  457. ["c.ueq.d_3"] = "46200033VGH",
  458. ["c.olt.d_2"] = "46200034GH",
  459. ["c.olt.d_3"] = "46200034VGH",
  460. ["c.ult.d_2"] = "46200035GH",
  461. ["c.ult.d_3"] = "46200035VGH",
  462. ["c.ole.d_2"] = "46200036GH",
  463. ["c.ole.d_3"] = "46200036VGH",
  464. ["c.ule.d_2"] = "46200037GH",
  465. ["c.ule.d_3"] = "46200037VGH",
  466. ["c.sf.d_2"] = "46200038GH",
  467. ["c.sf.d_3"] = "46200038VGH",
  468. ["c.ngle.d_2"] = "46200039GH",
  469. ["c.ngle.d_3"] = "46200039VGH",
  470. ["c.seq.d_2"] = "4620003aGH",
  471. ["c.seq.d_3"] = "4620003aVGH",
  472. ["c.ngl.d_2"] = "4620003bGH",
  473. ["c.ngl.d_3"] = "4620003bVGH",
  474. ["c.lt.d_2"] = "4620003cGH",
  475. ["c.lt.d_3"] = "4620003cVGH",
  476. ["c.nge.d_2"] = "4620003dGH",
  477. ["c.nge.d_3"] = "4620003dVGH",
  478. ["c.le.d_2"] = "4620003eGH",
  479. ["c.le.d_3"] = "4620003eVGH",
  480. ["c.ngt.d_2"] = "4620003fGH",
  481. ["c.ngt.d_3"] = "4620003fVGH",
  482. ["add.ps_3"] = "46c00000FGH",
  483. ["sub.ps_3"] = "46c00001FGH",
  484. ["mul.ps_3"] = "46c00002FGH",
  485. ["abs.ps_2"] = "46c00005FG",
  486. ["mov.ps_2"] = "46c00006FG",
  487. ["neg.ps_2"] = "46c00007FG",
  488. ["movf.ps_2"] = "46c00011FG",
  489. ["movf.ps_3"] = "46c00011FGC",
  490. ["movt.ps_2"] = "46c10011FG",
  491. ["movt.ps_3"] = "46c10011FGC",
  492. ["movz.ps_3"] = "46c00012FGT",
  493. ["movn.ps_3"] = "46c00013FGT",
  494. ["cvt.s.pu_2"] = "46c00020FG",
  495. ["cvt.s.pl_2"] = "46c00028FG",
  496. ["pll.ps_3"] = "46c0002cFGH",
  497. ["plu.ps_3"] = "46c0002dFGH",
  498. ["pul.ps_3"] = "46c0002eFGH",
  499. ["puu.ps_3"] = "46c0002fFGH",
  500. ["c.f.ps_2"] = "46c00030GH",
  501. ["c.f.ps_3"] = "46c00030VGH",
  502. ["c.un.ps_2"] = "46c00031GH",
  503. ["c.un.ps_3"] = "46c00031VGH",
  504. ["c.eq.ps_2"] = "46c00032GH",
  505. ["c.eq.ps_3"] = "46c00032VGH",
  506. ["c.ueq.ps_2"] = "46c00033GH",
  507. ["c.ueq.ps_3"] = "46c00033VGH",
  508. ["c.olt.ps_2"] = "46c00034GH",
  509. ["c.olt.ps_3"] = "46c00034VGH",
  510. ["c.ult.ps_2"] = "46c00035GH",
  511. ["c.ult.ps_3"] = "46c00035VGH",
  512. ["c.ole.ps_2"] = "46c00036GH",
  513. ["c.ole.ps_3"] = "46c00036VGH",
  514. ["c.ule.ps_2"] = "46c00037GH",
  515. ["c.ule.ps_3"] = "46c00037VGH",
  516. ["c.sf.ps_2"] = "46c00038GH",
  517. ["c.sf.ps_3"] = "46c00038VGH",
  518. ["c.ngle.ps_2"] = "46c00039GH",
  519. ["c.ngle.ps_3"] = "46c00039VGH",
  520. ["c.seq.ps_2"] = "46c0003aGH",
  521. ["c.seq.ps_3"] = "46c0003aVGH",
  522. ["c.ngl.ps_2"] = "46c0003bGH",
  523. ["c.ngl.ps_3"] = "46c0003bVGH",
  524. ["c.lt.ps_2"] = "46c0003cGH",
  525. ["c.lt.ps_3"] = "46c0003cVGH",
  526. ["c.nge.ps_2"] = "46c0003dGH",
  527. ["c.nge.ps_3"] = "46c0003dVGH",
  528. ["c.le.ps_2"] = "46c0003eGH",
  529. ["c.le.ps_3"] = "46c0003eVGH",
  530. ["c.ngt.ps_2"] = "46c0003fGH",
  531. ["c.ngt.ps_3"] = "46c0003fVGH",
  532. ["cvt.s.w_2"] = "46800020FG",
  533. ["cvt.d.w_2"] = "46800021FG",
  534. ["cvt.s.l_2"] = "46a00020FG",
  535. ["cvt.d.l_2"] = "46a00021FG",
  536. -- Opcode COP1X.
  537. lwxc1_2 = "4c000000FX",
  538. ldxc1_2 = "4c000001FX",
  539. luxc1_2 = "4c000005FX",
  540. swxc1_2 = "4c000008FX",
  541. sdxc1_2 = "4c000009FX",
  542. suxc1_2 = "4c00000dFX",
  543. prefx_2 = "4c00000fMX",
  544. ["alnv.ps_4"] = "4c00001eFGHS",
  545. ["madd.s_4"] = "4c000020FRGH",
  546. ["madd.d_4"] = "4c000021FRGH",
  547. ["madd.ps_4"] = "4c000026FRGH",
  548. ["msub.s_4"] = "4c000028FRGH",
  549. ["msub.d_4"] = "4c000029FRGH",
  550. ["msub.ps_4"] = "4c00002eFRGH",
  551. ["nmadd.s_4"] = "4c000030FRGH",
  552. ["nmadd.d_4"] = "4c000031FRGH",
  553. ["nmadd.ps_4"] = "4c000036FRGH",
  554. ["nmsub.s_4"] = "4c000038FRGH",
  555. ["nmsub.d_4"] = "4c000039FRGH",
  556. ["nmsub.ps_4"] = "4c00003eFRGH",
  557. }
  558. ------------------------------------------------------------------------------
  559. local function parse_gpr(expr)
  560. local tname, ovreg = match(expr, "^([%w_]+):(r[1-3]?[0-9])$")
  561. local tp = map_type[tname or expr]
  562. if tp then
  563. local reg = ovreg or tp.reg
  564. if not reg then
  565. werror("type `"..(tname or expr).."' needs a register override")
  566. end
  567. expr = reg
  568. end
  569. local r = match(expr, "^r([1-3]?[0-9])$")
  570. if r then
  571. r = tonumber(r)
  572. if r <= 31 then return r, tp end
  573. end
  574. werror("bad register name `"..expr.."'")
  575. end
  576. local function parse_fpr(expr)
  577. local r = match(expr, "^f([1-3]?[0-9])$")
  578. if r then
  579. r = tonumber(r)
  580. if r <= 31 then return r end
  581. end
  582. werror("bad register name `"..expr.."'")
  583. end
  584. local function parse_imm(imm, bits, shift, scale, signed)
  585. local n = tonumber(imm)
  586. if n then
  587. local m = sar(n, scale)
  588. if shl(m, scale) == n then
  589. if signed then
  590. local s = sar(m, bits-1)
  591. if s == 0 then return shl(m, shift)
  592. elseif s == -1 then return shl(m + shl(1, bits), shift) end
  593. else
  594. if sar(m, bits) == 0 then return shl(m, shift) end
  595. end
  596. end
  597. werror("out of range immediate `"..imm.."'")
  598. elseif match(imm, "^[rf]([1-3]?[0-9])$") or
  599. match(imm, "^([%w_]+):([rf][1-3]?[0-9])$") then
  600. werror("expected immediate operand, got register")
  601. else
  602. waction("IMM", (signed and 32768 or 0)+scale*1024+bits*32+shift, imm)
  603. return 0
  604. end
  605. end
  606. local function parse_disp(disp)
  607. local imm, reg = match(disp, "^(.*)%(([%w_:]+)%)$")
  608. if imm then
  609. local r = shl(parse_gpr(reg), 21)
  610. local extname = match(imm, "^extern%s+(%S+)$")
  611. if extname then
  612. waction("REL_EXT", map_extern[extname], nil, 1)
  613. return r
  614. else
  615. return r + parse_imm(imm, 16, 0, 0, true)
  616. end
  617. end
  618. local reg, tailr = match(disp, "^([%w_:]+)%s*(.*)$")
  619. if reg and tailr ~= "" then
  620. local r, tp = parse_gpr(reg)
  621. if tp then
  622. waction("IMM", 32768+16*32, format(tp.ctypefmt, tailr))
  623. return shl(r, 21)
  624. end
  625. end
  626. werror("bad displacement `"..disp.."'")
  627. end
  628. local function parse_index(idx)
  629. local rt, rs = match(idx, "^(.*)%(([%w_:]+)%)$")
  630. if rt then
  631. rt = parse_gpr(rt)
  632. rs = parse_gpr(rs)
  633. return shl(rt, 16) + shl(rs, 21)
  634. end
  635. werror("bad index `"..idx.."'")
  636. end
  637. local function parse_label(label, def)
  638. local prefix = sub(label, 1, 2)
  639. -- =>label (pc label reference)
  640. if prefix == "=>" then
  641. return "PC", 0, sub(label, 3)
  642. end
  643. -- ->name (global label reference)
  644. if prefix == "->" then
  645. return "LG", map_global[sub(label, 3)]
  646. end
  647. if def then
  648. -- [1-9] (local label definition)
  649. if match(label, "^[1-9]$") then
  650. return "LG", 10+tonumber(label)
  651. end
  652. else
  653. -- [<>][1-9] (local label reference)
  654. local dir, lnum = match(label, "^([<>])([1-9])$")
  655. if dir then -- Fwd: 1-9, Bkwd: 11-19.
  656. return "LG", lnum + (dir == ">" and 0 or 10)
  657. end
  658. -- extern label (extern label reference)
  659. local extname = match(label, "^extern%s+(%S+)$")
  660. if extname then
  661. return "EXT", map_extern[extname]
  662. end
  663. end
  664. werror("bad label `"..label.."'")
  665. end
  666. ------------------------------------------------------------------------------
  667. -- Handle opcodes defined with template strings.
  668. map_op[".template__"] = function(params, template, nparams)
  669. if not params then return sub(template, 9) end
  670. local op = tonumber(sub(template, 1, 8), 16)
  671. local n = 1
  672. -- Limit number of section buffer positions used by a single dasm_put().
  673. -- A single opcode needs a maximum of 2 positions (ins/ext).
  674. if secpos+2 > maxsecpos then wflush() end
  675. local pos = wpos()
  676. -- Process each character.
  677. for p in gmatch(sub(template, 9), ".") do
  678. if p == "D" then
  679. op = op + shl(parse_gpr(params[n]), 11); n = n + 1
  680. elseif p == "T" then
  681. op = op + shl(parse_gpr(params[n]), 16); n = n + 1
  682. elseif p == "S" then
  683. op = op + shl(parse_gpr(params[n]), 21); n = n + 1
  684. elseif p == "F" then
  685. op = op + shl(parse_fpr(params[n]), 6); n = n + 1
  686. elseif p == "G" then
  687. op = op + shl(parse_fpr(params[n]), 11); n = n + 1
  688. elseif p == "H" then
  689. op = op + shl(parse_fpr(params[n]), 16); n = n + 1
  690. elseif p == "R" then
  691. op = op + shl(parse_fpr(params[n]), 21); n = n + 1
  692. elseif p == "I" then
  693. op = op + parse_imm(params[n], 16, 0, 0, true); n = n + 1
  694. elseif p == "U" then
  695. op = op + parse_imm(params[n], 16, 0, 0, false); n = n + 1
  696. elseif p == "O" then
  697. op = op + parse_disp(params[n]); n = n + 1
  698. elseif p == "X" then
  699. op = op + parse_index(params[n]); n = n + 1
  700. elseif p == "B" or p == "J" then
  701. local mode, n, s = parse_label(params[n], false)
  702. if p == "B" then n = n + 2048 end
  703. waction("REL_"..mode, n, s, 1)
  704. n = n + 1
  705. elseif p == "A" then
  706. op = op + parse_imm(params[n], 5, 6, 0, false); n = n + 1
  707. elseif p == "M" then
  708. op = op + parse_imm(params[n], 5, 11, 0, false); n = n + 1
  709. elseif p == "N" then
  710. op = op + parse_imm(params[n], 5, 16, 0, false); n = n + 1
  711. elseif p == "C" then
  712. op = op + parse_imm(params[n], 3, 18, 0, false); n = n + 1
  713. elseif p == "V" then
  714. op = op + parse_imm(params[n], 3, 8, 0, false); n = n + 1
  715. elseif p == "W" then
  716. op = op + parse_imm(params[n], 3, 0, 0, false); n = n + 1
  717. elseif p == "Y" then
  718. op = op + parse_imm(params[n], 20, 6, 0, false); n = n + 1
  719. elseif p == "Z" then
  720. op = op + parse_imm(params[n], 10, 6, 0, false); n = n + 1
  721. elseif p == "=" then
  722. op = op + shl(band(op, 0xf800), 5) -- Copy D to T for clz, clo.
  723. else
  724. assert(false)
  725. end
  726. end
  727. wputpos(pos, op)
  728. end
  729. ------------------------------------------------------------------------------
  730. -- Pseudo-opcode to mark the position where the action list is to be emitted.
  731. map_op[".actionlist_1"] = function(params)
  732. if not params then return "cvar" end
  733. local name = params[1] -- No syntax check. You get to keep the pieces.
  734. wline(function(out) writeactions(out, name) end)
  735. end
  736. -- Pseudo-opcode to mark the position where the global enum is to be emitted.
  737. map_op[".globals_1"] = function(params)
  738. if not params then return "prefix" end
  739. local prefix = params[1] -- No syntax check. You get to keep the pieces.
  740. wline(function(out) writeglobals(out, prefix) end)
  741. end
  742. -- Pseudo-opcode to mark the position where the global names are to be emitted.
  743. map_op[".globalnames_1"] = function(params)
  744. if not params then return "cvar" end
  745. local name = params[1] -- No syntax check. You get to keep the pieces.
  746. wline(function(out) writeglobalnames(out, name) end)
  747. end
  748. -- Pseudo-opcode to mark the position where the extern names are to be emitted.
  749. map_op[".externnames_1"] = function(params)
  750. if not params then return "cvar" end
  751. local name = params[1] -- No syntax check. You get to keep the pieces.
  752. wline(function(out) writeexternnames(out, name) end)
  753. end
  754. ------------------------------------------------------------------------------
  755. -- Label pseudo-opcode (converted from trailing colon form).
  756. map_op[".label_1"] = function(params)
  757. if not params then return "[1-9] | ->global | =>pcexpr" end
  758. if secpos+1 > maxsecpos then wflush() end
  759. local mode, n, s = parse_label(params[1], true)
  760. if mode == "EXT" then werror("bad label definition") end
  761. waction("LABEL_"..mode, n, s, 1)
  762. end
  763. ------------------------------------------------------------------------------
  764. -- Pseudo-opcodes for data storage.
  765. map_op[".long_*"] = function(params)
  766. if not params then return "imm..." end
  767. for _,p in ipairs(params) do
  768. local n = tonumber(p)
  769. if not n then werror("bad immediate `"..p.."'") end
  770. if n < 0 then n = n + 2^32 end
  771. wputw(n)
  772. if secpos+2 > maxsecpos then wflush() end
  773. end
  774. end
  775. -- Alignment pseudo-opcode.
  776. map_op[".align_1"] = function(params)
  777. if not params then return "numpow2" end
  778. if secpos+1 > maxsecpos then wflush() end
  779. local align = tonumber(params[1])
  780. if align then
  781. local x = align
  782. -- Must be a power of 2 in the range (2 ... 256).
  783. for i=1,8 do
  784. x = x / 2
  785. if x == 1 then
  786. waction("ALIGN", align-1, nil, 1) -- Action byte is 2**n-1.
  787. return
  788. end
  789. end
  790. end
  791. werror("bad alignment")
  792. end
  793. ------------------------------------------------------------------------------
  794. -- Pseudo-opcode for (primitive) type definitions (map to C types).
  795. map_op[".type_3"] = function(params, nparams)
  796. if not params then
  797. return nparams == 2 and "name, ctype" or "name, ctype, reg"
  798. end
  799. local name, ctype, reg = params[1], params[2], params[3]
  800. if not match(name, "^[%a_][%w_]*$") then
  801. werror("bad type name `"..name.."'")
  802. end
  803. local tp = map_type[name]
  804. if tp then
  805. werror("duplicate type `"..name.."'")
  806. end
  807. -- Add #type to defines. A bit unclean to put it in map_archdef.
  808. map_archdef["#"..name] = "sizeof("..ctype..")"
  809. -- Add new type and emit shortcut define.
  810. local num = ctypenum + 1
  811. map_type[name] = {
  812. ctype = ctype,
  813. ctypefmt = format("Dt%X(%%s)", num),
  814. reg = reg,
  815. }
  816. wline(format("#define Dt%X(_V) (int)(ptrdiff_t)&(((%s *)0)_V)", num, ctype))
  817. ctypenum = num
  818. end
  819. map_op[".type_2"] = map_op[".type_3"]
  820. -- Dump type definitions.
  821. local function dumptypes(out, lvl)
  822. local t = {}
  823. for name in pairs(map_type) do t[#t+1] = name end
  824. sort(t)
  825. out:write("Type definitions:\n")
  826. for _,name in ipairs(t) do
  827. local tp = map_type[name]
  828. local reg = tp.reg or ""
  829. out:write(format(" %-20s %-20s %s\n", name, tp.ctype, reg))
  830. end
  831. out:write("\n")
  832. end
  833. ------------------------------------------------------------------------------
  834. -- Set the current section.
  835. function _M.section(num)
  836. waction("SECTION", num)
  837. wflush(true) -- SECTION is a terminal action.
  838. end
  839. ------------------------------------------------------------------------------
  840. -- Dump architecture description.
  841. function _M.dumparch(out)
  842. out:write(format("DynASM %s version %s, released %s\n\n",
  843. _info.arch, _info.version, _info.release))
  844. dumpactions(out)
  845. end
  846. -- Dump all user defined elements.
  847. function _M.dumpdef(out, lvl)
  848. dumptypes(out, lvl)
  849. dumpglobals(out, lvl)
  850. dumpexterns(out, lvl)
  851. end
  852. ------------------------------------------------------------------------------
  853. -- Pass callbacks from/to the DynASM core.
  854. function _M.passcb(wl, we, wf, ww)
  855. wline, werror, wfatal, wwarn = wl, we, wf, ww
  856. return wflush
  857. end
  858. -- Setup the arch-specific module.
  859. function _M.setup(arch, opt)
  860. g_arch, g_opt = arch, opt
  861. end
  862. -- Merge the core maps and the arch-specific maps.
  863. function _M.mergemaps(map_coreop, map_def)
  864. setmetatable(map_op, { __index = map_coreop })
  865. setmetatable(map_def, { __index = map_archdef })
  866. return map_op, map_def
  867. end
  868. return _M
  869. ------------------------------------------------------------------------------