diff options
Diffstat (limited to 'tcg')
-rw-r--r-- | tcg/README | 7 | ||||
-rw-r--r-- | tcg/arm/tcg-target.c | 9 | ||||
-rw-r--r-- | tcg/hppa/tcg-target.c | 25 | ||||
-rw-r--r-- | tcg/i386/tcg-target.c | 11 | ||||
-rw-r--r-- | tcg/ia64/tcg-target.c | 4 | ||||
-rw-r--r-- | tcg/mips/tcg-target.c | 5 | ||||
-rw-r--r-- | tcg/optimize.c | 6 | ||||
-rw-r--r-- | tcg/ppc/tcg-target.c | 12 | ||||
-rw-r--r-- | tcg/ppc64/tcg-target.c | 12 | ||||
-rw-r--r-- | tcg/s390/tcg-target.c | 12 | ||||
-rw-r--r-- | tcg/sparc/tcg-target.c | 4 | ||||
-rw-r--r-- | tcg/tcg-op.h | 82 | ||||
-rw-r--r-- | tcg/tcg-opc.h | 1 | ||||
-rw-r--r-- | tcg/tcg.c | 2 | ||||
-rw-r--r-- | tcg/tcg.h | 57 | ||||
-rw-r--r-- | tcg/tci/tcg-target.c | 4 |
16 files changed, 127 insertions, 126 deletions
diff --git a/tcg/README b/tcg/README index 27846f1ea4..aa86992bca 100644 --- a/tcg/README +++ b/tcg/README @@ -88,8 +88,7 @@ supported. * Branches: -Use the instruction 'br' to jump to a label. Use 'jmp' to jump to an -explicit address. Conditional branches can only jump to labels. +Use the instruction 'br' to jump to a label. 3.3) Code Optimizations @@ -129,10 +128,6 @@ call function 'ptr' (pointer type) ********* Jumps/Labels -* jmp t0 - -Absolute jump to address t0 (pointer type). - * set_label $label Define label 'label' at the current program point. diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c index 5e8dbdd888..737200e5e6 100644 --- a/tcg/arm/tcg-target.c +++ b/tcg/arm/tcg-target.c @@ -335,7 +335,7 @@ enum arm_cond_code_e { COND_AL = 0xe, }; -static const uint8_t tcg_cond_to_arm_cond[10] = { +static const uint8_t tcg_cond_to_arm_cond[] = { [TCG_COND_EQ] = COND_EQ, [TCG_COND_NE] = COND_NE, [TCG_COND_LT] = COND_LT, @@ -1521,12 +1521,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, else tcg_out_callr(s, COND_AL, args[0]); break; - case INDEX_op_jmp: - if (const_args[0]) - tcg_out_goto(s, COND_AL, args[0]); - else - tcg_out_bx(s, COND_AL, args[0]); - break; case INDEX_op_br: tcg_out_goto_label(s, COND_AL, args[0]); break; @@ -1760,7 +1754,6 @@ static const TCGTargetOpDef arm_op_defs[] = { { INDEX_op_exit_tb, { } }, { INDEX_op_goto_tb, { } }, { INDEX_op_call, { "ri" } }, - { INDEX_op_jmp, { "ri" } }, { INDEX_op_br, { } }, { INDEX_op_mov_i32, { "r", "r" } }, diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c index 2c79c1081e..de500ae181 100644 --- a/tcg/hppa/tcg-target.c +++ b/tcg/hppa/tcg-target.c @@ -732,7 +732,7 @@ static void tcg_out_branch(TCGContext *s, int label_index, int nul) } } -static const uint8_t tcg_cond_to_cmp_cond[10] = +static const uint8_t tcg_cond_to_cmp_cond[] = { [TCG_COND_EQ] = COND_EQ, [TCG_COND_NE] = COND_EQ | COND_FALSE, @@ -814,19 +814,6 @@ static void tcg_out_comclr(TCGContext *s, int cond, TCGArg ret, tcg_out32(s, op); } -static TCGCond const tcg_high_cond[] = { - [TCG_COND_EQ] = TCG_COND_EQ, - [TCG_COND_NE] = TCG_COND_NE, - [TCG_COND_LT] = TCG_COND_LT, - [TCG_COND_LE] = TCG_COND_LT, - [TCG_COND_GT] = TCG_COND_GT, - [TCG_COND_GE] = TCG_COND_GT, - [TCG_COND_LTU] = TCG_COND_LTU, - [TCG_COND_LEU] = TCG_COND_LTU, - [TCG_COND_GTU] = TCG_COND_GTU, - [TCG_COND_GEU] = TCG_COND_GTU -}; - static void tcg_out_brcond2(TCGContext *s, int cond, TCGArg al, TCGArg ah, TCGArg bl, int blconst, TCGArg bh, int bhconst, int label_index) @@ -841,7 +828,7 @@ static void tcg_out_brcond2(TCGContext *s, int cond, TCGArg al, TCGArg ah, tcg_out_brcond(s, TCG_COND_NE, ah, bh, bhconst, label_index); break; default: - tcg_out_brcond(s, tcg_high_cond[cond], ah, bh, bhconst, label_index); + tcg_out_brcond(s, tcg_high_cond(cond), ah, bh, bhconst, label_index); tcg_out_comclr(s, TCG_COND_NE, TCG_REG_R0, ah, bh, bhconst); tcg_out_brcond(s, tcg_unsigned_cond(cond), al, bl, blconst, label_index); @@ -894,7 +881,7 @@ static void tcg_out_setcond2(TCGContext *s, int cond, TCGArg ret, tcg_out_setcond(s, tcg_unsigned_cond(cond), scratch, al, bl, blconst); tcg_out_comclr(s, TCG_COND_EQ, TCG_REG_R0, ah, bh, bhconst); tcg_out_movi(s, TCG_TYPE_I32, scratch, 0); - tcg_out_comclr(s, tcg_invert_cond(tcg_high_cond[cond]), + tcg_out_comclr(s, tcg_invert_cond(tcg_high_cond(cond)), TCG_REG_R0, ah, bh, bhconst); tcg_out_movi(s, TCG_TYPE_I32, scratch, 1); break; @@ -1353,11 +1340,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, } break; - case INDEX_op_jmp: - fprintf(stderr, "unimplemented jmp\n"); - tcg_abort(); - break; - case INDEX_op_br: tcg_out_branch(s, args[0], 1); break; @@ -1592,7 +1574,6 @@ static const TCGTargetOpDef hppa_op_defs[] = { { INDEX_op_goto_tb, { } }, { INDEX_op_call, { "ri" } }, - { INDEX_op_jmp, { "r" } }, { INDEX_op_br, { } }, { INDEX_op_mov_i32, { "r", "r" } }, diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c index 0e218c8614..4952c057b3 100644 --- a/tcg/i386/tcg-target.c +++ b/tcg/i386/tcg-target.c @@ -338,7 +338,7 @@ static inline int tcg_target_const_match(tcg_target_long val, #define JCC_JLE 0xe #define JCC_JG 0xf -static const uint8_t tcg_cond_to_jcc[10] = { +static const uint8_t tcg_cond_to_jcc[] = { [TCG_COND_EQ] = JCC_JE, [TCG_COND_NE] = JCC_JNE, [TCG_COND_LT] = JCC_JL, @@ -1513,14 +1513,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_modrm(s, OPC_GRP5, EXT5_CALLN_Ev, args[0]); } break; - case INDEX_op_jmp: - if (const_args[0]) { - tcg_out_jmp(s, args[0]); - } else { - /* jmp *reg */ - tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, args[0]); - } - break; case INDEX_op_br: tcg_out_jxx(s, JCC_JMP, args[0], 0); break; @@ -1848,7 +1840,6 @@ static const TCGTargetOpDef x86_op_defs[] = { { INDEX_op_exit_tb, { } }, { INDEX_op_goto_tb, { } }, { INDEX_op_call, { "ri" } }, - { INDEX_op_jmp, { "ri" } }, { INDEX_op_br, { } }, { INDEX_op_mov_i32, { "r", "r" } }, { INDEX_op_movi_i32, { "r" } }, diff --git a/tcg/ia64/tcg-target.c b/tcg/ia64/tcg-target.c index dc9c12cf18..705712f775 100644 --- a/tcg/ia64/tcg-target.c +++ b/tcg/ia64/tcg-target.c @@ -1916,9 +1916,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_goto_tb: tcg_out_goto_tb(s, args[0]); break; - case INDEX_op_jmp: - tcg_out_jmp(s, args[0]); - break; case INDEX_op_movi_i32: tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]); @@ -2156,7 +2153,6 @@ static const TCGTargetOpDef ia64_op_defs[] = { { INDEX_op_call, { "r" } }, { INDEX_op_exit_tb, { } }, { INDEX_op_goto_tb, { } }, - { INDEX_op_jmp, { "r" } }, { INDEX_op_mov_i32, { "r", "r" } }, { INDEX_op_movi_i32, { "r" } }, diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c index 34e3e7f823..7e4013e1e6 100644 --- a/tcg/mips/tcg-target.c +++ b/tcg/mips/tcg-target.c @@ -1322,10 +1322,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, args[0], 0); tcg_out_nop(s); break; - case INDEX_op_jmp: - tcg_out_opc_reg(s, OPC_JR, 0, args[0], 0); - tcg_out_nop(s); - break; case INDEX_op_br: tcg_out_brcond(s, TCG_COND_EQ, TCG_REG_ZERO, TCG_REG_ZERO, args[0]); break; @@ -1577,7 +1573,6 @@ static const TCGTargetOpDef mips_op_defs[] = { { INDEX_op_exit_tb, { } }, { INDEX_op_goto_tb, { } }, { INDEX_op_call, { "C" } }, - { INDEX_op_jmp, { "r" } }, { INDEX_op_br, { } }, { INDEX_op_mov_i32, { "r", "r" } }, diff --git a/tcg/optimize.c b/tcg/optimize.c index 35532a1e03..edb2b0ea90 100644 --- a/tcg/optimize.c +++ b/tcg/optimize.c @@ -321,6 +321,8 @@ static TCGArg do_constant_folding_cond(TCGOpcode op, TCGArg x, return (uint32_t)temps[x].val <= (uint32_t)temps[y].val; case TCG_COND_GTU: return (uint32_t)temps[x].val > (uint32_t)temps[y].val; + default: + break; } break; case 64: @@ -345,6 +347,8 @@ static TCGArg do_constant_folding_cond(TCGOpcode op, TCGArg x, return (uint64_t)temps[x].val <= (uint64_t)temps[y].val; case TCG_COND_GTU: return (uint64_t)temps[x].val > (uint64_t)temps[y].val; + default: + break; } break; } @@ -362,6 +366,8 @@ static TCGArg do_constant_folding_cond(TCGOpcode op, TCGArg x, case TCG_COND_LEU: case TCG_COND_EQ: return 1; + default: + break; } } else if (temps[y].state == TCG_TEMP_CONST && temps[y].val == 0) { switch (c) { diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c index 90c275d698..60b7b92621 100644 --- a/tcg/ppc/tcg-target.c +++ b/tcg/ppc/tcg-target.c @@ -437,7 +437,7 @@ enum { CR_SO }; -static const uint32_t tcg_to_bc[10] = { +static const uint32_t tcg_to_bc[] = { [TCG_COND_EQ] = BC | BI (7, CR_EQ) | BO_COND_TRUE, [TCG_COND_NE] = BC | BI (7, CR_EQ) | BO_COND_FALSE, [TCG_COND_LT] = BC | BI (7, CR_LT) | BO_COND_TRUE, @@ -1417,15 +1417,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, case INDEX_op_call: tcg_out_call (s, args[0], const_args[0]); break; - case INDEX_op_jmp: - if (const_args[0]) { - tcg_out_b (s, 0, args[0]); - } - else { - tcg_out32 (s, MTSPR | RS (args[0]) | CTR); - tcg_out32 (s, BCCTR | BO_ALWAYS); - } - break; case INDEX_op_movi_i32: tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]); break; @@ -1904,7 +1895,6 @@ static const TCGTargetOpDef ppc_op_defs[] = { { INDEX_op_exit_tb, { } }, { INDEX_op_goto_tb, { } }, { INDEX_op_call, { "ri" } }, - { INDEX_op_jmp, { "ri" } }, { INDEX_op_br, { } }, { INDEX_op_mov_i32, { "r", "r" } }, diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c index 19944bc427..5403fc1f91 100644 --- a/tcg/ppc64/tcg-target.c +++ b/tcg/ppc64/tcg-target.c @@ -418,7 +418,7 @@ enum { CR_SO }; -static const uint32_t tcg_to_bc[10] = { +static const uint32_t tcg_to_bc[] = { [TCG_COND_EQ] = BC | BI (7, CR_EQ) | BO_COND_TRUE, [TCG_COND_NE] = BC | BI (7, CR_EQ) | BO_COND_FALSE, [TCG_COND_LT] = BC | BI (7, CR_LT) | BO_COND_TRUE, @@ -1245,15 +1245,6 @@ static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args, case INDEX_op_call: tcg_out_call (s, args[0], const_args[0]); break; - case INDEX_op_jmp: - if (const_args[0]) { - tcg_out_b (s, 0, args[0]); - } - else { - tcg_out32 (s, MTSPR | RS (args[0]) | CTR); - tcg_out32 (s, BCCTR | BO_ALWAYS); - } - break; case INDEX_op_movi_i32: tcg_out_movi (s, TCG_TYPE_I32, args[0], args[1]); break; @@ -1588,7 +1579,6 @@ static const TCGTargetOpDef ppc_op_defs[] = { { INDEX_op_exit_tb, { } }, { INDEX_op_goto_tb, { } }, { INDEX_op_call, { "ri" } }, - { INDEX_op_jmp, { "ri" } }, { INDEX_op_br, { } }, { INDEX_op_mov_i32, { "r", "r" } }, diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c index 3b90605fb1..fd9286f52d 100644 --- a/tcg/s390/tcg-target.c +++ b/tcg/s390/tcg-target.c @@ -268,7 +268,7 @@ static const int tcg_target_call_oarg_regs[] = { #define S390_CC_ALWAYS 15 /* Condition codes that result from a COMPARE and COMPARE LOGICAL. */ -static const uint8_t tcg_cond_to_s390_cond[10] = { +static const uint8_t tcg_cond_to_s390_cond[] = { [TCG_COND_EQ] = S390_CC_EQ, [TCG_COND_NE] = S390_CC_NE, [TCG_COND_LT] = S390_CC_LT, @@ -284,7 +284,7 @@ static const uint8_t tcg_cond_to_s390_cond[10] = { /* Condition codes that result from a LOAD AND TEST. Here, we have no unsigned instruction variation, however since the test is vs zero we can re-map the outcomes appropriately. */ -static const uint8_t tcg_cond_to_ltr_cond[10] = { +static const uint8_t tcg_cond_to_ltr_cond[] = { [TCG_COND_EQ] = S390_CC_EQ, [TCG_COND_NE] = S390_CC_NE, [TCG_COND_LT] = S390_CC_LT, @@ -1113,7 +1113,7 @@ static void tgen64_xori(TCGContext *s, TCGReg dest, tcg_target_ulong val) static int tgen_cmp(TCGContext *s, TCGType type, TCGCond c, TCGReg r1, TCGArg c2, int c2const) { - bool is_unsigned = (c > TCG_COND_GT); + bool is_unsigned = is_unsigned_cond(c); if (c2const) { if (c2 == 0) { if (type == TCG_TYPE_I32) { @@ -2037,11 +2037,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, break; #endif /* TCG_TARGET_REG_BITS == 64 */ - case INDEX_op_jmp: - /* This one is obsolete and never emitted. */ - tcg_abort(); - break; - default: fprintf(stderr,"unimplemented opc 0x%x\n",opc); tcg_abort(); @@ -2052,7 +2047,6 @@ static const TCGTargetOpDef s390_op_defs[] = { { INDEX_op_exit_tb, { } }, { INDEX_op_goto_tb, { } }, { INDEX_op_call, { "ri" } }, - { INDEX_op_jmp, { "ri" } }, { INDEX_op_br, { } }, { INDEX_op_mov_i32, { "r", "r" } }, diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c index 8fd7f86de0..0c32baa50e 100644 --- a/tcg/sparc/tcg-target.c +++ b/tcg/sparc/tcg-target.c @@ -512,7 +512,7 @@ static void tcg_out_branch_i64(TCGContext *s, int opc, int label_index) } #endif -static const uint8_t tcg_cond_to_bcond[10] = { +static const uint8_t tcg_cond_to_bcond[] = { [TCG_COND_EQ] = COND_E, [TCG_COND_NE] = COND_NE, [TCG_COND_LT] = COND_L, @@ -1097,7 +1097,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, /* delay slot */ tcg_out_nop(s); break; - case INDEX_op_jmp: case INDEX_op_br: tcg_out_branch_i32(s, COND_A, args[0]); tcg_out_nop(s); @@ -1367,7 +1366,6 @@ static const TCGTargetOpDef sparc_op_defs[] = { { INDEX_op_exit_tb, { } }, { INDEX_op_goto_tb, { } }, { INDEX_op_call, { "ri" } }, - { INDEX_op_jmp, { "ri" } }, { INDEX_op_br, { } }, { INDEX_op_mov_i32, { "r", "r" } }, diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h index bd93fe4f03..551845801d 100644 --- a/tcg/tcg-op.h +++ b/tcg/tcg-op.h @@ -646,29 +646,49 @@ static inline void tcg_gen_sari_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) static inline void tcg_gen_brcond_i32(TCGCond cond, TCGv_i32 arg1, TCGv_i32 arg2, int label_index) { - tcg_gen_op4ii_i32(INDEX_op_brcond_i32, arg1, arg2, cond, label_index); + if (cond == TCG_COND_ALWAYS) { + tcg_gen_br(label_index); + } else if (cond != TCG_COND_NEVER) { + tcg_gen_op4ii_i32(INDEX_op_brcond_i32, arg1, arg2, cond, label_index); + } } static inline void tcg_gen_brcondi_i32(TCGCond cond, TCGv_i32 arg1, int32_t arg2, int label_index) { - TCGv_i32 t0 = tcg_const_i32(arg2); - tcg_gen_brcond_i32(cond, arg1, t0, label_index); - tcg_temp_free_i32(t0); + if (cond == TCG_COND_ALWAYS) { + tcg_gen_br(label_index); + } else if (cond != TCG_COND_NEVER) { + TCGv_i32 t0 = tcg_const_i32(arg2); + tcg_gen_brcond_i32(cond, arg1, t0, label_index); + tcg_temp_free_i32(t0); + } } static inline void tcg_gen_setcond_i32(TCGCond cond, TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) { - tcg_gen_op4i_i32(INDEX_op_setcond_i32, ret, arg1, arg2, cond); + if (cond == TCG_COND_ALWAYS) { + tcg_gen_movi_i32(ret, 1); + } else if (cond == TCG_COND_NEVER) { + tcg_gen_movi_i32(ret, 0); + } else { + tcg_gen_op4i_i32(INDEX_op_setcond_i32, ret, arg1, arg2, cond); + } } static inline void tcg_gen_setcondi_i32(TCGCond cond, TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) { - TCGv_i32 t0 = tcg_const_i32(arg2); - tcg_gen_setcond_i32(cond, ret, arg1, t0); - tcg_temp_free_i32(t0); + if (cond == TCG_COND_ALWAYS) { + tcg_gen_movi_i32(ret, 1); + } else if (cond == TCG_COND_NEVER) { + tcg_gen_movi_i32(ret, 0); + } else { + TCGv_i32 t0 = tcg_const_i32(arg2); + tcg_gen_setcond_i32(cond, ret, arg1, t0); + tcg_temp_free_i32(t0); + } } static inline void tcg_gen_mul_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) @@ -964,17 +984,27 @@ static inline void tcg_gen_sari_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) static inline void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1, TCGv_i64 arg2, int label_index) { - tcg_gen_op6ii_i32(INDEX_op_brcond2_i32, - TCGV_LOW(arg1), TCGV_HIGH(arg1), TCGV_LOW(arg2), - TCGV_HIGH(arg2), cond, label_index); + if (cond == TCG_COND_ALWAYS) { + tcg_gen_br(label_index); + } else if (cond != TCG_COND_NEVER) { + tcg_gen_op6ii_i32(INDEX_op_brcond2_i32, + TCGV_LOW(arg1), TCGV_HIGH(arg1), TCGV_LOW(arg2), + TCGV_HIGH(arg2), cond, label_index); + } } static inline void tcg_gen_setcond_i64(TCGCond cond, TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) { - tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret), - TCGV_LOW(arg1), TCGV_HIGH(arg1), - TCGV_LOW(arg2), TCGV_HIGH(arg2), cond); + if (cond == TCG_COND_ALWAYS) { + tcg_gen_movi_i32(TCGV_LOW(ret), 1); + } else if (cond == TCG_COND_NEVER) { + tcg_gen_movi_i32(TCGV_LOW(ret), 0); + } else { + tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret), + TCGV_LOW(arg1), TCGV_HIGH(arg1), + TCGV_LOW(arg2), TCGV_HIGH(arg2), cond); + } tcg_gen_movi_i32(TCGV_HIGH(ret), 0); } @@ -1273,13 +1303,23 @@ static inline void tcg_gen_sari_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) static inline void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1, TCGv_i64 arg2, int label_index) { - tcg_gen_op4ii_i64(INDEX_op_brcond_i64, arg1, arg2, cond, label_index); + if (cond == TCG_COND_ALWAYS) { + tcg_gen_br(label_index); + } else if (cond != TCG_COND_NEVER) { + tcg_gen_op4ii_i64(INDEX_op_brcond_i64, arg1, arg2, cond, label_index); + } } static inline void tcg_gen_setcond_i64(TCGCond cond, TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) { - tcg_gen_op4i_i64(INDEX_op_setcond_i64, ret, arg1, arg2, cond); + if (cond == TCG_COND_ALWAYS) { + tcg_gen_movi_i64(ret, 1); + } else if (cond == TCG_COND_NEVER) { + tcg_gen_movi_i64(ret, 0); + } else { + tcg_gen_op4i_i64(INDEX_op_setcond_i64, ret, arg1, arg2, cond); + } } static inline void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) @@ -1397,9 +1437,13 @@ static inline void tcg_gen_subi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) static inline void tcg_gen_brcondi_i64(TCGCond cond, TCGv_i64 arg1, int64_t arg2, int label_index) { - TCGv_i64 t0 = tcg_const_i64(arg2); - tcg_gen_brcond_i64(cond, arg1, t0, label_index); - tcg_temp_free_i64(t0); + if (cond == TCG_COND_ALWAYS) { + tcg_gen_br(label_index); + } else if (cond != TCG_COND_NEVER) { + TCGv_i64 t0 = tcg_const_i64(arg2); + tcg_gen_brcond_i64(cond, arg1, t0, label_index); + tcg_temp_free_i64(t0); + } } static inline void tcg_gen_setcondi_i64(TCGCond cond, TCGv_i64 ret, diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h index dbb0e3916a..04cb7ca038 100644 --- a/tcg/tcg-opc.h +++ b/tcg/tcg-opc.h @@ -38,7 +38,6 @@ DEF(discard, 1, 0, 0, 0) DEF(set_label, 0, 0, 1, TCG_OPF_BB_END) DEF(call, 0, 1, 2, TCG_OPF_SIDE_EFFECTS) /* variable number of parameters */ -DEF(jmp, 0, 1, 0, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS) DEF(br, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS) #define IMPL(X) (X ? 0 : TCG_OPF_NOT_PRESENT) @@ -864,6 +864,8 @@ static TCGHelperInfo *tcg_find_helper(TCGContext *s, tcg_target_ulong val) static const char * const cond_name[] = { + [TCG_COND_NEVER] = "never", + [TCG_COND_ALWAYS] = "always", [TCG_COND_EQ] = "eq", [TCG_COND_NE] = "ne", [TCG_COND_LT] = "lt", @@ -266,18 +266,28 @@ typedef int TCGv_i64; #define TCG_CALL_DUMMY_TCGV MAKE_TCGV_I32(-1) #define TCG_CALL_DUMMY_ARG ((TCGArg)(-1)) +/* Conditions. Note that these are layed out for easy manipulation by + the the functions below: + bit 0 is used for inverting; + bit 1 is signed, + bit 2 is unsigned, + bit 3 is used with bit 0 for swapping signed/unsigned. */ typedef enum { - TCG_COND_EQ, - TCG_COND_NE, - TCG_COND_LT, - TCG_COND_GE, - TCG_COND_LE, - TCG_COND_GT, + /* non-signed */ + TCG_COND_NEVER = 0 | 0 | 0 | 0, + TCG_COND_ALWAYS = 0 | 0 | 0 | 1, + TCG_COND_EQ = 8 | 0 | 0 | 0, + TCG_COND_NE = 8 | 0 | 0 | 1, + /* signed */ + TCG_COND_LT = 0 | 0 | 2 | 0, + TCG_COND_GE = 0 | 0 | 2 | 1, + TCG_COND_LE = 8 | 0 | 2 | 0, + TCG_COND_GT = 8 | 0 | 2 | 1, /* unsigned */ - TCG_COND_LTU, - TCG_COND_GEU, - TCG_COND_LEU, - TCG_COND_GTU, + TCG_COND_LTU = 0 | 4 | 0 | 0, + TCG_COND_GEU = 0 | 4 | 0 | 1, + TCG_COND_LEU = 8 | 4 | 0 | 0, + TCG_COND_GTU = 8 | 4 | 0 | 1, } TCGCond; /* Invert the sense of the comparison. */ @@ -289,13 +299,34 @@ static inline TCGCond tcg_invert_cond(TCGCond c) /* Swap the operands in a comparison. */ static inline TCGCond tcg_swap_cond(TCGCond c) { - int mask = (c < TCG_COND_LT ? 0 : c < TCG_COND_LTU ? 7 : 15); - return (TCGCond)(c ^ mask); + return c & 6 ? (TCGCond)(c ^ 9) : c; } +/* Create an "unsigned" version of a "signed" comparison. */ static inline TCGCond tcg_unsigned_cond(TCGCond c) { - return (c >= TCG_COND_LT && c <= TCG_COND_GT ? c + 4 : c); + return c & 2 ? (TCGCond)(c ^ 6) : c; +} + +/* Must a comparison be considered unsigned? */ +static inline bool is_unsigned_cond(TCGCond c) +{ + return (c & 4) != 0; +} + +/* Create a "high" version of a double-word comparison. + This removes equality from a LTE or GTE comparison. */ +static inline TCGCond tcg_high_cond(TCGCond c) +{ + switch (c) { + case TCG_COND_GE: + case TCG_COND_LE: + case TCG_COND_GEU: + case TCG_COND_LEU: + return (TCGCond)(c ^ 8); + default: + return c; + } } #define TEMP_VAL_DEAD 0 diff --git a/tcg/tci/tcg-target.c b/tcg/tci/tcg-target.c index d272a906e8..e930740835 100644 --- a/tcg/tci/tcg-target.c +++ b/tcg/tci/tcg-target.c @@ -69,7 +69,6 @@ static const TCGTargetOpDef tcg_target_op_defs[] = { { INDEX_op_exit_tb, { NULL } }, { INDEX_op_goto_tb, { NULL } }, { INDEX_op_call, { RI } }, - { INDEX_op_jmp, { RI } }, { INDEX_op_br, { NULL } }, { INDEX_op_mov_i32, { R, R } }, @@ -583,9 +582,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, case INDEX_op_call: tcg_out_ri(s, const_args[0], args[0]); break; - case INDEX_op_jmp: - TODO(); - break; case INDEX_op_setcond_i32: tcg_out_r(s, args[0]); tcg_out_r(s, args[1]); |