Commit 101d64c1 authored by ulan@chromium.org's avatar ulan@chromium.org

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
parent 8a3f19f7
...@@ -5999,23 +5999,28 @@ void SubStringStub::Generate(MacroAssembler* masm) { ...@@ -5999,23 +5999,28 @@ void SubStringStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(kSmiTag == 0); STATIC_ASSERT(kSmiTag == 0);
STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1); STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1);
// I.e., arithmetic shift right by one un-smi-tags. // Arithmetic shift right by one un-smi-tags. In this case we rotate right
__ mov(r2, Operand(r2, ASR, 1), SetCC); // instead because we bail out on non-smi values: ROR and ASR are equivalent
__ mov(r3, Operand(r3, ASR, 1), SetCC, cc); // for smis but they set the flags in a way that's easier to optimize.
// If either to or from had the smi tag bit set, then carry is set now. __ mov(r2, Operand(r2, ROR, 1), SetCC);
__ b(cs, &runtime); // Either "from" or "to" is not a smi. __ 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 // 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 // next instruction is not executed and we fall through to bailing out to
// runtime. pl is the opposite of mi. // runtime.
// Both r2 and r3 are untagged integers. // Executed if both r2 and r3 are untagged integers.
__ sub(r2, r2, Operand(r3), SetCC, pl); __ sub(r2, r2, Operand(r3), SetCC, cc);
__ b(mi, &runtime); // Fail if from > to. // 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. // Make sure first argument is a string.
__ ldr(r0, MemOperand(sp, kStringOffset)); __ ldr(r0, MemOperand(sp, kStringOffset));
STATIC_ASSERT(kSmiTag == 0); STATIC_ASSERT(kSmiTag == 0);
__ JumpIfSmi(r0, &runtime); // Do a JumpIfSmi, but fold its jump into the subsequent string test.
Condition is_string = masm->IsObjectStringType(r0, r1); __ tst(r0, Operand(kSmiTagMask));
Condition is_string = masm->IsObjectStringType(r0, r1, ne);
ASSERT(is_string == eq);
__ b(NegateCondition(is_string), &runtime); __ b(NegateCondition(is_string), &runtime);
// Short-cut for the case of trivial substring. // Short-cut for the case of trivial substring.
......
...@@ -893,12 +893,15 @@ class MacroAssembler: public Assembler { ...@@ -893,12 +893,15 @@ class MacroAssembler: public Assembler {
// Load and check the instance type of an object for being a string. // Load and check the instance type of an object for being a string.
// Loads the type into the second argument register. // 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, Condition IsObjectStringType(Register obj,
Register type) { Register type,
ldr(type, FieldMemOperand(obj, HeapObject::kMapOffset)); Condition cond = al) {
ldrb(type, FieldMemOperand(type, Map::kInstanceTypeOffset)); ldr(type, FieldMemOperand(obj, HeapObject::kMapOffset), cond);
tst(type, Operand(kIsNotStringMask)); ldrb(type, FieldMemOperand(type, Map::kInstanceTypeOffset), cond);
tst(type, Operand(kIsNotStringMask), cond);
ASSERT_EQ(0, kStringTag); ASSERT_EQ(0, kStringTag);
return eq; return eq;
} }
...@@ -1202,7 +1205,7 @@ class MacroAssembler: public Assembler { ...@@ -1202,7 +1205,7 @@ class MacroAssembler: public Assembler {
// Souce and destination can be the same register. // Souce and destination can be the same register.
void UntagAndJumpIfNotSmi(Register dst, Register src, Label* non_smi_case); 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) { inline void JumpIfSmi(Register value, Label* smi_label) {
tst(value, Operand(kSmiTagMask)); tst(value, Operand(kSmiTagMask));
b(eq, smi_label); b(eq, smi_label);
......
...@@ -1387,7 +1387,14 @@ int32_t Simulator::GetShiftRm(Instruction* instr, bool* carry_out) { ...@@ -1387,7 +1387,14 @@ int32_t Simulator::GetShiftRm(Instruction* instr, bool* carry_out) {
} }
case ROR: { 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; break;
} }
......
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