Skip to content

Commit

Permalink
Support unary - operator for SMIs
Browse files Browse the repository at this point in the history
  • Loading branch information
paulfryzel committed Dec 9, 2014
1 parent 021d3de commit 1c5af67
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 2 deletions.
24 changes: 24 additions & 0 deletions lib/js/platform/base/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ Base.prototype.optimize = function optimize(ssa) {
// Replace store property/load property with a stub call
this.spliceCFG(block, this.replaceProp);

// unary = stub unary
this.spliceCFG(block, this.replaceUnary);

// binary = stub binary
this.spliceCFG(block, this.replaceBinary);

Expand Down Expand Up @@ -198,6 +201,27 @@ Base.prototype.replaceFn = function replaceFn(instr) {
};
};

Base.prototype.replaceUnary = function replaceUnary(instr) {
if (instr.type !== 'unary')
return;

var state = this._baseState;
var inputs = instr.removeAllInputs();

var op = inputs[0].id;
var src = this.instr('pushArg', [ inputs[1] ]);
var call = this.instr('callStub', [
state.createJS('stub'),
state.createJS('unary/' + op),
state.createJS(1)
]);

return {
list: [ src, call ],
replace: call
};
};

Base.prototype.replaceBinary = function replaceBinary(instr) {
if (instr.type !== 'binary')
return;
Expand Down
7 changes: 7 additions & 0 deletions lib/js/platform/base/instructions.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ exports.get = function get() {
alignStubStack: { inputs: [ js ], output: null },
runtimeId: { inputs: [ js ], output: reg, shallow: true },
ic: { inputs: [ ], output: reg, shallow: true },
unary: {
inputs: [ js, reg ],
output: out,
shallow: true
},
binary: {
inputs: [ js, reg, reg ],
output: out,
Expand All @@ -64,6 +69,8 @@ exports.get = function get() {
checkOverflow: { inputs: [], output: null, shallow: true },
reverseBranch: { inputs: [], output: null, shallow: true },

smiNeg: { inputs: [ reg ], output: reg, shallow: true },

smiUntag: { inputs: [ reg ], output: reg, shallow: true, tainted: true },
smiAdd: { inputs: [ reg, reg ], output: reg, shallow: true },
smiSub: { inputs: [ reg, reg ], output: reg, shallow: true },
Expand Down
30 changes: 30 additions & 0 deletions lib/js/platform/base/stub.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ function initStubs() {
propertyStubs.call(this);
allocStubs.call(this);
typeStubs.call(this);
unaryStubs.call(this);
binaryStubs.call(this);
}

Expand Down Expand Up @@ -377,6 +378,35 @@ function typeStubs() {
}, this);
}

function unaryStubs() {
var ops = [ '-' ];
ops.forEach(function(op) {
this.declareStub('unary/' + op, function() {/*
block UnaryExpression -> SrcSmi, SrcNonSmi
src = loadStubArg %0
isSmi src
block SrcSmi -> Overflow, Success
#if op === '-'
r = smiNeg src
#endif
checkOverflow
block Success
ret r
block SrcNonSmi -> Overflow
block Overflow
// not SMI
brk
*/}, {
locals: {
op: op
}
});
}, this);
}

function binaryStubs() {
var ops = [ '+', '-', '*' ];
ops.forEach(function(op) {
Expand Down
8 changes: 8 additions & 0 deletions lib/js/platform/x64/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,14 @@ X64.prototype.genIsSmi = function genIsSmi(instr) {
masm.isSmi(instr.inputs[0].id);
};

X64.prototype.genSmiNeg = function genSmiNeg(instr) {
var masm = this.masm();
var src = instr.inputs[0].id;
var dst = instr.output.id;

masm.neg(dst, src);
};

X64.prototype.genSmiAdd = function genSmiAdd(instr) {
var masm = this.masm();
var left = instr.inputs[0].id;
Expand Down
10 changes: 8 additions & 2 deletions test/api-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,18 @@ describe('js.js API', function() {
}

describe('basics', function() {
it('should do basic unary expression', function() {
var fn = compile(function() { -1 });
r.heap.gc();
assert.equal(fn.call(null, []).cast().value(), -1);
});

it('should do basic binary expression', function() {
var fn = compile(function() {
(1 * 2) + (3 - 6);
(1 * 2) + (-3 - 6);
});
r.heap.gc();
assert.equal(fn.call(null, []).cast().value(), -1);
assert.equal(fn.call(null, []).cast().value(), -7);
});

it('should do basic binary with spills', function() {
Expand Down

0 comments on commit 1c5af67

Please sign in to comment.