DynASM/MIPS: Add missing MIPS64 instructions.

Contributed by Djordje Kovacevic and Stefan Pejic from RT-RK.com.
Sponsored by Cisco Systems, Inc.
This commit is contained in:
Mike Pall 2016-05-28 05:03:18 +02:00
parent 5e2b609b3f
commit e3c4c9af0f
3 changed files with 84 additions and 14 deletions

View File

@ -21,7 +21,7 @@ enum {
/* The following actions need a buffer position. */ /* The following actions need a buffer position. */
DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG, DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG,
/* The following actions also have an argument. */ /* The following actions also have an argument. */
DASM_REL_PC, DASM_LABEL_PC, DASM_IMM, DASM_REL_PC, DASM_LABEL_PC, DASM_IMM, DASM_IMMS,
DASM__MAX DASM__MAX
}; };
@ -231,7 +231,7 @@ void dasm_put(Dst_DECL, int start, ...)
*pl = -pos; /* Label exists now. */ *pl = -pos; /* Label exists now. */
b[pos++] = ofs; /* Store pass1 offset estimate. */ b[pos++] = ofs; /* Store pass1 offset estimate. */
break; break;
case DASM_IMM: case DASM_IMM: case DASM_IMMS:
#ifdef DASM_CHECKS #ifdef DASM_CHECKS
CK((n & ((1<<((ins>>10)&31))-1)) == 0, RANGE_I); CK((n & ((1<<((ins>>10)&31))-1)) == 0, RANGE_I);
#endif #endif
@ -299,7 +299,7 @@ int dasm_link(Dst_DECL, size_t *szp)
case DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break; case DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break;
case DASM_REL_LG: case DASM_REL_PC: pos++; break; case DASM_REL_LG: case DASM_REL_PC: pos++; break;
case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break; case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;
case DASM_IMM: pos++; break; case DASM_IMM: case DASM_IMMS: pos++; break;
} }
} }
stop: (void)0; stop: (void)0;
@ -356,7 +356,7 @@ int dasm_encode(Dst_DECL, void *buffer)
if (ins & 2048) if (ins & 2048)
n = n - (int)((char *)cp - base); n = n - (int)((char *)cp - base);
else else
n = (n + (int)base) & 0x0fffffff; n = (n + (int)(size_t)base) & 0x0fffffff;
patchrel: patchrel:
CK((n & 3) == 0 && CK((n & 3) == 0 &&
((n + ((ins & 2048) ? 0x00020000 : 0)) >> ((n + ((ins & 2048) ? 0x00020000 : 0)) >>
@ -367,6 +367,9 @@ int dasm_encode(Dst_DECL, void *buffer)
ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n); ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n);
break; break;
case DASM_LABEL_PC: break; case DASM_LABEL_PC: break;
case DASM_IMMS:
cp[-1] |= ((n>>3) & 4); n &= 0x1f;
/* fallthrough */
case DASM_IMM: case DASM_IMM:
cp[-1] |= (n & ((1<<((ins>>5)&31))-1)) << (ins&31); cp[-1] |= (n & ((1<<((ins>>5)&31))-1)) << (ins&31);
break; break;

View File

@ -1,17 +1,19 @@
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
-- DynASM MIPS module. -- DynASM MIPS32/MIPS64 module.
-- --
-- Copyright (C) 2005-2016 Mike Pall. All rights reserved. -- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
-- See dynasm.lua for full copyright notice. -- See dynasm.lua for full copyright notice.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
local mips64 = mips64
-- Module information: -- Module information:
local _info = { local _info = {
arch = "mips", arch = mips64 and "mips64" or "mips",
description = "DynASM MIPS module", description = "DynASM MIPS32/MIPS64 module",
version = "1.4.0", version = "1.4.0",
vernum = 10400, vernum = 10400,
release = "2015-10-18", release = "2016-05-24",
author = "Mike Pall", author = "Mike Pall",
license = "MIT", license = "MIT",
} }
@ -27,7 +29,8 @@ local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
local match, gmatch = _s.match, _s.gmatch local match, gmatch = _s.match, _s.gmatch
local concat, sort = table.concat, table.sort local concat, sort = table.concat, table.sort
local bit = bit or require("bit") local bit = bit or require("bit")
local band, shl, sar, tohex = bit.band, bit.lshift, bit.arshift, bit.tohex local band, shl, shr, sar = bit.band, bit.lshift, bit.rshift, bit.arshift
local tohex = bit.tohex
-- Inherited tables and callbacks. -- Inherited tables and callbacks.
local g_opt, g_arch local g_opt, g_arch
@ -38,7 +41,7 @@ local wline, werror, wfatal, wwarn
local action_names = { local action_names = {
"STOP", "SECTION", "ESC", "REL_EXT", "STOP", "SECTION", "ESC", "REL_EXT",
"ALIGN", "REL_LG", "LABEL_LG", "ALIGN", "REL_LG", "LABEL_LG",
"REL_PC", "LABEL_PC", "IMM", "REL_PC", "LABEL_PC", "IMM", "IMMS",
} }
-- Maximum number of section buffer positions for dasm_put(). -- Maximum number of section buffer positions for dasm_put().
@ -251,6 +254,10 @@ local map_op = {
bnel_3 = "54000000STB", bnel_3 = "54000000STB",
blezl_2 = "58000000SB", blezl_2 = "58000000SB",
bgtzl_2 = "5c000000SB", bgtzl_2 = "5c000000SB",
daddi_3 = mips64 and "60000000TSI",
daddiu_3 = mips64 and "64000000TSI",
ldl_2 = mips64 and "68000000TO",
ldr_2 = mips64 and "6c000000TO",
lb_2 = "80000000TO", lb_2 = "80000000TO",
lh_2 = "84000000TO", lh_2 = "84000000TO",
lwl_2 = "88000000TO", lwl_2 = "88000000TO",
@ -258,23 +265,30 @@ local map_op = {
lbu_2 = "90000000TO", lbu_2 = "90000000TO",
lhu_2 = "94000000TO", lhu_2 = "94000000TO",
lwr_2 = "98000000TO", lwr_2 = "98000000TO",
lwu_2 = mips64 and "9c000000TO",
sb_2 = "a0000000TO", sb_2 = "a0000000TO",
sh_2 = "a4000000TO", sh_2 = "a4000000TO",
swl_2 = "a8000000TO", swl_2 = "a8000000TO",
sw_2 = "ac000000TO", sw_2 = "ac000000TO",
sdl_2 = mips64 and "b0000000TO",
sdr_2 = mips64 and "b1000000TO",
swr_2 = "b8000000TO", swr_2 = "b8000000TO",
cache_2 = "bc000000NO", cache_2 = "bc000000NO",
ll_2 = "c0000000TO", ll_2 = "c0000000TO",
lwc1_2 = "c4000000HO", lwc1_2 = "c4000000HO",
pref_2 = "cc000000NO", pref_2 = "cc000000NO",
ldc1_2 = "d4000000HO", ldc1_2 = "d4000000HO",
ld_2 = mips64 and "dc000000TO",
sc_2 = "e0000000TO", sc_2 = "e0000000TO",
swc1_2 = "e4000000HO", swc1_2 = "e4000000HO",
scd_2 = mips64 and "f0000000TO",
sdc1_2 = "f4000000HO", sdc1_2 = "f4000000HO",
sd_2 = mips64 and "fc000000TO",
-- Opcode SPECIAL. -- Opcode SPECIAL.
nop_0 = "00000000", nop_0 = "00000000",
sll_3 = "00000000DTA", sll_3 = "00000000DTA",
sextw_2 = "00000000DT",
movf_2 = "00000001DS", movf_2 = "00000001DS",
movf_3 = "00000001DSC", movf_3 = "00000001DSC",
movt_2 = "00010001DS", movt_2 = "00010001DS",
@ -285,6 +299,7 @@ local map_op = {
sllv_3 = "00000004DTS", sllv_3 = "00000004DTS",
srlv_3 = "00000006DTS", srlv_3 = "00000006DTS",
rotrv_3 = "00000046DTS", rotrv_3 = "00000046DTS",
drotrv_3 = mips64 and "00000056DTS",
srav_3 = "00000007DTS", srav_3 = "00000007DTS",
jr_1 = "00000008S", jr_1 = "00000008S",
jalr_1 = "0000f809S", jalr_1 = "0000f809S",
@ -300,15 +315,22 @@ local map_op = {
mthi_1 = "00000011S", mthi_1 = "00000011S",
mflo_1 = "00000012D", mflo_1 = "00000012D",
mtlo_1 = "00000013S", mtlo_1 = "00000013S",
dsllv_3 = mips64 and "00000014DTS",
dsrlv_3 = mips64 and "00000016DTS",
dsrav_3 = mips64 and "00000017DTS",
mult_2 = "00000018ST", mult_2 = "00000018ST",
multu_2 = "00000019ST", multu_2 = "00000019ST",
div_2 = "0000001aST", div_2 = "0000001aST",
divu_2 = "0000001bST", divu_2 = "0000001bST",
dmult_2 = mips64 and "0000001cST",
dmultu_2 = mips64 and "0000001dST",
ddiv_2 = mips64 and "0000001eST",
ddivu_2 = mips64 and "0000001fST",
add_3 = "00000020DST", add_3 = "00000020DST",
move_2 = "00000021DS", move_2 = mips64 and "00000025DS" or "00000021DS",
addu_3 = "00000021DST", addu_3 = "00000021DST",
sub_3 = "00000022DST", sub_3 = "00000022DST",
negu_2 = "00000023DT", negu_2 = mips64 and "0000002fDT" or "00000023DT",
subu_3 = "00000023DST", subu_3 = "00000023DST",
and_3 = "00000024DST", and_3 = "00000024DST",
or_3 = "00000025DST", or_3 = "00000025DST",
@ -317,6 +339,10 @@ local map_op = {
nor_3 = "00000027DST", nor_3 = "00000027DST",
slt_3 = "0000002aDST", slt_3 = "0000002aDST",
sltu_3 = "0000002bDST", sltu_3 = "0000002bDST",
dadd_3 = mips64 and "0000002cDST",
daddu_3 = mips64 and "0000002dDST",
dsub_3 = mips64 and "0000002eDST",
dsubu_3 = mips64 and "0000002fDST",
tge_2 = "00000030ST", tge_2 = "00000030ST",
tge_3 = "00000030STZ", tge_3 = "00000030STZ",
tgeu_2 = "00000031ST", tgeu_2 = "00000031ST",
@ -329,6 +355,14 @@ local map_op = {
teq_3 = "00000034STZ", teq_3 = "00000034STZ",
tne_2 = "00000036ST", tne_2 = "00000036ST",
tne_3 = "00000036STZ", tne_3 = "00000036STZ",
dsll_3 = mips64 and "00000038DTa",
dsrl_3 = mips64 and "0000003aDTa",
drotr_3 = mips64 and "0020003aDTa",
dsra_3 = mips64 and "0000003bDTa",
dsll32_3 = mips64 and "0000003cDTA",
dsrl32_3 = mips64 and "0000003eDTA",
drotr32_3 = mips64 and "0020003eDTA",
dsra32_3 = mips64 and "0000003fDTA",
-- Opcode REGIMM. -- Opcode REGIMM.
bltz_2 = "04000000SB", bltz_2 = "04000000SB",
@ -356,13 +390,24 @@ local map_op = {
msubu_2 = "70000005ST", msubu_2 = "70000005ST",
clz_2 = "70000020DS=", clz_2 = "70000020DS=",
clo_2 = "70000021DS=", clo_2 = "70000021DS=",
dclz_2 = mips64 and "70000024DS=",
dclo_2 = mips64 and "70000025DS=",
sdbbp_0 = "7000003f", sdbbp_0 = "7000003f",
sdbbp_1 = "7000003fY", sdbbp_1 = "7000003fY",
-- Opcode SPECIAL3. -- Opcode SPECIAL3.
ext_4 = "7c000000TSAM", -- Note: last arg is msbd = size-1 ext_4 = "7c000000TSAM", -- Note: last arg is msbd = size-1
dextm_4 = mips64 and "7c000001TSAM", -- Args: pos | size-1-32
dextu_4 = mips64 and "7c000002TSAM", -- Args: pos-32 | size-1
dext_4 = mips64 and "7c000003TSAM", -- Args: pos | size-1
zextw_2 = mips64 and "7c00f803TS",
ins_4 = "7c000004TSAM", -- Note: last arg is msb = pos+size-1 ins_4 = "7c000004TSAM", -- Note: last arg is msb = pos+size-1
dinsm_4 = mips64 and "7c000005TSAM", -- Args: pos | pos+size-33
dinsu_4 = mips64 and "7c000006TSAM", -- Args: pos-32 | pos+size-33
dins_4 = mips64 and "7c000007TSAM", -- Args: pos | pos+size-1
wsbh_2 = "7c0000a0DT", wsbh_2 = "7c0000a0DT",
dsbh_2 = mips64 and "7c0000a4DT",
dshd_2 = mips64 and "7c000164DT",
seb_2 = "7c000420DT", seb_2 = "7c000420DT",
seh_2 = "7c000620DT", seh_2 = "7c000620DT",
rdhwr_2 = "7c00003bTD", rdhwr_2 = "7c00003bTD",
@ -370,8 +415,12 @@ local map_op = {
-- Opcode COP0. -- Opcode COP0.
mfc0_2 = "40000000TD", mfc0_2 = "40000000TD",
mfc0_3 = "40000000TDW", mfc0_3 = "40000000TDW",
dmfc0_2 = mips64 and "40200000TD",
dmfc0_3 = mips64 and "40200000TDW",
mtc0_2 = "40800000TD", mtc0_2 = "40800000TD",
mtc0_3 = "40800000TDW", mtc0_3 = "40800000TDW",
dmtc0_2 = mips64 and "40a00000TD",
dmtc0_3 = mips64 and "40a00000TDW",
rdpgpr_2 = "41400000DT", rdpgpr_2 = "41400000DT",
di_0 = "41606000", di_0 = "41606000",
di_1 = "41606000T", di_1 = "41606000T",
@ -388,9 +437,11 @@ local map_op = {
-- Opcode COP1. -- Opcode COP1.
mfc1_2 = "44000000TG", mfc1_2 = "44000000TG",
dmfc1_2 = mips64 and "44200000TG",
cfc1_2 = "44400000TG", cfc1_2 = "44400000TG",
mfhc1_2 = "44600000TG", mfhc1_2 = "44600000TG",
mtc1_2 = "44800000TG", mtc1_2 = "44800000TG",
dmtc1_2 = mips64 and "44a00000TG",
ctc1_2 = "44c00000TG", ctc1_2 = "44c00000TG",
mthc1_2 = "44e00000TG", mthc1_2 = "44e00000TG",
@ -633,7 +684,7 @@ local function parse_fpr(expr)
werror("bad register name `"..expr.."'") werror("bad register name `"..expr.."'")
end end
local function parse_imm(imm, bits, shift, scale, signed) local function parse_imm(imm, bits, shift, scale, signed, action)
local n = tonumber(imm) local n = tonumber(imm)
if n then if n then
local m = sar(n, scale) local m = sar(n, scale)
@ -651,7 +702,8 @@ local function parse_imm(imm, bits, shift, scale, signed)
match(imm, "^([%w_]+):([rf][1-3]?[0-9])$") then match(imm, "^([%w_]+):([rf][1-3]?[0-9])$") then
werror("expected immediate operand, got register") werror("expected immediate operand, got register")
else else
waction("IMM", (signed and 32768 or 0)+scale*1024+bits*32+shift, imm) waction(action or "IMM",
(signed and 32768 or 0)+shl(scale, 10)+shl(bits, 5)+shift, imm)
return 0 return 0
end end
end end
@ -763,6 +815,9 @@ map_op[".template__"] = function(params, template, nparams)
n = n + 1 n = n + 1
elseif p == "A" then elseif p == "A" then
op = op + parse_imm(params[n], 5, 6, 0, false); n = n + 1 op = op + parse_imm(params[n], 5, 6, 0, false); n = n + 1
elseif p == "a" then
local m = parse_imm(params[n], 6, 6, 0, false, "IMMS"); n = n + 1
op = op + band(m, 0x7c0) + band(shr(m, 9), 4)
elseif p == "M" then elseif p == "M" then
op = op + parse_imm(params[n], 5, 11, 0, false); n = n + 1 op = op + parse_imm(params[n], 5, 11, 0, false); n = n + 1
elseif p == "N" then elseif p == "N" then

12
dynasm/dasm_mips64.lua Normal file
View File

@ -0,0 +1,12 @@
------------------------------------------------------------------------------
-- DynASM MIPS64 module.
--
-- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
-- See dynasm.lua for full copyright notice.
------------------------------------------------------------------------------
-- This module just sets 64 bit mode for the combined MIPS/MIPS64 module.
-- All the interesting stuff is there.
------------------------------------------------------------------------------
mips64 = true -- Using a global is an ugly, but effective solution.
return require("dasm_mips")