[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 13/14] target/i386: use higher-precision arithmetic to compute CF
From: |
Paolo Bonzini |
Subject: |
[PATCH 13/14] target/i386: use higher-precision arithmetic to compute CF |
Date: |
Sun, 20 Oct 2024 17:53:23 +0200 |
If the operands of the arithmetic instruction fit within a half-register,
it's easiest to use a comparison instruction to compute the carry.
`
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/tcg/cc_helper_template.h.inc | 37 ++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/target/i386/tcg/cc_helper_template.h.inc
b/target/i386/tcg/cc_helper_template.h.inc
index 8af8b8539f9..f29a6dfb77c 100644
--- a/target/i386/tcg/cc_helper_template.h.inc
+++ b/target/i386/tcg/cc_helper_template.h.inc
@@ -22,12 +22,17 @@
#if DATA_BITS == 8
#define SUFFIX b
#define DATA_TYPE uint8_t
+#define WIDER_TYPE uint32_t
#elif DATA_BITS == 16
#define SUFFIX w
#define DATA_TYPE uint16_t
+#define WIDER_TYPE uint32_t
#elif DATA_BITS == 32
#define SUFFIX l
#define DATA_TYPE uint32_t
+#if HOST_LONG_BITS <= 64
+#define WIDER_TYPE uint64_t
+#endif
#elif DATA_BITS == 64
#define SUFFIX q
#define DATA_TYPE uint64_t
@@ -62,9 +67,18 @@ static uint32_t glue(compute_all_adc, SUFFIX)(DATA_TYPE dst,
DATA_TYPE src1,
DATA_TYPE src3)
{
uint32_t cf, pf, af, zf, sf, of;
+
+#ifdef WIDER_TYPE
+ WIDER_TYPE src13 = (WIDER_TYPE) src1 + (WIDER_TYPE) src3;
+ DATA_TYPE src2 = dst - src13;
+
+ cf = dst < src13;
+#else
DATA_TYPE src2 = dst - src1 - src3;
cf = (src3 ? dst <= src1 : dst < src1);
+#endif
+
pf = compute_pf(dst);
af = (dst ^ src1 ^ src2) & 0x10;
zf = (dst == 0) << 6;
@@ -76,7 +90,13 @@ static uint32_t glue(compute_all_adc, SUFFIX)(DATA_TYPE dst,
DATA_TYPE src1,
static int glue(compute_c_adc, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1,
DATA_TYPE src3)
{
+#ifdef WIDER_TYPE
+ WIDER_TYPE src13 = (WIDER_TYPE) src1 + (WIDER_TYPE) src3;
+
+ return dst < src13;
+#else
return src3 ? dst <= src1 : dst < src1;
+#endif
}
static uint32_t glue(compute_all_sub, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2)
@@ -104,9 +124,18 @@ static uint32_t glue(compute_all_sbb, SUFFIX)(DATA_TYPE
dst, DATA_TYPE src2,
DATA_TYPE src3)
{
uint32_t cf, pf, af, zf, sf, of;
+
+#ifdef WIDER_TYPE
+ WIDER_TYPE src23 = (WIDER_TYPE) src2 + (WIDER_TYPE) src3;
+ DATA_TYPE src1 = dst + src23;
+
+ cf = src1 < src23;
+#else
DATA_TYPE src1 = dst + src2 + src3;
cf = (src3 ? src1 <= src2 : src1 < src2);
+#endif
+
pf = compute_pf(dst);
af = (dst ^ src1 ^ src2) & 0x10;
zf = (dst == 0) << 6;
@@ -118,9 +147,16 @@ static uint32_t glue(compute_all_sbb, SUFFIX)(DATA_TYPE
dst, DATA_TYPE src2,
static int glue(compute_c_sbb, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2,
DATA_TYPE src3)
{
+#ifdef WIDER_TYPE
+ WIDER_TYPE src23 = (WIDER_TYPE) src2 + (WIDER_TYPE) src3;
+ DATA_TYPE src1 = dst + src23;
+
+ return src1 < src23;
+#else
DATA_TYPE src1 = dst + src2 + src3;
return (src3 ? src1 <= src2 : src1 < src2);
+#endif
}
static uint32_t glue(compute_all_logic, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
@@ -258,3 +294,4 @@ static int glue(compute_c_blsi, SUFFIX)(DATA_TYPE dst,
DATA_TYPE src1)
#undef DATA_TYPE
#undef DATA_MASK
#undef SUFFIX
+#undef WIDER_TYPE
--
2.46.2
- [PATCH 04/14] target/i386: Rearrange CCOp, (continued)
- [PATCH 04/14] target/i386: Rearrange CCOp, Paolo Bonzini, 2024/10/20
- [PATCH 08/14] target/i386: optimize TEST+Jxx sequences, Paolo Bonzini, 2024/10/20
- [PATCH 09/14] target/i386: add a few more trivial CCPrepare cases, Paolo Bonzini, 2024/10/20
- [PATCH 11/14] target/i386: make flag variables unsigned, Paolo Bonzini, 2024/10/20
- [PATCH 14/14] target/i386: use + to put flags together, Paolo Bonzini, 2024/10/20
- [PATCH 12/14] target/i386: use builtin popcnt or parity to compute PF, if available, Paolo Bonzini, 2024/10/20
- [PATCH 13/14] target/i386: use higher-precision arithmetic to compute CF,
Paolo Bonzini <=