From 101d64c1a65018fa782b7fef912317b737490cd1 Mon Sep 17 00:00:00 2001 From: "ulan@chromium.org" Date: Wed, 7 Nov 2012 13:22:03 +0000 Subject: [PATCH] Simplify some of the startup code for SubStringStub::Generate. R=ulan@chromium.org Review URL: https://chromiumcodereview.appspot.com/11098043 Patch from JF Bastien . git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12887 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/code-stubs-arm.cc | 27 ++++++++++++++++----------- src/arm/macro-assembler-arm.h | 15 +++++++++------ src/arm/simulator-arm.cc | 9 ++++++++- 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index ceb108ffae..399cfe4ed5 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -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. diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h index e3e39a3879..1d97a6c169 100644 --- a/src/arm/macro-assembler-arm.h +++ b/src/arm/macro-assembler-arm.h @@ -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); diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc index 5cdba9c467..bd7f1bdf98 100644 --- a/src/arm/simulator-arm.cc +++ b/src/arm/simulator-arm.cc @@ -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(result) >> shift_amount; + uint32_t right = static_cast(result) << (32 - shift_amount); + result = right | left; + *carry_out = (static_cast(result) >> 31) != 0; + } break; }