* [Qemu-devel] [PATCH 0/6] tcg sparc improvements @ 2014-08-06 19:49 Richard Henderson 2014-08-06 19:49 ` [Qemu-devel] [PATCH 1/6] tcg-sparc: Support addsub2_i64 Richard Henderson ` (5 more replies) 0 siblings, 6 replies; 7+ messages in thread From: Richard Henderson @ 2014-08-06 19:49 UTC (permalink / raw) To: qemu-devel Three of these patches are related to the new instructions added in 2011 with the VIS3 instruction set, as present in the T4 cpus. r~ Richard Henderson (6): tcg-sparc: Support addsub2_i64 tcg-sparc: Use ADDXC in addsub2_i64 tcg-sparc: Fix setcond_i32 uninitialized value tcg-sparc: Use ADDXC in setcond_i64 tcg-sparc: Rename ADDX/SUBX insns tcg-sparc: Use UMULXHI instruction disas/sparc.c | 34 ++++++------- include/elf.h | 37 +++++++++++--- tcg/sparc/tcg-target.c | 129 +++++++++++++++++++++++++++++++++++++++++++------ tcg/sparc/tcg-target.h | 12 +++-- 4 files changed, 167 insertions(+), 45 deletions(-) -- 1.9.3 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 1/6] tcg-sparc: Support addsub2_i64 2014-08-06 19:49 [Qemu-devel] [PATCH 0/6] tcg sparc improvements Richard Henderson @ 2014-08-06 19:49 ` Richard Henderson 2014-08-06 19:49 ` [Qemu-devel] [PATCH 2/6] tcg-sparc: Use ADDXC in addsub2_i64 Richard Henderson ` (4 subsequent siblings) 5 siblings, 0 replies; 7+ messages in thread From: Richard Henderson @ 2014-08-06 19:49 UTC (permalink / raw) To: qemu-devel Signed-off-by: Richard Henderson <rth@twiddle.net> --- tcg/sparc/tcg-target.c | 72 +++++++++++++++++++++++++++++++++++++++++++++----- tcg/sparc/tcg-target.h | 4 +-- 2 files changed, 67 insertions(+), 9 deletions(-) diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c index 40f2ec1..21981d8 100644 --- a/tcg/sparc/tcg-target.c +++ b/tcg/sparc/tcg-target.c @@ -719,9 +719,9 @@ static void tcg_out_setcond_i64(TCGContext *s, TCGCond cond, TCGReg ret, } } -static void tcg_out_addsub2(TCGContext *s, TCGReg rl, TCGReg rh, - TCGReg al, TCGReg ah, int32_t bl, int blconst, - int32_t bh, int bhconst, int opl, int oph) +static void tcg_out_addsub2_i32(TCGContext *s, TCGReg rl, TCGReg rh, + TCGReg al, TCGReg ah, int32_t bl, int blconst, + int32_t bh, int bhconst, int opl, int oph) { TCGReg tmp = TCG_REG_T1; @@ -735,6 +735,51 @@ static void tcg_out_addsub2(TCGContext *s, TCGReg rl, TCGReg rh, tcg_out_mov(s, TCG_TYPE_I32, rl, tmp); } +static void tcg_out_addsub2_i64(TCGContext *s, TCGReg rl, TCGReg rh, + TCGReg al, TCGReg ah, int32_t bl, int blconst, + int32_t bh, int bhconst, bool is_sub) +{ + TCGReg tmp = TCG_REG_T1; + + /* Note that the low parts are fully consumed before tmp is set. */ + if (rl != ah && (bhconst || rl != bh)) { + tmp = rl; + } + + tcg_out_arithc(s, tmp, al, bl, blconst, is_sub ? ARITH_SUBCC : ARITH_ADDCC); + + /* Note that ADDX/SUBX take the carry-in from %icc, the 32-bit carry, + while we want %xcc, the 64-bit carry. */ + /* ??? There is a 2011 VIS3 ADDXC insn that does take a 64-bit carry. */ + + if (bh == TCG_REG_G0) { + /* If we have a zero, we can perform the operation in two insns, + with the arithmetic first, and a conditional move into place. */ + if (rh == ah) { + tcg_out_arithi(s, TCG_REG_T2, ah, 1, + is_sub ? ARITH_SUB : ARITH_ADD); + tcg_out_movcc(s, TCG_COND_LTU, MOVCC_XCC, rh, TCG_REG_T2, 0); + } else { + tcg_out_arithi(s, rh, ah, 1, is_sub ? ARITH_SUB : ARITH_ADD); + tcg_out_movcc(s, TCG_COND_GEU, MOVCC_XCC, rh, ah, 0); + } + } else { + /* Otherwise adjust BH as if there is carry into T2 ... */ + if (bhconst) { + tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_T2, bh + (is_sub ? -1 : 1)); + } else { + tcg_out_arithi(s, TCG_REG_T2, bh, 1, + is_sub ? ARITH_SUB : ARITH_ADD); + } + /* ... smoosh T2 back to original BH if carry is clear ... */ + tcg_out_movcc(s, TCG_COND_GEU, MOVCC_XCC, TCG_REG_T2, bh, bhconst); + /* ... and finally perform the arithmetic with the new operand. */ + tcg_out_arith(s, rh, ah, TCG_REG_T2, is_sub ? ARITH_SUB : ARITH_ADD); + } + + tcg_out_mov(s, TCG_TYPE_I64, rl, tmp); +} + static void tcg_out_call_nodelay(TCGContext *s, tcg_insn_unit *dest) { ptrdiff_t disp = tcg_pcrel_diff(s, dest); @@ -1264,12 +1309,14 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, break; case INDEX_op_add2_i32: - tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], const_args[4], - args[5], const_args[5], ARITH_ADDCC, ARITH_ADDX); + tcg_out_addsub2_i32(s, args[0], args[1], args[2], args[3], + args[4], const_args[4], args[5], const_args[5], + ARITH_ADDCC, ARITH_ADDX); break; case INDEX_op_sub2_i32: - tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], const_args[4], - args[5], const_args[5], ARITH_SUBCC, ARITH_SUBX); + tcg_out_addsub2_i32(s, args[0], args[1], args[2], args[3], + args[4], const_args[4], args[5], const_args[5], + ARITH_SUBCC, ARITH_SUBX); break; case INDEX_op_mulu2_i32: c = ARITH_UMUL; @@ -1351,6 +1398,14 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_movcond_i64: tcg_out_movcond_i64(s, args[5], a0, a1, a2, c2, args[3], const_args[3]); break; + case INDEX_op_add2_i64: + tcg_out_addsub2_i64(s, args[0], args[1], args[2], args[3], args[4], + const_args[4], args[5], const_args[5], false); + break; + case INDEX_op_sub2_i64: + tcg_out_addsub2_i64(s, args[0], args[1], args[2], args[3], args[4], + const_args[4], args[5], const_args[5], true); + break; gen_arith: tcg_out_arithc(s, a0, a1, a2, c2, c); @@ -1449,6 +1504,9 @@ static const TCGTargetOpDef sparc_op_defs[] = { { INDEX_op_setcond_i64, { "R", "RZ", "RJ" } }, { INDEX_op_movcond_i64, { "R", "RZ", "RJ", "RI", "0" } }, + { INDEX_op_add2_i64, { "R", "R", "RZ", "RZ", "RJ", "RI" } }, + { INDEX_op_sub2_i64, { "R", "R", "RZ", "RZ", "RJ", "RI" } }, + { INDEX_op_qemu_ld_i32, { "r", "A" } }, { INDEX_op_qemu_ld_i64, { "R", "A" } }, { INDEX_op_qemu_st_i32, { "sZ", "A" } }, diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h index 089f976..a44d34f 100644 --- a/tcg/sparc/tcg-target.h +++ b/tcg/sparc/tcg-target.h @@ -133,8 +133,8 @@ typedef enum { #define TCG_TARGET_HAS_nor_i64 0 #define TCG_TARGET_HAS_deposit_i64 0 #define TCG_TARGET_HAS_movcond_i64 1 -#define TCG_TARGET_HAS_add2_i64 0 -#define TCG_TARGET_HAS_sub2_i64 0 +#define TCG_TARGET_HAS_add2_i64 1 +#define TCG_TARGET_HAS_sub2_i64 1 #define TCG_TARGET_HAS_mulu2_i64 0 #define TCG_TARGET_HAS_muls2_i64 0 #define TCG_TARGET_HAS_muluh_i64 0 -- 1.9.3 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 2/6] tcg-sparc: Use ADDXC in addsub2_i64 2014-08-06 19:49 [Qemu-devel] [PATCH 0/6] tcg sparc improvements Richard Henderson 2014-08-06 19:49 ` [Qemu-devel] [PATCH 1/6] tcg-sparc: Support addsub2_i64 Richard Henderson @ 2014-08-06 19:49 ` Richard Henderson 2014-08-06 19:49 ` [Qemu-devel] [PATCH 3/6] tcg-sparc: Fix setcond_i32 uninitialized value Richard Henderson ` (3 subsequent siblings) 5 siblings, 0 replies; 7+ messages in thread From: Richard Henderson @ 2014-08-06 19:49 UTC (permalink / raw) To: qemu-devel On T4 and newer Sparc chips we have an add-with-carry insn that takes its input from %xcc instead of %icc. Signed-off-by: Richard Henderson <rth@twiddle.net> --- disas/sparc.c | 3 +++ include/elf.h | 37 +++++++++++++++++++++++++++++-------- tcg/sparc/tcg-target.c | 28 +++++++++++++++++++++++----- tcg/sparc/tcg-target.h | 6 ++++++ 4 files changed, 61 insertions(+), 13 deletions(-) diff --git a/disas/sparc.c b/disas/sparc.c index 8eb22e6..092e1b6 100644 --- a/disas/sparc.c +++ b/disas/sparc.c @@ -2042,6 +2042,9 @@ IMPDEP ("impdep2", 0x37), #undef IMPDEP +{ "addxc", F3F(2, 0x36, 0x011), F3F(~2, ~0x36, ~0x011), "1,2,d", 0, v9b }, +{ "addxccc", F3F(2, 0x36, 0x013), F3F(~2, ~0x36, ~0x013), "1,2,d", 0, v9b }, + }; static const int sparc_num_opcodes = ((sizeof sparc_opcodes)/(sizeof sparc_opcodes[0])); diff --git a/include/elf.h b/include/elf.h index e88d52f..d7730a2 100644 --- a/include/elf.h +++ b/include/elf.h @@ -471,14 +471,35 @@ typedef struct { #define PPC_FEATURE_TRUE_LE 0x00000002 #define PPC_FEATURE_PPC_LE 0x00000001 -/* Bits present in AT_HWCAP, primarily for Sparc32. */ - -#define HWCAP_SPARC_FLUSH 1 /* CPU supports flush instruction. */ -#define HWCAP_SPARC_STBAR 2 -#define HWCAP_SPARC_SWAP 4 -#define HWCAP_SPARC_MULDIV 8 -#define HWCAP_SPARC_V9 16 -#define HWCAP_SPARC_ULTRA3 32 +/* Bits present in AT_HWCAP for Sparc. */ + +#define HWCAP_SPARC_FLUSH 0x00000001 +#define HWCAP_SPARC_STBAR 0x00000002 +#define HWCAP_SPARC_SWAP 0x00000004 +#define HWCAP_SPARC_MULDIV 0x00000008 +#define HWCAP_SPARC_V9 0x00000010 +#define HWCAP_SPARC_ULTRA3 0x00000020 +#define HWCAP_SPARC_BLKINIT 0x00000040 +#define HWCAP_SPARC_N2 0x00000080 +#define HWCAP_SPARC_MUL32 0x00000100 +#define HWCAP_SPARC_DIV32 0x00000200 +#define HWCAP_SPARC_FSMULD 0x00000400 +#define HWCAP_SPARC_V8PLUS 0x00000800 +#define HWCAP_SPARC_POPC 0x00001000 +#define HWCAP_SPARC_VIS 0x00002000 +#define HWCAP_SPARC_VIS2 0x00004000 +#define HWCAP_SPARC_ASI_BLK_INIT 0x00008000 +#define HWCAP_SPARC_FMAF 0x00010000 +#define HWCAP_SPARC_VIS3 0x00020000 +#define HWCAP_SPARC_HPC 0x00040000 +#define HWCAP_SPARC_RANDOM 0x00080000 +#define HWCAP_SPARC_TRANS 0x00100000 +#define HWCAP_SPARC_FJFMAU 0x00200000 +#define HWCAP_SPARC_IMA 0x00400000 +#define HWCAP_SPARC_ASI_CACHE_SPARING 0x00800000 +#define HWCAP_SPARC_PAUSE 0x01000000 +#define HWCAP_SPARC_CBCOND 0x02000000 +#define HWCAP_SPARC_CRYPTO 0x04000000 /* Bits present in AT_HWCAP for s390. */ diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c index 21981d8..08ca482 100644 --- a/tcg/sparc/tcg-target.c +++ b/tcg/sparc/tcg-target.c @@ -209,6 +209,8 @@ static const int tcg_target_call_oarg_regs[] = { #define ARITH_MOVCC (INSN_OP(2) | INSN_OP3(0x2c)) #define ARITH_MOVR (INSN_OP(2) | INSN_OP3(0x2f)) +#define ARITH_ADDXC (INSN_OP(2) | INSN_OP3(0x36) | INSN_OPF(0x11)) + #define SHIFT_SLL (INSN_OP(2) | INSN_OP3(0x25)) #define SHIFT_SRL (INSN_OP(2) | INSN_OP3(0x26)) #define SHIFT_SRA (INSN_OP(2) | INSN_OP3(0x27)) @@ -262,6 +264,10 @@ static const int tcg_target_call_oarg_regs[] = { #define STW_LE (STWA | INSN_ASI(ASI_PRIMARY_LITTLE)) #define STX_LE (STXA | INSN_ASI(ASI_PRIMARY_LITTLE)) +#ifndef use_vis3_instructions +bool use_vis3_instructions; +#endif + static inline int check_fit_i64(int64_t val, unsigned int bits) { return val == sextract64(val, 0, bits); @@ -748,11 +754,14 @@ static void tcg_out_addsub2_i64(TCGContext *s, TCGReg rl, TCGReg rh, tcg_out_arithc(s, tmp, al, bl, blconst, is_sub ? ARITH_SUBCC : ARITH_ADDCC); - /* Note that ADDX/SUBX take the carry-in from %icc, the 32-bit carry, - while we want %xcc, the 64-bit carry. */ - /* ??? There is a 2011 VIS3 ADDXC insn that does take a 64-bit carry. */ - - if (bh == TCG_REG_G0) { + if (use_vis3_instructions && !is_sub) { + /* Note that ADDXC doesn't accept immediates. */ + if (bhconst && bh != 0) { + tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_T2, bh); + bh = TCG_REG_T2; + } + tcg_out_arith(s, rh, ah, bh, ARITH_ADDXC); + } else if (bh == TCG_REG_G0) { /* If we have a zero, we can perform the operation in two insns, with the arithmetic first, and a conditional move into place. */ if (rh == ah) { @@ -1517,6 +1526,15 @@ static const TCGTargetOpDef sparc_op_defs[] = { static void tcg_target_init(TCGContext *s) { + /* Only probe for the platform and capabilities if we havn't already + determined maximum values at compile time. */ +#ifndef use_vis3_instructions + { + unsigned long hwcap = qemu_getauxval(AT_HWCAP); + use_vis3_instructions = (hwcap & HWCAP_SPARC_VIS3) != 0; + } +#endif + tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff); tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, ALL_64); diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h index a44d34f..099b308 100644 --- a/tcg/sparc/tcg-target.h +++ b/tcg/sparc/tcg-target.h @@ -85,6 +85,12 @@ typedef enum { #define TCG_TARGET_EXTEND_ARGS 1 #endif +#if defined(__VIS__) && __VIS__ >= 0x300 +#define use_vis3_instructions 1 +#else +extern bool use_vis3_instructions; +#endif + /* optional instructions */ #define TCG_TARGET_HAS_div_i32 1 #define TCG_TARGET_HAS_rem_i32 0 -- 1.9.3 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 3/6] tcg-sparc: Fix setcond_i32 uninitialized value 2014-08-06 19:49 [Qemu-devel] [PATCH 0/6] tcg sparc improvements Richard Henderson 2014-08-06 19:49 ` [Qemu-devel] [PATCH 1/6] tcg-sparc: Support addsub2_i64 Richard Henderson 2014-08-06 19:49 ` [Qemu-devel] [PATCH 2/6] tcg-sparc: Use ADDXC in addsub2_i64 Richard Henderson @ 2014-08-06 19:49 ` Richard Henderson 2014-08-06 19:49 ` [Qemu-devel] [PATCH 4/6] tcg-sparc: Use ADDXC in setcond_i64 Richard Henderson ` (2 subsequent siblings) 5 siblings, 0 replies; 7+ messages in thread From: Richard Henderson @ 2014-08-06 19:49 UTC (permalink / raw) To: qemu-devel We failed to swap c1 and c2 correctly for NE c2 == 0. Signed-off-by: Richard Henderson <rth@twiddle.net> --- tcg/sparc/tcg-target.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c index 08ca482..3b232d6 100644 --- a/tcg/sparc/tcg-target.c +++ b/tcg/sparc/tcg-target.c @@ -674,9 +674,12 @@ static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGReg ret, case TCG_COND_NE: /* For equality, we can transform to inequality vs zero. */ if (c2 != 0) { - tcg_out_arithc(s, ret, c1, c2, c2const, ARITH_XOR); + tcg_out_arithc(s, TCG_REG_T1, c1, c2, c2const, ARITH_XOR); + c2 = TCG_REG_T1; + } else { + c2 = c1; } - c1 = TCG_REG_G0, c2 = ret, c2const = 0; + c1 = TCG_REG_G0, c2const = 0; cond = (cond == TCG_COND_EQ ? TCG_COND_GEU : TCG_COND_LTU); break; -- 1.9.3 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 4/6] tcg-sparc: Use ADDXC in setcond_i64 2014-08-06 19:49 [Qemu-devel] [PATCH 0/6] tcg sparc improvements Richard Henderson ` (2 preceding siblings ...) 2014-08-06 19:49 ` [Qemu-devel] [PATCH 3/6] tcg-sparc: Fix setcond_i32 uninitialized value Richard Henderson @ 2014-08-06 19:49 ` Richard Henderson 2014-08-06 19:49 ` [Qemu-devel] [PATCH 5/6] tcg-sparc: Rename ADDX/SUBX insns Richard Henderson 2014-08-06 19:49 ` [Qemu-devel] [PATCH 6/6] tcg-sparc: Use UMULXHI instruction Richard Henderson 5 siblings, 0 replies; 7+ messages in thread From: Richard Henderson @ 2014-08-06 19:49 UTC (permalink / raw) To: qemu-devel Similar to the ADDC tricks we use in setcond_i32. Signed-off-by: Richard Henderson <rth@twiddle.net> --- tcg/sparc/tcg-target.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c index 3b232d6..d0bd08c 100644 --- a/tcg/sparc/tcg-target.c +++ b/tcg/sparc/tcg-target.c @@ -716,6 +716,23 @@ static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGReg ret, static void tcg_out_setcond_i64(TCGContext *s, TCGCond cond, TCGReg ret, TCGReg c1, int32_t c2, int c2const) { + if (use_vis3_instructions) { + switch (cond) { + case TCG_COND_NE: + if (c2 != 0) { + break; + } + c2 = c1, c2const = 0, c1 = TCG_REG_G0; + /* FALLTHRU */ + case TCG_COND_LTU: + tcg_out_cmp(s, c1, c2, c2const); + tcg_out_arith(s, ret, TCG_REG_G0, TCG_REG_G0, ARITH_ADDXC); + return; + default: + break; + } + } + /* For 64-bit signed comparisons vs zero, we can avoid the compare if the input does not overlap the output. */ if (c2 == 0 && !is_unsigned_cond(cond) && c1 != ret) { -- 1.9.3 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 5/6] tcg-sparc: Rename ADDX/SUBX insns 2014-08-06 19:49 [Qemu-devel] [PATCH 0/6] tcg sparc improvements Richard Henderson ` (3 preceding siblings ...) 2014-08-06 19:49 ` [Qemu-devel] [PATCH 4/6] tcg-sparc: Use ADDXC in setcond_i64 Richard Henderson @ 2014-08-06 19:49 ` Richard Henderson 2014-08-06 19:49 ` [Qemu-devel] [PATCH 6/6] tcg-sparc: Use UMULXHI instruction Richard Henderson 5 siblings, 0 replies; 7+ messages in thread From: Richard Henderson @ 2014-08-06 19:49 UTC (permalink / raw) To: qemu-devel The pre-v9 ADDX/SUBX insns were renamed ADDC/SUBC for v9. Standardizing on the v9 name makes things less confusing. Signed-off-by: Richard Henderson <rth@twiddle.net> --- disas/sparc.c | 32 +++++++++++--------------------- tcg/sparc/tcg-target.c | 14 +++++++------- 2 files changed, 18 insertions(+), 28 deletions(-) diff --git a/disas/sparc.c b/disas/sparc.c index 092e1b6..22ceac3 100644 --- a/disas/sparc.c +++ b/disas/sparc.c @@ -1175,15 +1175,11 @@ static const struct sparc_opcode sparc_opcodes[] = { { "subcc", F3(2, 0x14, 0), F3(~2, ~0x14, ~0)|ASI(~0), "1,2,d", 0, v6 }, { "subcc", F3(2, 0x14, 1), F3(~2, ~0x14, ~1), "1,i,d", 0, v6 }, -{ "subx", F3(2, 0x0c, 0), F3(~2, ~0x0c, ~0)|ASI(~0), "1,2,d", 0, v6notv9 }, -{ "subx", F3(2, 0x0c, 1), F3(~2, ~0x0c, ~1), "1,i,d", 0, v6notv9 }, -{ "subc", F3(2, 0x0c, 0), F3(~2, ~0x0c, ~0)|ASI(~0), "1,2,d", 0, v9 }, -{ "subc", F3(2, 0x0c, 1), F3(~2, ~0x0c, ~1), "1,i,d", 0, v9 }, +{ "subc", F3(2, 0x0c, 0), F3(~2, ~0x0c, ~0)|ASI(~0), "1,2,d", 0, v6 }, +{ "subc", F3(2, 0x0c, 1), F3(~2, ~0x0c, ~1), "1,i,d", 0, v6 }, -{ "subxcc", F3(2, 0x1c, 0), F3(~2, ~0x1c, ~0)|ASI(~0), "1,2,d", 0, v6notv9 }, -{ "subxcc", F3(2, 0x1c, 1), F3(~2, ~0x1c, ~1), "1,i,d", 0, v6notv9 }, -{ "subccc", F3(2, 0x1c, 0), F3(~2, ~0x1c, ~0)|ASI(~0), "1,2,d", 0, v9 }, -{ "subccc", F3(2, 0x1c, 1), F3(~2, ~0x1c, ~1), "1,i,d", 0, v9 }, +{ "subccc", F3(2, 0x1c, 0), F3(~2, ~0x1c, ~0)|ASI(~0), "1,2,d", 0, v6 }, +{ "subccc", F3(2, 0x1c, 1), F3(~2, ~0x1c, ~1), "1,i,d", 0, v6 }, { "and", F3(2, 0x01, 0), F3(~2, ~0x01, ~0)|ASI(~0), "1,2,d", 0, v6 }, { "and", F3(2, 0x01, 1), F3(~2, ~0x01, ~1), "1,i,d", 0, v6 }, @@ -1215,19 +1211,13 @@ static const struct sparc_opcode sparc_opcodes[] = { { "addcc", F3(2, 0x10, 1), F3(~2, ~0x10, ~1), "1,i,d", 0, v6 }, { "addcc", F3(2, 0x10, 1), F3(~2, ~0x10, ~1), "i,1,d", 0, v6 }, -{ "addx", F3(2, 0x08, 0), F3(~2, ~0x08, ~0)|ASI(~0), "1,2,d", 0, v6notv9 }, -{ "addx", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "1,i,d", 0, v6notv9 }, -{ "addx", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "i,1,d", 0, v6notv9 }, -{ "addc", F3(2, 0x08, 0), F3(~2, ~0x08, ~0)|ASI(~0), "1,2,d", 0, v9 }, -{ "addc", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "1,i,d", 0, v9 }, -{ "addc", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "i,1,d", 0, v9 }, - -{ "addxcc", F3(2, 0x18, 0), F3(~2, ~0x18, ~0)|ASI(~0), "1,2,d", 0, v6notv9 }, -{ "addxcc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "1,i,d", 0, v6notv9 }, -{ "addxcc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "i,1,d", 0, v6notv9 }, -{ "addccc", F3(2, 0x18, 0), F3(~2, ~0x18, ~0)|ASI(~0), "1,2,d", 0, v9 }, -{ "addccc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "1,i,d", 0, v9 }, -{ "addccc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "i,1,d", 0, v9 }, +{ "addc", F3(2, 0x08, 0), F3(~2, ~0x08, ~0)|ASI(~0), "1,2,d", 0, v6 }, +{ "addc", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "1,i,d", 0, v6 }, +{ "addc", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "i,1,d", 0, v6 }, + +{ "addccc", F3(2, 0x18, 0), F3(~2, ~0x18, ~0)|ASI(~0), "1,2,d", 0, v6 }, +{ "addccc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "1,i,d", 0, v6 }, +{ "addccc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "i,1,d", 0, v6 }, { "smul", F3(2, 0x0b, 0), F3(~2, ~0x0b, ~0)|ASI(~0), "1,2,d", 0, v8 }, { "smul", F3(2, 0x0b, 1), F3(~2, ~0x0b, ~1), "1,i,d", 0, v8 }, diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c index d0bd08c..0a8c26a 100644 --- a/tcg/sparc/tcg-target.c +++ b/tcg/sparc/tcg-target.c @@ -197,8 +197,8 @@ static const int tcg_target_call_oarg_regs[] = { #define ARITH_XOR (INSN_OP(2) | INSN_OP3(0x03)) #define ARITH_SUB (INSN_OP(2) | INSN_OP3(0x04)) #define ARITH_SUBCC (INSN_OP(2) | INSN_OP3(0x14)) -#define ARITH_ADDX (INSN_OP(2) | INSN_OP3(0x08)) -#define ARITH_SUBX (INSN_OP(2) | INSN_OP3(0x0c)) +#define ARITH_ADDC (INSN_OP(2) | INSN_OP3(0x08)) +#define ARITH_SUBC (INSN_OP(2) | INSN_OP3(0x0c)) #define ARITH_UMUL (INSN_OP(2) | INSN_OP3(0x0a)) #define ARITH_SMUL (INSN_OP(2) | INSN_OP3(0x0b)) #define ARITH_UDIV (INSN_OP(2) | INSN_OP3(0x0e)) @@ -663,7 +663,7 @@ static void tcg_out_movcond_i64(TCGContext *s, TCGCond cond, TCGReg ret, static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGReg ret, TCGReg c1, int32_t c2, int c2const) { - /* For 32-bit comparisons, we can play games with ADDX/SUBX. */ + /* For 32-bit comparisons, we can play games with ADDC/SUBC. */ switch (cond) { case TCG_COND_LTU: case TCG_COND_GEU: @@ -707,9 +707,9 @@ static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGReg ret, tcg_out_cmp(s, c1, c2, c2const); if (cond == TCG_COND_LTU) { - tcg_out_arithi(s, ret, TCG_REG_G0, 0, ARITH_ADDX); + tcg_out_arithi(s, ret, TCG_REG_G0, 0, ARITH_ADDC); } else { - tcg_out_arithi(s, ret, TCG_REG_G0, -1, ARITH_SUBX); + tcg_out_arithi(s, ret, TCG_REG_G0, -1, ARITH_SUBC); } } @@ -1340,12 +1340,12 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_add2_i32: tcg_out_addsub2_i32(s, args[0], args[1], args[2], args[3], args[4], const_args[4], args[5], const_args[5], - ARITH_ADDCC, ARITH_ADDX); + ARITH_ADDCC, ARITH_ADDC); break; case INDEX_op_sub2_i32: tcg_out_addsub2_i32(s, args[0], args[1], args[2], args[3], args[4], const_args[4], args[5], const_args[5], - ARITH_SUBCC, ARITH_SUBX); + ARITH_SUBCC, ARITH_SUBC); break; case INDEX_op_mulu2_i32: c = ARITH_UMUL; -- 1.9.3 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 6/6] tcg-sparc: Use UMULXHI instruction 2014-08-06 19:49 [Qemu-devel] [PATCH 0/6] tcg sparc improvements Richard Henderson ` (4 preceding siblings ...) 2014-08-06 19:49 ` [Qemu-devel] [PATCH 5/6] tcg-sparc: Rename ADDX/SUBX insns Richard Henderson @ 2014-08-06 19:49 ` Richard Henderson 5 siblings, 0 replies; 7+ messages in thread From: Richard Henderson @ 2014-08-06 19:49 UTC (permalink / raw) To: qemu-devel Signed-off-by: Richard Henderson <rth@twiddle.net> --- disas/sparc.c | 1 + tcg/sparc/tcg-target.c | 5 +++++ tcg/sparc/tcg-target.h | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/disas/sparc.c b/disas/sparc.c index 22ceac3..8e755d1 100644 --- a/disas/sparc.c +++ b/disas/sparc.c @@ -2034,6 +2034,7 @@ IMPDEP ("impdep2", 0x37), { "addxc", F3F(2, 0x36, 0x011), F3F(~2, ~0x36, ~0x011), "1,2,d", 0, v9b }, { "addxccc", F3F(2, 0x36, 0x013), F3F(~2, ~0x36, ~0x013), "1,2,d", 0, v9b }, +{ "umulxhi", F3F(2, 0x36, 0x016), F3F(~2, ~0x36, ~0x016), "1,2,d", 0, v9b }, }; diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c index 0a8c26a..0c4b028 100644 --- a/tcg/sparc/tcg-target.c +++ b/tcg/sparc/tcg-target.c @@ -210,6 +210,7 @@ static const int tcg_target_call_oarg_regs[] = { #define ARITH_MOVR (INSN_OP(2) | INSN_OP3(0x2f)) #define ARITH_ADDXC (INSN_OP(2) | INSN_OP3(0x36) | INSN_OPF(0x11)) +#define ARITH_UMULXHI (INSN_OP(2) | INSN_OP3(0x36) | INSN_OPF(0x16)) #define SHIFT_SLL (INSN_OP(2) | INSN_OP3(0x25)) #define SHIFT_SRL (INSN_OP(2) | INSN_OP3(0x26)) @@ -1435,6 +1436,9 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_addsub2_i64(s, args[0], args[1], args[2], args[3], args[4], const_args[4], args[5], const_args[5], true); break; + case INDEX_op_muluh_i64: + tcg_out_arith(s, args[0], args[1], args[2], ARITH_UMULXHI); + break; gen_arith: tcg_out_arithc(s, a0, a1, a2, c2, c); @@ -1535,6 +1539,7 @@ static const TCGTargetOpDef sparc_op_defs[] = { { INDEX_op_add2_i64, { "R", "R", "RZ", "RZ", "RJ", "RI" } }, { INDEX_op_sub2_i64, { "R", "R", "RZ", "RZ", "RJ", "RI" } }, + { INDEX_op_muluh_i64, { "R", "RZ", "RZ" } }, { INDEX_op_qemu_ld_i32, { "r", "A" } }, { INDEX_op_qemu_ld_i64, { "R", "A" } }, diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h index 099b308..0c4c8af 100644 --- a/tcg/sparc/tcg-target.h +++ b/tcg/sparc/tcg-target.h @@ -143,7 +143,7 @@ extern bool use_vis3_instructions; #define TCG_TARGET_HAS_sub2_i64 1 #define TCG_TARGET_HAS_mulu2_i64 0 #define TCG_TARGET_HAS_muls2_i64 0 -#define TCG_TARGET_HAS_muluh_i64 0 +#define TCG_TARGET_HAS_muluh_i64 use_vis3_instructions #define TCG_TARGET_HAS_mulsh_i64 0 #define TCG_AREG0 TCG_REG_I0 -- 1.9.3 ^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2014-08-06 19:50 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-08-06 19:49 [Qemu-devel] [PATCH 0/6] tcg sparc improvements Richard Henderson 2014-08-06 19:49 ` [Qemu-devel] [PATCH 1/6] tcg-sparc: Support addsub2_i64 Richard Henderson 2014-08-06 19:49 ` [Qemu-devel] [PATCH 2/6] tcg-sparc: Use ADDXC in addsub2_i64 Richard Henderson 2014-08-06 19:49 ` [Qemu-devel] [PATCH 3/6] tcg-sparc: Fix setcond_i32 uninitialized value Richard Henderson 2014-08-06 19:49 ` [Qemu-devel] [PATCH 4/6] tcg-sparc: Use ADDXC in setcond_i64 Richard Henderson 2014-08-06 19:49 ` [Qemu-devel] [PATCH 5/6] tcg-sparc: Rename ADDX/SUBX insns Richard Henderson 2014-08-06 19:49 ` [Qemu-devel] [PATCH 6/6] tcg-sparc: Use UMULXHI instruction Richard Henderson
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).