aboutsummaryrefslogtreecommitdiff
path: root/dynasm/dasm_mips.lua
diff options
context:
space:
mode:
Diffstat (limited to 'dynasm/dasm_mips.lua')
-rw-r--r--dynasm/dasm_mips.lua79
1 files changed, 67 insertions, 12 deletions
diff --git a/dynasm/dasm_mips.lua b/dynasm/dasm_mips.lua
index af530427..bd2a2b43 100644
--- a/dynasm/dasm_mips.lua
+++ b/dynasm/dasm_mips.lua
@@ -1,17 +1,19 @@
1------------------------------------------------------------------------------ 1------------------------------------------------------------------------------
2-- DynASM MIPS module. 2-- DynASM MIPS32/MIPS64 module.
3-- 3--
4-- Copyright (C) 2005-2017 Mike Pall. All rights reserved. 4-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
5-- See dynasm.lua for full copyright notice. 5-- See dynasm.lua for full copyright notice.
6------------------------------------------------------------------------------ 6------------------------------------------------------------------------------
7 7
8local mips64 = mips64
9
8-- Module information: 10-- Module information:
9local _info = { 11local _info = {
10 arch = "mips", 12 arch = mips64 and "mips64" or "mips",
11 description = "DynASM MIPS module", 13 description = "DynASM MIPS32/MIPS64 module",
12 version = "1.3.0", 14 version = "1.4.0",
13 vernum = 10300, 15 vernum = 10400,
14 release = "2012-01-23", 16 release = "2016-05-24",
15 author = "Mike Pall", 17 author = "Mike Pall",
16 license = "MIT", 18 license = "MIT",
17} 19}
@@ -27,7 +29,8 @@ local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
27local match, gmatch = _s.match, _s.gmatch 29local match, gmatch = _s.match, _s.gmatch
28local concat, sort = table.concat, table.sort 30local concat, sort = table.concat, table.sort
29local bit = bit or require("bit") 31local bit = bit or require("bit")
30local band, shl, sar, tohex = bit.band, bit.lshift, bit.arshift, bit.tohex 32local band, shl, shr, sar = bit.band, bit.lshift, bit.rshift, bit.arshift
33local tohex = bit.tohex
31 34
32-- Inherited tables and callbacks. 35-- Inherited tables and callbacks.
33local g_opt, g_arch 36local g_opt, g_arch
@@ -38,7 +41,7 @@ local wline, werror, wfatal, wwarn
38local action_names = { 41local action_names = {
39 "STOP", "SECTION", "ESC", "REL_EXT", 42 "STOP", "SECTION", "ESC", "REL_EXT",
40 "ALIGN", "REL_LG", "LABEL_LG", 43 "ALIGN", "REL_LG", "LABEL_LG",
41 "REL_PC", "LABEL_PC", "IMM", 44 "REL_PC", "LABEL_PC", "IMM", "IMMS",
42} 45}
43 46
44-- Maximum number of section buffer positions for dasm_put(). 47-- Maximum number of section buffer positions for dasm_put().
@@ -251,6 +254,10 @@ local map_op = {
251 bnel_3 = "54000000STB", 254 bnel_3 = "54000000STB",
252 blezl_2 = "58000000SB", 255 blezl_2 = "58000000SB",
253 bgtzl_2 = "5c000000SB", 256 bgtzl_2 = "5c000000SB",
257 daddi_3 = mips64 and "60000000TSI",
258 daddiu_3 = mips64 and "64000000TSI",
259 ldl_2 = mips64 and "68000000TO",
260 ldr_2 = mips64 and "6c000000TO",
254 lb_2 = "80000000TO", 261 lb_2 = "80000000TO",
255 lh_2 = "84000000TO", 262 lh_2 = "84000000TO",
256 lwl_2 = "88000000TO", 263 lwl_2 = "88000000TO",
@@ -258,23 +265,30 @@ local map_op = {
258 lbu_2 = "90000000TO", 265 lbu_2 = "90000000TO",
259 lhu_2 = "94000000TO", 266 lhu_2 = "94000000TO",
260 lwr_2 = "98000000TO", 267 lwr_2 = "98000000TO",
268 lwu_2 = mips64 and "9c000000TO",
261 sb_2 = "a0000000TO", 269 sb_2 = "a0000000TO",
262 sh_2 = "a4000000TO", 270 sh_2 = "a4000000TO",
263 swl_2 = "a8000000TO", 271 swl_2 = "a8000000TO",
264 sw_2 = "ac000000TO", 272 sw_2 = "ac000000TO",
273 sdl_2 = mips64 and "b0000000TO",
274 sdr_2 = mips64 and "b1000000TO",
265 swr_2 = "b8000000TO", 275 swr_2 = "b8000000TO",
266 cache_2 = "bc000000NO", 276 cache_2 = "bc000000NO",
267 ll_2 = "c0000000TO", 277 ll_2 = "c0000000TO",
268 lwc1_2 = "c4000000HO", 278 lwc1_2 = "c4000000HO",
269 pref_2 = "cc000000NO", 279 pref_2 = "cc000000NO",
270 ldc1_2 = "d4000000HO", 280 ldc1_2 = "d4000000HO",
281 ld_2 = mips64 and "dc000000TO",
271 sc_2 = "e0000000TO", 282 sc_2 = "e0000000TO",
272 swc1_2 = "e4000000HO", 283 swc1_2 = "e4000000HO",
284 scd_2 = mips64 and "f0000000TO",
273 sdc1_2 = "f4000000HO", 285 sdc1_2 = "f4000000HO",
286 sd_2 = mips64 and "fc000000TO",
274 287
275 -- Opcode SPECIAL. 288 -- Opcode SPECIAL.
276 nop_0 = "00000000", 289 nop_0 = "00000000",
277 sll_3 = "00000000DTA", 290 sll_3 = "00000000DTA",
291 sextw_2 = "00000000DT",
278 movf_2 = "00000001DS", 292 movf_2 = "00000001DS",
279 movf_3 = "00000001DSC", 293 movf_3 = "00000001DSC",
280 movt_2 = "00010001DS", 294 movt_2 = "00010001DS",
@@ -285,6 +299,7 @@ local map_op = {
285 sllv_3 = "00000004DTS", 299 sllv_3 = "00000004DTS",
286 srlv_3 = "00000006DTS", 300 srlv_3 = "00000006DTS",
287 rotrv_3 = "00000046DTS", 301 rotrv_3 = "00000046DTS",
302 drotrv_3 = mips64 and "00000056DTS",
288 srav_3 = "00000007DTS", 303 srav_3 = "00000007DTS",
289 jr_1 = "00000008S", 304 jr_1 = "00000008S",
290 jalr_1 = "0000f809S", 305 jalr_1 = "0000f809S",
@@ -300,15 +315,22 @@ local map_op = {
300 mthi_1 = "00000011S", 315 mthi_1 = "00000011S",
301 mflo_1 = "00000012D", 316 mflo_1 = "00000012D",
302 mtlo_1 = "00000013S", 317 mtlo_1 = "00000013S",
318 dsllv_3 = mips64 and "00000014DTS",
319 dsrlv_3 = mips64 and "00000016DTS",
320 dsrav_3 = mips64 and "00000017DTS",
303 mult_2 = "00000018ST", 321 mult_2 = "00000018ST",
304 multu_2 = "00000019ST", 322 multu_2 = "00000019ST",
305 div_2 = "0000001aST", 323 div_2 = "0000001aST",
306 divu_2 = "0000001bST", 324 divu_2 = "0000001bST",
325 dmult_2 = mips64 and "0000001cST",
326 dmultu_2 = mips64 and "0000001dST",
327 ddiv_2 = mips64 and "0000001eST",
328 ddivu_2 = mips64 and "0000001fST",
307 add_3 = "00000020DST", 329 add_3 = "00000020DST",
308 move_2 = "00000021DS", 330 move_2 = mips64 and "00000025DS" or "00000021DS",
309 addu_3 = "00000021DST", 331 addu_3 = "00000021DST",
310 sub_3 = "00000022DST", 332 sub_3 = "00000022DST",
311 negu_2 = "00000023DT", 333 negu_2 = mips64 and "0000002fDT" or "00000023DT",
312 subu_3 = "00000023DST", 334 subu_3 = "00000023DST",
313 and_3 = "00000024DST", 335 and_3 = "00000024DST",
314 or_3 = "00000025DST", 336 or_3 = "00000025DST",
@@ -317,6 +339,10 @@ local map_op = {
317 nor_3 = "00000027DST", 339 nor_3 = "00000027DST",
318 slt_3 = "0000002aDST", 340 slt_3 = "0000002aDST",
319 sltu_3 = "0000002bDST", 341 sltu_3 = "0000002bDST",
342 dadd_3 = mips64 and "0000002cDST",
343 daddu_3 = mips64 and "0000002dDST",
344 dsub_3 = mips64 and "0000002eDST",
345 dsubu_3 = mips64 and "0000002fDST",
320 tge_2 = "00000030ST", 346 tge_2 = "00000030ST",
321 tge_3 = "00000030STZ", 347 tge_3 = "00000030STZ",
322 tgeu_2 = "00000031ST", 348 tgeu_2 = "00000031ST",
@@ -329,6 +355,14 @@ local map_op = {
329 teq_3 = "00000034STZ", 355 teq_3 = "00000034STZ",
330 tne_2 = "00000036ST", 356 tne_2 = "00000036ST",
331 tne_3 = "00000036STZ", 357 tne_3 = "00000036STZ",
358 dsll_3 = mips64 and "00000038DTa",
359 dsrl_3 = mips64 and "0000003aDTa",
360 drotr_3 = mips64 and "0020003aDTa",
361 dsra_3 = mips64 and "0000003bDTa",
362 dsll32_3 = mips64 and "0000003cDTA",
363 dsrl32_3 = mips64 and "0000003eDTA",
364 drotr32_3 = mips64 and "0020003eDTA",
365 dsra32_3 = mips64 and "0000003fDTA",
332 366
333 -- Opcode REGIMM. 367 -- Opcode REGIMM.
334 bltz_2 = "04000000SB", 368 bltz_2 = "04000000SB",
@@ -356,13 +390,24 @@ local map_op = {
356 msubu_2 = "70000005ST", 390 msubu_2 = "70000005ST",
357 clz_2 = "70000020DS=", 391 clz_2 = "70000020DS=",
358 clo_2 = "70000021DS=", 392 clo_2 = "70000021DS=",
393 dclz_2 = mips64 and "70000024DS=",
394 dclo_2 = mips64 and "70000025DS=",
359 sdbbp_0 = "7000003f", 395 sdbbp_0 = "7000003f",
360 sdbbp_1 = "7000003fY", 396 sdbbp_1 = "7000003fY",
361 397
362 -- Opcode SPECIAL3. 398 -- Opcode SPECIAL3.
363 ext_4 = "7c000000TSAM", -- Note: last arg is msbd = size-1 399 ext_4 = "7c000000TSAM", -- Note: last arg is msbd = size-1
400 dextm_4 = mips64 and "7c000001TSAM", -- Args: pos | size-1-32
401 dextu_4 = mips64 and "7c000002TSAM", -- Args: pos-32 | size-1
402 dext_4 = mips64 and "7c000003TSAM", -- Args: pos | size-1
403 zextw_2 = mips64 and "7c00f803TS",
364 ins_4 = "7c000004TSAM", -- Note: last arg is msb = pos+size-1 404 ins_4 = "7c000004TSAM", -- Note: last arg is msb = pos+size-1
405 dinsm_4 = mips64 and "7c000005TSAM", -- Args: pos | pos+size-33
406 dinsu_4 = mips64 and "7c000006TSAM", -- Args: pos-32 | pos+size-33
407 dins_4 = mips64 and "7c000007TSAM", -- Args: pos | pos+size-1
365 wsbh_2 = "7c0000a0DT", 408 wsbh_2 = "7c0000a0DT",
409 dsbh_2 = mips64 and "7c0000a4DT",
410 dshd_2 = mips64 and "7c000164DT",
366 seb_2 = "7c000420DT", 411 seb_2 = "7c000420DT",
367 seh_2 = "7c000620DT", 412 seh_2 = "7c000620DT",
368 rdhwr_2 = "7c00003bTD", 413 rdhwr_2 = "7c00003bTD",
@@ -370,8 +415,12 @@ local map_op = {
370 -- Opcode COP0. 415 -- Opcode COP0.
371 mfc0_2 = "40000000TD", 416 mfc0_2 = "40000000TD",
372 mfc0_3 = "40000000TDW", 417 mfc0_3 = "40000000TDW",
418 dmfc0_2 = mips64 and "40200000TD",
419 dmfc0_3 = mips64 and "40200000TDW",
373 mtc0_2 = "40800000TD", 420 mtc0_2 = "40800000TD",
374 mtc0_3 = "40800000TDW", 421 mtc0_3 = "40800000TDW",
422 dmtc0_2 = mips64 and "40a00000TD",
423 dmtc0_3 = mips64 and "40a00000TDW",
375 rdpgpr_2 = "41400000DT", 424 rdpgpr_2 = "41400000DT",
376 di_0 = "41606000", 425 di_0 = "41606000",
377 di_1 = "41606000T", 426 di_1 = "41606000T",
@@ -388,9 +437,11 @@ local map_op = {
388 437
389 -- Opcode COP1. 438 -- Opcode COP1.
390 mfc1_2 = "44000000TG", 439 mfc1_2 = "44000000TG",
440 dmfc1_2 = mips64 and "44200000TG",
391 cfc1_2 = "44400000TG", 441 cfc1_2 = "44400000TG",
392 mfhc1_2 = "44600000TG", 442 mfhc1_2 = "44600000TG",
393 mtc1_2 = "44800000TG", 443 mtc1_2 = "44800000TG",
444 dmtc1_2 = mips64 and "44a00000TG",
394 ctc1_2 = "44c00000TG", 445 ctc1_2 = "44c00000TG",
395 mthc1_2 = "44e00000TG", 446 mthc1_2 = "44e00000TG",
396 447
@@ -633,7 +684,7 @@ local function parse_fpr(expr)
633 werror("bad register name `"..expr.."'") 684 werror("bad register name `"..expr.."'")
634end 685end
635 686
636local function parse_imm(imm, bits, shift, scale, signed) 687local function parse_imm(imm, bits, shift, scale, signed, action)
637 local n = tonumber(imm) 688 local n = tonumber(imm)
638 if n then 689 if n then
639 local m = sar(n, scale) 690 local m = sar(n, scale)
@@ -651,7 +702,8 @@ local function parse_imm(imm, bits, shift, scale, signed)
651 match(imm, "^([%w_]+):([rf][1-3]?[0-9])$") then 702 match(imm, "^([%w_]+):([rf][1-3]?[0-9])$") then
652 werror("expected immediate operand, got register") 703 werror("expected immediate operand, got register")
653 else 704 else
654 waction("IMM", (signed and 32768 or 0)+scale*1024+bits*32+shift, imm) 705 waction(action or "IMM",
706 (signed and 32768 or 0)+shl(scale, 10)+shl(bits, 5)+shift, imm)
655 return 0 707 return 0
656 end 708 end
657end 709end
@@ -763,6 +815,9 @@ map_op[".template__"] = function(params, template, nparams)
763 n = n + 1 815 n = n + 1
764 elseif p == "A" then 816 elseif p == "A" then
765 op = op + parse_imm(params[n], 5, 6, 0, false); n = n + 1 817 op = op + parse_imm(params[n], 5, 6, 0, false); n = n + 1
818 elseif p == "a" then
819 local m = parse_imm(params[n], 6, 6, 0, false, "IMMS"); n = n + 1
820 op = op + band(m, 0x7c0) + band(shr(m, 9), 4)
766 elseif p == "M" then 821 elseif p == "M" then
767 op = op + parse_imm(params[n], 5, 11, 0, false); n = n + 1 822 op = op + parse_imm(params[n], 5, 11, 0, false); n = n + 1
768 elseif p == "N" then 823 elseif p == "N" then