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);
|
||||
}
|
||||
|
||||
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