diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-03-05 21:55:36 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-03-05 21:55:36 -0800 |
commit | aeb905a51654cd46866d853e62322e2cb77b2425 (patch) | |
tree | 756747fb6665739b325e6c670510f232c891f19b | |
parent | a9c1100839bd70225a9d0a7e127797356ce180c4 (diff) |
handle signedness properly in 64-bit div, mul, rem
-rw-r--r-- | src/parseTools.js | 12 | ||||
-rwxr-xr-x | tests/runner.py | 24 |
2 files changed, 30 insertions, 6 deletions
diff --git a/src/parseTools.js b/src/parseTools.js index a2fc11ed..520d278e 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -559,12 +559,12 @@ function splitI64(value) { return makeInlineCalculation(makeI64('VALUE>>>0', 'Math.min(Math.floor(VALUE/4294967296), 4294967295)'), value, 'tempBigIntP'); } } -function mergeI64(value) { +function mergeI64(value, unsigned) { assert(USE_TYPED_ARRAYS == 2); if (legalizedI64s) { - return RuntimeGenerator.makeBigInt(value + '$0', value + '$1'); + return RuntimeGenerator.makeBigInt(value + '$0', value + '$1', unsigned); } else { - return makeInlineCalculation(RuntimeGenerator.makeBigInt('VALUE[0]', 'VALUE[1]'), value, 'tempI64'); + return makeInlineCalculation(RuntimeGenerator.makeBigInt('VALUE[0]', 'VALUE[1]', unsigned), value, 'tempI64'); } } @@ -1704,9 +1704,9 @@ function processMathop(item) { // Dangerous, rounded operations. TODO: Fully emulate case 'add': warnI64_1(); return finish(splitI64(mergeI64(idents[0]) + '+' + mergeI64(idents[1]))); case 'sub': warnI64_1(); return finish(splitI64(mergeI64(idents[0]) + '-' + mergeI64(idents[1]))); - case 'sdiv': case 'udiv': warnI64_1(); return finish(splitI64(makeRounding(mergeI64(idents[0]) + '/' + mergeI64(idents[1]), bits, op[0] === 's'))); - case 'mul': warnI64_1(); return finish(splitI64(mergeI64(idents[0]) + '*' + mergeI64(idents[1]))); - case 'urem': case 'srem': warnI64_1(); return finish(splitI64(mergeI64(idents[0]) + '%' + mergeI64(idents[1]))); + case 'sdiv': case 'udiv': warnI64_1(); return finish(splitI64(makeRounding(mergeI64(idents[0], op[0] === 'u') + '/' + mergeI64(idents[1], op[0] === 'u'), bits, op[0] === 's'))); + case 'mul': warnI64_1(); return finish(splitI64(mergeI64(idents[0], op[0] === 'u') + '*' + mergeI64(idents[1], op[0] === 'u'))); + case 'urem': case 'srem': warnI64_1(); return finish(splitI64(mergeI64(idents[0], op[0] === 'u') + '%' + mergeI64(idents[1], op[0] === 'u'))); case 'bitcast': { // Pointers are not 64-bit, so there is really only one possible type of bitcast here, int to float or vice versa assert(USE_TYPED_ARRAYS == 2, 'Can only bitcast ints <-> floats with typed arrays mode 2'); diff --git a/tests/runner.py b/tests/runner.py index 11fe7677..e8bcb72e 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -776,6 +776,30 @@ m_divisor is 1091269979 ''' self.do_run(src, '*0,0,0,0*\n*1,1,0,0*\n') # same as gcc + def test_i64_umul(self): + if Settings.USE_TYPED_ARRAYS != 2: return self.skip('full i64 stuff only in ta2') + src = r''' + #include <inttypes.h> + #include <stdio.h> + + typedef uint32_t UINT32; + typedef uint64_t UINT64; + + int main() { + volatile UINT32 testu32a = 2375724032U; + UINT32 bigu32 = 0xffffffffU; + volatile UINT64 testu64a = 14746250828952703000U; + + while ((UINT64)testu32a * (UINT64)bigu32 < testu64a) { + printf("testu64a is %llu\n", testu64a); + testu64a /= 2; + } + + return 0; + } + ''' + self.do_run(src, 'testu64a is 14746250828952703000\n') + def test_unaligned(self): if Settings.QUANTUM_SIZE == 1: return self.skip('No meaning to unaligned addresses in q1') |