roundy math ops (add etc.) in i64=1
This commit is contained in:
Родитель
7ea5dd5b4e
Коммит
43c47cb259
|
@ -540,10 +540,15 @@ function makeI64(low, high) {
|
|||
}
|
||||
}
|
||||
|
||||
// Splits a number (an integer in a double, possibly > 32 bits) into an I64_MODE 1 i64 value
|
||||
// Splits a number (an integer in a double, possibly > 32 bits) into an I64_MODE 1 i64 value.
|
||||
// Will suffer from rounding. margeI64 does the opposite.
|
||||
function splitI64(value) {
|
||||
assert(I64_MODE == 1);
|
||||
return makeI64(value + '|0', 'Math.floor(' + value + '/4294967296)');
|
||||
return '(tempInt=' + value + ',' + makeI64('tempInt|0', 'Math.floor(tempInt/4294967296)') + ')';
|
||||
}
|
||||
function mergeI64(value) {
|
||||
assert(I64_MODE == 1);
|
||||
return '(tempI64=' + value + ',tempI64[0]+tempI64[1]*4294967296)';
|
||||
}
|
||||
|
||||
function makeCopyI64(value) {
|
||||
|
@ -1469,6 +1474,12 @@ function processMathop(item) { with(item) {
|
|||
}
|
||||
case 'select': return ident1 + ' ? ' + makeCopyI64(ident2) + ' : ' + makeCopyI64(ident3);
|
||||
case 'ptrtoint': case 'inttoptr': throw 'Pointers cannot be 64-bit!';
|
||||
// Dangerous, rounded operations. TODO: Fully emulate
|
||||
case 'add': return handleOverflow(splitI64(mergeI64(ident1) + '+' + mergeI64(ident2)), bits);
|
||||
case 'sub': return handleOverflow(splitI64(mergeI64(ident1) + '-' + mergeI64(ident2)), bits);
|
||||
case 'sdiv': case 'udiv': return splitI64(makeRounding(mergeI64(ident1) + '/' + mergeI64(ident2), bits, op[0] === 's'));
|
||||
case 'mul': return handleOverflow(splitI64(mergeI64(ident1) + '*' + mergeI64(ident2)), bits);
|
||||
case 'urem': return splitI64(mergeI64(ident1) + '%' + mergeI64(ident2));
|
||||
default: throw 'Unsupported i64 mode 1 op: ' + item.op;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -382,6 +382,9 @@ var ABORT = false;
|
|||
|
||||
var undef = 0;
|
||||
var tempValue, tempInt, tempBigInt;
|
||||
#if I64_MODE == 1
|
||||
var tempI64, tempI64b;
|
||||
#endif
|
||||
|
||||
function abort(text) {
|
||||
print(text + ':\n' + (new Error).stack);
|
||||
|
|
|
@ -397,6 +397,7 @@ if 'benchmark' not in str(sys.argv):
|
|||
|
||||
Settings.I64_MODE = 1
|
||||
src = r'''
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
@ -414,6 +415,15 @@ if 'benchmark' not in str(sys.argv):
|
|||
t |= 12;
|
||||
}
|
||||
|
||||
int truthy() {
|
||||
int x = time(0);
|
||||
while (x > 10) {
|
||||
x |= 7;
|
||||
x /= 2;
|
||||
}
|
||||
return x < 3;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int64_t x1 = 0x1234def123450789ULL;
|
||||
|
@ -434,13 +444,20 @@ if 'benchmark' not in str(sys.argv):
|
|||
modifier2(t);
|
||||
printf("*%Ld*\n", t);
|
||||
|
||||
//
|
||||
// Basic (rounded, for now) math
|
||||
int64_t a = 0x1234def123450789ULL;
|
||||
a--; if (truthy()) a--; // confuse optimizer
|
||||
int64_t b = 0x1234000000450789ULL;
|
||||
b++; if (truthy()) b--; // confuse optimizer
|
||||
printf("*%Ld,%Ld,%Ld*\n", a+b, a-b, a*3, a/5);
|
||||
|
||||
return 0;
|
||||
}
|
||||
'''
|
||||
self.do_run(src, '*1311918518731868200\n0,0,0,1,1\n1,0,1,0,1*\n*245127260211081*\n*245127260209443*\n' +
|
||||
'*18446744073709552000*\n*576460752303423500*\n' +
|
||||
'm1: 127\n*123*\n*127*\n')
|
||||
'm1: 127\n*123*\n*127*\n' +
|
||||
'*2623591910208049000,245127255687168,3935755556195604500*\n')
|
||||
|
||||
|
||||
def test_unsigned(self):
|
||||
|
|
Загрузка…
Ссылка в новой задаче