Commit c9e004a8 authored by erik.corry@gmail.com's avatar erik.corry@gmail.com

Add a compare stub on ARM.

Review URL: http://codereview.chromium.org/151003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2295 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 829146e2
This diff is collapsed.
...@@ -292,7 +292,10 @@ class CodeGenerator: public AstVisitor { ...@@ -292,7 +292,10 @@ class CodeGenerator: public AstVisitor {
void ToBoolean(JumpTarget* true_target, JumpTarget* false_target); void ToBoolean(JumpTarget* true_target, JumpTarget* false_target);
void GenericBinaryOperation(Token::Value op, OverwriteMode overwrite_mode); void GenericBinaryOperation(Token::Value op, OverwriteMode overwrite_mode);
void Comparison(Condition cc, bool strict = false); void Comparison(Condition cc,
Expression* left,
Expression* right,
bool strict = false);
void SmiOperation(Token::Value op, void SmiOperation(Token::Value op,
Handle<Object> value, Handle<Object> value,
......
...@@ -1046,6 +1046,9 @@ void Simulator::SoftwareInterrupt(Instr* instr) { ...@@ -1046,6 +1046,9 @@ void Simulator::SoftwareInterrupt(Instr* instr) {
int64_t result = target(arg0, arg1, arg2, arg3); int64_t result = target(arg0, arg1, arg2, arg3);
int32_t lo_res = static_cast<int32_t>(result); int32_t lo_res = static_cast<int32_t>(result);
int32_t hi_res = static_cast<int32_t>(result >> 32); int32_t hi_res = static_cast<int32_t>(result >> 32);
if (::v8::internal::FLAG_trace_sim) {
PrintF("Returned %08x\n", lo_res);
}
set_register(r0, lo_res); set_register(r0, lo_res);
set_register(r1, hi_res); set_register(r1, hi_res);
set_register(r0, result); set_register(r0, result);
......
...@@ -608,6 +608,12 @@ static double mul_two_doubles(double x, double y) { ...@@ -608,6 +608,12 @@ static double mul_two_doubles(double x, double y) {
} }
static int native_compare_doubles(double x, double y) {
if (x == y) return 0;
return x < y ? 1 : -1;
}
ExternalReference ExternalReference::double_fp_operation( ExternalReference ExternalReference::double_fp_operation(
Token::Value operation) { Token::Value operation) {
typedef double BinaryFPOperation(double x, double y); typedef double BinaryFPOperation(double x, double y);
...@@ -630,6 +636,12 @@ ExternalReference ExternalReference::double_fp_operation( ...@@ -630,6 +636,12 @@ ExternalReference ExternalReference::double_fp_operation(
} }
ExternalReference ExternalReference::compare_doubles() {
return ExternalReference(Redirect(FUNCTION_ADDR(native_compare_doubles),
false));
}
ExternalReferenceRedirector* ExternalReference::redirector_ = NULL; ExternalReferenceRedirector* ExternalReference::redirector_ = NULL;
......
...@@ -413,6 +413,7 @@ class ExternalReference BASE_EMBEDDED { ...@@ -413,6 +413,7 @@ class ExternalReference BASE_EMBEDDED {
static ExternalReference new_space_allocation_limit_address(); static ExternalReference new_space_allocation_limit_address();
static ExternalReference double_fp_operation(Token::Value operation); static ExternalReference double_fp_operation(Token::Value operation);
static ExternalReference compare_doubles();
Address address() const {return reinterpret_cast<Address>(address_);} Address address() const {return reinterpret_cast<Address>(address_);}
......
...@@ -249,6 +249,36 @@ class UnarySubStub : public CodeStub { ...@@ -249,6 +249,36 @@ class UnarySubStub : public CodeStub {
}; };
class CompareStub: public CodeStub {
public:
CompareStub(Condition cc, bool strict) : cc_(cc), strict_(strict) { }
void Generate(MacroAssembler* masm);
private:
Condition cc_;
bool strict_;
Major MajorKey() { return Compare; }
int MinorKey();
// Branch to the label if the given object isn't a symbol.
void BranchIfNonSymbol(MacroAssembler* masm,
Label* label,
Register object,
Register scratch);
#ifdef DEBUG
void Print() {
PrintF("CompareStub (cc %d), (strict %s)\n",
static_cast<int>(cc_),
strict_ ? "true" : "false");
}
#endif
};
class CEntryStub : public CodeStub { class CEntryStub : public CodeStub {
public: public:
CEntryStub() { } CEntryStub() { }
......
...@@ -1856,40 +1856,6 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, ...@@ -1856,40 +1856,6 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op,
} }
class CompareStub: public CodeStub {
public:
CompareStub(Condition cc, bool strict) : cc_(cc), strict_(strict) { }
void Generate(MacroAssembler* masm);
private:
Condition cc_;
bool strict_;
Major MajorKey() { return Compare; }
int MinorKey() {
// Encode the three parameters in a unique 16 bit value.
ASSERT(static_cast<int>(cc_) < (1 << 15));
return (static_cast<int>(cc_) << 1) | (strict_ ? 1 : 0);
}
// Branch to the label if the given object isn't a symbol.
void BranchIfNonSymbol(MacroAssembler* masm,
Label* label,
Register object,
Register scratch);
#ifdef DEBUG
void Print() {
PrintF("CompareStub (cc %d), (strict %s)\n",
static_cast<int>(cc_),
strict_ ? "true" : "false");
}
#endif
};
void CodeGenerator::Comparison(Condition cc, void CodeGenerator::Comparison(Condition cc,
bool strict, bool strict,
ControlDestination* dest) { ControlDestination* dest) {
...@@ -7943,6 +7909,12 @@ void InstanceofStub::Generate(MacroAssembler* masm) { ...@@ -7943,6 +7909,12 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
} }
int CompareStub::MinorKey() {
// Encode the two parameters in a unique 16 bit value.
ASSERT(static_cast<unsigned>(cc_) < (1 << 15));
return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0);
}
#undef __ #undef __
} } // namespace v8::internal } } // namespace v8::internal
...@@ -711,6 +711,10 @@ void ExternalReferenceTable::PopulateTable() { ...@@ -711,6 +711,10 @@ void ExternalReferenceTable::PopulateTable() {
UNCLASSIFIED, UNCLASSIFIED,
13, 13,
"mul_two_doubles"); "mul_two_doubles");
Add(ExternalReference::compare_doubles().address(),
UNCLASSIFIED,
14,
"compare_doubles");
#endif #endif
} }
......
...@@ -6811,6 +6811,13 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) { ...@@ -6811,6 +6811,13 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
} }
int CompareStub::MinorKey() {
// Encode the two parameters in a unique 16 bit value.
ASSERT(static_cast<unsigned>(cc_) < (1 << 15));
return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0);
}
#undef __ #undef __
} } // namespace v8::internal } } // namespace v8::internal
...@@ -28,17 +28,17 @@ ...@@ -28,17 +28,17 @@
var a = [NaN, -1, 0, 1, 1.2, -7.9, true, false, 'foo', '0', 'NaN' ]; var a = [NaN, -1, 0, 1, 1.2, -7.9, true, false, 'foo', '0', 'NaN' ];
for (var i in a) { for (var i in a) {
var x = a[i]; var x = a[i];
assertFalse(NaN == x); assertFalse(NaN == x, "NaN == " + x);
assertFalse(NaN === x); assertFalse(NaN === x, "NaN === " + x);
assertFalse(NaN < x); assertFalse(NaN < x, "NaN < " + x);
assertFalse(NaN > x); assertFalse(NaN > x, "NaN > " + x);
assertFalse(NaN <= x); assertFalse(NaN <= x, "NaN <= " + x);
assertFalse(NaN >= x); assertFalse(NaN >= x, "NaN >= " + x);
assertFalse(x == NaN); assertFalse(x == NaN, "" + x + " == NaN");
assertFalse(x === NaN); assertFalse(x === NaN, "" + x + " === NaN");
assertFalse(x < NaN); assertFalse(x < NaN, "" + x + " < NaN");
assertFalse(x > NaN); assertFalse(x > NaN, "" + x + " > NaN");
assertFalse(x <= NaN); assertFalse(x <= NaN, "" + x + " <= NaN");
assertFalse(x >= NaN); assertFalse(x >= NaN, "" + x + " >= NaN");
} }
...@@ -32,26 +32,26 @@ var x = 1; ...@@ -32,26 +32,26 @@ var x = 1;
--> so must this... --> so must this...
--> and this. --> and this.
x-->0; x-->0;
assertEquals(0, x); assertEquals(0, x, 'a');
var x = 0; x <!-- x var x = 0; x <!-- x
assertEquals(0, x); assertEquals(0, x, 'b');
var x = 1; x <!--x var x = 1; x <!--x
assertEquals(1, x); assertEquals(1, x, 'c');
var x = 2; x <!-- x; x = 42; var x = 2; x <!-- x; x = 42;
assertEquals(2, x); assertEquals(2, x, 'd');
var x = 1; x <! x--; var x = 1; x <! x--;
assertEquals(0, x); assertEquals(0, x, 'e');
var x = 1; x <!- x--; var x = 1; x <!- x--;
assertEquals(0, x); assertEquals(0, x, 'f');
var b = true <! true; var b = true <! true;
assertFalse(b); assertFalse(b, 'g');
var b = true <!- true; var b = true <!- true;
assertFalse(b); assertFalse(b, 'h');
...@@ -196,6 +196,54 @@ assertEquals(78, Xor100Reversed(OBJ_42)); ...@@ -196,6 +196,54 @@ assertEquals(78, Xor100Reversed(OBJ_42));
var x = 0x23; var y = 0x35; var x = 0x23; var y = 0x35;
assertEquals(0x16, x ^ y); assertEquals(0x16, x ^ y);
// Bitwise not.
var v = 0;
assertEquals(-1, ~v);
v = SMI_MIN;
assertEquals(0x3fffffff, ~v);
v = SMI_MAX;
assertEquals(-0x40000000, ~v);
// Overflowing ++ and --.
v = SMI_MAX;
v++;
assertEquals(0x40000000, v);
v = SMI_MIN;
v--;
assertEquals(-0x40000001, v);
// Not actually Smi operations.
// Check that relations on unary ops work.
var v = -1.2;
assertTrue(v == v);
assertTrue(v === v);
assertTrue(v <= v);
assertTrue(v >= v);
assertFalse(v < v);
assertFalse(v > v);
assertFalse(v != v);
assertFalse(v !== v);
// Right hand side of unary minus is overwritable.
v = 1.5
assertEquals(-2.25, -(v * v));
// Smi input to bitop gives non-smi result where the rhs is a float that
// can be overwritten.
var x1 = 0x10000000;
var x2 = 0x40000002;
var x3 = 0x40000000;
assertEquals(0x40000000, x1 << (x2 - x3));
// Smi input to bitop gives non-smi result where the rhs could be overwritten
// if it were a float, but it isn't.
x1 = 0x10000000
x2 = 4
x3 = 2
assertEquals(0x40000000, x1 << (x2 - x3));
// Test shift operators on non-smi inputs, giving smi and non-smi results. // Test shift operators on non-smi inputs, giving smi and non-smi results.
function testShiftNonSmis() { function testShiftNonSmis() {
var pos_non_smi = 2000000000; var pos_non_smi = 2000000000;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment