diff mbox series

[RFC,v1,08/23] riscv: tcg-target: Add support for the constraints

Message ID 1d5f88588063393fe28b689ce9501715022052ed.1542321076.git.alistair.francis@wdc.com
State New
Headers show
Series Add RISC-V TCG backend support | expand

Commit Message

Alistair Francis Nov. 15, 2018, 10:35 p.m. UTC
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
---
 tcg/riscv/tcg-target.inc.c | 139 +++++++++++++++++++++++++++++++++++++
 1 file changed, 139 insertions(+)

Comments

Richard Henderson Nov. 16, 2018, 8:13 a.m. UTC | #1
On 11/15/18 11:35 PM, Alistair Francis wrote:
> +    case 'L':
> +        /* qemu_ld/qemu_st constraint */
> +        ct->ct |= TCG_CT_REG;
> +        ct->u.regs = 0xffffffff;
> +        /* qemu_ld/qemu_st uses TCG_REG_TMP0 */
> +#if defined(CONFIG_SOFTMMU)
> +        /* tcg_out_tlb_load uses TCG_REG_TMP0/TMP1 and TCG_REG_L0/L1 */
> +        /* tcg_regset_reset_reg(ct->u.regs, TCG_REG_TMP0); */
> +        /* tcg_regset_reset_reg(ct->u.regs, TCG_REG_TMP1); */
> +        tcg_regset_reset_reg(ct->u.regs, TCG_REG_TMP2);

Normally TMP registers are reserved and do not need to be mentioned in
constraints at all.

> +    if ((ct & TCG_CT_CONST_S12) && val >= -2048 && val <= 2047) {
> +        return 1;
> +    }
> +    if ((ct & TCG_CT_CONST_N12) && val >= -2047 && val <= 2048) {
> +        return 1;
> +    }

Clearer as val == sextracttl(val, 0, 12)
and -val == sextracttl(-val, 0, 12)?


r~
diff mbox series

Patch

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index a9c57493a0..e585740870 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -119,6 +119,145 @@  static const int tcg_target_call_oarg_regs[] = {
 #define TCG_CT_CONST_S12   0x200
 #define TCG_CT_CONST_N12   0x400
 
+/* parse target specific constraints */
+static const char *target_parse_constraint(TCGArgConstraint *ct,
+                                           const char *ct_str, TCGType type)
+{
+    switch (*ct_str++) {
+    case 'r':
+        ct->ct |= TCG_CT_REG;
+        ct->u.regs = 0xffffffff;
+        break;
+    case 'L':
+        /* qemu_ld/qemu_st constraint */
+        ct->ct |= TCG_CT_REG;
+        ct->u.regs = 0xffffffff;
+        /* qemu_ld/qemu_st uses TCG_REG_TMP0 */
+#if defined(CONFIG_SOFTMMU)
+        /* tcg_out_tlb_load uses TCG_REG_TMP0/TMP1 and TCG_REG_L0/L1 */
+        /* tcg_regset_reset_reg(ct->u.regs, TCG_REG_TMP0); */
+        /* tcg_regset_reset_reg(ct->u.regs, TCG_REG_TMP1); */
+        tcg_regset_reset_reg(ct->u.regs, TCG_REG_TMP2);
+
+        tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[0]);
+        tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[1]);
+        tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[2]);
+        tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[3]);
+        tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[4]);
+#endif
+        break;
+    case 'I':
+        ct->ct |= TCG_CT_CONST_S12;
+        break;
+    case 'N':
+        ct->ct |= TCG_CT_CONST_N12;
+        break;
+    case 'Z':
+        /* we can use a zero immediate as a zero register argument. */
+        ct->ct |= TCG_CT_CONST_ZERO;
+        break;
+    default:
+        return NULL;
+    }
+    return ct_str;
+}
+
+/* test if a constant matches the constraint */
+static int tcg_target_const_match(tcg_target_long val, TCGType type,
+                                  const TCGArgConstraint *arg_ct)
+{
+    int ct = arg_ct->ct;
+    if (ct & TCG_CT_CONST) {
+        return 1;
+    }
+    if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
+        return 1;
+    }
+    if ((ct & TCG_CT_CONST_S12) && val >= -2048 && val <= 2047) {
+        return 1;
+    }
+    if ((ct & TCG_CT_CONST_N12) && val >= -2047 && val <= 2048) {
+        return 1;
+    }
+    return 0;
+}
+
+/*
+ * RISC-V Base ISA opcodes (IM)
+ */
+
+typedef enum {
+    OPC_ADD = 0x33,
+    OPC_ADDI = 0x13,
+    OPC_ADDIW = 0x1b,
+    OPC_ADDW = 0x3b,
+    OPC_AND = 0x7033,
+    OPC_ANDI = 0x7013,
+    OPC_AUIPC = 0x17,
+    OPC_BEQ = 0x63,
+    OPC_BGE = 0x5063,
+    OPC_BGEU = 0x7063,
+    OPC_BLT = 0x4063,
+    OPC_BLTU = 0x6063,
+    OPC_BNE = 0x1063,
+    OPC_DIV = 0x2004033,
+    OPC_DIVU = 0x2005033,
+    OPC_DIVUW = 0x200503b,
+    OPC_DIVW = 0x200403b,
+    OPC_JAL = 0x6f,
+    OPC_JALR = 0x67,
+    OPC_LB = 0x3,
+    OPC_LBU = 0x4003,
+    OPC_LD = 0x3003,
+    OPC_LH = 0x1003,
+    OPC_LHU = 0x5003,
+    OPC_LUI = 0x37,
+    OPC_LW = 0x2003,
+    OPC_LWU = 0x6003,
+    OPC_MUL = 0x2000033,
+    OPC_MULH = 0x2001033,
+    OPC_MULHSU = 0x2002033,
+    OPC_MULHU = 0x2003033,
+    OPC_MULW = 0x200003b,
+    OPC_OR = 0x6033,
+    OPC_ORI = 0x6013,
+    OPC_REM = 0x2006033,
+    OPC_REMU = 0x2007033,
+    OPC_REMUW = 0x200703b,
+    OPC_REMW = 0x200603b,
+    OPC_SB = 0x23,
+    OPC_SD = 0x3023,
+    OPC_SH = 0x1023,
+    OPC_SLL = 0x1033,
+    OPC_SLLI = 0x1013,
+    OPC_SLLIW = 0x101b,
+    OPC_SLLW = 0x103b,
+    OPC_SLT = 0x2033,
+    OPC_SLTI = 0x2013,
+    OPC_SLTIU = 0x3013,
+    OPC_SLTU = 0x3033,
+    OPC_SRA = 0x40005033,
+    OPC_SRAI = 0x40005013,
+    OPC_SRAIW = 0x4000501b,
+    OPC_SRAW = 0x4000503b,
+    OPC_SRL = 0x5033,
+    OPC_SRLI = 0x5013,
+    OPC_SRLIW = 0x501b,
+    OPC_SRLW = 0x503b,
+    OPC_SUB = 0x40000033,
+    OPC_SUBW = 0x4000003b,
+    OPC_SW = 0x2023,
+    OPC_XOR = 0x4033,
+    OPC_XORI = 0x4013,
+    OPC_FENCE_RW_RW = 0x0330000f,
+    OPC_FENCE_R_R = 0x0220000f,
+    OPC_FENCE_W_R = 0x0120000f,
+    OPC_FENCE_R_W = 0x0210000f,
+    OPC_FENCE_W_W = 0x0110000f,
+    OPC_FENCE_R_RW = 0x0230000f,
+    OPC_FENCE_RW_W = 0x0310000f,
+} RISCVInsn;
+
 typedef struct {
     DebugFrameHeader h;
     uint8_t fde_def_cfa[4];