tcg/riscv: Add the out load and store instructions
Signed-off-by: Alistair Francis <alistair.francis@wdc.com> Signed-off-by: Michael Clark <mjc@sifive.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <d5d88ff29163788938368bbdbd18815d59cef6a0.1545246859.git.alistair.francis@wdc.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
27fd64144b
commit
61535d4988
@ -630,3 +630,68 @@ static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg)
|
|||||||
{
|
{
|
||||||
tcg_out_opc_imm(s, OPC_ADDIW, ret, arg, 0);
|
tcg_out_opc_imm(s, OPC_ADDIW, ret, arg, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tcg_out_ldst(TCGContext *s, RISCVInsn opc, TCGReg data,
|
||||||
|
TCGReg addr, intptr_t offset)
|
||||||
|
{
|
||||||
|
intptr_t imm12 = sextreg(offset, 0, 12);
|
||||||
|
|
||||||
|
if (offset != imm12) {
|
||||||
|
intptr_t diff = offset - (uintptr_t)s->code_ptr;
|
||||||
|
|
||||||
|
if (addr == TCG_REG_ZERO && diff == (int32_t)diff) {
|
||||||
|
imm12 = sextreg(diff, 0, 12);
|
||||||
|
tcg_out_opc_upper(s, OPC_AUIPC, TCG_REG_TMP2, diff - imm12);
|
||||||
|
} else {
|
||||||
|
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP2, offset - imm12);
|
||||||
|
if (addr != TCG_REG_ZERO) {
|
||||||
|
tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP2, TCG_REG_TMP2, addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addr = TCG_REG_TMP2;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (opc) {
|
||||||
|
case OPC_SB:
|
||||||
|
case OPC_SH:
|
||||||
|
case OPC_SW:
|
||||||
|
case OPC_SD:
|
||||||
|
tcg_out_opc_store(s, opc, addr, data, imm12);
|
||||||
|
break;
|
||||||
|
case OPC_LB:
|
||||||
|
case OPC_LBU:
|
||||||
|
case OPC_LH:
|
||||||
|
case OPC_LHU:
|
||||||
|
case OPC_LW:
|
||||||
|
case OPC_LWU:
|
||||||
|
case OPC_LD:
|
||||||
|
tcg_out_opc_imm(s, opc, data, addr, imm12);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
|
||||||
|
TCGReg arg1, intptr_t arg2)
|
||||||
|
{
|
||||||
|
bool is32bit = (TCG_TARGET_REG_BITS == 32 || type == TCG_TYPE_I32);
|
||||||
|
tcg_out_ldst(s, is32bit ? OPC_LW : OPC_LD, arg, arg1, arg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
|
||||||
|
TCGReg arg1, intptr_t arg2)
|
||||||
|
{
|
||||||
|
bool is32bit = (TCG_TARGET_REG_BITS == 32 || type == TCG_TYPE_I32);
|
||||||
|
tcg_out_ldst(s, is32bit ? OPC_SW : OPC_SD, arg, arg1, arg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
|
||||||
|
TCGReg base, intptr_t ofs)
|
||||||
|
{
|
||||||
|
if (val == 0) {
|
||||||
|
tcg_out_st(s, type, TCG_REG_ZERO, base, ofs);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user