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