aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2011-11-17 20:28:32 -0800
committerAlon Zakai <alonzakai@gmail.com>2011-11-17 20:28:32 -0800
commit77efd8b75777e43a3b2fc4eff61b2ef186a08ff2 (patch)
treed6f4152334d478503d00c557566f1cf927254186
parentc1fb23123271f4250b80e76c0393842d2d4dbd2b (diff)
proper support for sext of i64s in i64 mode 1
-rw-r--r--src/parseTools.js10
-rw-r--r--tests/runner.py26
2 files changed, 35 insertions, 1 deletions
diff --git a/src/parseTools.js b/src/parseTools.js
index d7514ef5..591e6add 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -1339,6 +1339,7 @@ function getGetElementPtrIndexes(item) {
}
function handleOverflow(text, bits) {
+ // TODO: handle overflows of i64s
if (!bits) return text;
var correct = correctOverflows();
warn(!correct || bits <= 32, 'Cannot correct overflows of this many bits: ' + bits + ' at line ' + Framework.currItem.lineNum);
@@ -1393,6 +1394,10 @@ function finalizeLLVMParameter(param, noIndexizeFunctions) {
}
function makeSignOp(value, type, op, force) {
+ if (I64_MODE == 1 && type == 'i64') {
+ return '(tempPair=' + value + ',[' + makeSignOp('tempPair[0]', 'i32', op, force) + ',' + makeSignOp('tempPair[1]', 'i32', op, force) + '])';
+ }
+
if (isPointerType(type)) type = 'i32'; // Pointers are treated as 32-bit ints
if (!value) return value;
var bits, full;
@@ -1430,6 +1435,8 @@ function makeSignOp(value, type, op, force) {
}
function makeRounding(value, bits, signed) {
+ // TODO: handle roundings of i64s
+
// C rounds to 0 (-5.5 to -5, +5.5 to 5), while JS has no direct way to do that.
// With 32 bits and less, and a signed value, |0 will round it like C does.
if (bits && bits <= 32 && signed) return '(('+value+')|0)';
@@ -1531,7 +1538,8 @@ function processMathop(item) { with(item) {
default: throw 'Unknown icmp variant: ' + variant;
}
}
- case 'zext': case 'sext': return makeI64(ident1, 0);
+ case 'zext': return makeI64(ident1, 0);
+ case 'sext': return '(tempInt=' + ident1 + ',' + makeI64('tempInt', 'tempInt<0 ? 4294967295 : 0') + ')';
case 'trunc': {
return '((' + ident1 + '[0]) & ' + (Math.pow(2, bitsLeft)-1) + ')';
}
diff --git a/tests/runner.py b/tests/runner.py
index 6dade2aa..2a050deb 100644
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -396,6 +396,7 @@ if 'benchmark' not in str(sys.argv):
# Stuff that only works in i64_mode = 1
Settings.I64_MODE = 1
+
src = r'''
#include <time.h>
#include <stdio.h>
@@ -458,6 +459,31 @@ if 'benchmark' not in str(sys.argv):
'*18446744073709552000*\n*576460752303423500*\n' +
'm1: 127\n*123*\n*127*\n')
+ Settings.CORRECT_SIGNS = 1
+
+ src = r'''
+ #include <stdio.h>
+ #include <stdint.h>
+
+ int main()
+ {
+ // i32 vs i64
+ int32_t small = -1;
+ int64_t large = -1;
+ printf("*%d*\n", small == large);
+ small++;
+ printf("*%d*\n", small == large);
+ uint32_t usmall = -1;
+ uint64_t ularge = -1;
+ printf("*%d*\n", usmall == ularge);
+ usmall++;
+ printf("*%d*\n", usmall == ularge);
+ return 0;
+ }
+ '''
+
+ self.do_run(src, '*1*\n*0*\n*1*\n*0*')
+
def test_unaligned(self):
if Settings.QUANTUM_SIZE == 1: return self.skip('No meaning to unaligned addresses in q1')
if Settings.USE_TYPED_ARRAYS != 2: return self.skip('No meaning to unaligned addresses without t2')