Index: src/mips/lithium-codegen-mips.cc |
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc |
index e790798f77e18c6a579b4833c7e6d30c4659787e..fafe7adb868e3637808245e72e29d4e97110de1c 100644 |
--- a/src/mips/lithium-codegen-mips.cc |
+++ b/src/mips/lithium-codegen-mips.cc |
@@ -3509,89 +3509,13 @@ void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { |
LStringCharCodeAt* instr_; |
}; |
- Register temp = scratch1(); |
- Register string = ToRegister(instr->string()); |
- Register index = ToRegister(instr->index()); |
- Register result = ToRegister(instr->result()); |
DeferredStringCharCodeAt* deferred = |
new DeferredStringCharCodeAt(this, instr); |
- |
- // Fetch the instance type of the receiver into result register. |
- __ lw(result, FieldMemOperand(string, HeapObject::kMapOffset)); |
- __ lbu(result, FieldMemOperand(result, Map::kInstanceTypeOffset)); |
- |
- // We need special handling for indirect strings. |
- Label check_sequential; |
- __ And(temp, result, kIsIndirectStringMask); |
- __ Branch(&check_sequential, eq, temp, Operand(zero_reg)); |
- |
- // Dispatch on the indirect string shape: slice or cons. |
- Label cons_string; |
- __ And(temp, result, kSlicedNotConsMask); |
- __ Branch(&cons_string, eq, temp, Operand(zero_reg)); |
- |
- // Handle slices. |
- Label indirect_string_loaded; |
- __ lw(result, FieldMemOperand(string, SlicedString::kOffsetOffset)); |
- __ sra(temp, result, kSmiTagSize); |
- __ addu(index, index, temp); |
- __ lw(string, FieldMemOperand(string, SlicedString::kParentOffset)); |
- __ jmp(&indirect_string_loaded); |
- |
- // Handle conses. |
- // Check whether the right hand side is the empty string (i.e. if |
- // this is really a flat string in a cons string). If that is not |
- // the case we would rather go to the runtime system now to flatten |
- // the string. |
- __ bind(&cons_string); |
- __ lw(result, FieldMemOperand(string, ConsString::kSecondOffset)); |
- __ LoadRoot(temp, Heap::kEmptyStringRootIndex); |
- __ Branch(deferred->entry(), ne, result, Operand(temp)); |
- // Get the first of the two strings and load its instance type. |
- __ lw(string, FieldMemOperand(string, ConsString::kFirstOffset)); |
- |
- __ bind(&indirect_string_loaded); |
- __ lw(result, FieldMemOperand(string, HeapObject::kMapOffset)); |
- __ lbu(result, FieldMemOperand(result, Map::kInstanceTypeOffset)); |
- |
- // Check whether the string is sequential. The only non-sequential |
- // shapes we support have just been unwrapped above. |
- // Note that if the original string is a cons or slice with an external |
- // string as underlying string, we pass that unpacked underlying string with |
- // the adjusted index to the runtime function. |
- __ bind(&check_sequential); |
- STATIC_ASSERT(kSeqStringTag == 0); |
- __ And(temp, result, Operand(kStringRepresentationMask)); |
- __ Branch(deferred->entry(), ne, temp, Operand(zero_reg)); |
- |
- // Dispatch on the encoding: ASCII or two-byte. |
- Label ascii_string; |
- STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0); |
- STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0); |
- __ And(temp, result, Operand(kStringEncodingMask)); |
- __ Branch(&ascii_string, ne, temp, Operand(zero_reg)); |
- |
- // Two-byte string. |
- // Load the two-byte character code into the result register. |
- Label done; |
- __ Addu(result, |
- string, |
- Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); |
- __ sll(temp, index, 1); |
- __ Addu(result, result, temp); |
- __ lhu(result, MemOperand(result, 0)); |
- __ Branch(&done); |
- |
- // ASCII string. |
- // Load the byte into the result register. |
- __ bind(&ascii_string); |
- __ Addu(result, |
- string, |
- Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); |
- __ Addu(result, result, index); |
- __ lbu(result, MemOperand(result, 0)); |
- |
- __ bind(&done); |
+ StringCharLoadGenerator::Generate(masm(), |
+ ToRegister(instr->string()), |
+ ToRegister(instr->index()), |
+ ToRegister(instr->result()), |
+ deferred->entry()); |
__ bind(deferred->exit()); |
} |