Commit ecbb5ea1041d2894f5efb9317acd519c4fd81ad5

Authored by aurel32
1 parent 68238a9e

target-alpha: overflow condition for sublv and subqv

The conditions to detect overflow in sub operations was wrong.

This patch is necessary to boot Tru64.

Signed-off-by: Tristan Gingold <gingold@adacore.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@7073 c046a42c-6fe2-441c-8c8c-71466251a162
target-alpha/op_helper.c
... ... @@ -158,22 +158,22 @@ uint64_t helper_addlv (uint64_t op1, uint64_t op2)
158 158  
159 159 uint64_t helper_subqv (uint64_t op1, uint64_t op2)
160 160 {
161   - uint64_t tmp = op1;
162   - op1 -= op2;
163   - if (unlikely(((~tmp) ^ op1 ^ (-1ULL)) & ((~tmp) ^ op2) & (1ULL << 63))) {
  161 + uint64_t res;
  162 + res = op1 - op2;
  163 + if (unlikely((op1 ^ op2) & (res ^ op1) & (1ULL << 63))) {
164 164 helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
165 165 }
166   - return op1;
  166 + return res;
167 167 }
168 168  
169 169 uint64_t helper_sublv (uint64_t op1, uint64_t op2)
170 170 {
171   - uint64_t tmp = op1;
172   - op1 = (uint32_t)(op1 - op2);
173   - if (unlikely(((~tmp) ^ op1 ^ (-1UL)) & ((~tmp) ^ op2) & (1UL << 31))) {
  171 + uint32_t res;
  172 + res = op1 - op2;
  173 + if (unlikely((op1 ^ op2) & (res ^ op1) & (1UL << 31))) {
174 174 helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
175 175 }
176   - return op1;
  176 + return res;
177 177 }
178 178  
179 179 uint64_t helper_mullv (uint64_t op1, uint64_t op2)
... ...
tests/alpha/Makefile
... ... @@ -23,6 +23,9 @@ test-cmov.o: test-cond.c
23 23 test-cmov: test-cmov.o crt.o
24 24 $(LINK)
25 25  
  26 +test-ovf: test-ovf.o crt.o
  27 + $(LINK)
  28 +
26 29 check: $(TESTS)
27 30 for f in $(TESTS); do $(SIM) $$f || exit 1; done
28 31  
... ...
tests/alpha/test-ovf.c 0 → 100644
  1 +static long test_subqv (long a, long b)
  2 +{
  3 + long res;
  4 +
  5 + asm ("subq/v %1,%2,%0"
  6 + : "=r" (res) : "r" (a), "r" (b));
  7 + return res;
  8 +}
  9 +static struct {
  10 + long (*func)(long, long);
  11 + long a;
  12 + long b;
  13 + long r;
  14 +} vectors[] =
  15 + {
  16 + {test_subqv, 0, 0x7d54000, 0xfffffffff82ac000L}
  17 + };
  18 +
  19 +int main (void)
  20 +{
  21 + int i;
  22 +
  23 + for (i = 0; i < sizeof (vectors)/sizeof(vectors[0]); i++)
  24 + if ((*vectors[i].func)(vectors[i].a, vectors[i].b) != vectors[i].r) {
  25 + write(1, "Failed\n", 7);
  26 + }
  27 + write(1, "OK\n", 3);
  28 + return 0;
  29 +}
... ...