aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2013-02-19 23:51:52 -0800
committerBlue Swirl <blauwirbel@gmail.com>2013-02-23 17:25:28 +0000
commitd7156f7ce4581c874df4a27409e7d99873faa413 (patch)
tree1708b382c2a448c404d54980dadb4a5a496f212a
parent803d805bcef4ea7b7d6ef0b4929263e1160d6b3c (diff)
downloadqemu-d7156f7ce4581c874df4a27409e7d99873faa413.zip
qemu-d7156f7ce4581c874df4a27409e7d99873faa413.tar.gz
qemu-d7156f7ce4581c874df4a27409e7d99873faa413.tar.bz2
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>
-rw-r--r--tcg/README26
-rw-r--r--tcg/i386/tcg-target.h3
-rw-r--r--tcg/ia64/tcg-target.h3
-rw-r--r--tcg/optimize.c4
-rw-r--r--tcg/ppc64/tcg-target.h3
-rw-r--r--tcg/s390/tcg-target.h3
-rw-r--r--tcg/sparc/tcg-target.h3
-rw-r--r--tcg/tcg-opc.h4
-rw-r--r--tcg/tcg.h3
-rw-r--r--tcg/tci/tcg-target.h3
10 files changed, 41 insertions, 14 deletions
diff --git a/tcg/README b/tcg/README
index ec1ac79..89f0cdd 100644
--- a/tcg/README
+++ b/tcg/README
@@ -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
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
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
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
Similar to setcond, except that the 64-bit values T1 and T2 are
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index 487dc23..4f00171 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -117,6 +117,9 @@ typedef enum {
#define TCG_TARGET_HAS_nor_i64 0
#define TCG_TARGET_HAS_deposit_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
#define TCG_TARGET_deposit_i32_valid(ofs, len) \
diff --git a/tcg/ia64/tcg-target.h b/tcg/ia64/tcg-target.h
index b4ff7c3..40f442e 100644
--- a/tcg/ia64/tcg-target.h
+++ b/tcg/ia64/tcg-target.h
@@ -137,8 +137,11 @@ typedef enum {
#define TCG_TARGET_HAS_deposit_i32 1
#define TCG_TARGET_HAS_deposit_i64 1
#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_i64 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_i64_valid(ofs, len) ((len) <= 16)
diff --git a/tcg/optimize.c b/tcg/optimize.c
index 973d2d6..027b3a5 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -554,11 +554,11 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
args[5] = tcg_invert_cond(args[5]);
}
break;
- case INDEX_op_add2_i32:
+ CASE_OP_32_64(add2):
swap_commutative(args[0], &args[2], &args[4]);
swap_commutative(args[1], &args[3], &args[5]);
break;
- case INDEX_op_mulu2_i32:
+ CASE_OP_32_64(mulu2):
swap_commutative(args[0], &args[2], &args[3]);
break;
case INDEX_op_brcond2_i32:
diff --git a/tcg/ppc64/tcg-target.h b/tcg/ppc64/tcg-target.h
index ea976ad..86929c1 100644
--- a/tcg/ppc64/tcg-target.h
+++ b/tcg/ppc64/tcg-target.h
@@ -109,6 +109,9 @@ typedef enum {
#define TCG_TARGET_HAS_nor_i64 0
#define TCG_TARGET_HAS_deposit_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
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
index 7772c35..ee31c37 100644
--- a/tcg/s390/tcg-target.h
+++ b/tcg/s390/tcg-target.h
@@ -90,6 +90,9 @@ typedef enum TCGReg {
#define TCG_TARGET_HAS_nor_i64 0
#define TCG_TARGET_HAS_deposit_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
/* used for function call generation */
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
index 8446721..e440ad2 100644
--- a/tcg/sparc/tcg-target.h
+++ b/tcg/sparc/tcg-target.h
@@ -127,6 +127,9 @@ 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_mulu2_i64 0
#endif
#define TCG_AREG0 TCG_REG_I0
diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h
index 1d9a9a2..e93698e 100644
--- a/tcg/tcg-opc.h
+++ b/tcg/tcg-opc.h
@@ -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(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 */
#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
DEF(debug_insn_start, 0, 0, 2, 0)
diff --git a/tcg/tcg.h b/tcg/tcg.h
index e5c7ce4..255cbdb 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -80,6 +80,9 @@ typedef uint64_t TCGRegSet;
#define TCG_TARGET_HAS_nor_i64 0
#define TCG_TARGET_HAS_deposit_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. */
#define TCG_TARGET_HAS_add2_i32 1
#define TCG_TARGET_HAS_sub2_i32 1
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index 3e235bd..5986da2 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -104,6 +104,9 @@
#define TCG_TARGET_HAS_add2_i32 0
#define TCG_TARGET_HAS_sub2_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 */
/* Number of registers available.