diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc index 307c7ad1aa2..4ee0e27619f 100644 --- a/runtime/vm/compiler/backend/il.cc +++ b/runtime/vm/compiler/backend/il.cc @@ -4048,8 +4048,8 @@ static RawCode* TwoArgsSmiOpInlineCacheEntry(Token::Kind kind) { switch (kind) { case Token::kADD: return StubCode::SmiAddInlineCache().raw(); - case Token::kSUB: - return StubCode::SmiSubInlineCache().raw(); + case Token::kLT: + return StubCode::SmiLessInlineCache().raw(); case Token::kEQ: return StubCode::SmiEqualInlineCache().raw(); default: diff --git a/runtime/vm/compiler/stub_code_compiler_arm.cc b/runtime/vm/compiler/stub_code_compiler_arm.cc index 7024fd8556b..8038fbddd07 100644 --- a/runtime/vm/compiler/stub_code_compiler_arm.cc +++ b/runtime/vm/compiler/stub_code_compiler_arm.cc @@ -1841,8 +1841,8 @@ static void EmitFastSmiOp(Assembler* assembler, intptr_t num_args, Label* not_smi_or_overflow) { __ Comment("Fast Smi op"); - __ ldr(R0, Address(SP, 0 * target::kWordSize)); - __ ldr(R1, Address(SP, 1 * target::kWordSize)); + __ ldr(R0, Address(SP, 1 * target::kWordSize)); // Left. + __ ldr(R1, Address(SP, 0 * target::kWordSize)); // Right. __ orr(TMP, R0, Operand(R1)); __ tst(TMP, Operand(kSmiTagMask)); __ b(not_smi_or_overflow, NE); @@ -1852,9 +1852,10 @@ static void EmitFastSmiOp(Assembler* assembler, __ b(not_smi_or_overflow, VS); // Branch if overflow. break; } - case Token::kSUB: { - __ subs(R0, R1, Operand(R0)); // Subtract. - __ b(not_smi_or_overflow, VS); // Branch if overflow. + case Token::kLT: { + __ cmp(R0, Operand(R1)); + __ LoadObject(R0, CastHandle(TrueObject()), LT); + __ LoadObject(R0, CastHandle(FalseObject()), GE); break; } case Token::kEQ: { @@ -2114,10 +2115,10 @@ void StubCodeCompiler::GenerateSmiAddInlineCacheStub(Assembler* assembler) { assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD); } -void StubCodeCompiler::GenerateSmiSubInlineCacheStub(Assembler* assembler) { +void StubCodeCompiler::GenerateSmiLessInlineCacheStub(Assembler* assembler) { GenerateUsageCounterIncrement(assembler, R8); GenerateNArgsCheckInlineCacheStub( - assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB); + assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kLT); } void StubCodeCompiler::GenerateSmiEqualInlineCacheStub(Assembler* assembler) { diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc index 2205c2b04be..01a0e20d27d 100644 --- a/runtime/vm/compiler/stub_code_compiler_arm64.cc +++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc @@ -1903,8 +1903,8 @@ static void EmitFastSmiOp(Assembler* assembler, intptr_t num_args, Label* not_smi_or_overflow) { __ Comment("Fast Smi op"); - __ ldr(R0, Address(SP, +0 * target::kWordSize)); // Right. - __ ldr(R1, Address(SP, +1 * target::kWordSize)); // Left. + __ ldr(R0, Address(SP, +1 * target::kWordSize)); // Left. + __ ldr(R1, Address(SP, +0 * target::kWordSize)); // Right. __ orr(TMP, R0, Operand(R1)); __ BranchIfNotSmi(TMP, not_smi_or_overflow); switch (kind) { @@ -1913,16 +1913,18 @@ static void EmitFastSmiOp(Assembler* assembler, __ b(not_smi_or_overflow, VS); // Branch if overflow. break; } - case Token::kSUB: { - __ subs(R0, R1, Operand(R0)); // Subtract. - __ b(not_smi_or_overflow, VS); // Branch if overflow. + case Token::kLT: { + __ CompareRegisters(R0, R1); + __ LoadObject(R0, CastHandle(TrueObject())); + __ LoadObject(R1, CastHandle(FalseObject())); + __ csel(R0, R0, R1, LT); break; } case Token::kEQ: { __ CompareRegisters(R0, R1); __ LoadObject(R0, CastHandle(TrueObject())); __ LoadObject(R1, CastHandle(FalseObject())); - __ csel(R0, R1, R0, NE); + __ csel(R0, R0, R1, EQ); break; } default: @@ -2188,10 +2190,10 @@ void StubCodeCompiler::GenerateSmiAddInlineCacheStub(Assembler* assembler) { assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD); } -void StubCodeCompiler::GenerateSmiSubInlineCacheStub(Assembler* assembler) { +void StubCodeCompiler::GenerateSmiLessInlineCacheStub(Assembler* assembler) { GenerateUsageCounterIncrement(assembler, R6); GenerateNArgsCheckInlineCacheStub( - assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB); + assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kLT); } void StubCodeCompiler::GenerateSmiEqualInlineCacheStub(Assembler* assembler) { diff --git a/runtime/vm/compiler/stub_code_compiler_ia32.cc b/runtime/vm/compiler/stub_code_compiler_ia32.cc index 12259cc67e2..570d2f80d2c 100644 --- a/runtime/vm/compiler/stub_code_compiler_ia32.cc +++ b/runtime/vm/compiler/stub_code_compiler_ia32.cc @@ -1539,8 +1539,8 @@ static void EmitFastSmiOp(Assembler* assembler, Label* not_smi_or_overflow) { __ Comment("Fast Smi op"); ASSERT(num_args == 2); - __ movl(EDI, Address(ESP, +1 * target::kWordSize)); // Right __ movl(EAX, Address(ESP, +2 * target::kWordSize)); // Left + __ movl(EDI, Address(ESP, +1 * target::kWordSize)); // Right __ movl(EBX, EDI); __ orl(EBX, EAX); __ testl(EBX, Immediate(kSmiTagMask)); @@ -1551,26 +1551,26 @@ static void EmitFastSmiOp(Assembler* assembler, __ j(OVERFLOW, not_smi_or_overflow, Assembler::kNearJump); break; } - case Token::kSUB: { - __ subl(EAX, EDI); - __ j(OVERFLOW, not_smi_or_overflow, Assembler::kNearJump); - break; - } - case Token::kMUL: { - __ SmiUntag(EAX); - __ imull(EAX, EDI); - __ j(OVERFLOW, not_smi_or_overflow, Assembler::kNearJump); + case Token::kLT: { + Label done, is_true; + __ cmpl(EAX, EDI); + __ setcc(GREATER_EQUAL, AL); + __ movzxb(EAX, AL); // EAX := EAX < EDI ? 0 : 1 + __ movl(EAX, + Address(THR, EAX, TIMES_4, target::Thread::bool_true_offset())); + ASSERT(target::Thread::bool_true_offset() + 4 == + target::Thread::bool_false_offset()); break; } case Token::kEQ: { Label done, is_true; __ cmpl(EAX, EDI); - __ j(EQUAL, &is_true, Assembler::kNearJump); - __ LoadObject(EAX, CastHandle(FalseObject())); - __ jmp(&done, Assembler::kNearJump); - __ Bind(&is_true); - __ LoadObject(EAX, CastHandle(TrueObject())); - __ Bind(&done); + __ setcc(NOT_EQUAL, AL); + __ movzxb(EAX, AL); // EAX := EAX == EDI ? 0 : 1 + __ movl(EAX, + Address(THR, EAX, TIMES_4, target::Thread::bool_true_offset())); + ASSERT(target::Thread::bool_true_offset() + 4 == + target::Thread::bool_false_offset()); break; } default: @@ -1825,10 +1825,10 @@ void StubCodeCompiler::GenerateSmiAddInlineCacheStub(Assembler* assembler) { assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD); } -void StubCodeCompiler::GenerateSmiSubInlineCacheStub(Assembler* assembler) { +void StubCodeCompiler::GenerateSmiLessInlineCacheStub(Assembler* assembler) { GenerateUsageCounterIncrement(assembler, EBX); GenerateNArgsCheckInlineCacheStub( - assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB); + assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kLT); } void StubCodeCompiler::GenerateSmiEqualInlineCacheStub(Assembler* assembler) { diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc index 0df3f7afeb4..8c8e0be3ce6 100644 --- a/runtime/vm/compiler/stub_code_compiler_x64.cc +++ b/runtime/vm/compiler/stub_code_compiler_x64.cc @@ -1872,8 +1872,8 @@ static void EmitFastSmiOp(Assembler* assembler, Label* not_smi_or_overflow) { __ Comment("Fast Smi op"); ASSERT(num_args == 2); - __ movq(RCX, Address(RSP, +1 * target::kWordSize)); // Right __ movq(RAX, Address(RSP, +2 * target::kWordSize)); // Left. + __ movq(RCX, Address(RSP, +1 * target::kWordSize)); // Right __ movq(R13, RCX); __ orq(R13, RAX); __ testq(R13, Immediate(kSmiTagMask)); @@ -1884,20 +1884,24 @@ static void EmitFastSmiOp(Assembler* assembler, __ j(OVERFLOW, not_smi_or_overflow); break; } - case Token::kSUB: { - __ subq(RAX, RCX); - __ j(OVERFLOW, not_smi_or_overflow); + case Token::kLT: { + __ cmpq(RAX, RCX); + __ setcc(GREATER_EQUAL, ByteRegisterOf(RAX)); + __ movzxb(RAX, RAX); // RAX := RAX < RCX ? 0 : 1 + __ movq(RAX, + Address(THR, RAX, TIMES_8, target::Thread::bool_true_offset())); + ASSERT(target::Thread::bool_true_offset() + 8 == + target::Thread::bool_false_offset()); break; } case Token::kEQ: { - Label done, is_true; __ cmpq(RAX, RCX); - __ j(EQUAL, &is_true, Assembler::kNearJump); - __ LoadObject(RAX, CastHandle(FalseObject())); - __ jmp(&done, Assembler::kNearJump); - __ Bind(&is_true); - __ LoadObject(RAX, CastHandle(TrueObject())); - __ Bind(&done); + __ setcc(NOT_EQUAL, ByteRegisterOf(RAX)); + __ movzxb(RAX, RAX); // RAX := RAX == RCX ? 0 : 1 + __ movq(RAX, + Address(THR, RAX, TIMES_8, target::Thread::bool_true_offset())); + ASSERT(target::Thread::bool_true_offset() + 8 == + target::Thread::bool_false_offset()); break; } default: @@ -2192,10 +2196,10 @@ void StubCodeCompiler::GenerateSmiAddInlineCacheStub(Assembler* assembler) { assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD); } -void StubCodeCompiler::GenerateSmiSubInlineCacheStub(Assembler* assembler) { +void StubCodeCompiler::GenerateSmiLessInlineCacheStub(Assembler* assembler) { GenerateUsageCounterIncrement(assembler, RCX); GenerateNArgsCheckInlineCacheStub( - assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB); + assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kLT); } void StubCodeCompiler::GenerateSmiEqualInlineCacheStub(Assembler* assembler) { diff --git a/runtime/vm/stub_code_list.h b/runtime/vm/stub_code_list.h index 602ec4da15b..7f93f5b83c2 100644 --- a/runtime/vm/stub_code_list.h +++ b/runtime/vm/stub_code_list.h @@ -50,7 +50,7 @@ namespace dart { V(OneArgCheckInlineCache) \ V(TwoArgsCheckInlineCache) \ V(SmiAddInlineCache) \ - V(SmiSubInlineCache) \ + V(SmiLessInlineCache) \ V(SmiEqualInlineCache) \ V(OneArgOptimizedCheckInlineCache) \ V(TwoArgsOptimizedCheckInlineCache) \