From d472a3cc1cbdd8a820f2638291d0968bb6312f47 Mon Sep 17 00:00:00 2001 From: Michael Munday Date: Thu, 8 Dec 2016 15:29:26 -0500 Subject: [PATCH] Add support for .type directives. --- dynasm/Examples/test_z_inst.c | 20 +++++++++++++++++++- dynasm/dasm_s390x.lua | 25 +++++++++++++++++++++---- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/dynasm/Examples/test_z_inst.c b/dynasm/Examples/test_z_inst.c index c17aebcd..a8895c05 100644 --- a/dynasm/Examples/test_z_inst.c +++ b/dynasm/Examples/test_z_inst.c @@ -291,6 +291,23 @@ static void ssa_act(dasm_State *state) { | br r14 } +typedef struct { + int a; + int b; +} SimpleStruct; + +static void type(dasm_State *state) { + dasm_State **Dst = &state; + + | .type SIMPLE, SimpleStruct + | lay sp, -8(sp) + | stg r2, 0(sp) + | xgr r2, r2 + | l r2, SIMPLE:sp->b + | la sp, 8(sp) + | br r14 +} + typedef struct { int64_t arg1; int64_t arg2; @@ -317,7 +334,8 @@ test_table test[] = { // { 9,8, add_rrd, 25, "add_rrd"}, // { 2,4, load_test, 4,"load_test"}, {-1, 0, ssa, 65535<<8, "ssa"}, - {-1, 0, ssa_act, 65535<<8, "ssa_act"} + {-1, 0, ssa_act, 65535<<8, "ssa_act"}, + {27, 0, type, 27, "type"} }; static void *jitcode(dasm_State **state, size_t *size) diff --git a/dynasm/dasm_s390x.lua b/dynasm/dasm_s390x.lua index 3fa4c13a..3a5c5000 100644 --- a/dynasm/dasm_s390x.lua +++ b/dynasm/dasm_s390x.lua @@ -247,7 +247,17 @@ local map_cond = { ------------------------------------------------------------------------------ local function parse_reg(expr) - local r = match(expr, "^[r|f](1?[0-9])$") + if not expr then werror("expected register name") end + local tname, ovreg = match(expr, "^([%w_]+):(r1?%d)$") + local tp = map_type[tname or expr] + if tp then + local reg = ovreg or tp.reg + if not reg then + werror("type `"..(tname or expr).."' needs a register override") + end + expr = reg + end + local r = match(expr, "^[rf](1?%d)$") if r then r = tonumber(r) if r <= 15 then return r, tp end @@ -296,15 +306,22 @@ end -- Split a memory operand of the form d(b) or d(x,b) into d, x and b. -- If x is not specified then it is 0. local function split_memop(arg) - local reg = "r1?[0-9]" - local d, x, b = match(arg, "^(.*)%(("..reg.."), ("..reg..")%)$") + local reg = "[%w_:]+" + local d, x, b = match(arg, "^(.*)%(%s*("..reg..")%s*,%s*("..reg..")%s*%)$") if d then return d, parse_reg(x), parse_reg(b) end - local d, b = match(arg, "^(.*)%(("..reg..")%)$") + local d, b = match(arg, "^(.*)%(%s*("..reg..")%s*%)$") if d then return d, 0, parse_reg(b) end + local reg, tailr = match(arg, "^([%w_:]+)%s*(.*)$") + if reg then + local r, tp = parse_reg(reg) + if tp then + return format(tp.ctypefmt, tailr), 0, r + end + end -- TODO: handle values without registers? -- TODO: handle registers without a displacement? werror("bad memory operand: "..arg)