Simplify some of the startup code for SubStringStub::Generate.
R=ulan@chromium.org Review URL: https://chromiumcodereview.appspot.com/11098043 Patch from JF Bastien <jfb@chromium.org>. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12887 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
8a3f19f720
commit
101d64c1a6
@ -5999,23 +5999,28 @@ void SubStringStub::Generate(MacroAssembler* masm) {
|
||||
STATIC_ASSERT(kSmiTag == 0);
|
||||
STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1);
|
||||
|
||||
// I.e., arithmetic shift right by one un-smi-tags.
|
||||
__ mov(r2, Operand(r2, ASR, 1), SetCC);
|
||||
__ mov(r3, Operand(r3, ASR, 1), SetCC, cc);
|
||||
// If either to or from had the smi tag bit set, then carry is set now.
|
||||
__ b(cs, &runtime); // Either "from" or "to" is not a smi.
|
||||
// Arithmetic shift right by one un-smi-tags. In this case we rotate right
|
||||
// instead because we bail out on non-smi values: ROR and ASR are equivalent
|
||||
// for smis but they set the flags in a way that's easier to optimize.
|
||||
__ mov(r2, Operand(r2, ROR, 1), SetCC);
|
||||
__ mov(r3, Operand(r3, ROR, 1), SetCC, cc);
|
||||
// If either to or from had the smi tag bit set, then C is set now, and N
|
||||
// has the same value: we rotated by 1, so the bottom bit is now the top bit.
|
||||
// We want to bailout to runtime here if From is negative. In that case, the
|
||||
// next instruction is not executed and we fall through to bailing out to
|
||||
// runtime. pl is the opposite of mi.
|
||||
// Both r2 and r3 are untagged integers.
|
||||
__ sub(r2, r2, Operand(r3), SetCC, pl);
|
||||
__ b(mi, &runtime); // Fail if from > to.
|
||||
// runtime.
|
||||
// Executed if both r2 and r3 are untagged integers.
|
||||
__ sub(r2, r2, Operand(r3), SetCC, cc);
|
||||
// One of the above un-smis or the above SUB could have set N==1.
|
||||
__ b(mi, &runtime); // Either "from" or "to" is not an smi, or from > to.
|
||||
|
||||
// Make sure first argument is a string.
|
||||
__ ldr(r0, MemOperand(sp, kStringOffset));
|
||||
STATIC_ASSERT(kSmiTag == 0);
|
||||
__ JumpIfSmi(r0, &runtime);
|
||||
Condition is_string = masm->IsObjectStringType(r0, r1);
|
||||
// Do a JumpIfSmi, but fold its jump into the subsequent string test.
|
||||
__ tst(r0, Operand(kSmiTagMask));
|
||||
Condition is_string = masm->IsObjectStringType(r0, r1, ne);
|
||||
ASSERT(is_string == eq);
|
||||
__ b(NegateCondition(is_string), &runtime);
|
||||
|
||||
// Short-cut for the case of trivial substring.
|
||||
|
@ -893,12 +893,15 @@ class MacroAssembler: public Assembler {
|
||||
|
||||
// Load and check the instance type of an object for being a string.
|
||||
// Loads the type into the second argument register.
|
||||
// Returns a condition that will be enabled if the object was a string.
|
||||
// Returns a condition that will be enabled if the object was a string
|
||||
// and the passed-in condition passed. If the passed-in condition failed
|
||||
// then flags remain unchanged.
|
||||
Condition IsObjectStringType(Register obj,
|
||||
Register type) {
|
||||
ldr(type, FieldMemOperand(obj, HeapObject::kMapOffset));
|
||||
ldrb(type, FieldMemOperand(type, Map::kInstanceTypeOffset));
|
||||
tst(type, Operand(kIsNotStringMask));
|
||||
Register type,
|
||||
Condition cond = al) {
|
||||
ldr(type, FieldMemOperand(obj, HeapObject::kMapOffset), cond);
|
||||
ldrb(type, FieldMemOperand(type, Map::kInstanceTypeOffset), cond);
|
||||
tst(type, Operand(kIsNotStringMask), cond);
|
||||
ASSERT_EQ(0, kStringTag);
|
||||
return eq;
|
||||
}
|
||||
@ -1202,7 +1205,7 @@ class MacroAssembler: public Assembler {
|
||||
// Souce and destination can be the same register.
|
||||
void UntagAndJumpIfNotSmi(Register dst, Register src, Label* non_smi_case);
|
||||
|
||||
// Jump the register contains a smi.
|
||||
// Jump if the register contains a smi.
|
||||
inline void JumpIfSmi(Register value, Label* smi_label) {
|
||||
tst(value, Operand(kSmiTagMask));
|
||||
b(eq, smi_label);
|
||||
|
@ -1387,7 +1387,14 @@ int32_t Simulator::GetShiftRm(Instruction* instr, bool* carry_out) {
|
||||
}
|
||||
|
||||
case ROR: {
|
||||
UNIMPLEMENTED();
|
||||
if (shift_amount == 0) {
|
||||
*carry_out = c_flag_;
|
||||
} else {
|
||||
uint32_t left = static_cast<uint32_t>(result) >> shift_amount;
|
||||
uint32_t right = static_cast<uint32_t>(result) << (32 - shift_amount);
|
||||
result = right | left;
|
||||
*carry_out = (static_cast<uint32_t>(result) >> 31) != 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user