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)
This commit is contained in:
Michael Munday 2016-12-01 17:09:45 -05:00
parent c71a6189bb
commit 77f283c328
2 changed files with 17 additions and 12 deletions

View File

@ -234,8 +234,10 @@ void dasm_put(Dst_DECL, int start, ...)
case DASM_IMM16: case DASM_IMM16:
case DASM_IMM32: case DASM_IMM32:
case DASM_DISP20: case DASM_DISP20:
case DASM_DISP12:
fprintf(stderr, "not implemented\n"); fprintf(stderr, "not implemented\n");
case DASM_DISP12:
CK((n>>12) == 0, RANGE_I);
b[pos++] = n;
break; break;
} }
} }
@ -296,7 +298,7 @@ int dasm_link(Dst_DECL, size_t *szp)
case DASM_IMM32: case DASM_IMM32:
case DASM_DISP20: case DASM_DISP20:
case DASM_DISP12: case DASM_DISP12:
fprintf(stderr, "not implemented\n"); pos++;
break; break;
} }
} }
@ -364,9 +366,11 @@ int dasm_encode(Dst_DECL, void *buffer)
case DASM_IMM16: case DASM_IMM16:
case DASM_IMM32: case DASM_IMM32:
case DASM_DISP20: case DASM_DISP20:
case DASM_DISP12:
fprintf(stderr, "not implemented\n"); fprintf(stderr, "not implemented\n");
break; break;
case DASM_DISP12:
cp[-1] |= n&0xfff;
break;
default: *cp++ = ins; break; default: *cp++ = ins; break;
} }
} }

View File

@ -316,6 +316,8 @@ end
-- Parse memory operand of the form d(x, b) where 0 <= d < 4096 and b and x -- Parse memory operand of the form d(x, b) where 0 <= d < 4096 and b and x
-- are GPRs. -- are GPRs.
-- If the fourth return value is not-nil then it needs to be called to
-- insert an action.
-- Encoded as: xbddd -- Encoded as: xbddd
local function parse_mem_bx(arg) local function parse_mem_bx(arg)
local d, x, b = split_memop(arg) local d, x, b = split_memop(arg)
@ -326,11 +328,10 @@ local function parse_mem_bx(arg)
end end
return dval, x, b, nil return dval, x, b, nil
end end
-- TODO: handle d being a symbol. if match(d, "^[rf]1?[0-9]?") then
-- Action is currently the final return value (the caller needs to add it werror("expected immediate operand, got register")
-- to the action list at a later point). end
werror("parse_mem_bx: not implemented") return 0, x, b, function() waction("DISP12", nil, d) end
return nil
end end
-- Parse memory operand of the form d(b) where -(2^20)/2 <= d < (2^20)/2 and -- 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 op2 = op2 + shl(b, 12) + d
wputhw(op1); wputhw(op2); wputhw(op1); wputhw(op2);
if a then if a then
werror("disp12 actions not yet implemented") a()
end end
elseif p == "k" then elseif p == "k" then
@ -1034,7 +1035,7 @@ local function parse_template(params, template, nparams, pos)
op2 = op2 + shl(b, 12) + d op2 = op2 + shl(b, 12) + d
wputhw(op1); wputhw(op2); wputhw(op1); wputhw(op2);
if a then if a then
werror("disp12 actions not yet implemented") a()
end end
elseif p == "z" then elseif p == "z" then
op2 = op2 + parse_gpr(params[1]) op2 = op2 + parse_gpr(params[1])
@ -1046,8 +1047,8 @@ end
function op_template(params, template, nparams) function op_template(params, template, nparams)
if not params then return template:gsub("%x%x%x%x%x%x%x%x", "") end 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(). -- Limit number of section buffer positions used by a single dasm_put().
-- A single opcode needs a maximum of 3 positions. -- A single opcode needs a maximum of 5 positions.
if secpos+3 > maxsecpos then wflush() end if secpos+5 > maxsecpos then wflush() end
local lpos, apos, spos = #actlist, #actargs, secpos local lpos, apos, spos = #actlist, #actargs, secpos
local ok, err local ok, err
for t in gmatch(template, "[^|]+") do for t in gmatch(template, "[^|]+") do