|
@@ -184,12 +184,11 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
|
|
|
g_assert_not_reached();
|
|
|
}
|
|
|
|
|
|
-#define TCG_CT_CONST_ZERO 0x100
|
|
|
-#define TCG_CT_CONST_U16 0x200 /* Unsigned 16-bit: 0 - 0xffff. */
|
|
|
-#define TCG_CT_CONST_S16 0x400 /* Signed 16-bit: -32768 - 32767 */
|
|
|
-#define TCG_CT_CONST_P2M1 0x800 /* Power of 2 minus 1. */
|
|
|
-#define TCG_CT_CONST_N16 0x1000 /* "Negatable" 16-bit: -32767 - 32767 */
|
|
|
-#define TCG_CT_CONST_WSZ 0x2000 /* word size */
|
|
|
+#define TCG_CT_CONST_U16 0x100 /* Unsigned 16-bit: 0 - 0xffff. */
|
|
|
+#define TCG_CT_CONST_S16 0x200 /* Signed 16-bit: -32768 - 32767 */
|
|
|
+#define TCG_CT_CONST_P2M1 0x400 /* Power of 2 minus 1. */
|
|
|
+#define TCG_CT_CONST_N16 0x800 /* "Negatable" 16-bit: -32767 - 32767 */
|
|
|
+#define TCG_CT_CONST_WSZ 0x1000 /* word size */
|
|
|
|
|
|
#define ALL_GENERAL_REGS 0xffffffffu
|
|
|
|
|
@@ -204,8 +203,6 @@ static bool tcg_target_const_match(int64_t val, int ct,
|
|
|
{
|
|
|
if (ct & TCG_CT_CONST) {
|
|
|
return 1;
|
|
|
- } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
|
|
|
- return 1;
|
|
|
} else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val) {
|
|
|
return 1;
|
|
|
} else if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) {
|
|
@@ -1217,8 +1214,7 @@ bool tcg_target_has_memory_bswap(MemOp memop)
|
|
|
* is required and fill in @h with the host address for the fast path.
|
|
|
*/
|
|
|
static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|
|
- TCGReg addrlo, TCGReg addrhi,
|
|
|
- MemOpIdx oi, bool is_ld)
|
|
|
+ TCGReg addr, MemOpIdx oi, bool is_ld)
|
|
|
{
|
|
|
TCGType addr_type = s->addr_type;
|
|
|
TCGLabelQemuLdst *ldst = NULL;
|
|
@@ -1245,8 +1241,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|
|
ldst = new_ldst_label(s);
|
|
|
ldst->is_ld = is_ld;
|
|
|
ldst->oi = oi;
|
|
|
- ldst->addrlo_reg = addrlo;
|
|
|
- ldst->addrhi_reg = addrhi;
|
|
|
+ ldst->addr_reg = addr;
|
|
|
|
|
|
/* Load tlb_mask[mmu_idx] and tlb_table[mmu_idx]. */
|
|
|
tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP0, TCG_AREG0, mask_off);
|
|
@@ -1254,29 +1249,26 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|
|
|
|
|
/* Extract the TLB index from the address into TMP3. */
|
|
|
if (TCG_TARGET_REG_BITS == 32 || addr_type == TCG_TYPE_I32) {
|
|
|
- tcg_out_opc_sa(s, OPC_SRL, TCG_TMP3, addrlo,
|
|
|
+ tcg_out_opc_sa(s, OPC_SRL, TCG_TMP3, addr,
|
|
|
s->page_bits - CPU_TLB_ENTRY_BITS);
|
|
|
} else {
|
|
|
- tcg_out_dsrl(s, TCG_TMP3, addrlo,
|
|
|
- s->page_bits - CPU_TLB_ENTRY_BITS);
|
|
|
+ tcg_out_dsrl(s, TCG_TMP3, addr, s->page_bits - CPU_TLB_ENTRY_BITS);
|
|
|
}
|
|
|
tcg_out_opc_reg(s, OPC_AND, TCG_TMP3, TCG_TMP3, TCG_TMP0);
|
|
|
|
|
|
/* Add the tlb_table pointer, creating the CPUTLBEntry address. */
|
|
|
tcg_out_opc_reg(s, ALIAS_PADD, TCG_TMP3, TCG_TMP3, TCG_TMP1);
|
|
|
|
|
|
- if (TCG_TARGET_REG_BITS == 32 || addr_type == TCG_TYPE_I32) {
|
|
|
- /* Load the (low half) tlb comparator. */
|
|
|
+ /* Load the tlb comparator. */
|
|
|
+ if (TCG_TARGET_REG_BITS == 64 && addr_type == TCG_TYPE_I32) {
|
|
|
tcg_out_ld(s, TCG_TYPE_I32, TCG_TMP0, TCG_TMP3,
|
|
|
cmp_off + HOST_BIG_ENDIAN * 4);
|
|
|
} else {
|
|
|
- tcg_out_ld(s, TCG_TYPE_I64, TCG_TMP0, TCG_TMP3, cmp_off);
|
|
|
+ tcg_out_ld(s, TCG_TYPE_REG, TCG_TMP0, TCG_TMP3, cmp_off);
|
|
|
}
|
|
|
|
|
|
- if (TCG_TARGET_REG_BITS == 64 || addr_type == TCG_TYPE_I32) {
|
|
|
- /* Load the tlb addend for the fast path. */
|
|
|
- tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP3, TCG_TMP3, add_off);
|
|
|
- }
|
|
|
+ /* Load the tlb addend for the fast path. */
|
|
|
+ tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP3, TCG_TMP3, add_off);
|
|
|
|
|
|
/*
|
|
|
* Mask the page bits, keeping the alignment bits to compare against.
|
|
@@ -1288,48 +1280,35 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|
|
tcg_out_opc_imm(s, (TCG_TARGET_REG_BITS == 32
|
|
|
|| addr_type == TCG_TYPE_I32
|
|
|
? OPC_ADDIU : OPC_DADDIU),
|
|
|
- TCG_TMP2, addrlo, s_mask - a_mask);
|
|
|
+ TCG_TMP2, addr, s_mask - a_mask);
|
|
|
tcg_out_opc_reg(s, OPC_AND, TCG_TMP1, TCG_TMP1, TCG_TMP2);
|
|
|
} else {
|
|
|
- tcg_out_opc_reg(s, OPC_AND, TCG_TMP1, TCG_TMP1, addrlo);
|
|
|
+ tcg_out_opc_reg(s, OPC_AND, TCG_TMP1, TCG_TMP1, addr);
|
|
|
}
|
|
|
|
|
|
/* Zero extend a 32-bit guest address for a 64-bit host. */
|
|
|
if (TCG_TARGET_REG_BITS == 64 && addr_type == TCG_TYPE_I32) {
|
|
|
- tcg_out_ext32u(s, TCG_TMP2, addrlo);
|
|
|
- addrlo = TCG_TMP2;
|
|
|
+ tcg_out_ext32u(s, TCG_TMP2, addr);
|
|
|
+ addr = TCG_TMP2;
|
|
|
}
|
|
|
|
|
|
ldst->label_ptr[0] = s->code_ptr;
|
|
|
tcg_out_opc_br(s, OPC_BNE, TCG_TMP1, TCG_TMP0);
|
|
|
|
|
|
- /* Load and test the high half tlb comparator. */
|
|
|
- if (TCG_TARGET_REG_BITS == 32 && addr_type != TCG_TYPE_I32) {
|
|
|
- /* delay slot */
|
|
|
- tcg_out_ldst(s, OPC_LW, TCG_TMP0, TCG_TMP3, cmp_off + HI_OFF);
|
|
|
-
|
|
|
- /* Load the tlb addend for the fast path. */
|
|
|
- tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP3, TCG_TMP3, add_off);
|
|
|
-
|
|
|
- ldst->label_ptr[1] = s->code_ptr;
|
|
|
- tcg_out_opc_br(s, OPC_BNE, addrhi, TCG_TMP0);
|
|
|
- }
|
|
|
-
|
|
|
/* delay slot */
|
|
|
base = TCG_TMP3;
|
|
|
- tcg_out_opc_reg(s, ALIAS_PADD, base, TCG_TMP3, addrlo);
|
|
|
+ tcg_out_opc_reg(s, ALIAS_PADD, base, TCG_TMP3, addr);
|
|
|
} else {
|
|
|
if (a_mask && (use_mips32r6_instructions || a_bits != s_bits)) {
|
|
|
ldst = new_ldst_label(s);
|
|
|
|
|
|
ldst->is_ld = is_ld;
|
|
|
ldst->oi = oi;
|
|
|
- ldst->addrlo_reg = addrlo;
|
|
|
- ldst->addrhi_reg = addrhi;
|
|
|
+ ldst->addr_reg = addr;
|
|
|
|
|
|
/* We are expecting a_bits to max out at 7, much lower than ANDI. */
|
|
|
tcg_debug_assert(a_bits < 16);
|
|
|
- tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP0, addrlo, a_mask);
|
|
|
+ tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP0, addr, a_mask);
|
|
|
|
|
|
ldst->label_ptr[0] = s->code_ptr;
|
|
|
if (use_mips32r6_instructions) {
|
|
@@ -1340,7 +1319,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- base = addrlo;
|
|
|
+ base = addr;
|
|
|
if (TCG_TARGET_REG_BITS == 64 && addr_type == TCG_TYPE_I32) {
|
|
|
tcg_out_ext32u(s, TCG_REG_A0, base);
|
|
|
base = TCG_REG_A0;
|
|
@@ -1460,14 +1439,13 @@ static void tcg_out_qemu_ld_unalign(TCGContext *s, TCGReg lo, TCGReg hi,
|
|
|
}
|
|
|
|
|
|
static void tcg_out_qemu_ld(TCGContext *s, TCGReg datalo, TCGReg datahi,
|
|
|
- TCGReg addrlo, TCGReg addrhi,
|
|
|
- MemOpIdx oi, TCGType data_type)
|
|
|
+ TCGReg addr, MemOpIdx oi, TCGType data_type)
|
|
|
{
|
|
|
MemOp opc = get_memop(oi);
|
|
|
TCGLabelQemuLdst *ldst;
|
|
|
HostAddress h;
|
|
|
|
|
|
- ldst = prepare_host_addr(s, &h, addrlo, addrhi, oi, true);
|
|
|
+ ldst = prepare_host_addr(s, &h, addr, oi, true);
|
|
|
|
|
|
if (use_mips32r6_instructions || h.aa.align >= (opc & MO_SIZE)) {
|
|
|
tcg_out_qemu_ld_direct(s, datalo, datahi, h.base, opc, data_type);
|
|
@@ -1547,14 +1525,13 @@ static void tcg_out_qemu_st_unalign(TCGContext *s, TCGReg lo, TCGReg hi,
|
|
|
}
|
|
|
|
|
|
static void tcg_out_qemu_st(TCGContext *s, TCGReg datalo, TCGReg datahi,
|
|
|
- TCGReg addrlo, TCGReg addrhi,
|
|
|
- MemOpIdx oi, TCGType data_type)
|
|
|
+ TCGReg addr, MemOpIdx oi, TCGType data_type)
|
|
|
{
|
|
|
MemOp opc = get_memop(oi);
|
|
|
TCGLabelQemuLdst *ldst;
|
|
|
HostAddress h;
|
|
|
|
|
|
- ldst = prepare_host_addr(s, &h, addrlo, addrhi, oi, false);
|
|
|
+ ldst = prepare_host_addr(s, &h, addr, oi, false);
|
|
|
|
|
|
if (use_mips32r6_instructions || h.aa.align >= (opc & MO_SIZE)) {
|
|
|
tcg_out_qemu_st_direct(s, datalo, datahi, h.base, opc);
|
|
@@ -1686,11 +1663,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|
|
TCGArg a0, a1, a2;
|
|
|
int c2;
|
|
|
|
|
|
- /*
|
|
|
- * Note that many operands use the constraint set "rZ".
|
|
|
- * We make use of the fact that 0 is the ZERO register,
|
|
|
- * and hence such cases need not check for const_args.
|
|
|
- */
|
|
|
a0 = args[0];
|
|
|
a1 = args[1];
|
|
|
a2 = args[2];
|
|
@@ -2095,51 +2067,25 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|
|
tcg_out_setcond2(s, args[5], a0, a1, a2, args[3], args[4]);
|
|
|
break;
|
|
|
|
|
|
- case INDEX_op_qemu_ld_a64_i32:
|
|
|
- if (TCG_TARGET_REG_BITS == 32) {
|
|
|
- tcg_out_qemu_ld(s, a0, 0, a1, a2, args[3], TCG_TYPE_I32);
|
|
|
- break;
|
|
|
- }
|
|
|
- /* fall through */
|
|
|
- case INDEX_op_qemu_ld_a32_i32:
|
|
|
- tcg_out_qemu_ld(s, a0, 0, a1, 0, a2, TCG_TYPE_I32);
|
|
|
- break;
|
|
|
- case INDEX_op_qemu_ld_a32_i64:
|
|
|
- if (TCG_TARGET_REG_BITS == 64) {
|
|
|
- tcg_out_qemu_ld(s, a0, 0, a1, 0, a2, TCG_TYPE_I64);
|
|
|
- } else {
|
|
|
- tcg_out_qemu_ld(s, a0, a1, a2, 0, args[3], TCG_TYPE_I64);
|
|
|
- }
|
|
|
+ case INDEX_op_qemu_ld_i32:
|
|
|
+ tcg_out_qemu_ld(s, a0, 0, a1, a2, TCG_TYPE_I32);
|
|
|
break;
|
|
|
- case INDEX_op_qemu_ld_a64_i64:
|
|
|
+ case INDEX_op_qemu_ld_i64:
|
|
|
if (TCG_TARGET_REG_BITS == 64) {
|
|
|
- tcg_out_qemu_ld(s, a0, 0, a1, 0, a2, TCG_TYPE_I64);
|
|
|
+ tcg_out_qemu_ld(s, a0, 0, a1, a2, TCG_TYPE_I64);
|
|
|
} else {
|
|
|
- tcg_out_qemu_ld(s, a0, a1, a2, args[3], args[4], TCG_TYPE_I64);
|
|
|
+ tcg_out_qemu_ld(s, a0, a1, a2, args[3], TCG_TYPE_I64);
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
- case INDEX_op_qemu_st_a64_i32:
|
|
|
- if (TCG_TARGET_REG_BITS == 32) {
|
|
|
- tcg_out_qemu_st(s, a0, 0, a1, a2, args[3], TCG_TYPE_I32);
|
|
|
- break;
|
|
|
- }
|
|
|
- /* fall through */
|
|
|
- case INDEX_op_qemu_st_a32_i32:
|
|
|
- tcg_out_qemu_st(s, a0, 0, a1, 0, a2, TCG_TYPE_I32);
|
|
|
- break;
|
|
|
- case INDEX_op_qemu_st_a32_i64:
|
|
|
- if (TCG_TARGET_REG_BITS == 64) {
|
|
|
- tcg_out_qemu_st(s, a0, 0, a1, 0, a2, TCG_TYPE_I64);
|
|
|
- } else {
|
|
|
- tcg_out_qemu_st(s, a0, a1, a2, 0, args[3], TCG_TYPE_I64);
|
|
|
- }
|
|
|
+ case INDEX_op_qemu_st_i32:
|
|
|
+ tcg_out_qemu_st(s, a0, 0, a1, a2, TCG_TYPE_I32);
|
|
|
break;
|
|
|
- case INDEX_op_qemu_st_a64_i64:
|
|
|
+ case INDEX_op_qemu_st_i64:
|
|
|
if (TCG_TARGET_REG_BITS == 64) {
|
|
|
- tcg_out_qemu_st(s, a0, 0, a1, 0, a2, TCG_TYPE_I64);
|
|
|
+ tcg_out_qemu_st(s, a0, 0, a1, a2, TCG_TYPE_I64);
|
|
|
} else {
|
|
|
- tcg_out_qemu_st(s, a0, a1, a2, args[3], args[4], TCG_TYPE_I64);
|
|
|
+ tcg_out_qemu_st(s, a0, a1, a2, args[3], TCG_TYPE_I64);
|
|
|
}
|
|
|
break;
|
|
|
|
|
@@ -2227,14 +2173,14 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|
|
case INDEX_op_st16_i64:
|
|
|
case INDEX_op_st32_i64:
|
|
|
case INDEX_op_st_i64:
|
|
|
- return C_O0_I2(rZ, r);
|
|
|
+ return C_O0_I2(rz, r);
|
|
|
|
|
|
case INDEX_op_add_i32:
|
|
|
case INDEX_op_add_i64:
|
|
|
return C_O1_I2(r, r, rJ);
|
|
|
case INDEX_op_sub_i32:
|
|
|
case INDEX_op_sub_i64:
|
|
|
- return C_O1_I2(r, rZ, rN);
|
|
|
+ return C_O1_I2(r, rz, rN);
|
|
|
case INDEX_op_mul_i32:
|
|
|
case INDEX_op_mulsh_i32:
|
|
|
case INDEX_op_muluh_i32:
|
|
@@ -2253,7 +2199,7 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|
|
case INDEX_op_remu_i64:
|
|
|
case INDEX_op_nor_i64:
|
|
|
case INDEX_op_setcond_i64:
|
|
|
- return C_O1_I2(r, rZ, rZ);
|
|
|
+ return C_O1_I2(r, rz, rz);
|
|
|
case INDEX_op_muls2_i32:
|
|
|
case INDEX_op_mulu2_i32:
|
|
|
case INDEX_op_muls2_i64:
|
|
@@ -2280,44 +2226,35 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|
|
return C_O1_I2(r, r, ri);
|
|
|
case INDEX_op_clz_i32:
|
|
|
case INDEX_op_clz_i64:
|
|
|
- return C_O1_I2(r, r, rWZ);
|
|
|
+ return C_O1_I2(r, r, rzW);
|
|
|
|
|
|
case INDEX_op_deposit_i32:
|
|
|
case INDEX_op_deposit_i64:
|
|
|
- return C_O1_I2(r, 0, rZ);
|
|
|
+ return C_O1_I2(r, 0, rz);
|
|
|
case INDEX_op_brcond_i32:
|
|
|
case INDEX_op_brcond_i64:
|
|
|
- return C_O0_I2(rZ, rZ);
|
|
|
+ return C_O0_I2(rz, rz);
|
|
|
case INDEX_op_movcond_i32:
|
|
|
case INDEX_op_movcond_i64:
|
|
|
return (use_mips32r6_instructions
|
|
|
- ? C_O1_I4(r, rZ, rZ, rZ, rZ)
|
|
|
- : C_O1_I4(r, rZ, rZ, rZ, 0));
|
|
|
+ ? C_O1_I4(r, rz, rz, rz, rz)
|
|
|
+ : C_O1_I4(r, rz, rz, rz, 0));
|
|
|
case INDEX_op_add2_i32:
|
|
|
case INDEX_op_sub2_i32:
|
|
|
- return C_O2_I4(r, r, rZ, rZ, rN, rN);
|
|
|
+ return C_O2_I4(r, r, rz, rz, rN, rN);
|
|
|
case INDEX_op_setcond2_i32:
|
|
|
- return C_O1_I4(r, rZ, rZ, rZ, rZ);
|
|
|
+ return C_O1_I4(r, rz, rz, rz, rz);
|
|
|
case INDEX_op_brcond2_i32:
|
|
|
- return C_O0_I4(rZ, rZ, rZ, rZ);
|
|
|
+ return C_O0_I4(rz, rz, rz, rz);
|
|
|
|
|
|
- case INDEX_op_qemu_ld_a32_i32:
|
|
|
+ case INDEX_op_qemu_ld_i32:
|
|
|
return C_O1_I1(r, r);
|
|
|
- case INDEX_op_qemu_ld_a64_i32:
|
|
|
- return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O1_I2(r, r, r);
|
|
|
- case INDEX_op_qemu_st_a32_i32:
|
|
|
- return C_O0_I2(rZ, r);
|
|
|
- case INDEX_op_qemu_st_a64_i32:
|
|
|
- return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(rZ, r) : C_O0_I3(rZ, r, r);
|
|
|
- case INDEX_op_qemu_ld_a32_i64:
|
|
|
+ case INDEX_op_qemu_st_i32:
|
|
|
+ return C_O0_I2(rz, r);
|
|
|
+ case INDEX_op_qemu_ld_i64:
|
|
|
return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O2_I1(r, r, r);
|
|
|
- case INDEX_op_qemu_ld_a64_i64:
|
|
|
- return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O2_I2(r, r, r, r);
|
|
|
- case INDEX_op_qemu_st_a32_i64:
|
|
|
- return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(rZ, r) : C_O0_I3(rZ, rZ, r);
|
|
|
- case INDEX_op_qemu_st_a64_i64:
|
|
|
- return (TCG_TARGET_REG_BITS == 64 ? C_O0_I2(rZ, r)
|
|
|
- : C_O0_I4(rZ, rZ, r, r));
|
|
|
+ case INDEX_op_qemu_st_i64:
|
|
|
+ return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(rz, r) : C_O0_I3(rz, rz, r);
|
|
|
|
|
|
default:
|
|
|
return C_NotImplemented;
|