Add support for .type directives.

This commit is contained in:
Michael Munday 2016-12-08 15:29:26 -05:00
parent b98c92e142
commit d472a3cc1c
2 changed files with 40 additions and 5 deletions

View File

@ -291,6 +291,23 @@ static void ssa_act(dasm_State *state) {
| br r14 | 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 { typedef struct {
int64_t arg1; int64_t arg1;
int64_t arg2; int64_t arg2;
@ -317,7 +334,8 @@ test_table test[] = {
// { 9,8, add_rrd, 25, "add_rrd"}, // { 9,8, add_rrd, 25, "add_rrd"},
// { 2,4, load_test, 4,"load_test"}, // { 2,4, load_test, 4,"load_test"},
{-1, 0, ssa, 65535<<8, "ssa"}, {-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) static void *jitcode(dasm_State **state, size_t *size)

View File

@ -247,7 +247,17 @@ local map_cond = {
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
local function parse_reg(expr) 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 if r then
r = tonumber(r) r = tonumber(r)
if r <= 15 then return r, tp end 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. -- 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. -- If x is not specified then it is 0.
local function split_memop(arg) local function split_memop(arg)
local reg = "r1?[0-9]" local reg = "[%w_:]+"
local d, x, b = match(arg, "^(.*)%(("..reg.."), ("..reg..")%)$") local d, x, b = match(arg, "^(.*)%(%s*("..reg..")%s*,%s*("..reg..")%s*%)$")
if d then if d then
return d, parse_reg(x), parse_reg(b) return d, parse_reg(x), parse_reg(b)
end end
local d, b = match(arg, "^(.*)%(("..reg..")%)$") local d, b = match(arg, "^(.*)%(%s*("..reg..")%s*%)$")
if d then if d then
return d, 0, parse_reg(b) return d, 0, parse_reg(b)
end 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 values without registers?
-- TODO: handle registers without a displacement? -- TODO: handle registers without a displacement?
werror("bad memory operand: "..arg) werror("bad memory operand: "..arg)