tcg: Add 64-bit multiword arithmetic operations

Matching the 32-bit multiword arithmetic that we already have.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
This commit is contained in:
Richard Henderson 2013-02-19 23:51:52 -08:00 committed by Blue Swirl
parent 803d805bce
commit d7156f7ce4
10 changed files with 41 additions and 14 deletions

View File

@ -361,6 +361,20 @@ Write 8, 16, 32 or 64 bits to host memory.
All this opcodes assume that the pointed host memory doesn't correspond All this opcodes assume that the pointed host memory doesn't correspond
to a global. In the latter case the behaviour is unpredictable. to a global. In the latter case the behaviour is unpredictable.
********* Multiword arithmetic support
* add2_i32/i64 t0_low, t0_high, t1_low, t1_high, t2_low, t2_high
* sub2_i32/i64 t0_low, t0_high, t1_low, t1_high, t2_low, t2_high
Similar to add/sub, except that the double-word inputs T1 and T2 are
formed from two single-word arguments, and the double-word output T0
is returned in two single-word outputs.
* mulu2_i32/i64 t0_low, t0_high, t1, t2
Similar to mul, except two unsigned inputs T1 and T2 yielding the full
double-word product T0. The later is returned in two single-word outputs.
********* 64-bit target on 32-bit host support ********* 64-bit target on 32-bit host support
The following opcodes are internal to TCG. Thus they are to be implemented by The following opcodes are internal to TCG. Thus they are to be implemented by
@ -372,18 +386,6 @@ They are emitted as needed by inline functions within "tcg-op.h".
Similar to brcond, except that the 64-bit values T0 and T1 Similar to brcond, except that the 64-bit values T0 and T1
are formed from two 32-bit arguments. are formed from two 32-bit arguments.
* add2_i32 t0_low, t0_high, t1_low, t1_high, t2_low, t2_high
* sub2_i32 t0_low, t0_high, t1_low, t1_high, t2_low, t2_high
Similar to add/sub, except that the 64-bit inputs T1 and T2 are
formed from two 32-bit arguments, and the 64-bit output T0
is returned in two 32-bit outputs.
* mulu2_i32 t0_low, t0_high, t1, t2
Similar to mul, except two 32-bit (unsigned) inputs T1 and T2 yielding
the full 64-bit product T0. The later is returned in two 32-bit outputs.
* setcond2_i32 dest, t1_low, t1_high, t2_low, t2_high, cond * setcond2_i32 dest, t1_low, t1_high, t2_low, t2_high, cond
Similar to setcond, except that the 64-bit values T1 and T2 are Similar to setcond, except that the 64-bit values T1 and T2 are

View File

@ -117,6 +117,9 @@ typedef enum {
#define TCG_TARGET_HAS_nor_i64 0 #define TCG_TARGET_HAS_nor_i64 0
#define TCG_TARGET_HAS_deposit_i64 1 #define TCG_TARGET_HAS_deposit_i64 1
#define TCG_TARGET_HAS_movcond_i64 1 #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_mulu2_i64 0
#endif #endif
#define TCG_TARGET_deposit_i32_valid(ofs, len) \ #define TCG_TARGET_deposit_i32_valid(ofs, len) \

View File

@ -137,8 +137,11 @@ typedef enum {
#define TCG_TARGET_HAS_deposit_i32 1 #define TCG_TARGET_HAS_deposit_i32 1
#define TCG_TARGET_HAS_deposit_i64 1 #define TCG_TARGET_HAS_deposit_i64 1
#define TCG_TARGET_HAS_add2_i32 0 #define TCG_TARGET_HAS_add2_i32 0
#define TCG_TARGET_HAS_add2_i64 0
#define TCG_TARGET_HAS_sub2_i32 0 #define TCG_TARGET_HAS_sub2_i32 0
#define TCG_TARGET_HAS_sub2_i64 0
#define TCG_TARGET_HAS_mulu2_i32 0 #define TCG_TARGET_HAS_mulu2_i32 0
#define TCG_TARGET_HAS_mulu2_i64 0
#define TCG_TARGET_deposit_i32_valid(ofs, len) ((len) <= 16) #define TCG_TARGET_deposit_i32_valid(ofs, len) ((len) <= 16)
#define TCG_TARGET_deposit_i64_valid(ofs, len) ((len) <= 16) #define TCG_TARGET_deposit_i64_valid(ofs, len) ((len) <= 16)

View File

@ -554,11 +554,11 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
args[5] = tcg_invert_cond(args[5]); args[5] = tcg_invert_cond(args[5]);
} }
break; break;
case INDEX_op_add2_i32: CASE_OP_32_64(add2):
swap_commutative(args[0], &args[2], &args[4]); swap_commutative(args[0], &args[2], &args[4]);
swap_commutative(args[1], &args[3], &args[5]); swap_commutative(args[1], &args[3], &args[5]);
break; break;
case INDEX_op_mulu2_i32: CASE_OP_32_64(mulu2):
swap_commutative(args[0], &args[2], &args[3]); swap_commutative(args[0], &args[2], &args[3]);
break; break;
case INDEX_op_brcond2_i32: case INDEX_op_brcond2_i32:

View File

@ -109,6 +109,9 @@ typedef enum {
#define TCG_TARGET_HAS_nor_i64 0 #define TCG_TARGET_HAS_nor_i64 0
#define TCG_TARGET_HAS_deposit_i64 0 #define TCG_TARGET_HAS_deposit_i64 0
#define TCG_TARGET_HAS_movcond_i64 0 #define TCG_TARGET_HAS_movcond_i64 0
#define TCG_TARGET_HAS_add2_i64 0
#define TCG_TARGET_HAS_sub2_i64 0
#define TCG_TARGET_HAS_mulu2_i64 0
#define TCG_AREG0 TCG_REG_R27 #define TCG_AREG0 TCG_REG_R27

View File

@ -90,6 +90,9 @@ typedef enum TCGReg {
#define TCG_TARGET_HAS_nor_i64 0 #define TCG_TARGET_HAS_nor_i64 0
#define TCG_TARGET_HAS_deposit_i64 0 #define TCG_TARGET_HAS_deposit_i64 0
#define TCG_TARGET_HAS_movcond_i64 0 #define TCG_TARGET_HAS_movcond_i64 0
#define TCG_TARGET_HAS_add2_i64 0
#define TCG_TARGET_HAS_sub2_i64 0
#define TCG_TARGET_HAS_mulu2_i64 0
#endif #endif
/* used for function call generation */ /* used for function call generation */

View File

@ -127,6 +127,9 @@ typedef enum {
#define TCG_TARGET_HAS_nor_i64 0 #define TCG_TARGET_HAS_nor_i64 0
#define TCG_TARGET_HAS_deposit_i64 0 #define TCG_TARGET_HAS_deposit_i64 0
#define TCG_TARGET_HAS_movcond_i64 1 #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_mulu2_i64 0
#endif #endif
#define TCG_AREG0 TCG_REG_I0 #define TCG_AREG0 TCG_REG_I0

View File

@ -158,6 +158,10 @@ DEF(eqv_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_eqv_i64))
DEF(nand_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_nand_i64)) DEF(nand_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_nand_i64))
DEF(nor_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_nor_i64)) DEF(nor_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_nor_i64))
DEF(add2_i64, 2, 4, 0, IMPL64 | IMPL(TCG_TARGET_HAS_add2_i64))
DEF(sub2_i64, 2, 4, 0, IMPL64 | IMPL(TCG_TARGET_HAS_sub2_i64))
DEF(mulu2_i64, 2, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_mulu2_i64))
/* QEMU specific */ /* QEMU specific */
#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
DEF(debug_insn_start, 0, 0, 2, 0) DEF(debug_insn_start, 0, 0, 2, 0)

View File

@ -80,6 +80,9 @@ typedef uint64_t TCGRegSet;
#define TCG_TARGET_HAS_nor_i64 0 #define TCG_TARGET_HAS_nor_i64 0
#define TCG_TARGET_HAS_deposit_i64 0 #define TCG_TARGET_HAS_deposit_i64 0
#define TCG_TARGET_HAS_movcond_i64 0 #define TCG_TARGET_HAS_movcond_i64 0
#define TCG_TARGET_HAS_add2_i64 0
#define TCG_TARGET_HAS_sub2_i64 0
#define TCG_TARGET_HAS_mulu2_i64 0
/* Turn some undef macros into true macros. */ /* Turn some undef macros into true macros. */
#define TCG_TARGET_HAS_add2_i32 1 #define TCG_TARGET_HAS_add2_i32 1
#define TCG_TARGET_HAS_sub2_i32 1 #define TCG_TARGET_HAS_sub2_i32 1

View File

@ -104,6 +104,9 @@
#define TCG_TARGET_HAS_add2_i32 0 #define TCG_TARGET_HAS_add2_i32 0
#define TCG_TARGET_HAS_sub2_i32 0 #define TCG_TARGET_HAS_sub2_i32 0
#define TCG_TARGET_HAS_mulu2_i32 0 #define TCG_TARGET_HAS_mulu2_i32 0
#define TCG_TARGET_HAS_add2_i64 0
#define TCG_TARGET_HAS_sub2_i64 0
#define TCG_TARGET_HAS_mulu2_i64 0
#endif /* TCG_TARGET_REG_BITS == 64 */ #endif /* TCG_TARGET_REG_BITS == 64 */
/* Number of registers available. /* Number of registers available.