Index: src/arm/lithium-codegen-arm.cc |
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc |
index 8dd35b6b8394251c79842b7a56e4097d82b5cd5b..5ade3d64a20f4c82ea624f27378dfe206164bcf6 100644 |
--- a/src/arm/lithium-codegen-arm.cc |
+++ b/src/arm/lithium-codegen-arm.cc |
@@ -3098,6 +3098,56 @@ void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) { |
} |
+void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) { |
+ class DeferredStringCharFromCode: public LDeferredCode { |
+ public: |
+ DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr) |
+ : LDeferredCode(codegen), instr_(instr) { } |
+ virtual void Generate() { codegen()->DoDeferredStringCharFromCode(instr_); } |
+ private: |
+ LStringCharFromCode* instr_; |
+ }; |
+ |
+ DeferredStringCharFromCode* deferred = |
+ new DeferredStringCharFromCode(this, instr); |
+ |
+ ASSERT(instr->hydrogen()->value()->representation().IsInteger32()); |
+ Register char_code = ToRegister(instr->char_code()); |
+ Register result = ToRegister(instr->result()); |
+ ASSERT(!char_code.is(result)); |
+ |
+ __ cmp(char_code, Operand(String::kMaxAsciiCharCode)); |
+ __ b(hi, deferred->entry()); |
+ __ LoadRoot(result, Heap::kSingleCharacterStringCacheRootIndex); |
+ __ add(result, result, Operand(char_code, LSL, kPointerSizeLog2)); |
+ __ ldr(result, FieldMemOperand(result, FixedArray::kHeaderSize)); |
+ __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
+ __ cmp(result, ip); |
+ __ b(eq, deferred->entry()); |
+ __ bind(deferred->exit()); |
+} |
+ |
+ |
+void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) { |
+ Register char_code = ToRegister(instr->char_code()); |
+ Register result = ToRegister(instr->result()); |
+ |
+ // TODO(3095996): Get rid of this. For now, we need to make the |
+ // result register contain a valid pointer because it is already |
+ // contained in the register pointer map. |
+ __ mov(result, Operand(0)); |
+ |
+ __ PushSafepointRegisters(); |
+ __ SmiTag(char_code); |
+ __ push(char_code); |
+ __ CallRuntimeSaveDoubles(Runtime::kCharFromCode); |
+ RecordSafepointWithRegisters( |
+ instr->pointer_map(), 1, Safepoint::kNoDeoptimizationIndex); |
+ __ StoreToSafepointRegisterSlot(r0, result); |
+ __ PopSafepointRegisters(); |
+} |
+ |
+ |
void LCodeGen::DoStringLength(LStringLength* instr) { |
Register string = ToRegister(instr->InputAt(0)); |
Register result = ToRegister(instr->result()); |