From b2a5cc82338aad90ca16fced8631ac1a634949e9 Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Sun, 12 Apr 2015 01:25:14 +0200 Subject: [PATCH] DynASM/PPC: Add support for parameterized shifts/masks. --- dynasm/dasm_ppc.h | 11 +++++++++-- dynasm/dasm_ppc.lua | 9 +++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/dynasm/dasm_ppc.h b/dynasm/dasm_ppc.h index 2ded2580..332c64dc 100644 --- a/dynasm/dasm_ppc.h +++ b/dynasm/dasm_ppc.h @@ -21,7 +21,7 @@ enum { /* The following actions need a buffer position. */ DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG, /* The following actions also have an argument. */ - DASM_REL_PC, DASM_LABEL_PC, DASM_IMM, + DASM_REL_PC, DASM_LABEL_PC, DASM_IMM, DASM_IMMSH, DASM__MAX }; @@ -244,6 +244,10 @@ void dasm_put(Dst_DECL, int start, ...) #endif b[pos++] = n; break; + case DASM_IMMSH: + CK((n >> 6) == 0, RANGE_I); + b[pos++] = n; + break; } } } @@ -299,7 +303,7 @@ int dasm_link(Dst_DECL, size_t *szp) case DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); 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_IMM: pos++; break; + case DASM_IMM: case DASM_IMMSH: pos++; break; } } stop: (void)0; @@ -366,6 +370,9 @@ int dasm_encode(Dst_DECL, void *buffer) case DASM_IMM: cp[-1] |= (n & ((1<<((ins>>5)&31))-1)) << (ins&31); break; + case DASM_IMMSH: + cp[-1] |= (ins & 1) ? ((n&31)<<11)|((n&32)>>4) : ((n&31)<<6)|(n&32); + break; default: *cp++ = ins; break; } } diff --git a/dynasm/dasm_ppc.lua b/dynasm/dasm_ppc.lua index 37447072..784223df 100644 --- a/dynasm/dasm_ppc.lua +++ b/dynasm/dasm_ppc.lua @@ -41,7 +41,7 @@ local wline, werror, wfatal, wwarn local action_names = { "STOP", "SECTION", "ESC", "REL_EXT", "ALIGN", "REL_LG", "LABEL_LG", - "REL_PC", "LABEL_PC", "IMM", + "REL_PC", "LABEL_PC", "IMM", "IMMSH" } -- Maximum number of section buffer positions for dasm_put(). @@ -1482,8 +1482,8 @@ local function parse_shiftmask(imm, isshift) local n = tonumber(imm) if n then if shr(n, 6) == 0 then - local lsb = band(imm, 31) - local msb = imm - lsb + local lsb = band(n, 31) + local msb = n - lsb return isshift and (shl(lsb, 11)+shr(msb, 4)) or (shl(lsb, 6)+msb) end werror("out of range immediate `"..imm.."'") @@ -1491,7 +1491,8 @@ local function parse_shiftmask(imm, isshift) match(imm, "^([%w_]+):(r[1-3]?[0-9])$") then werror("expected immediate operand, got register") else - werror("NYI: parameterized 64 bit shift/mask") + waction("IMMSH", isshift and 1 or 0, imm) + return 0; end end