From 77f283c328b45f65656075443757522a860a9910 Mon Sep 17 00:00:00 2001 From: Michael Munday Date: Thu, 1 Dec 2016 17:09:45 -0500 Subject: [PATCH] Allow symbols to be used for 12-bit displacements. The parse_mem_bx function now returns a function to call to add an action to the action list to handle the evaluation of the displacement. This allows us to delay adding said action until after we have emitted the actions for the instruction encodings themselves. Code like this should now work: int x = 24 | st r1, x(sp) --- dynasm/dasm_s390x.h | 10 +++++++--- dynasm/dasm_s390x.lua | 19 ++++++++++--------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/dynasm/dasm_s390x.h b/dynasm/dasm_s390x.h index 837a2ed0..8b43a78c 100644 --- a/dynasm/dasm_s390x.h +++ b/dynasm/dasm_s390x.h @@ -234,8 +234,10 @@ void dasm_put(Dst_DECL, int start, ...) case DASM_IMM16: case DASM_IMM32: case DASM_DISP20: - case DASM_DISP12: fprintf(stderr, "not implemented\n"); + case DASM_DISP12: + CK((n>>12) == 0, RANGE_I); + b[pos++] = n; break; } } @@ -296,7 +298,7 @@ int dasm_link(Dst_DECL, size_t *szp) case DASM_IMM32: case DASM_DISP20: case DASM_DISP12: - fprintf(stderr, "not implemented\n"); + pos++; break; } } @@ -364,8 +366,10 @@ int dasm_encode(Dst_DECL, void *buffer) case DASM_IMM16: case DASM_IMM32: case DASM_DISP20: - case DASM_DISP12: fprintf(stderr, "not implemented\n"); + break; + case DASM_DISP12: + cp[-1] |= n&0xfff; break; default: *cp++ = ins; break; } diff --git a/dynasm/dasm_s390x.lua b/dynasm/dasm_s390x.lua index 2ee94930..b3061653 100644 --- a/dynasm/dasm_s390x.lua +++ b/dynasm/dasm_s390x.lua @@ -316,6 +316,8 @@ end -- Parse memory operand of the form d(x, b) where 0 <= d < 4096 and b and x -- are GPRs. +-- If the fourth return value is not-nil then it needs to be called to +-- insert an action. -- Encoded as: xbddd local function parse_mem_bx(arg) local d, x, b = split_memop(arg) @@ -326,11 +328,10 @@ local function parse_mem_bx(arg) end return dval, x, b, nil end - -- TODO: handle d being a symbol. - -- Action is currently the final return value (the caller needs to add it - -- to the action list at a later point). - werror("parse_mem_bx: not implemented") - return nil + if match(d, "^[rf]1?[0-9]?") then + werror("expected immediate operand, got register") + end + return 0, x, b, function() waction("DISP12", nil, d) end end -- Parse memory operand of the form d(b) where -(2^20)/2 <= d < (2^20)/2 and @@ -1018,7 +1019,7 @@ local function parse_template(params, template, nparams, pos) op2 = op2 + shl(b, 12) + d wputhw(op1); wputhw(op2); if a then - werror("disp12 actions not yet implemented") + a() end elseif p == "k" then @@ -1034,7 +1035,7 @@ local function parse_template(params, template, nparams, pos) op2 = op2 + shl(b, 12) + d wputhw(op1); wputhw(op2); if a then - werror("disp12 actions not yet implemented") + a() end elseif p == "z" then op2 = op2 + parse_gpr(params[1]) @@ -1046,8 +1047,8 @@ end function op_template(params, template, nparams) if not params then return template:gsub("%x%x%x%x%x%x%x%x", "") end -- Limit number of section buffer positions used by a single dasm_put(). - -- A single opcode needs a maximum of 3 positions. - if secpos+3 > maxsecpos then wflush() end + -- A single opcode needs a maximum of 5 positions. + if secpos+5 > maxsecpos then wflush() end local lpos, apos, spos = #actlist, #actargs, secpos local ok, err for t in gmatch(template, "[^|]+") do