Commit bde0733a authored by Toon Verwaest's avatar Toon Verwaest Committed by Commit Bot

[code-stubs] Remove StringHelper and related helpers

Bug: v8:6921
Change-Id: I651b54a061a1ea401bb345569b96763daef0abe4
Reviewed-on: https://chromium-review.googlesource.com/707238
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48520}
parent c1f7694b
......@@ -605,100 +605,6 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
__ ldm(ia_w, sp, kCalleeSaved | pc.bit());
}
void StringHelper::GenerateFlatOneByteStringEquals(
MacroAssembler* masm, Register left, Register right, Register scratch1,
Register scratch2, Register scratch3) {
Register length = scratch1;
// Compare lengths.
Label strings_not_equal, check_zero_length;
__ ldr(length, FieldMemOperand(left, String::kLengthOffset));
__ ldr(scratch2, FieldMemOperand(right, String::kLengthOffset));
__ cmp(length, scratch2);
__ b(eq, &check_zero_length);
__ bind(&strings_not_equal);
__ mov(r0, Operand(Smi::FromInt(NOT_EQUAL)));
__ Ret();
// Check if the length is zero.
Label compare_chars;
__ bind(&check_zero_length);
STATIC_ASSERT(kSmiTag == 0);
__ cmp(length, Operand::Zero());
__ b(ne, &compare_chars);
__ mov(r0, Operand(Smi::FromInt(EQUAL)));
__ Ret();
// Compare characters.
__ bind(&compare_chars);
GenerateOneByteCharsCompareLoop(masm, left, right, length, scratch2, scratch3,
&strings_not_equal);
// Characters are equal.
__ mov(r0, Operand(Smi::FromInt(EQUAL)));
__ Ret();
}
void StringHelper::GenerateCompareFlatOneByteStrings(
MacroAssembler* masm, Register left, Register right, Register scratch1,
Register scratch2, Register scratch3, Register scratch4) {
Label result_not_equal, compare_lengths;
// Find minimum length and length difference.
__ ldr(scratch1, FieldMemOperand(left, String::kLengthOffset));
__ ldr(scratch2, FieldMemOperand(right, String::kLengthOffset));
__ sub(scratch3, scratch1, Operand(scratch2), SetCC);
Register length_delta = scratch3;
__ mov(scratch1, scratch2, LeaveCC, gt);
Register min_length = scratch1;
STATIC_ASSERT(kSmiTag == 0);
__ cmp(min_length, Operand::Zero());
__ b(eq, &compare_lengths);
// Compare loop.
GenerateOneByteCharsCompareLoop(masm, left, right, min_length, scratch2,
scratch4, &result_not_equal);
// Compare lengths - strings up to min-length are equal.
__ bind(&compare_lengths);
DCHECK(Smi::FromInt(EQUAL) == static_cast<Smi*>(0));
// Use length_delta as result if it's zero.
__ mov(r0, Operand(length_delta), SetCC);
__ bind(&result_not_equal);
// Conditionally update the result based either on length_delta or
// the last comparion performed in the loop above.
__ mov(r0, Operand(Smi::FromInt(GREATER)), LeaveCC, gt);
__ mov(r0, Operand(Smi::FromInt(LESS)), LeaveCC, lt);
__ Ret();
}
void StringHelper::GenerateOneByteCharsCompareLoop(
MacroAssembler* masm, Register left, Register right, Register length,
Register scratch1, Register scratch2, Label* chars_not_equal) {
// Change index to run from -length to -1 by adding length to string
// start. This means that loop ends when index reaches zero, which
// doesn't need an additional compare.
__ SmiUntag(length);
__ add(scratch1, length,
Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
__ add(left, left, Operand(scratch1));
__ add(right, right, Operand(scratch1));
__ rsb(length, length, Operand::Zero());
Register index = length; // index = -length;
// Compare loop.
Label loop;
__ bind(&loop);
__ ldrb(scratch1, MemOperand(left, index));
__ ldrb(scratch2, MemOperand(right, index));
__ cmp(scratch1, scratch2);
__ b(ne, chars_not_equal);
__ add(index, index, Operand(1), SetCC);
__ b(ne, &loop);
}
void DirectCEntryStub::Generate(MacroAssembler* masm) {
// Place the return address on the stack, making the call
// GC safe. The RegExp backend also relies on this.
......
......@@ -9,29 +9,6 @@ namespace v8 {
namespace internal {
class StringHelper : public AllStatic {
public:
// Compares two flat one-byte strings and returns result in r0.
static void GenerateCompareFlatOneByteStrings(
MacroAssembler* masm, Register left, Register right, Register scratch1,
Register scratch2, Register scratch3, Register scratch4);
// Compares two flat one-byte strings for equality and returns result in r0.
static void GenerateFlatOneByteStringEquals(MacroAssembler* masm,
Register left, Register right,
Register scratch1,
Register scratch2,
Register scratch3);
private:
static void GenerateOneByteCharsCompareLoop(
MacroAssembler* masm, Register left, Register right, Register length,
Register scratch1, Register scratch2, Label* chars_not_equal);
DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper);
};
class RecordWriteStub: public PlatformCodeStub {
public:
RecordWriteStub(Isolate* isolate,
......
......@@ -739,113 +739,6 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
}
void StringHelper::GenerateFlatOneByteStringEquals(
MacroAssembler* masm, Register left, Register right, Register scratch1,
Register scratch2, Register scratch3) {
DCHECK(!AreAliased(left, right, scratch1, scratch2, scratch3));
Register result = x0;
Register left_length = scratch1;
Register right_length = scratch2;
// Compare lengths. If lengths differ, strings can't be equal. Lengths are
// smis, and don't need to be untagged.
Label strings_not_equal, check_zero_length;
__ Ldr(left_length, FieldMemOperand(left, String::kLengthOffset));
__ Ldr(right_length, FieldMemOperand(right, String::kLengthOffset));
__ Cmp(left_length, right_length);
__ B(eq, &check_zero_length);
__ Bind(&strings_not_equal);
__ Mov(result, Smi::FromInt(NOT_EQUAL));
__ Ret();
// Check if the length is zero. If so, the strings must be equal (and empty.)
Label compare_chars;
__ Bind(&check_zero_length);
STATIC_ASSERT(kSmiTag == 0);
__ Cbnz(left_length, &compare_chars);
__ Mov(result, Smi::FromInt(EQUAL));
__ Ret();
// Compare characters. Falls through if all characters are equal.
__ Bind(&compare_chars);
GenerateOneByteCharsCompareLoop(masm, left, right, left_length, scratch2,
scratch3, &strings_not_equal);
// Characters in strings are equal.
__ Mov(result, Smi::FromInt(EQUAL));
__ Ret();
}
void StringHelper::GenerateCompareFlatOneByteStrings(
MacroAssembler* masm, Register left, Register right, Register scratch1,
Register scratch2, Register scratch3, Register scratch4) {
DCHECK(!AreAliased(left, right, scratch1, scratch2, scratch3, scratch4));
Label result_not_equal, compare_lengths;
// Find minimum length and length difference.
Register length_delta = scratch3;
__ Ldr(scratch1, FieldMemOperand(left, String::kLengthOffset));
__ Ldr(scratch2, FieldMemOperand(right, String::kLengthOffset));
__ Subs(length_delta, scratch1, scratch2);
Register min_length = scratch1;
__ Csel(min_length, scratch2, scratch1, gt);
__ Cbz(min_length, &compare_lengths);
// Compare loop.
GenerateOneByteCharsCompareLoop(masm, left, right, min_length, scratch2,
scratch4, &result_not_equal);
// Compare lengths - strings up to min-length are equal.
__ Bind(&compare_lengths);
DCHECK(Smi::FromInt(EQUAL) == static_cast<Smi*>(0));
// Use length_delta as result if it's zero.
Register result = x0;
__ Subs(result, length_delta, 0);
__ Bind(&result_not_equal);
Register greater = x10;
Register less = x11;
__ Mov(greater, Smi::FromInt(GREATER));
__ Mov(less, Smi::FromInt(LESS));
__ CmovX(result, greater, gt);
__ CmovX(result, less, lt);
__ Ret();
}
void StringHelper::GenerateOneByteCharsCompareLoop(
MacroAssembler* masm, Register left, Register right, Register length,
Register scratch1, Register scratch2, Label* chars_not_equal) {
DCHECK(!AreAliased(left, right, length, scratch1, scratch2));
// Change index to run from -length to -1 by adding length to string
// start. This means that loop ends when index reaches zero, which
// doesn't need an additional compare.
__ SmiUntag(length);
__ Add(scratch1, length, SeqOneByteString::kHeaderSize - kHeapObjectTag);
__ Add(left, left, scratch1);
__ Add(right, right, scratch1);
Register index = length;
__ Neg(index, length); // index = -length;
// Compare loop
Label loop;
__ Bind(&loop);
__ Ldrb(scratch1, MemOperand(left, index));
__ Ldrb(scratch2, MemOperand(right, index));
__ Cmp(scratch1, scratch2);
__ B(ne, chars_not_equal);
__ Add(index, index, 1);
__ Cbnz(index, &loop);
}
RecordWriteStub::RegisterAllocation::RegisterAllocation(Register object,
Register address,
Register scratch)
......
......@@ -9,29 +9,6 @@ namespace v8 {
namespace internal {
class StringHelper : public AllStatic {
public:
// Compares two flat one-byte strings and returns result in x0.
static void GenerateCompareFlatOneByteStrings(
MacroAssembler* masm, Register left, Register right, Register scratch1,
Register scratch2, Register scratch3, Register scratch4);
// Compare two flat one-byte strings for equality and returns result in x0.
static void GenerateFlatOneByteStringEquals(MacroAssembler* masm,
Register left, Register right,
Register scratch1,
Register scratch2,
Register scratch3);
private:
static void GenerateOneByteCharsCompareLoop(
MacroAssembler* masm, Register left, Register right, Register length,
Register scratch1, Register scratch2, Label* chars_not_equal);
DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper);
};
class RecordWriteStub: public PlatformCodeStub {
public:
// Stub to record the write of 'value' at 'address' in 'object'.
......
......@@ -97,8 +97,6 @@ namespace internal {
V(kRememberedSetPointerInNewSpace, "Remembered set pointer is in new space") \
V(kRestParameter, "Rest parameters") \
V(kReturnAddressNotFoundInFrame, "Return address not found in frame") \
V(kSmiAdditionOverflow, "Smi addition overflow") \
V(kSmiSubtractionOverflow, "Smi subtraction overflow") \
V(kSpreadCall, "Call with spread argument") \
V(kStackAccessBelowStackPointer, "Stack access below stack pointer") \
V(kStackFrameTypesMustMatch, "Stack frame types must match") \
......
......@@ -689,131 +689,6 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
__ ret(0);
}
void StringHelper::GenerateFlatOneByteStringEquals(MacroAssembler* masm,
Register left,
Register right,
Register scratch1,
Register scratch2) {
Register length = scratch1;
// Compare lengths.
Label strings_not_equal, check_zero_length;
__ mov(length, FieldOperand(left, String::kLengthOffset));
__ cmp(length, FieldOperand(right, String::kLengthOffset));
__ j(equal, &check_zero_length, Label::kNear);
__ bind(&strings_not_equal);
__ Move(eax, Immediate(Smi::FromInt(NOT_EQUAL)));
__ ret(0);
// Check if the length is zero.
Label compare_chars;
__ bind(&check_zero_length);
STATIC_ASSERT(kSmiTag == 0);
__ test(length, length);
__ j(not_zero, &compare_chars, Label::kNear);
__ Move(eax, Immediate(Smi::FromInt(EQUAL)));
__ ret(0);
// Compare characters.
__ bind(&compare_chars);
GenerateOneByteCharsCompareLoop(masm, left, right, length, scratch2,
&strings_not_equal, Label::kNear);
// Characters are equal.
__ Move(eax, Immediate(Smi::FromInt(EQUAL)));
__ ret(0);
}
void StringHelper::GenerateCompareFlatOneByteStrings(
MacroAssembler* masm, Register left, Register right, Register scratch1,
Register scratch2, Register scratch3) {
Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->string_compare_native(), 1);
// Find minimum length.
Label left_shorter;
__ mov(scratch1, FieldOperand(left, String::kLengthOffset));
__ mov(scratch3, scratch1);
__ sub(scratch3, FieldOperand(right, String::kLengthOffset));
Register length_delta = scratch3;
__ j(less_equal, &left_shorter, Label::kNear);
// Right string is shorter. Change scratch1 to be length of right string.
__ sub(scratch1, length_delta);
__ bind(&left_shorter);
Register min_length = scratch1;
// If either length is zero, just compare lengths.
Label compare_lengths;
__ test(min_length, min_length);
__ j(zero, &compare_lengths, Label::kNear);
// Compare characters.
Label result_not_equal;
GenerateOneByteCharsCompareLoop(masm, left, right, min_length, scratch2,
&result_not_equal, Label::kNear);
// Compare lengths - strings up to min-length are equal.
__ bind(&compare_lengths);
__ test(length_delta, length_delta);
Label length_not_equal;
__ j(not_zero, &length_not_equal, Label::kNear);
// Result is EQUAL.
STATIC_ASSERT(EQUAL == 0);
STATIC_ASSERT(kSmiTag == 0);
__ Move(eax, Immediate(Smi::FromInt(EQUAL)));
__ ret(0);
Label result_greater;
Label result_less;
__ bind(&length_not_equal);
__ j(greater, &result_greater, Label::kNear);
__ jmp(&result_less, Label::kNear);
__ bind(&result_not_equal);
__ j(above, &result_greater, Label::kNear);
__ bind(&result_less);
// Result is LESS.
__ Move(eax, Immediate(Smi::FromInt(LESS)));
__ ret(0);
// Result is GREATER.
__ bind(&result_greater);
__ Move(eax, Immediate(Smi::FromInt(GREATER)));
__ ret(0);
}
void StringHelper::GenerateOneByteCharsCompareLoop(
MacroAssembler* masm, Register left, Register right, Register length,
Register scratch, Label* chars_not_equal,
Label::Distance chars_not_equal_near) {
// Change index to run from -length to -1 by adding length to string
// start. This means that loop ends when index reaches zero, which
// doesn't need an additional compare.
__ SmiUntag(length);
__ lea(left,
FieldOperand(left, length, times_1, SeqOneByteString::kHeaderSize));
__ lea(right,
FieldOperand(right, length, times_1, SeqOneByteString::kHeaderSize));
__ neg(length);
Register index = length; // index = -length;
// Compare loop.
Label loop;
__ bind(&loop);
__ mov_b(scratch, Operand(left, index, times_1, 0));
__ cmpb(scratch, Operand(right, index, times_1, 0));
__ j(not_equal, chars_not_equal, chars_not_equal_near);
__ inc(index);
__ j(not_zero, &loop);
}
// Helper function used to check that the dictionary doesn't contain
// the property. This function may return false negatives, so miss_label
// must always call a backup property check that is complete.
......
......@@ -9,31 +9,6 @@ namespace v8 {
namespace internal {
class StringHelper : public AllStatic {
public:
// Compares two flat one byte strings and returns result in eax.
static void GenerateCompareFlatOneByteStrings(MacroAssembler* masm,
Register left, Register right,
Register scratch1,
Register scratch2,
Register scratch3);
// Compares two flat one byte strings for equality and returns result in eax.
static void GenerateFlatOneByteStringEquals(MacroAssembler* masm,
Register left, Register right,
Register scratch1,
Register scratch2);
private:
static void GenerateOneByteCharsCompareLoop(
MacroAssembler* masm, Register left, Register right, Register length,
Register scratch, Label* chars_not_equal,
Label::Distance chars_not_equal_near = Label::kFar);
DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper);
};
class NameDictionaryLookupStub: public PlatformCodeStub {
public:
enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP };
......
......@@ -706,111 +706,6 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
__ Jump(ra);
}
void StringHelper::GenerateFlatOneByteStringEquals(
MacroAssembler* masm, Register left, Register right, Register scratch1,
Register scratch2, Register scratch3) {
Register length = scratch1;
// Compare lengths.
Label strings_not_equal, check_zero_length;
__ lw(length, FieldMemOperand(left, String::kLengthOffset));
__ lw(scratch2, FieldMemOperand(right, String::kLengthOffset));
__ Branch(&check_zero_length, eq, length, Operand(scratch2));
__ bind(&strings_not_equal);
DCHECK(is_int16(NOT_EQUAL));
__ Ret(USE_DELAY_SLOT);
__ li(v0, Operand(Smi::FromInt(NOT_EQUAL)));
// Check if the length is zero.
Label compare_chars;
__ bind(&check_zero_length);
STATIC_ASSERT(kSmiTag == 0);
__ Branch(&compare_chars, ne, length, Operand(zero_reg));
DCHECK(is_int16(EQUAL));
__ Ret(USE_DELAY_SLOT);
__ li(v0, Operand(Smi::FromInt(EQUAL)));
// Compare characters.
__ bind(&compare_chars);
GenerateOneByteCharsCompareLoop(masm, left, right, length, scratch2, scratch3,
v0, &strings_not_equal);
// Characters are equal.
__ Ret(USE_DELAY_SLOT);
__ li(v0, Operand(Smi::FromInt(EQUAL)));
}
void StringHelper::GenerateCompareFlatOneByteStrings(
MacroAssembler* masm, Register left, Register right, Register scratch1,
Register scratch2, Register scratch3, Register scratch4) {
Label result_not_equal, compare_lengths;
// Find minimum length and length difference.
__ lw(scratch1, FieldMemOperand(left, String::kLengthOffset));
__ lw(scratch2, FieldMemOperand(right, String::kLengthOffset));
__ Subu(scratch3, scratch1, Operand(scratch2));
Register length_delta = scratch3;
__ slt(scratch4, scratch2, scratch1);
__ Movn(scratch1, scratch2, scratch4);
Register min_length = scratch1;
STATIC_ASSERT(kSmiTag == 0);
__ Branch(&compare_lengths, eq, min_length, Operand(zero_reg));
// Compare loop.
GenerateOneByteCharsCompareLoop(masm, left, right, min_length, scratch2,
scratch4, v0, &result_not_equal);
// Compare lengths - strings up to min-length are equal.
__ bind(&compare_lengths);
DCHECK(Smi::FromInt(EQUAL) == static_cast<Smi*>(0));
// Use length_delta as result if it's zero.
__ mov(scratch2, length_delta);
__ mov(scratch4, zero_reg);
__ mov(v0, zero_reg);
__ bind(&result_not_equal);
// Conditionally update the result based either on length_delta or
// the last comparion performed in the loop above.
Label ret;
__ Branch(&ret, eq, scratch2, Operand(scratch4));
__ li(v0, Operand(Smi::FromInt(GREATER)));
__ Branch(&ret, gt, scratch2, Operand(scratch4));
__ li(v0, Operand(Smi::FromInt(LESS)));
__ bind(&ret);
__ Ret();
}
void StringHelper::GenerateOneByteCharsCompareLoop(
MacroAssembler* masm, Register left, Register right, Register length,
Register scratch1, Register scratch2, Register scratch3,
Label* chars_not_equal) {
// Change index to run from -length to -1 by adding length to string
// start. This means that loop ends when index reaches zero, which
// doesn't need an additional compare.
__ SmiUntag(length);
__ Addu(scratch1, length,
Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
__ Addu(left, left, Operand(scratch1));
__ Addu(right, right, Operand(scratch1));
__ Subu(length, zero_reg, length);
Register index = length; // index = -length;
// Compare loop.
Label loop;
__ bind(&loop);
__ Addu(scratch3, left, index);
__ lbu(scratch1, MemOperand(scratch3));
__ Addu(scratch3, right, index);
__ lbu(scratch2, MemOperand(scratch3));
__ Branch(chars_not_equal, ne, scratch1, Operand(scratch2));
__ Addu(index, index, 1);
__ Branch(&loop, ne, index, Operand(zero_reg));
}
void DirectCEntryStub::Generate(MacroAssembler* masm) {
// Make place for arguments to fit C calling convention. Most of the callers
// of DirectCEntryStub::GenerateCall are using EnterExitFrame/LeaveExitFrame
......
......@@ -8,31 +8,6 @@
namespace v8 {
namespace internal {
class StringHelper : public AllStatic {
public:
// Compares two flat one-byte strings and returns result in v0.
static void GenerateCompareFlatOneByteStrings(
MacroAssembler* masm, Register left, Register right, Register scratch1,
Register scratch2, Register scratch3, Register scratch4);
// Compares two flat one-byte strings for equality and returns result in v0.
static void GenerateFlatOneByteStringEquals(MacroAssembler* masm,
Register left, Register right,
Register scratch1,
Register scratch2,
Register scratch3);
private:
static void GenerateOneByteCharsCompareLoop(
MacroAssembler* masm, Register left, Register right, Register length,
Register scratch1, Register scratch2, Register scratch3,
Label* chars_not_equal);
DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper);
};
class StoreRegistersStateStub: public PlatformCodeStub {
public:
explicit StoreRegistersStateStub(Isolate* isolate)
......
......@@ -704,111 +704,6 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
__ Jump(ra);
}
void StringHelper::GenerateFlatOneByteStringEquals(
MacroAssembler* masm, Register left, Register right, Register scratch1,
Register scratch2, Register scratch3) {
Register length = scratch1;
// Compare lengths.
Label strings_not_equal, check_zero_length;
__ Ld(length, FieldMemOperand(left, String::kLengthOffset));
__ Ld(scratch2, FieldMemOperand(right, String::kLengthOffset));
__ Branch(&check_zero_length, eq, length, Operand(scratch2));
__ bind(&strings_not_equal);
// Can not put li in delayslot, it has multi instructions.
__ li(v0, Operand(Smi::FromInt(NOT_EQUAL)));
__ Ret();
// Check if the length is zero.
Label compare_chars;
__ bind(&check_zero_length);
STATIC_ASSERT(kSmiTag == 0);
__ Branch(&compare_chars, ne, length, Operand(zero_reg));
DCHECK(is_int16((intptr_t)Smi::FromInt(EQUAL)));
__ Ret(USE_DELAY_SLOT);
__ li(v0, Operand(Smi::FromInt(EQUAL)));
// Compare characters.
__ bind(&compare_chars);
GenerateOneByteCharsCompareLoop(masm, left, right, length, scratch2, scratch3,
v0, &strings_not_equal);
// Characters are equal.
__ Ret(USE_DELAY_SLOT);
__ li(v0, Operand(Smi::FromInt(EQUAL)));
}
void StringHelper::GenerateCompareFlatOneByteStrings(
MacroAssembler* masm, Register left, Register right, Register scratch1,
Register scratch2, Register scratch3, Register scratch4) {
Label result_not_equal, compare_lengths;
// Find minimum length and length difference.
__ Ld(scratch1, FieldMemOperand(left, String::kLengthOffset));
__ Ld(scratch2, FieldMemOperand(right, String::kLengthOffset));
__ Dsubu(scratch3, scratch1, Operand(scratch2));
Register length_delta = scratch3;
__ slt(scratch4, scratch2, scratch1);
__ Movn(scratch1, scratch2, scratch4);
Register min_length = scratch1;
STATIC_ASSERT(kSmiTag == 0);
__ Branch(&compare_lengths, eq, min_length, Operand(zero_reg));
// Compare loop.
GenerateOneByteCharsCompareLoop(masm, left, right, min_length, scratch2,
scratch4, v0, &result_not_equal);
// Compare lengths - strings up to min-length are equal.
__ bind(&compare_lengths);
DCHECK(Smi::FromInt(EQUAL) == static_cast<Smi*>(0));
// Use length_delta as result if it's zero.
__ mov(scratch2, length_delta);
__ mov(scratch4, zero_reg);
__ mov(v0, zero_reg);
__ bind(&result_not_equal);
// Conditionally update the result based either on length_delta or
// the last comparion performed in the loop above.
Label ret;
__ Branch(&ret, eq, scratch2, Operand(scratch4));
__ li(v0, Operand(Smi::FromInt(GREATER)));
__ Branch(&ret, gt, scratch2, Operand(scratch4));
__ li(v0, Operand(Smi::FromInt(LESS)));
__ bind(&ret);
__ Ret();
}
void StringHelper::GenerateOneByteCharsCompareLoop(
MacroAssembler* masm, Register left, Register right, Register length,
Register scratch1, Register scratch2, Register scratch3,
Label* chars_not_equal) {
// Change index to run from -length to -1 by adding length to string
// start. This means that loop ends when index reaches zero, which
// doesn't need an additional compare.
__ SmiUntag(length);
__ Daddu(scratch1, length,
Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
__ Daddu(left, left, Operand(scratch1));
__ Daddu(right, right, Operand(scratch1));
__ Dsubu(length, zero_reg, length);
Register index = length; // index = -length;
// Compare loop.
Label loop;
__ bind(&loop);
__ Daddu(scratch3, left, index);
__ Lbu(scratch1, MemOperand(scratch3));
__ Daddu(scratch3, right, index);
__ Lbu(scratch2, MemOperand(scratch3));
__ Branch(chars_not_equal, ne, scratch1, Operand(scratch2));
__ Daddu(index, index, 1);
__ Branch(&loop, ne, index, Operand(zero_reg));
}
void DirectCEntryStub::Generate(MacroAssembler* masm) {
// Make place for arguments to fit C calling convention. Most of the callers
// of DirectCEntryStub::GenerateCall are using EnterExitFrame/LeaveExitFrame
......
......@@ -8,32 +8,6 @@
namespace v8 {
namespace internal {
class StringHelper : public AllStatic {
public:
// Compares two flat one-byte strings and returns result in v0.
static void GenerateCompareFlatOneByteStrings(
MacroAssembler* masm, Register left, Register right, Register scratch1,
Register scratch2, Register scratch3, Register scratch4);
// Compares two flat one-byte strings for equality and returns result in v0.
static void GenerateFlatOneByteStringEquals(MacroAssembler* masm,
Register left, Register right,
Register scratch1,
Register scratch2,
Register scratch3);
private:
static void GenerateOneByteCharsCompareLoop(
MacroAssembler* masm, Register left, Register right, Register length,
Register scratch1, Register scratch2, Register scratch3,
Label* chars_not_equal);
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper);
};
class StoreRegistersStateStub: public PlatformCodeStub {
public:
explicit StoreRegistersStateStub(Isolate* isolate)
......
......@@ -677,125 +677,6 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
__ blr();
}
void StringHelper::GenerateFlatOneByteStringEquals(MacroAssembler* masm,
Register left,
Register right,
Register scratch1,
Register scratch2) {
Register length = scratch1;
// Compare lengths.
Label strings_not_equal, check_zero_length;
__ LoadP(length, FieldMemOperand(left, String::kLengthOffset));
__ LoadP(scratch2, FieldMemOperand(right, String::kLengthOffset));
__ cmp(length, scratch2);
__ beq(&check_zero_length);
__ bind(&strings_not_equal);
__ LoadSmiLiteral(r3, Smi::FromInt(NOT_EQUAL));
__ Ret();
// Check if the length is zero.
Label compare_chars;
__ bind(&check_zero_length);
STATIC_ASSERT(kSmiTag == 0);
__ cmpi(length, Operand::Zero());
__ bne(&compare_chars);
__ LoadSmiLiteral(r3, Smi::FromInt(EQUAL));
__ Ret();
// Compare characters.
__ bind(&compare_chars);
GenerateOneByteCharsCompareLoop(masm, left, right, length, scratch2,
&strings_not_equal);
// Characters are equal.
__ LoadSmiLiteral(r3, Smi::FromInt(EQUAL));
__ Ret();
}
void StringHelper::GenerateCompareFlatOneByteStrings(
MacroAssembler* masm, Register left, Register right, Register scratch1,
Register scratch2, Register scratch3) {
Label result_not_equal, compare_lengths;
// Find minimum length and length difference.
__ LoadP(scratch1, FieldMemOperand(left, String::kLengthOffset));
__ LoadP(scratch2, FieldMemOperand(right, String::kLengthOffset));
__ sub(scratch3, scratch1, scratch2, LeaveOE, SetRC);
Register length_delta = scratch3;
if (CpuFeatures::IsSupported(ISELECT)) {
__ isel(gt, scratch1, scratch2, scratch1, cr0);
} else {
Label skip;
__ ble(&skip, cr0);
__ mr(scratch1, scratch2);
__ bind(&skip);
}
Register min_length = scratch1;
STATIC_ASSERT(kSmiTag == 0);
__ cmpi(min_length, Operand::Zero());
__ beq(&compare_lengths);
// Compare loop.
GenerateOneByteCharsCompareLoop(masm, left, right, min_length, scratch2,
&result_not_equal);
// Compare lengths - strings up to min-length are equal.
__ bind(&compare_lengths);
DCHECK(Smi::FromInt(EQUAL) == static_cast<Smi*>(0));
// Use length_delta as result if it's zero.
__ mr(r3, length_delta);
__ cmpi(r3, Operand::Zero());
__ bind(&result_not_equal);
// Conditionally update the result based either on length_delta or
// the last comparion performed in the loop above.
if (CpuFeatures::IsSupported(ISELECT)) {
__ LoadSmiLiteral(r4, Smi::FromInt(GREATER));
__ LoadSmiLiteral(r5, Smi::FromInt(LESS));
__ isel(eq, r3, r0, r4);
__ isel(lt, r3, r5, r3);
__ Ret();
} else {
Label less_equal, equal;
__ ble(&less_equal);
__ LoadSmiLiteral(r3, Smi::FromInt(GREATER));
__ Ret();
__ bind(&less_equal);
__ beq(&equal);
__ LoadSmiLiteral(r3, Smi::FromInt(LESS));
__ bind(&equal);
__ Ret();
}
}
void StringHelper::GenerateOneByteCharsCompareLoop(
MacroAssembler* masm, Register left, Register right, Register length,
Register scratch1, Label* chars_not_equal) {
// Change index to run from -length to -1 by adding length to string
// start. This means that loop ends when index reaches zero, which
// doesn't need an additional compare.
__ SmiUntag(length);
__ addi(scratch1, length,
Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
__ add(left, left, scratch1);
__ add(right, right, scratch1);
__ subfic(length, length, Operand::Zero());
Register index = length; // index = -length;
// Compare loop.
Label loop;
__ bind(&loop);
__ lbzx(scratch1, MemOperand(left, index));
__ lbzx(r0, MemOperand(right, index));
__ cmp(scratch1, r0);
__ bne(chars_not_equal);
__ addi(index, index, Operand(1));
__ cmpi(index, Operand::Zero());
__ bne(&loop);
}
// This stub is paired with DirectCEntryStub::GenerateCall
void DirectCEntryStub::Generate(MacroAssembler* masm) {
// Place the return address on the stack, making the call
......
......@@ -9,32 +9,6 @@ namespace v8 {
namespace internal {
class StringHelper : public AllStatic {
public:
// Compares two flat one-byte strings and returns result in r0.
static void GenerateCompareFlatOneByteStrings(MacroAssembler* masm,
Register left, Register right,
Register scratch1,
Register scratch2,
Register scratch3);
// Compares two flat one-byte strings for equality and returns result in r0.
static void GenerateFlatOneByteStringEquals(MacroAssembler* masm,
Register left, Register right,
Register scratch1,
Register scratch2);
private:
static void GenerateOneByteCharsCompareLoop(MacroAssembler* masm,
Register left, Register right,
Register length,
Register scratch1,
Label* chars_not_equal);
DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper);
};
class StoreRegistersStateStub : public PlatformCodeStub {
public:
explicit StoreRegistersStateStub(Isolate* isolate)
......
......@@ -684,110 +684,6 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
__ b(r14);
}
void StringHelper::GenerateFlatOneByteStringEquals(MacroAssembler* masm,
Register left,
Register right,
Register scratch1,
Register scratch2) {
Register length = scratch1;
// Compare lengths.
Label strings_not_equal, check_zero_length;
__ LoadP(length, FieldMemOperand(left, String::kLengthOffset));
__ LoadP(scratch2, FieldMemOperand(right, String::kLengthOffset));
__ CmpP(length, scratch2);
__ beq(&check_zero_length);
__ bind(&strings_not_equal);
__ LoadSmiLiteral(r2, Smi::FromInt(NOT_EQUAL));
__ Ret();
// Check if the length is zero.
Label compare_chars;
__ bind(&check_zero_length);
STATIC_ASSERT(kSmiTag == 0);
__ CmpP(length, Operand::Zero());
__ bne(&compare_chars);
__ LoadSmiLiteral(r2, Smi::FromInt(EQUAL));
__ Ret();
// Compare characters.
__ bind(&compare_chars);
GenerateOneByteCharsCompareLoop(masm, left, right, length, scratch2,
&strings_not_equal);
// Characters are equal.
__ LoadSmiLiteral(r2, Smi::FromInt(EQUAL));
__ Ret();
}
void StringHelper::GenerateCompareFlatOneByteStrings(
MacroAssembler* masm, Register left, Register right, Register scratch1,
Register scratch2, Register scratch3) {
Label skip, result_not_equal, compare_lengths;
// Find minimum length and length difference.
__ LoadP(scratch1, FieldMemOperand(left, String::kLengthOffset));
__ LoadP(scratch2, FieldMemOperand(right, String::kLengthOffset));
__ SubP(scratch3, scratch1, scratch2 /*, LeaveOE, SetRC*/);
// Removing RC looks okay here.
Register length_delta = scratch3;
__ ble(&skip, Label::kNear);
__ LoadRR(scratch1, scratch2);
__ bind(&skip);
Register min_length = scratch1;
STATIC_ASSERT(kSmiTag == 0);
__ CmpP(min_length, Operand::Zero());
__ beq(&compare_lengths);
// Compare loop.
GenerateOneByteCharsCompareLoop(masm, left, right, min_length, scratch2,
&result_not_equal);
// Compare lengths - strings up to min-length are equal.
__ bind(&compare_lengths);
DCHECK(Smi::FromInt(EQUAL) == static_cast<Smi*>(0));
// Use length_delta as result if it's zero.
__ LoadRR(r2, length_delta);
__ CmpP(length_delta, Operand::Zero());
__ bind(&result_not_equal);
// Conditionally update the result based either on length_delta or
// the last comparion performed in the loop above.
Label less_equal, equal;
__ ble(&less_equal);
__ LoadSmiLiteral(r2, Smi::FromInt(GREATER));
__ Ret();
__ bind(&less_equal);
__ beq(&equal);
__ LoadSmiLiteral(r2, Smi::FromInt(LESS));
__ bind(&equal);
__ Ret();
}
void StringHelper::GenerateOneByteCharsCompareLoop(
MacroAssembler* masm, Register left, Register right, Register length,
Register scratch1, Label* chars_not_equal) {
// Change index to run from -length to -1 by adding length to string
// start. This means that loop ends when index reaches zero, which
// doesn't need an additional compare.
__ SmiUntag(length);
__ AddP(scratch1, length,
Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
__ AddP(left, scratch1);
__ AddP(right, scratch1);
__ LoadComplementRR(length, length);
Register index = length; // index = -length;
// Compare loop.
Label loop;
__ bind(&loop);
__ LoadlB(scratch1, MemOperand(left, index));
__ LoadlB(r0, MemOperand(right, index));
__ CmpP(scratch1, r0);
__ bne(chars_not_equal);
__ AddP(index, Operand(1));
__ CmpP(index, Operand::Zero());
__ bne(&loop);
}
// This stub is paired with DirectCEntryStub::GenerateCall
void DirectCEntryStub::Generate(MacroAssembler* masm) {
__ CleanseP(r14);
......
......@@ -8,31 +8,6 @@
namespace v8 {
namespace internal {
class StringHelper : public AllStatic {
public:
// Compares two flat one-byte strings and returns result in r0.
static void GenerateCompareFlatOneByteStrings(MacroAssembler* masm,
Register left, Register right,
Register scratch1,
Register scratch2,
Register scratch3);
// Compares two flat one-byte strings for equality and returns result in r0.
static void GenerateFlatOneByteStringEquals(MacroAssembler* masm,
Register left, Register right,
Register scratch1,
Register scratch2);
private:
static void GenerateOneByteCharsCompareLoop(MacroAssembler* masm,
Register left, Register right,
Register length,
Register scratch1,
Label* chars_not_equal);
DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper);
};
class StoreRegistersStateStub : public PlatformCodeStub {
public:
explicit StoreRegistersStateStub(Isolate* isolate)
......
......@@ -669,142 +669,6 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
__ ret(0);
}
void StringHelper::GenerateFlatOneByteStringEquals(MacroAssembler* masm,
Register left,
Register right,
Register scratch1,
Register scratch2) {
Register length = scratch1;
// Compare lengths.
Label check_zero_length;
__ movp(length, FieldOperand(left, String::kLengthOffset));
__ SmiCompare(length, FieldOperand(right, String::kLengthOffset));
__ j(equal, &check_zero_length, Label::kNear);
__ Move(rax, Smi::FromInt(NOT_EQUAL));
__ ret(0);
// Check if the length is zero.
Label compare_chars;
__ bind(&check_zero_length);
STATIC_ASSERT(kSmiTag == 0);
__ SmiTest(length);
__ j(not_zero, &compare_chars, Label::kNear);
__ Move(rax, Smi::FromInt(EQUAL));
__ ret(0);
// Compare characters.
__ bind(&compare_chars);
Label strings_not_equal;
GenerateOneByteCharsCompareLoop(masm, left, right, length, scratch2,
&strings_not_equal, Label::kNear);
// Characters are equal.
__ Move(rax, Smi::FromInt(EQUAL));
__ ret(0);
// Characters are not equal.
__ bind(&strings_not_equal);
__ Move(rax, Smi::FromInt(NOT_EQUAL));
__ ret(0);
}
void StringHelper::GenerateCompareFlatOneByteStrings(
MacroAssembler* masm, Register left, Register right, Register scratch1,
Register scratch2, Register scratch3, Register scratch4) {
// Ensure that you can always subtract a string length from a non-negative
// number (e.g. another length).
STATIC_ASSERT(String::kMaxLength < 0x7fffffff);
// Find minimum length and length difference.
__ movp(scratch1, FieldOperand(left, String::kLengthOffset));
__ movp(scratch4, scratch1);
__ SmiSub(scratch4,
scratch4,
FieldOperand(right, String::kLengthOffset));
// Register scratch4 now holds left.length - right.length.
const Register length_difference = scratch4;
Label left_shorter;
__ j(less, &left_shorter, Label::kNear);
// The right string isn't longer that the left one.
// Get the right string's length by subtracting the (non-negative) difference
// from the left string's length.
__ SmiSub(scratch1, scratch1, length_difference);
__ bind(&left_shorter);
// Register scratch1 now holds Min(left.length, right.length).
const Register min_length = scratch1;
Label compare_lengths;
// If min-length is zero, go directly to comparing lengths.
__ SmiTest(min_length);
__ j(zero, &compare_lengths, Label::kNear);
// Compare loop.
Label result_not_equal;
GenerateOneByteCharsCompareLoop(
masm, left, right, min_length, scratch2, &result_not_equal,
// In debug-code mode, SmiTest below might push
// the target label outside the near range.
Label::kFar);
// Completed loop without finding different characters.
// Compare lengths (precomputed).
__ bind(&compare_lengths);
__ SmiTest(length_difference);
Label length_not_equal;
__ j(not_zero, &length_not_equal, Label::kNear);
// Result is EQUAL.
__ Move(rax, Smi::FromInt(EQUAL));
__ ret(0);
Label result_greater;
Label result_less;
__ bind(&length_not_equal);
__ j(greater, &result_greater, Label::kNear);
__ jmp(&result_less, Label::kNear);
__ bind(&result_not_equal);
// Unequal comparison of left to right, either character or length.
__ j(above, &result_greater, Label::kNear);
__ bind(&result_less);
// Result is LESS.
__ Move(rax, Smi::FromInt(LESS));
__ ret(0);
// Result is GREATER.
__ bind(&result_greater);
__ Move(rax, Smi::FromInt(GREATER));
__ ret(0);
}
void StringHelper::GenerateOneByteCharsCompareLoop(
MacroAssembler* masm, Register left, Register right, Register length,
Register scratch, Label* chars_not_equal, Label::Distance near_jump) {
// Change index to run from -length to -1 by adding length to string
// start. This means that loop ends when index reaches zero, which
// doesn't need an additional compare.
__ SmiToInteger32(length, length);
__ leap(left,
FieldOperand(left, length, times_1, SeqOneByteString::kHeaderSize));
__ leap(right,
FieldOperand(right, length, times_1, SeqOneByteString::kHeaderSize));
__ negq(length);
Register index = length; // index = -length;
// Compare loop.
Label loop;
__ bind(&loop);
__ movb(scratch, Operand(left, index, times_1, 0));
__ cmpb(scratch, Operand(right, index, times_1, 0));
__ j(not_equal, chars_not_equal, near_jump);
__ incq(index);
__ j(not_zero, &loop);
}
void NameDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm,
Label* miss,
Label* done,
......
......@@ -9,29 +9,6 @@ namespace v8 {
namespace internal {
class StringHelper : public AllStatic {
public:
// Compares two flat one-byte strings and returns result in rax.
static void GenerateCompareFlatOneByteStrings(
MacroAssembler* masm, Register left, Register right, Register scratch1,
Register scratch2, Register scratch3, Register scratch4);
// Compares two flat one-byte strings for equality and returns result in rax.
static void GenerateFlatOneByteStringEquals(MacroAssembler* masm,
Register left, Register right,
Register scratch1,
Register scratch2);
private:
static void GenerateOneByteCharsCompareLoop(
MacroAssembler* masm, Register left, Register right, Register length,
Register scratch, Label* chars_not_equal,
Label::Distance near_jump = Label::kFar);
DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper);
};
class NameDictionaryLookupStub: public PlatformCodeStub {
public:
enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP };
......
......@@ -1086,23 +1086,6 @@ void MacroAssembler::JumpIfNotSmi(Operand src, Label* on_not_smi,
j(NegateCondition(smi), on_not_smi, near_jump);
}
void MacroAssembler::SmiAddConstant(Register dst, Register src, Smi* constant) {
if (constant->value() == 0) {
if (dst != src) {
movp(dst, src);
}
return;
} else if (dst == src) {
DCHECK(dst != kScratchRegister);
Register constant_reg = GetSmiConstant(constant);
addp(dst, constant_reg);
} else {
Move(dst, constant);
addp(dst, src);
}
}
void MacroAssembler::SmiAddConstant(const Operand& dst, Smi* constant) {
if (constant->value() != 0) {
if (SmiValuesAre32Bits()) {
......@@ -1115,248 +1098,6 @@ void MacroAssembler::SmiAddConstant(const Operand& dst, Smi* constant) {
}
}
void MacroAssembler::SmiAddConstant(Register dst, Register src, Smi* constant,
SmiOperationConstraints constraints,
Label* bailout_label,
Label::Distance near_jump) {
if (constant->value() == 0) {
if (dst != src) {
movp(dst, src);
}
} else if (dst == src) {
DCHECK(dst != kScratchRegister);
Move(kScratchRegister, constant);
addp(dst, kScratchRegister);
if (constraints & SmiOperationConstraint::kBailoutOnNoOverflow) {
j(no_overflow, bailout_label, near_jump);
DCHECK(constraints & SmiOperationConstraint::kPreserveSourceRegister);
subp(dst, kScratchRegister);
} else if (constraints & SmiOperationConstraint::kBailoutOnOverflow) {
if (constraints & SmiOperationConstraint::kPreserveSourceRegister) {
Label done;
j(no_overflow, &done, Label::kNear);
subp(dst, kScratchRegister);
jmp(bailout_label, near_jump);
bind(&done);
} else {
// Bailout if overflow without reserving src.
j(overflow, bailout_label, near_jump);
}
} else {
UNREACHABLE();
}
} else {
DCHECK(constraints & SmiOperationConstraint::kPreserveSourceRegister);
DCHECK(constraints & SmiOperationConstraint::kBailoutOnOverflow);
Move(dst, constant);
addp(dst, src);
j(overflow, bailout_label, near_jump);
}
}
void MacroAssembler::SmiSubConstant(Register dst, Register src, Smi* constant) {
if (constant->value() == 0) {
if (dst != src) {
movp(dst, src);
}
} else if (dst == src) {
DCHECK(dst != kScratchRegister);
Register constant_reg = GetSmiConstant(constant);
subp(dst, constant_reg);
} else {
if (constant->value() == Smi::kMinValue) {
Move(dst, constant);
// Adding and subtracting the min-value gives the same result, it only
// differs on the overflow bit, which we don't check here.
addp(dst, src);
} else {
// Subtract by adding the negation.
Move(dst, Smi::FromInt(-constant->value()));
addp(dst, src);
}
}
}
void MacroAssembler::SmiSubConstant(Register dst, Register src, Smi* constant,
SmiOperationConstraints constraints,
Label* bailout_label,
Label::Distance near_jump) {
if (constant->value() == 0) {
if (dst != src) {
movp(dst, src);
}
} else if (dst == src) {
DCHECK(dst != kScratchRegister);
Move(kScratchRegister, constant);
subp(dst, kScratchRegister);
if (constraints & SmiOperationConstraint::kBailoutOnNoOverflow) {
j(no_overflow, bailout_label, near_jump);
DCHECK(constraints & SmiOperationConstraint::kPreserveSourceRegister);
addp(dst, kScratchRegister);
} else if (constraints & SmiOperationConstraint::kBailoutOnOverflow) {
if (constraints & SmiOperationConstraint::kPreserveSourceRegister) {
Label done;
j(no_overflow, &done, Label::kNear);
addp(dst, kScratchRegister);
jmp(bailout_label, near_jump);
bind(&done);
} else {
// Bailout if overflow without reserving src.
j(overflow, bailout_label, near_jump);
}
} else {
UNREACHABLE();
}
} else {
DCHECK(constraints & SmiOperationConstraint::kPreserveSourceRegister);
DCHECK(constraints & SmiOperationConstraint::kBailoutOnOverflow);
if (constant->value() == Smi::kMinValue) {
DCHECK(dst != kScratchRegister);
movp(dst, src);
Move(kScratchRegister, constant);
subp(dst, kScratchRegister);
j(overflow, bailout_label, near_jump);
} else {
// Subtract by adding the negation.
Move(dst, Smi::FromInt(-(constant->value())));
addp(dst, src);
j(overflow, bailout_label, near_jump);
}
}
}
template<class T>
static void SmiAddHelper(MacroAssembler* masm,
Register dst,
Register src1,
T src2,
Label* on_not_smi_result,
Label::Distance near_jump) {
if (dst == src1) {
Label done;
masm->addp(dst, src2);
masm->j(no_overflow, &done, Label::kNear);
// Restore src1.
masm->subp(dst, src2);
masm->jmp(on_not_smi_result, near_jump);
masm->bind(&done);
} else {
masm->movp(dst, src1);
masm->addp(dst, src2);
masm->j(overflow, on_not_smi_result, near_jump);
}
}
void MacroAssembler::SmiAdd(Register dst,
Register src1,
Register src2,
Label* on_not_smi_result,
Label::Distance near_jump) {
DCHECK_NOT_NULL(on_not_smi_result);
DCHECK(dst != src2);
SmiAddHelper<Register>(this, dst, src1, src2, on_not_smi_result, near_jump);
}
void MacroAssembler::SmiAdd(Register dst,
Register src1,
const Operand& src2,
Label* on_not_smi_result,
Label::Distance near_jump) {
DCHECK_NOT_NULL(on_not_smi_result);
DCHECK(!src2.AddressUsesRegister(dst));
SmiAddHelper<Operand>(this, dst, src1, src2, on_not_smi_result, near_jump);
}
void MacroAssembler::SmiAdd(Register dst,
Register src1,
Register src2) {
// No overflow checking. Use only when it's known that
// overflowing is impossible.
if (dst != src1) {
if (emit_debug_code()) {
movp(kScratchRegister, src1);
addp(kScratchRegister, src2);
Check(no_overflow, kSmiAdditionOverflow);
}
leap(dst, Operand(src1, src2, times_1, 0));
} else {
addp(dst, src2);
Assert(no_overflow, kSmiAdditionOverflow);
}
}
template<class T>
static void SmiSubHelper(MacroAssembler* masm,
Register dst,
Register src1,
T src2,
Label* on_not_smi_result,
Label::Distance near_jump) {
if (dst == src1) {
Label done;
masm->subp(dst, src2);
masm->j(no_overflow, &done, Label::kNear);
// Restore src1.
masm->addp(dst, src2);
masm->jmp(on_not_smi_result, near_jump);
masm->bind(&done);
} else {
masm->movp(dst, src1);
masm->subp(dst, src2);
masm->j(overflow, on_not_smi_result, near_jump);
}
}
void MacroAssembler::SmiSub(Register dst,
Register src1,
Register src2,
Label* on_not_smi_result,
Label::Distance near_jump) {
DCHECK_NOT_NULL(on_not_smi_result);
DCHECK(dst != src2);
SmiSubHelper<Register>(this, dst, src1, src2, on_not_smi_result, near_jump);
}
void MacroAssembler::SmiSub(Register dst,
Register src1,
const Operand& src2,
Label* on_not_smi_result,
Label::Distance near_jump) {
DCHECK_NOT_NULL(on_not_smi_result);
DCHECK(!src2.AddressUsesRegister(dst));
SmiSubHelper<Operand>(this, dst, src1, src2, on_not_smi_result, near_jump);
}
template<class T>
static void SmiSubNoOverflowHelper(MacroAssembler* masm,
Register dst,
Register src1,
T src2) {
// No overflow checking. Use only when it's known that
// overflowing is impossible (e.g., subtracting two positive smis).
if (dst != src1) {
masm->movp(dst, src1);
}
masm->subp(dst, src2);
masm->Assert(no_overflow, kSmiSubtractionOverflow);
}
void MacroAssembler::SmiSub(Register dst, Register src1, Register src2) {
DCHECK(dst != src2);
SmiSubNoOverflowHelper<Register>(this, dst, src1, src2);
}
void MacroAssembler::SmiSub(Register dst,
Register src1,
const Operand& src2) {
SmiSubNoOverflowHelper<Operand>(this, dst, src1, src2);
}
SmiIndex MacroAssembler::SmiToIndex(Register dst,
Register src,
int shift) {
......
......@@ -704,71 +704,10 @@ class MacroAssembler : public TurboAssembler {
// Smis represent a subset of integers. The subset is always equivalent to
// a two's complement interpretation of a fixed number of bits.
// Add an integer constant to a tagged smi, giving a tagged smi as result.
// No overflow testing on the result is done.
void SmiAddConstant(Register dst, Register src, Smi* constant);
// Add an integer constant to a tagged smi, giving a tagged smi as result.
// No overflow testing on the result is done.
void SmiAddConstant(const Operand& dst, Smi* constant);
// Add an integer constant to a tagged smi, giving a tagged smi as result,
// or jumping to a label if the result cannot be represented by a smi.
void SmiAddConstant(Register dst, Register src, Smi* constant,
SmiOperationConstraints constraints, Label* bailout_label,
Label::Distance near_jump = Label::kFar);
// Subtract an integer constant from a tagged smi, giving a tagged smi as
// result. No testing on the result is done. Sets the N and Z flags
// based on the value of the resulting integer.
void SmiSubConstant(Register dst, Register src, Smi* constant);
// Subtract an integer constant from a tagged smi, giving a tagged smi as
// result, or jumping to a label if the result cannot be represented by a smi.
void SmiSubConstant(Register dst, Register src, Smi* constant,
SmiOperationConstraints constraints, Label* bailout_label,
Label::Distance near_jump = Label::kFar);
// Adds smi values and return the result as a smi.
// If dst is src1, then src1 will be destroyed if the operation is
// successful, otherwise kept intact.
void SmiAdd(Register dst,
Register src1,
Register src2,
Label* on_not_smi_result,
Label::Distance near_jump = Label::kFar);
void SmiAdd(Register dst,
Register src1,
const Operand& src2,
Label* on_not_smi_result,
Label::Distance near_jump = Label::kFar);
void SmiAdd(Register dst,
Register src1,
Register src2);
// Subtracts smi values and return the result as a smi.
// If dst is src1, then src1 will be destroyed if the operation is
// successful, otherwise kept intact.
void SmiSub(Register dst,
Register src1,
Register src2,
Label* on_not_smi_result,
Label::Distance near_jump = Label::kFar);
void SmiSub(Register dst,
Register src1,
const Operand& src2,
Label* on_not_smi_result,
Label::Distance near_jump = Label::kFar);
void SmiSub(Register dst,
Register src1,
Register src2);
void SmiSub(Register dst,
Register src1,
const Operand& src2);
// Specialized operations
// Converts, if necessary, a smi to a combination of number and
......
This diff is collapsed.
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