dasm_mips.lua 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181
  1. ------------------------------------------------------------------------------
  2. -- DynASM MIPS32/MIPS64 module.
  3. --
  4. -- Copyright (C) 2005-2021 Mike Pall. All rights reserved.
  5. -- See dynasm.lua for full copyright notice.
  6. ------------------------------------------------------------------------------
  7. local mips64 = mips64
  8. local mipsr6 = _map_def.MIPSR6
  9. -- Module information:
  10. local _info = {
  11. arch = mips64 and "mips64" or "mips",
  12. description = "DynASM MIPS32/MIPS64 module",
  13. version = "1.5.0",
  14. vernum = 10500,
  15. release = "2021-05-02",
  16. author = "Mike Pall",
  17. license = "MIT",
  18. }
  19. -- Exported glue functions for the arch-specific module.
  20. local _M = { _info = _info }
  21. -- Cache library functions.
  22. local type, tonumber, pairs, ipairs = type, tonumber, pairs, ipairs
  23. local assert, setmetatable = assert, setmetatable
  24. local _s = string
  25. local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
  26. local match, gmatch = _s.match, _s.gmatch
  27. local concat, sort = table.concat, table.sort
  28. local bit = bit or require("bit")
  29. local band, shl, shr, sar = bit.band, bit.lshift, bit.rshift, bit.arshift
  30. local tohex = bit.tohex
  31. -- Inherited tables and callbacks.
  32. local g_opt, g_arch
  33. local wline, werror, wfatal, wwarn
  34. -- Action name list.
  35. -- CHECK: Keep this in sync with the C code!
  36. local action_names = {
  37. "STOP", "SECTION", "ESC", "REL_EXT",
  38. "ALIGN", "REL_LG", "LABEL_LG",
  39. "REL_PC", "LABEL_PC", "IMM", "IMMS",
  40. }
  41. -- Maximum number of section buffer positions for dasm_put().
  42. -- CHECK: Keep this in sync with the C code!
  43. local maxsecpos = 25 -- Keep this low, to avoid excessively long C lines.
  44. -- Action name -> action number.
  45. local map_action = {}
  46. for n,name in ipairs(action_names) do
  47. map_action[name] = n-1
  48. end
  49. -- Action list buffer.
  50. local actlist = {}
  51. -- Argument list for next dasm_put(). Start with offset 0 into action list.
  52. local actargs = { 0 }
  53. -- Current number of section buffer positions for dasm_put().
  54. local secpos = 1
  55. ------------------------------------------------------------------------------
  56. -- Dump action names and numbers.
  57. local function dumpactions(out)
  58. out:write("DynASM encoding engine action codes:\n")
  59. for n,name in ipairs(action_names) do
  60. local num = map_action[name]
  61. out:write(format(" %-10s %02X %d\n", name, num, num))
  62. end
  63. out:write("\n")
  64. end
  65. -- Write action list buffer as a huge static C array.
  66. local function writeactions(out, name)
  67. local nn = #actlist
  68. if nn == 0 then nn = 1; actlist[0] = map_action.STOP end
  69. out:write("static const unsigned int ", name, "[", nn, "] = {\n")
  70. for i = 1,nn-1 do
  71. assert(out:write("0x", tohex(actlist[i]), ",\n"))
  72. end
  73. assert(out:write("0x", tohex(actlist[nn]), "\n};\n\n"))
  74. end
  75. ------------------------------------------------------------------------------
  76. -- Add word to action list.
  77. local function wputxw(n)
  78. assert(n >= 0 and n <= 0xffffffff and n % 1 == 0, "word out of range")
  79. actlist[#actlist+1] = n
  80. end
  81. -- Add action to list with optional arg. Advance buffer pos, too.
  82. local function waction(action, val, a, num)
  83. local w = assert(map_action[action], "bad action name `"..action.."'")
  84. wputxw(0xff000000 + w * 0x10000 + (val or 0))
  85. if a then actargs[#actargs+1] = a end
  86. if a or num then secpos = secpos + (num or 1) end
  87. end
  88. -- Flush action list (intervening C code or buffer pos overflow).
  89. local function wflush(term)
  90. if #actlist == actargs[1] then return end -- Nothing to flush.
  91. if not term then waction("STOP") end -- Terminate action list.
  92. wline(format("dasm_put(Dst, %s);", concat(actargs, ", ")), true)
  93. actargs = { #actlist } -- Actionlist offset is 1st arg to next dasm_put().
  94. secpos = 1 -- The actionlist offset occupies a buffer position, too.
  95. end
  96. -- Put escaped word.
  97. local function wputw(n)
  98. if n >= 0xff000000 then waction("ESC") end
  99. wputxw(n)
  100. end
  101. -- Reserve position for word.
  102. local function wpos()
  103. local pos = #actlist+1
  104. actlist[pos] = ""
  105. return pos
  106. end
  107. -- Store word to reserved position.
  108. local function wputpos(pos, n)
  109. assert(n >= 0 and n <= 0xffffffff and n % 1 == 0, "word out of range")
  110. actlist[pos] = n
  111. end
  112. ------------------------------------------------------------------------------
  113. -- Global label name -> global label number. With auto assignment on 1st use.
  114. local next_global = 20
  115. local map_global = setmetatable({}, { __index = function(t, name)
  116. if not match(name, "^[%a_][%w_]*$") then werror("bad global label") end
  117. local n = next_global
  118. if n > 2047 then werror("too many global labels") end
  119. next_global = n + 1
  120. t[name] = n
  121. return n
  122. end})
  123. -- Dump global labels.
  124. local function dumpglobals(out, lvl)
  125. local t = {}
  126. for name, n in pairs(map_global) do t[n] = name end
  127. out:write("Global labels:\n")
  128. for i=20,next_global-1 do
  129. out:write(format(" %s\n", t[i]))
  130. end
  131. out:write("\n")
  132. end
  133. -- Write global label enum.
  134. local function writeglobals(out, prefix)
  135. local t = {}
  136. for name, n in pairs(map_global) do t[n] = name end
  137. out:write("enum {\n")
  138. for i=20,next_global-1 do
  139. out:write(" ", prefix, t[i], ",\n")
  140. end
  141. out:write(" ", prefix, "_MAX\n};\n")
  142. end
  143. -- Write global label names.
  144. local function writeglobalnames(out, name)
  145. local t = {}
  146. for name, n in pairs(map_global) do t[n] = name end
  147. out:write("static const char *const ", name, "[] = {\n")
  148. for i=20,next_global-1 do
  149. out:write(" \"", t[i], "\",\n")
  150. end
  151. out:write(" (const char *)0\n};\n")
  152. end
  153. ------------------------------------------------------------------------------
  154. -- Extern label name -> extern label number. With auto assignment on 1st use.
  155. local next_extern = 0
  156. local map_extern_ = {}
  157. local map_extern = setmetatable({}, { __index = function(t, name)
  158. -- No restrictions on the name for now.
  159. local n = next_extern
  160. if n > 2047 then werror("too many extern labels") end
  161. next_extern = n + 1
  162. t[name] = n
  163. map_extern_[n] = name
  164. return n
  165. end})
  166. -- Dump extern labels.
  167. local function dumpexterns(out, lvl)
  168. out:write("Extern labels:\n")
  169. for i=0,next_extern-1 do
  170. out:write(format(" %s\n", map_extern_[i]))
  171. end
  172. out:write("\n")
  173. end
  174. -- Write extern label names.
  175. local function writeexternnames(out, name)
  176. out:write("static const char *const ", name, "[] = {\n")
  177. for i=0,next_extern-1 do
  178. out:write(" \"", map_extern_[i], "\",\n")
  179. end
  180. out:write(" (const char *)0\n};\n")
  181. end
  182. ------------------------------------------------------------------------------
  183. -- Arch-specific maps.
  184. local map_archdef = { sp="r29", ra="r31" } -- Ext. register name -> int. name.
  185. local map_type = {} -- Type name -> { ctype, reg }
  186. local ctypenum = 0 -- Type number (for Dt... macros).
  187. -- Reverse defines for registers.
  188. function _M.revdef(s)
  189. if s == "r29" then return "sp"
  190. elseif s == "r31" then return "ra" end
  191. return s
  192. end
  193. ------------------------------------------------------------------------------
  194. -- Template strings for MIPS instructions.
  195. local map_op = {
  196. -- First-level opcodes.
  197. j_1 = "08000000J",
  198. jal_1 = "0c000000J",
  199. b_1 = "10000000B",
  200. beqz_2 = "10000000SB",
  201. beq_3 = "10000000STB",
  202. bnez_2 = "14000000SB",
  203. bne_3 = "14000000STB",
  204. blez_2 = "18000000SB",
  205. bgtz_2 = "1c000000SB",
  206. li_2 = "24000000TI",
  207. addiu_3 = "24000000TSI",
  208. slti_3 = "28000000TSI",
  209. sltiu_3 = "2c000000TSI",
  210. andi_3 = "30000000TSU",
  211. lu_2 = "34000000TU",
  212. ori_3 = "34000000TSU",
  213. xori_3 = "38000000TSU",
  214. lui_2 = "3c000000TU",
  215. daddiu_3 = mips64 and "64000000TSI",
  216. ldl_2 = mips64 and "68000000TO",
  217. ldr_2 = mips64 and "6c000000TO",
  218. lb_2 = "80000000TO",
  219. lh_2 = "84000000TO",
  220. lw_2 = "8c000000TO",
  221. lbu_2 = "90000000TO",
  222. lhu_2 = "94000000TO",
  223. lwu_2 = mips64 and "9c000000TO",
  224. sb_2 = "a0000000TO",
  225. sh_2 = "a4000000TO",
  226. sw_2 = "ac000000TO",
  227. lwc1_2 = "c4000000HO",
  228. ldc1_2 = "d4000000HO",
  229. ld_2 = mips64 and "dc000000TO",
  230. swc1_2 = "e4000000HO",
  231. sdc1_2 = "f4000000HO",
  232. sd_2 = mips64 and "fc000000TO",
  233. -- Opcode SPECIAL.
  234. nop_0 = "00000000",
  235. sll_3 = "00000000DTA",
  236. sextw_2 = "00000000DT",
  237. srl_3 = "00000002DTA",
  238. rotr_3 = "00200002DTA",
  239. sra_3 = "00000003DTA",
  240. sllv_3 = "00000004DTS",
  241. srlv_3 = "00000006DTS",
  242. rotrv_3 = "00000046DTS",
  243. drotrv_3 = mips64 and "00000056DTS",
  244. srav_3 = "00000007DTS",
  245. jalr_1 = "0000f809S",
  246. jalr_2 = "00000009DS",
  247. syscall_0 = "0000000c",
  248. syscall_1 = "0000000cY",
  249. break_0 = "0000000d",
  250. break_1 = "0000000dY",
  251. sync_0 = "0000000f",
  252. dsllv_3 = mips64 and "00000014DTS",
  253. dsrlv_3 = mips64 and "00000016DTS",
  254. dsrav_3 = mips64 and "00000017DTS",
  255. add_3 = "00000020DST",
  256. move_2 = mips64 and "00000025DS" or "00000021DS",
  257. addu_3 = "00000021DST",
  258. sub_3 = "00000022DST",
  259. negu_2 = mips64 and "0000002fDT" or "00000023DT",
  260. subu_3 = "00000023DST",
  261. and_3 = "00000024DST",
  262. or_3 = "00000025DST",
  263. xor_3 = "00000026DST",
  264. not_2 = "00000027DS",
  265. nor_3 = "00000027DST",
  266. slt_3 = "0000002aDST",
  267. sltu_3 = "0000002bDST",
  268. dadd_3 = mips64 and "0000002cDST",
  269. daddu_3 = mips64 and "0000002dDST",
  270. dsub_3 = mips64 and "0000002eDST",
  271. dsubu_3 = mips64 and "0000002fDST",
  272. tge_2 = "00000030ST",
  273. tge_3 = "00000030STZ",
  274. tgeu_2 = "00000031ST",
  275. tgeu_3 = "00000031STZ",
  276. tlt_2 = "00000032ST",
  277. tlt_3 = "00000032STZ",
  278. tltu_2 = "00000033ST",
  279. tltu_3 = "00000033STZ",
  280. teq_2 = "00000034ST",
  281. teq_3 = "00000034STZ",
  282. tne_2 = "00000036ST",
  283. tne_3 = "00000036STZ",
  284. dsll_3 = mips64 and "00000038DTa",
  285. dsrl_3 = mips64 and "0000003aDTa",
  286. drotr_3 = mips64 and "0020003aDTa",
  287. dsra_3 = mips64 and "0000003bDTa",
  288. dsll32_3 = mips64 and "0000003cDTA",
  289. dsrl32_3 = mips64 and "0000003eDTA",
  290. drotr32_3 = mips64 and "0020003eDTA",
  291. dsra32_3 = mips64 and "0000003fDTA",
  292. -- Opcode REGIMM.
  293. bltz_2 = "04000000SB",
  294. bgez_2 = "04010000SB",
  295. bltzl_2 = "04020000SB",
  296. bgezl_2 = "04030000SB",
  297. bal_1 = "04110000B",
  298. synci_1 = "041f0000O",
  299. -- Opcode SPECIAL3.
  300. ext_4 = "7c000000TSAM", -- Note: last arg is msbd = size-1
  301. dextm_4 = mips64 and "7c000001TSAM", -- Args: pos | size-1-32
  302. dextu_4 = mips64 and "7c000002TSAM", -- Args: pos-32 | size-1
  303. dext_4 = mips64 and "7c000003TSAM", -- Args: pos | size-1
  304. zextw_2 = mips64 and "7c00f803TS",
  305. ins_4 = "7c000004TSAM", -- Note: last arg is msb = pos+size-1
  306. dinsm_4 = mips64 and "7c000005TSAM", -- Args: pos | pos+size-33
  307. dinsu_4 = mips64 and "7c000006TSAM", -- Args: pos-32 | pos+size-33
  308. dins_4 = mips64 and "7c000007TSAM", -- Args: pos | pos+size-1
  309. wsbh_2 = "7c0000a0DT",
  310. dsbh_2 = mips64 and "7c0000a4DT",
  311. dshd_2 = mips64 and "7c000164DT",
  312. seb_2 = "7c000420DT",
  313. seh_2 = "7c000620DT",
  314. rdhwr_2 = "7c00003bTD",
  315. -- Opcode COP0.
  316. mfc0_2 = "40000000TD",
  317. mfc0_3 = "40000000TDW",
  318. dmfc0_2 = mips64 and "40200000TD",
  319. dmfc0_3 = mips64 and "40200000TDW",
  320. mtc0_2 = "40800000TD",
  321. mtc0_3 = "40800000TDW",
  322. dmtc0_2 = mips64 and "40a00000TD",
  323. dmtc0_3 = mips64 and "40a00000TDW",
  324. rdpgpr_2 = "41400000DT",
  325. di_0 = "41606000",
  326. di_1 = "41606000T",
  327. ei_0 = "41606020",
  328. ei_1 = "41606020T",
  329. wrpgpr_2 = "41c00000DT",
  330. tlbr_0 = "42000001",
  331. tlbwi_0 = "42000002",
  332. tlbwr_0 = "42000006",
  333. tlbp_0 = "42000008",
  334. eret_0 = "42000018",
  335. deret_0 = "4200001f",
  336. wait_0 = "42000020",
  337. -- Opcode COP1.
  338. mfc1_2 = "44000000TG",
  339. dmfc1_2 = mips64 and "44200000TG",
  340. cfc1_2 = "44400000TG",
  341. mfhc1_2 = "44600000TG",
  342. mtc1_2 = "44800000TG",
  343. dmtc1_2 = mips64 and "44a00000TG",
  344. ctc1_2 = "44c00000TG",
  345. mthc1_2 = "44e00000TG",
  346. ["add.s_3"] = "46000000FGH",
  347. ["sub.s_3"] = "46000001FGH",
  348. ["mul.s_3"] = "46000002FGH",
  349. ["div.s_3"] = "46000003FGH",
  350. ["sqrt.s_2"] = "46000004FG",
  351. ["abs.s_2"] = "46000005FG",
  352. ["mov.s_2"] = "46000006FG",
  353. ["neg.s_2"] = "46000007FG",
  354. ["round.l.s_2"] = "46000008FG",
  355. ["trunc.l.s_2"] = "46000009FG",
  356. ["ceil.l.s_2"] = "4600000aFG",
  357. ["floor.l.s_2"] = "4600000bFG",
  358. ["round.w.s_2"] = "4600000cFG",
  359. ["trunc.w.s_2"] = "4600000dFG",
  360. ["ceil.w.s_2"] = "4600000eFG",
  361. ["floor.w.s_2"] = "4600000fFG",
  362. ["recip.s_2"] = "46000015FG",
  363. ["rsqrt.s_2"] = "46000016FG",
  364. ["cvt.d.s_2"] = "46000021FG",
  365. ["cvt.w.s_2"] = "46000024FG",
  366. ["cvt.l.s_2"] = "46000025FG",
  367. ["add.d_3"] = "46200000FGH",
  368. ["sub.d_3"] = "46200001FGH",
  369. ["mul.d_3"] = "46200002FGH",
  370. ["div.d_3"] = "46200003FGH",
  371. ["sqrt.d_2"] = "46200004FG",
  372. ["abs.d_2"] = "46200005FG",
  373. ["mov.d_2"] = "46200006FG",
  374. ["neg.d_2"] = "46200007FG",
  375. ["round.l.d_2"] = "46200008FG",
  376. ["trunc.l.d_2"] = "46200009FG",
  377. ["ceil.l.d_2"] = "4620000aFG",
  378. ["floor.l.d_2"] = "4620000bFG",
  379. ["round.w.d_2"] = "4620000cFG",
  380. ["trunc.w.d_2"] = "4620000dFG",
  381. ["ceil.w.d_2"] = "4620000eFG",
  382. ["floor.w.d_2"] = "4620000fFG",
  383. ["recip.d_2"] = "46200015FG",
  384. ["rsqrt.d_2"] = "46200016FG",
  385. ["cvt.s.d_2"] = "46200020FG",
  386. ["cvt.w.d_2"] = "46200024FG",
  387. ["cvt.l.d_2"] = "46200025FG",
  388. ["cvt.s.w_2"] = "46800020FG",
  389. ["cvt.d.w_2"] = "46800021FG",
  390. ["cvt.s.l_2"] = "46a00020FG",
  391. ["cvt.d.l_2"] = "46a00021FG",
  392. }
  393. if mipsr6 then -- Instructions added with MIPSR6.
  394. for k,v in pairs({
  395. -- Add immediate to upper bits.
  396. aui_3 = "3c000000TSI",
  397. daui_3 = mips64 and "74000000TSI",
  398. dahi_2 = mips64 and "04060000SI",
  399. dati_2 = mips64 and "041e0000SI",
  400. -- TODO: addiupc, auipc, aluipc, lwpc, lwupc, ldpc.
  401. -- Compact branches.
  402. blezalc_2 = "18000000TB", -- rt != 0.
  403. bgezalc_2 = "18000000T=SB", -- rt != 0.
  404. bgtzalc_2 = "1c000000TB", -- rt != 0.
  405. bltzalc_2 = "1c000000T=SB", -- rt != 0.
  406. blezc_2 = "58000000TB", -- rt != 0.
  407. bgezc_2 = "58000000T=SB", -- rt != 0.
  408. bgec_3 = "58000000STB", -- rs != rt.
  409. blec_3 = "58000000TSB", -- rt != rs.
  410. bgtzc_2 = "5c000000TB", -- rt != 0.
  411. bltzc_2 = "5c000000T=SB", -- rt != 0.
  412. bltc_3 = "5c000000STB", -- rs != rt.
  413. bgtc_3 = "5c000000TSB", -- rt != rs.
  414. bgeuc_3 = "18000000STB", -- rs != rt.
  415. bleuc_3 = "18000000TSB", -- rt != rs.
  416. bltuc_3 = "1c000000STB", -- rs != rt.
  417. bgtuc_3 = "1c000000TSB", -- rt != rs.
  418. beqzalc_2 = "20000000TB", -- rt != 0.
  419. bnezalc_2 = "60000000TB", -- rt != 0.
  420. beqc_3 = "20000000STB", -- rs < rt.
  421. bnec_3 = "60000000STB", -- rs < rt.
  422. bovc_3 = "20000000STB", -- rs >= rt.
  423. bnvc_3 = "60000000STB", -- rs >= rt.
  424. beqzc_2 = "d8000000SK", -- rs != 0.
  425. bnezc_2 = "f8000000SK", -- rs != 0.
  426. jic_2 = "d8000000TI",
  427. jialc_2 = "f8000000TI",
  428. bc_1 = "c8000000L",
  429. balc_1 = "e8000000L",
  430. -- Opcode SPECIAL.
  431. jr_1 = "00000009S",
  432. sdbbp_0 = "0000000e",
  433. sdbbp_1 = "0000000eY",
  434. lsa_4 = "00000005DSTA",
  435. dlsa_4 = mips64 and "00000015DSTA",
  436. seleqz_3 = "00000035DST",
  437. selnez_3 = "00000037DST",
  438. clz_2 = "00000050DS",
  439. clo_2 = "00000051DS",
  440. dclz_2 = mips64 and "00000052DS",
  441. dclo_2 = mips64 and "00000053DS",
  442. mul_3 = "00000098DST",
  443. muh_3 = "000000d8DST",
  444. mulu_3 = "00000099DST",
  445. muhu_3 = "000000d9DST",
  446. div_3 = "0000009aDST",
  447. mod_3 = "000000daDST",
  448. divu_3 = "0000009bDST",
  449. modu_3 = "000000dbDST",
  450. dmul_3 = mips64 and "0000009cDST",
  451. dmuh_3 = mips64 and "000000dcDST",
  452. dmulu_3 = mips64 and "0000009dDST",
  453. dmuhu_3 = mips64 and "000000ddDST",
  454. ddiv_3 = mips64 and "0000009eDST",
  455. dmod_3 = mips64 and "000000deDST",
  456. ddivu_3 = mips64 and "0000009fDST",
  457. dmodu_3 = mips64 and "000000dfDST",
  458. -- Opcode SPECIAL3.
  459. align_4 = "7c000220DSTA",
  460. dalign_4 = mips64 and "7c000224DSTA",
  461. bitswap_2 = "7c000020DT",
  462. dbitswap_2 = mips64 and "7c000024DT",
  463. -- Opcode COP1.
  464. bc1eqz_2 = "45200000HB",
  465. bc1nez_2 = "45a00000HB",
  466. ["sel.s_3"] = "46000010FGH",
  467. ["seleqz.s_3"] = "46000014FGH",
  468. ["selnez.s_3"] = "46000017FGH",
  469. ["maddf.s_3"] = "46000018FGH",
  470. ["msubf.s_3"] = "46000019FGH",
  471. ["rint.s_2"] = "4600001aFG",
  472. ["class.s_2"] = "4600001bFG",
  473. ["min.s_3"] = "4600001cFGH",
  474. ["mina.s_3"] = "4600001dFGH",
  475. ["max.s_3"] = "4600001eFGH",
  476. ["maxa.s_3"] = "4600001fFGH",
  477. ["cmp.af.s_3"] = "46800000FGH",
  478. ["cmp.un.s_3"] = "46800001FGH",
  479. ["cmp.or.s_3"] = "46800011FGH",
  480. ["cmp.eq.s_3"] = "46800002FGH",
  481. ["cmp.une.s_3"] = "46800012FGH",
  482. ["cmp.ueq.s_3"] = "46800003FGH",
  483. ["cmp.ne.s_3"] = "46800013FGH",
  484. ["cmp.lt.s_3"] = "46800004FGH",
  485. ["cmp.ult.s_3"] = "46800005FGH",
  486. ["cmp.le.s_3"] = "46800006FGH",
  487. ["cmp.ule.s_3"] = "46800007FGH",
  488. ["cmp.saf.s_3"] = "46800008FGH",
  489. ["cmp.sun.s_3"] = "46800009FGH",
  490. ["cmp.sor.s_3"] = "46800019FGH",
  491. ["cmp.seq.s_3"] = "4680000aFGH",
  492. ["cmp.sune.s_3"] = "4680001aFGH",
  493. ["cmp.sueq.s_3"] = "4680000bFGH",
  494. ["cmp.sne.s_3"] = "4680001bFGH",
  495. ["cmp.slt.s_3"] = "4680000cFGH",
  496. ["cmp.sult.s_3"] = "4680000dFGH",
  497. ["cmp.sle.s_3"] = "4680000eFGH",
  498. ["cmp.sule.s_3"] = "4680000fFGH",
  499. ["sel.d_3"] = "46200010FGH",
  500. ["seleqz.d_3"] = "46200014FGH",
  501. ["selnez.d_3"] = "46200017FGH",
  502. ["maddf.d_3"] = "46200018FGH",
  503. ["msubf.d_3"] = "46200019FGH",
  504. ["rint.d_2"] = "4620001aFG",
  505. ["class.d_2"] = "4620001bFG",
  506. ["min.d_3"] = "4620001cFGH",
  507. ["mina.d_3"] = "4620001dFGH",
  508. ["max.d_3"] = "4620001eFGH",
  509. ["maxa.d_3"] = "4620001fFGH",
  510. ["cmp.af.d_3"] = "46a00000FGH",
  511. ["cmp.un.d_3"] = "46a00001FGH",
  512. ["cmp.or.d_3"] = "46a00011FGH",
  513. ["cmp.eq.d_3"] = "46a00002FGH",
  514. ["cmp.une.d_3"] = "46a00012FGH",
  515. ["cmp.ueq.d_3"] = "46a00003FGH",
  516. ["cmp.ne.d_3"] = "46a00013FGH",
  517. ["cmp.lt.d_3"] = "46a00004FGH",
  518. ["cmp.ult.d_3"] = "46a00005FGH",
  519. ["cmp.le.d_3"] = "46a00006FGH",
  520. ["cmp.ule.d_3"] = "46a00007FGH",
  521. ["cmp.saf.d_3"] = "46a00008FGH",
  522. ["cmp.sun.d_3"] = "46a00009FGH",
  523. ["cmp.sor.d_3"] = "46a00019FGH",
  524. ["cmp.seq.d_3"] = "46a0000aFGH",
  525. ["cmp.sune.d_3"] = "46a0001aFGH",
  526. ["cmp.sueq.d_3"] = "46a0000bFGH",
  527. ["cmp.sne.d_3"] = "46a0001bFGH",
  528. ["cmp.slt.d_3"] = "46a0000cFGH",
  529. ["cmp.sult.d_3"] = "46a0000dFGH",
  530. ["cmp.sle.d_3"] = "46a0000eFGH",
  531. ["cmp.sule.d_3"] = "46a0000fFGH",
  532. }) do map_op[k] = v end
  533. else -- Instructions removed by MIPSR6.
  534. for k,v in pairs({
  535. -- Traps, don't use.
  536. addi_3 = "20000000TSI",
  537. daddi_3 = mips64 and "60000000TSI",
  538. -- Branch on likely, don't use.
  539. beqzl_2 = "50000000SB",
  540. beql_3 = "50000000STB",
  541. bnezl_2 = "54000000SB",
  542. bnel_3 = "54000000STB",
  543. blezl_2 = "58000000SB",
  544. bgtzl_2 = "5c000000SB",
  545. lwl_2 = "88000000TO",
  546. lwr_2 = "98000000TO",
  547. swl_2 = "a8000000TO",
  548. sdl_2 = mips64 and "b0000000TO",
  549. sdr_2 = mips64 and "b1000000TO",
  550. swr_2 = "b8000000TO",
  551. cache_2 = "bc000000NO",
  552. ll_2 = "c0000000TO",
  553. pref_2 = "cc000000NO",
  554. sc_2 = "e0000000TO",
  555. scd_2 = mips64 and "f0000000TO",
  556. -- Opcode SPECIAL.
  557. movf_2 = "00000001DS",
  558. movf_3 = "00000001DSC",
  559. movt_2 = "00010001DS",
  560. movt_3 = "00010001DSC",
  561. jr_1 = "00000008S",
  562. movz_3 = "0000000aDST",
  563. movn_3 = "0000000bDST",
  564. mfhi_1 = "00000010D",
  565. mthi_1 = "00000011S",
  566. mflo_1 = "00000012D",
  567. mtlo_1 = "00000013S",
  568. mult_2 = "00000018ST",
  569. multu_2 = "00000019ST",
  570. div_3 = "0000001aST",
  571. divu_3 = "0000001bST",
  572. ddiv_3 = mips64 and "0000001eST",
  573. ddivu_3 = mips64 and "0000001fST",
  574. dmult_2 = mips64 and "0000001cST",
  575. dmultu_2 = mips64 and "0000001dST",
  576. -- Opcode REGIMM.
  577. tgei_2 = "04080000SI",
  578. tgeiu_2 = "04090000SI",
  579. tlti_2 = "040a0000SI",
  580. tltiu_2 = "040b0000SI",
  581. teqi_2 = "040c0000SI",
  582. tnei_2 = "040e0000SI",
  583. bltzal_2 = "04100000SB",
  584. bgezal_2 = "04110000SB",
  585. bltzall_2 = "04120000SB",
  586. bgezall_2 = "04130000SB",
  587. -- Opcode SPECIAL2.
  588. madd_2 = "70000000ST",
  589. maddu_2 = "70000001ST",
  590. mul_3 = "70000002DST",
  591. msub_2 = "70000004ST",
  592. msubu_2 = "70000005ST",
  593. clz_2 = "70000020D=TS",
  594. clo_2 = "70000021D=TS",
  595. dclz_2 = mips64 and "70000024D=TS",
  596. dclo_2 = mips64 and "70000025D=TS",
  597. sdbbp_0 = "7000003f",
  598. sdbbp_1 = "7000003fY",
  599. -- Opcode COP1.
  600. bc1f_1 = "45000000B",
  601. bc1f_2 = "45000000CB",
  602. bc1t_1 = "45010000B",
  603. bc1t_2 = "45010000CB",
  604. bc1fl_1 = "45020000B",
  605. bc1fl_2 = "45020000CB",
  606. bc1tl_1 = "45030000B",
  607. bc1tl_2 = "45030000CB",
  608. ["movf.s_2"] = "46000011FG",
  609. ["movf.s_3"] = "46000011FGC",
  610. ["movt.s_2"] = "46010011FG",
  611. ["movt.s_3"] = "46010011FGC",
  612. ["movz.s_3"] = "46000012FGT",
  613. ["movn.s_3"] = "46000013FGT",
  614. ["cvt.ps.s_3"] = "46000026FGH",
  615. ["c.f.s_2"] = "46000030GH",
  616. ["c.f.s_3"] = "46000030VGH",
  617. ["c.un.s_2"] = "46000031GH",
  618. ["c.un.s_3"] = "46000031VGH",
  619. ["c.eq.s_2"] = "46000032GH",
  620. ["c.eq.s_3"] = "46000032VGH",
  621. ["c.ueq.s_2"] = "46000033GH",
  622. ["c.ueq.s_3"] = "46000033VGH",
  623. ["c.olt.s_2"] = "46000034GH",
  624. ["c.olt.s_3"] = "46000034VGH",
  625. ["c.ult.s_2"] = "46000035GH",
  626. ["c.ult.s_3"] = "46000035VGH",
  627. ["c.ole.s_2"] = "46000036GH",
  628. ["c.ole.s_3"] = "46000036VGH",
  629. ["c.ule.s_2"] = "46000037GH",
  630. ["c.ule.s_3"] = "46000037VGH",
  631. ["c.sf.s_2"] = "46000038GH",
  632. ["c.sf.s_3"] = "46000038VGH",
  633. ["c.ngle.s_2"] = "46000039GH",
  634. ["c.ngle.s_3"] = "46000039VGH",
  635. ["c.seq.s_2"] = "4600003aGH",
  636. ["c.seq.s_3"] = "4600003aVGH",
  637. ["c.ngl.s_2"] = "4600003bGH",
  638. ["c.ngl.s_3"] = "4600003bVGH",
  639. ["c.lt.s_2"] = "4600003cGH",
  640. ["c.lt.s_3"] = "4600003cVGH",
  641. ["c.nge.s_2"] = "4600003dGH",
  642. ["c.nge.s_3"] = "4600003dVGH",
  643. ["c.le.s_2"] = "4600003eGH",
  644. ["c.le.s_3"] = "4600003eVGH",
  645. ["c.ngt.s_2"] = "4600003fGH",
  646. ["c.ngt.s_3"] = "4600003fVGH",
  647. ["movf.d_2"] = "46200011FG",
  648. ["movf.d_3"] = "46200011FGC",
  649. ["movt.d_2"] = "46210011FG",
  650. ["movt.d_3"] = "46210011FGC",
  651. ["movz.d_3"] = "46200012FGT",
  652. ["movn.d_3"] = "46200013FGT",
  653. ["c.f.d_2"] = "46200030GH",
  654. ["c.f.d_3"] = "46200030VGH",
  655. ["c.un.d_2"] = "46200031GH",
  656. ["c.un.d_3"] = "46200031VGH",
  657. ["c.eq.d_2"] = "46200032GH",
  658. ["c.eq.d_3"] = "46200032VGH",
  659. ["c.ueq.d_2"] = "46200033GH",
  660. ["c.ueq.d_3"] = "46200033VGH",
  661. ["c.olt.d_2"] = "46200034GH",
  662. ["c.olt.d_3"] = "46200034VGH",
  663. ["c.ult.d_2"] = "46200035GH",
  664. ["c.ult.d_3"] = "46200035VGH",
  665. ["c.ole.d_2"] = "46200036GH",
  666. ["c.ole.d_3"] = "46200036VGH",
  667. ["c.ule.d_2"] = "46200037GH",
  668. ["c.ule.d_3"] = "46200037VGH",
  669. ["c.sf.d_2"] = "46200038GH",
  670. ["c.sf.d_3"] = "46200038VGH",
  671. ["c.ngle.d_2"] = "46200039GH",
  672. ["c.ngle.d_3"] = "46200039VGH",
  673. ["c.seq.d_2"] = "4620003aGH",
  674. ["c.seq.d_3"] = "4620003aVGH",
  675. ["c.ngl.d_2"] = "4620003bGH",
  676. ["c.ngl.d_3"] = "4620003bVGH",
  677. ["c.lt.d_2"] = "4620003cGH",
  678. ["c.lt.d_3"] = "4620003cVGH",
  679. ["c.nge.d_2"] = "4620003dGH",
  680. ["c.nge.d_3"] = "4620003dVGH",
  681. ["c.le.d_2"] = "4620003eGH",
  682. ["c.le.d_3"] = "4620003eVGH",
  683. ["c.ngt.d_2"] = "4620003fGH",
  684. ["c.ngt.d_3"] = "4620003fVGH",
  685. ["add.ps_3"] = "46c00000FGH",
  686. ["sub.ps_3"] = "46c00001FGH",
  687. ["mul.ps_3"] = "46c00002FGH",
  688. ["abs.ps_2"] = "46c00005FG",
  689. ["mov.ps_2"] = "46c00006FG",
  690. ["neg.ps_2"] = "46c00007FG",
  691. ["movf.ps_2"] = "46c00011FG",
  692. ["movf.ps_3"] = "46c00011FGC",
  693. ["movt.ps_2"] = "46c10011FG",
  694. ["movt.ps_3"] = "46c10011FGC",
  695. ["movz.ps_3"] = "46c00012FGT",
  696. ["movn.ps_3"] = "46c00013FGT",
  697. ["cvt.s.pu_2"] = "46c00020FG",
  698. ["cvt.s.pl_2"] = "46c00028FG",
  699. ["pll.ps_3"] = "46c0002cFGH",
  700. ["plu.ps_3"] = "46c0002dFGH",
  701. ["pul.ps_3"] = "46c0002eFGH",
  702. ["puu.ps_3"] = "46c0002fFGH",
  703. ["c.f.ps_2"] = "46c00030GH",
  704. ["c.f.ps_3"] = "46c00030VGH",
  705. ["c.un.ps_2"] = "46c00031GH",
  706. ["c.un.ps_3"] = "46c00031VGH",
  707. ["c.eq.ps_2"] = "46c00032GH",
  708. ["c.eq.ps_3"] = "46c00032VGH",
  709. ["c.ueq.ps_2"] = "46c00033GH",
  710. ["c.ueq.ps_3"] = "46c00033VGH",
  711. ["c.olt.ps_2"] = "46c00034GH",
  712. ["c.olt.ps_3"] = "46c00034VGH",
  713. ["c.ult.ps_2"] = "46c00035GH",
  714. ["c.ult.ps_3"] = "46c00035VGH",
  715. ["c.ole.ps_2"] = "46c00036GH",
  716. ["c.ole.ps_3"] = "46c00036VGH",
  717. ["c.ule.ps_2"] = "46c00037GH",
  718. ["c.ule.ps_3"] = "46c00037VGH",
  719. ["c.sf.ps_2"] = "46c00038GH",
  720. ["c.sf.ps_3"] = "46c00038VGH",
  721. ["c.ngle.ps_2"] = "46c00039GH",
  722. ["c.ngle.ps_3"] = "46c00039VGH",
  723. ["c.seq.ps_2"] = "46c0003aGH",
  724. ["c.seq.ps_3"] = "46c0003aVGH",
  725. ["c.ngl.ps_2"] = "46c0003bGH",
  726. ["c.ngl.ps_3"] = "46c0003bVGH",
  727. ["c.lt.ps_2"] = "46c0003cGH",
  728. ["c.lt.ps_3"] = "46c0003cVGH",
  729. ["c.nge.ps_2"] = "46c0003dGH",
  730. ["c.nge.ps_3"] = "46c0003dVGH",
  731. ["c.le.ps_2"] = "46c0003eGH",
  732. ["c.le.ps_3"] = "46c0003eVGH",
  733. ["c.ngt.ps_2"] = "46c0003fGH",
  734. ["c.ngt.ps_3"] = "46c0003fVGH",
  735. -- Opcode COP1X.
  736. lwxc1_2 = "4c000000FX",
  737. ldxc1_2 = "4c000001FX",
  738. luxc1_2 = "4c000005FX",
  739. swxc1_2 = "4c000008FX",
  740. sdxc1_2 = "4c000009FX",
  741. suxc1_2 = "4c00000dFX",
  742. prefx_2 = "4c00000fMX",
  743. ["alnv.ps_4"] = "4c00001eFGHS",
  744. ["madd.s_4"] = "4c000020FRGH",
  745. ["madd.d_4"] = "4c000021FRGH",
  746. ["madd.ps_4"] = "4c000026FRGH",
  747. ["msub.s_4"] = "4c000028FRGH",
  748. ["msub.d_4"] = "4c000029FRGH",
  749. ["msub.ps_4"] = "4c00002eFRGH",
  750. ["nmadd.s_4"] = "4c000030FRGH",
  751. ["nmadd.d_4"] = "4c000031FRGH",
  752. ["nmadd.ps_4"] = "4c000036FRGH",
  753. ["nmsub.s_4"] = "4c000038FRGH",
  754. ["nmsub.d_4"] = "4c000039FRGH",
  755. ["nmsub.ps_4"] = "4c00003eFRGH",
  756. }) do map_op[k] = v end
  757. end
  758. ------------------------------------------------------------------------------
  759. local function parse_gpr(expr)
  760. local tname, ovreg = match(expr, "^([%w_]+):(r[1-3]?[0-9])$")
  761. local tp = map_type[tname or expr]
  762. if tp then
  763. local reg = ovreg or tp.reg
  764. if not reg then
  765. werror("type `"..(tname or expr).."' needs a register override")
  766. end
  767. expr = reg
  768. end
  769. local r = match(expr, "^r([1-3]?[0-9])$")
  770. if r then
  771. r = tonumber(r)
  772. if r <= 31 then return r, tp end
  773. end
  774. werror("bad register name `"..expr.."'")
  775. end
  776. local function parse_fpr(expr)
  777. local r = match(expr, "^f([1-3]?[0-9])$")
  778. if r then
  779. r = tonumber(r)
  780. if r <= 31 then return r end
  781. end
  782. werror("bad register name `"..expr.."'")
  783. end
  784. local function parse_imm(imm, bits, shift, scale, signed, action)
  785. local n = tonumber(imm)
  786. if n then
  787. local m = sar(n, scale)
  788. if shl(m, scale) == n then
  789. if signed then
  790. local s = sar(m, bits-1)
  791. if s == 0 then return shl(m, shift)
  792. elseif s == -1 then return shl(m + shl(1, bits), shift) end
  793. else
  794. if sar(m, bits) == 0 then return shl(m, shift) end
  795. end
  796. end
  797. werror("out of range immediate `"..imm.."'")
  798. elseif match(imm, "^[rf]([1-3]?[0-9])$") or
  799. match(imm, "^([%w_]+):([rf][1-3]?[0-9])$") then
  800. werror("expected immediate operand, got register")
  801. else
  802. waction(action or "IMM",
  803. (signed and 32768 or 0)+shl(scale, 10)+shl(bits, 5)+shift, imm)
  804. return 0
  805. end
  806. end
  807. local function parse_disp(disp)
  808. local imm, reg = match(disp, "^(.*)%(([%w_:]+)%)$")
  809. if imm then
  810. local r = shl(parse_gpr(reg), 21)
  811. local extname = match(imm, "^extern%s+(%S+)$")
  812. if extname then
  813. waction("REL_EXT", map_extern[extname], nil, 1)
  814. return r
  815. else
  816. return r + parse_imm(imm, 16, 0, 0, true)
  817. end
  818. end
  819. local reg, tailr = match(disp, "^([%w_:]+)%s*(.*)$")
  820. if reg and tailr ~= "" then
  821. local r, tp = parse_gpr(reg)
  822. if tp then
  823. waction("IMM", 32768+16*32, format(tp.ctypefmt, tailr))
  824. return shl(r, 21)
  825. end
  826. end
  827. werror("bad displacement `"..disp.."'")
  828. end
  829. local function parse_index(idx)
  830. local rt, rs = match(idx, "^(.*)%(([%w_:]+)%)$")
  831. if rt then
  832. rt = parse_gpr(rt)
  833. rs = parse_gpr(rs)
  834. return shl(rt, 16) + shl(rs, 21)
  835. end
  836. werror("bad index `"..idx.."'")
  837. end
  838. local function parse_label(label, def)
  839. local prefix = sub(label, 1, 2)
  840. -- =>label (pc label reference)
  841. if prefix == "=>" then
  842. return "PC", 0, sub(label, 3)
  843. end
  844. -- ->name (global label reference)
  845. if prefix == "->" then
  846. return "LG", map_global[sub(label, 3)]
  847. end
  848. if def then
  849. -- [1-9] (local label definition)
  850. if match(label, "^[1-9]$") then
  851. return "LG", 10+tonumber(label)
  852. end
  853. else
  854. -- [<>][1-9] (local label reference)
  855. local dir, lnum = match(label, "^([<>])([1-9])$")
  856. if dir then -- Fwd: 1-9, Bkwd: 11-19.
  857. return "LG", lnum + (dir == ">" and 0 or 10)
  858. end
  859. -- extern label (extern label reference)
  860. local extname = match(label, "^extern%s+(%S+)$")
  861. if extname then
  862. return "EXT", map_extern[extname]
  863. end
  864. end
  865. werror("bad label `"..label.."'")
  866. end
  867. ------------------------------------------------------------------------------
  868. -- Handle opcodes defined with template strings.
  869. map_op[".template__"] = function(params, template, nparams)
  870. if not params then return sub(template, 9) end
  871. local op = tonumber(sub(template, 1, 8), 16)
  872. local n = 1
  873. -- Limit number of section buffer positions used by a single dasm_put().
  874. -- A single opcode needs a maximum of 2 positions (ins/ext).
  875. if secpos+2 > maxsecpos then wflush() end
  876. local pos = wpos()
  877. -- Process each character.
  878. for p in gmatch(sub(template, 9), ".") do
  879. if p == "D" then
  880. op = op + shl(parse_gpr(params[n]), 11); n = n + 1
  881. elseif p == "T" then
  882. op = op + shl(parse_gpr(params[n]), 16); n = n + 1
  883. elseif p == "S" then
  884. op = op + shl(parse_gpr(params[n]), 21); n = n + 1
  885. elseif p == "F" then
  886. op = op + shl(parse_fpr(params[n]), 6); n = n + 1
  887. elseif p == "G" then
  888. op = op + shl(parse_fpr(params[n]), 11); n = n + 1
  889. elseif p == "H" then
  890. op = op + shl(parse_fpr(params[n]), 16); n = n + 1
  891. elseif p == "R" then
  892. op = op + shl(parse_fpr(params[n]), 21); n = n + 1
  893. elseif p == "I" then
  894. op = op + parse_imm(params[n], 16, 0, 0, true); n = n + 1
  895. elseif p == "U" then
  896. op = op + parse_imm(params[n], 16, 0, 0, false); n = n + 1
  897. elseif p == "O" then
  898. op = op + parse_disp(params[n]); n = n + 1
  899. elseif p == "X" then
  900. op = op + parse_index(params[n]); n = n + 1
  901. elseif p == "B" or p == "J" or p == "K" or p == "L" then
  902. local mode, m, s = parse_label(params[n], false)
  903. if p == "J" then m = m + 0xa800
  904. elseif p == "K" then m = m + 0x5000
  905. elseif p == "L" then m = m + 0xa000 end
  906. waction("REL_"..mode, m, s, 1)
  907. n = n + 1
  908. elseif p == "A" then
  909. op = op + parse_imm(params[n], 5, 6, 0, false); n = n + 1
  910. elseif p == "a" then
  911. local m = parse_imm(params[n], 6, 6, 0, false, "IMMS"); n = n + 1
  912. op = op + band(m, 0x7c0) + band(shr(m, 9), 4)
  913. elseif p == "M" then
  914. op = op + parse_imm(params[n], 5, 11, 0, false); n = n + 1
  915. elseif p == "N" then
  916. op = op + parse_imm(params[n], 5, 16, 0, false); n = n + 1
  917. elseif p == "C" then
  918. op = op + parse_imm(params[n], 3, 18, 0, false); n = n + 1
  919. elseif p == "V" then
  920. op = op + parse_imm(params[n], 3, 8, 0, false); n = n + 1
  921. elseif p == "W" then
  922. op = op + parse_imm(params[n], 3, 0, 0, false); n = n + 1
  923. elseif p == "Y" then
  924. op = op + parse_imm(params[n], 20, 6, 0, false); n = n + 1
  925. elseif p == "Z" then
  926. op = op + parse_imm(params[n], 10, 6, 0, false); n = n + 1
  927. elseif p == "=" then
  928. n = n - 1 -- Re-use previous parameter for next template char.
  929. else
  930. assert(false)
  931. end
  932. end
  933. wputpos(pos, op)
  934. end
  935. ------------------------------------------------------------------------------
  936. -- Pseudo-opcode to mark the position where the action list is to be emitted.
  937. map_op[".actionlist_1"] = function(params)
  938. if not params then return "cvar" end
  939. local name = params[1] -- No syntax check. You get to keep the pieces.
  940. wline(function(out) writeactions(out, name) end)
  941. end
  942. -- Pseudo-opcode to mark the position where the global enum is to be emitted.
  943. map_op[".globals_1"] = function(params)
  944. if not params then return "prefix" end
  945. local prefix = params[1] -- No syntax check. You get to keep the pieces.
  946. wline(function(out) writeglobals(out, prefix) end)
  947. end
  948. -- Pseudo-opcode to mark the position where the global names are to be emitted.
  949. map_op[".globalnames_1"] = function(params)
  950. if not params then return "cvar" end
  951. local name = params[1] -- No syntax check. You get to keep the pieces.
  952. wline(function(out) writeglobalnames(out, name) end)
  953. end
  954. -- Pseudo-opcode to mark the position where the extern names are to be emitted.
  955. map_op[".externnames_1"] = function(params)
  956. if not params then return "cvar" end
  957. local name = params[1] -- No syntax check. You get to keep the pieces.
  958. wline(function(out) writeexternnames(out, name) end)
  959. end
  960. ------------------------------------------------------------------------------
  961. -- Label pseudo-opcode (converted from trailing colon form).
  962. map_op[".label_1"] = function(params)
  963. if not params then return "[1-9] | ->global | =>pcexpr" end
  964. if secpos+1 > maxsecpos then wflush() end
  965. local mode, n, s = parse_label(params[1], true)
  966. if mode == "EXT" then werror("bad label definition") end
  967. waction("LABEL_"..mode, n, s, 1)
  968. end
  969. ------------------------------------------------------------------------------
  970. -- Pseudo-opcodes for data storage.
  971. map_op[".long_*"] = function(params)
  972. if not params then return "imm..." end
  973. for _,p in ipairs(params) do
  974. local n = tonumber(p)
  975. if not n then werror("bad immediate `"..p.."'") end
  976. if n < 0 then n = n + 2^32 end
  977. wputw(n)
  978. if secpos+2 > maxsecpos then wflush() end
  979. end
  980. end
  981. -- Alignment pseudo-opcode.
  982. map_op[".align_1"] = function(params)
  983. if not params then return "numpow2" end
  984. if secpos+1 > maxsecpos then wflush() end
  985. local align = tonumber(params[1])
  986. if align then
  987. local x = align
  988. -- Must be a power of 2 in the range (2 ... 256).
  989. for i=1,8 do
  990. x = x / 2
  991. if x == 1 then
  992. waction("ALIGN", align-1, nil, 1) -- Action byte is 2**n-1.
  993. return
  994. end
  995. end
  996. end
  997. werror("bad alignment")
  998. end
  999. ------------------------------------------------------------------------------
  1000. -- Pseudo-opcode for (primitive) type definitions (map to C types).
  1001. map_op[".type_3"] = function(params, nparams)
  1002. if not params then
  1003. return nparams == 2 and "name, ctype" or "name, ctype, reg"
  1004. end
  1005. local name, ctype, reg = params[1], params[2], params[3]
  1006. if not match(name, "^[%a_][%w_]*$") then
  1007. werror("bad type name `"..name.."'")
  1008. end
  1009. local tp = map_type[name]
  1010. if tp then
  1011. werror("duplicate type `"..name.."'")
  1012. end
  1013. -- Add #type to defines. A bit unclean to put it in map_archdef.
  1014. map_archdef["#"..name] = "sizeof("..ctype..")"
  1015. -- Add new type and emit shortcut define.
  1016. local num = ctypenum + 1
  1017. map_type[name] = {
  1018. ctype = ctype,
  1019. ctypefmt = format("Dt%X(%%s)", num),
  1020. reg = reg,
  1021. }
  1022. wline(format("#define Dt%X(_V) (int)(ptrdiff_t)&(((%s *)0)_V)", num, ctype))
  1023. ctypenum = num
  1024. end
  1025. map_op[".type_2"] = map_op[".type_3"]
  1026. -- Dump type definitions.
  1027. local function dumptypes(out, lvl)
  1028. local t = {}
  1029. for name in pairs(map_type) do t[#t+1] = name end
  1030. sort(t)
  1031. out:write("Type definitions:\n")
  1032. for _,name in ipairs(t) do
  1033. local tp = map_type[name]
  1034. local reg = tp.reg or ""
  1035. out:write(format(" %-20s %-20s %s\n", name, tp.ctype, reg))
  1036. end
  1037. out:write("\n")
  1038. end
  1039. ------------------------------------------------------------------------------
  1040. -- Set the current section.
  1041. function _M.section(num)
  1042. waction("SECTION", num)
  1043. wflush(true) -- SECTION is a terminal action.
  1044. end
  1045. ------------------------------------------------------------------------------
  1046. -- Dump architecture description.
  1047. function _M.dumparch(out)
  1048. out:write(format("DynASM %s version %s, released %s\n\n",
  1049. _info.arch, _info.version, _info.release))
  1050. dumpactions(out)
  1051. end
  1052. -- Dump all user defined elements.
  1053. function _M.dumpdef(out, lvl)
  1054. dumptypes(out, lvl)
  1055. dumpglobals(out, lvl)
  1056. dumpexterns(out, lvl)
  1057. end
  1058. ------------------------------------------------------------------------------
  1059. -- Pass callbacks from/to the DynASM core.
  1060. function _M.passcb(wl, we, wf, ww)
  1061. wline, werror, wfatal, wwarn = wl, we, wf, ww
  1062. return wflush
  1063. end
  1064. -- Setup the arch-specific module.
  1065. function _M.setup(arch, opt)
  1066. g_arch, g_opt = arch, opt
  1067. end
  1068. -- Merge the core maps and the arch-specific maps.
  1069. function _M.mergemaps(map_coreop, map_def)
  1070. setmetatable(map_op, { __index = map_coreop })
  1071. setmetatable(map_def, { __index = map_archdef })
  1072. return map_op, map_def
  1073. end
  1074. return _M
  1075. ------------------------------------------------------------------------------