DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG,
/* The following actions also have an argument. */
DASM_REL_PC, DASM_LABEL_PC,
- DASM_IMM, DASM_IMM12, DASM_IMM13W, DASM_IMM13X, DASM_IMML,
+ DASM_IMM, DASM_IMM6, DASM_IMM12, DASM_IMM13W, DASM_IMM13X, DASM_IMML,
DASM__MAX
};
#endif
b[pos++] = n;
break;
+ case DASM_IMM6:
+ CK((n >> 6) == 0, RANGE_I);
+ b[pos++] = n;
+ break;
case DASM_IMM12:
CK(dasm_imm12((unsigned int)n) != -1, RANGE_I);
b[pos++] = n;
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: case DASM_IMM12: case DASM_IMM13W:
+ case DASM_IMM: case DASM_IMM6: case DASM_IMM12: case DASM_IMM13W:
case DASM_IMML: pos++; break;
case DASM_IMM13X: pos += 2; break;
}
case DASM_IMM:
cp[-1] |= ((n>>((ins>>10)&31)) & ((1<<((ins>>5)&31))-1)) << (ins&31);
break;
+ case DASM_IMM6:
+ cp[-1] |= ((n&31) << 19) | ((n&32) << 26);
+ break;
case DASM_IMM12:
cp[-1] |= (dasm_imm12((unsigned int)n) << 10);
break;
local action_names = {
"STOP", "SECTION", "ESC", "REL_EXT",
"ALIGN", "REL_LG", "LABEL_LG",
- "REL_PC", "LABEL_PC", "IMM", "IMM12", "IMM13W", "IMM13X", "IMML",
+ "REL_PC", "LABEL_PC", "IMM", "IMM6", "IMM12", "IMM13W", "IMM13X", "IMML",
}
-- Maximum number of section buffer positions for dasm_put().
local function parse_reg_base(expr)
if expr == "sp" then return 0x3e0 end
- local base = parse_reg(expr)
+ local base, tp = parse_reg(expr)
if parse_reg_type ~= "x" then werror("bad register type") end
parse_reg_type = false
- return shl(base, 5)
+ return shl(base, 5), tp
end
local parse_ctx = {}
end
werror("out of range immediate `"..imm.."'")
else
- werror("NYI imm6 action")
+ waction("IMM6", 0, imm)
+ return 0
end
end
end
local function parse_load(params, nparams, n, op)
- local pn = params[n]
- local p1, wb = match(pn, "^%[%s*(.-)%s*%](!?)$")
- if not p1 then werror("expected address operand") end
if params[n+2] then werror("too many operands") end
+ local pn, p2 = params[n], params[n+1]
+ local p1, wb = match(pn, "^%[%s*(.-)%s*%](!?)$")
+ if not p1 then
+ if not p2 then
+ local reg, tailr = match(pn, "^([%w_:]+)%s*(.*)$")
+ if reg and tailr ~= "" then
+ local base, tp = parse_reg_base(reg)
+ if tp then
+ waction("IMML", 0, format(tp.ctypefmt, tailr))
+ return op + base
+ end
+ end
+ end
+ werror("expected address operand")
+ end
local scale = shr(op, 30)
- local p2 = params[n+1]
if p2 then
if wb == "!" then werror("bad use of '!'") end
op = op + parse_reg_base(p1) + parse_imm(p2, 9, 12, 0, true) + 0x400
end
local function parse_load_pair(params, nparams, n, op)
- local pn = params[n]
- local p1, wb = match(pn, "^%[%s*(.-)%s*%](!?)$")
- if not p1 then werror("expected address operand") end
if params[n+2] then werror("too many operands") end
+ local pn, p2 = params[n], params[n+1]
local scale = shr(op, 30) == 0 and 2 or 3
- local p2 = params[n+1]
+ local p1, wb = match(pn, "^%[%s*(.-)%s*%](!?)$")
+ if not p1 then
+ if not p2 then
+ local reg, tailr = match(pn, "^([%w_:]+)%s*(.*)$")
+ if reg and tailr ~= "" then
+ local base, tp = parse_reg_base(reg)
+ if tp then
+ waction("IMM", 32768+7*32+15+scale*1024, format(tp.ctypefmt, tailr))
+ return op + base + 0x01000000
+ end
+ end
+ end
+ werror("expected address operand")
+ end
if p2 then
if wb == "!" then werror("bad use of '!'") end
op = op + 0x00800000
sxtb_2 = "13001c00DNw|93401c00DNx",
sxth_2 = "13003c00DNw|93403c00DNx",
- sxtw_2 = "93407c00DNx",
+ sxtw_2 = "93407c00DxNw",
uxtb_2 = "53001c00DNw",
uxth_2 = "53003c00DNw",
}
for cond,c in pairs(map_cond) do
- map_op["b"..cond.."_1"] = tohex(0x54000000+c)
+ map_op["b"..cond.."_1"] = tohex(0x54000000+c).."B"
end
------------------------------------------------------------------------------
-- A single opcode needs a maximum of 3 positions.
if secpos+3 > maxsecpos then wflush() end
local pos = wpos()
- local apos, spos = #actargs, secpos
+ local lpos, apos, spos = #actlist, #actargs, secpos
local ok, err
for t in gmatch(template, "[^|]+") do
ok, err = pcall(parse_template, params, t, nparams, pos)
if ok then return end
secpos = spos
+ actlist[lpos+1] = nil
+ actlist[lpos+2] = nil
+ actlist[lpos+3] = nil
actargs[apos+1] = nil
actargs[apos+2] = nil
actargs[apos+3] = nil