OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 4546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4557 Label need_conversion_; | 4557 Label need_conversion_; |
4558 Label index_out_of_range_; | 4558 Label index_out_of_range_; |
4559 | 4559 |
4560 StringCharCodeAtGenerator char_code_at_generator_; | 4560 StringCharCodeAtGenerator char_code_at_generator_; |
4561 }; | 4561 }; |
4562 | 4562 |
4563 | 4563 |
4564 // This generates code that performs a String.prototype.charCodeAt() call | 4564 // This generates code that performs a String.prototype.charCodeAt() call |
4565 // or returns a smi in order to trigger conversion. | 4565 // or returns a smi in order to trigger conversion. |
4566 void CodeGenerator::GenerateStringCharCodeAt(ZoneList<Expression*>* args) { | 4566 void CodeGenerator::GenerateStringCharCodeAt(ZoneList<Expression*>* args) { |
4567 VirtualFrame::SpilledScope spilled_scope(frame_); | |
4568 Comment(masm_, "[ GenerateStringCharCodeAt"); | 4567 Comment(masm_, "[ GenerateStringCharCodeAt"); |
4569 ASSERT(args->length() == 2); | 4568 ASSERT(args->length() == 2); |
4570 | 4569 |
4571 Load(args->at(0)); | 4570 Load(args->at(0)); |
4572 Load(args->at(1)); | 4571 Load(args->at(1)); |
4573 | 4572 |
4574 Register index = r1; | 4573 Register index = frame_->PopToRegister(); |
4575 Register object = r2; | 4574 Register object = frame_->PopToRegister(index); |
4576 | |
4577 frame_->EmitPop(r1); | |
4578 frame_->EmitPop(r2); | |
4579 | 4575 |
4580 // We need two extra registers. | 4576 // We need two extra registers. |
4581 Register scratch = r3; | 4577 Register scratch = VirtualFrame::scratch0(); |
4582 Register result = r0; | 4578 Register result = VirtualFrame::scratch1(); |
4583 | 4579 |
4584 DeferredStringCharCodeAt* deferred = | 4580 DeferredStringCharCodeAt* deferred = |
4585 new DeferredStringCharCodeAt(object, | 4581 new DeferredStringCharCodeAt(object, |
4586 index, | 4582 index, |
4587 scratch, | 4583 scratch, |
4588 result); | 4584 result); |
4589 deferred->fast_case_generator()->GenerateFast(masm_); | 4585 deferred->fast_case_generator()->GenerateFast(masm_); |
4590 deferred->BindExit(); | 4586 deferred->BindExit(); |
4591 frame_->EmitPush(result); | 4587 frame_->EmitPush(result); |
4592 } | 4588 } |
(...skipping 14 matching lines...) Expand all Loading... |
4607 char_from_code_generator_.GenerateSlow(masm(), call_helper); | 4603 char_from_code_generator_.GenerateSlow(masm(), call_helper); |
4608 } | 4604 } |
4609 | 4605 |
4610 private: | 4606 private: |
4611 StringCharFromCodeGenerator char_from_code_generator_; | 4607 StringCharFromCodeGenerator char_from_code_generator_; |
4612 }; | 4608 }; |
4613 | 4609 |
4614 | 4610 |
4615 // Generates code for creating a one-char string from a char code. | 4611 // Generates code for creating a one-char string from a char code. |
4616 void CodeGenerator::GenerateStringCharFromCode(ZoneList<Expression*>* args) { | 4612 void CodeGenerator::GenerateStringCharFromCode(ZoneList<Expression*>* args) { |
4617 VirtualFrame::SpilledScope spilled_scope(frame_); | |
4618 Comment(masm_, "[ GenerateStringCharFromCode"); | 4613 Comment(masm_, "[ GenerateStringCharFromCode"); |
4619 ASSERT(args->length() == 1); | 4614 ASSERT(args->length() == 1); |
4620 | 4615 |
4621 Load(args->at(0)); | 4616 Load(args->at(0)); |
4622 | 4617 |
4623 Register code = r1; | 4618 Register result = frame_->GetTOSRegister(); |
4624 Register result = r0; | 4619 Register code = frame_->PopToRegister(result); |
4625 | |
4626 frame_->EmitPop(code); | |
4627 | 4620 |
4628 DeferredStringCharFromCode* deferred = new DeferredStringCharFromCode( | 4621 DeferredStringCharFromCode* deferred = new DeferredStringCharFromCode( |
4629 code, result); | 4622 code, result); |
4630 deferred->fast_case_generator()->GenerateFast(masm_); | 4623 deferred->fast_case_generator()->GenerateFast(masm_); |
4631 deferred->BindExit(); | 4624 deferred->BindExit(); |
4632 frame_->EmitPush(result); | 4625 frame_->EmitPush(result); |
4633 } | 4626 } |
4634 | 4627 |
4635 | 4628 |
4636 class DeferredStringCharAt : public DeferredCode { | 4629 class DeferredStringCharAt : public DeferredCode { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4678 Label need_conversion_; | 4671 Label need_conversion_; |
4679 Label index_out_of_range_; | 4672 Label index_out_of_range_; |
4680 | 4673 |
4681 StringCharAtGenerator char_at_generator_; | 4674 StringCharAtGenerator char_at_generator_; |
4682 }; | 4675 }; |
4683 | 4676 |
4684 | 4677 |
4685 // This generates code that performs a String.prototype.charAt() call | 4678 // This generates code that performs a String.prototype.charAt() call |
4686 // or returns a smi in order to trigger conversion. | 4679 // or returns a smi in order to trigger conversion. |
4687 void CodeGenerator::GenerateStringCharAt(ZoneList<Expression*>* args) { | 4680 void CodeGenerator::GenerateStringCharAt(ZoneList<Expression*>* args) { |
4688 VirtualFrame::SpilledScope spilled_scope(frame_); | |
4689 Comment(masm_, "[ GenerateStringCharAt"); | 4681 Comment(masm_, "[ GenerateStringCharAt"); |
4690 ASSERT(args->length() == 2); | 4682 ASSERT(args->length() == 2); |
4691 | 4683 |
4692 Load(args->at(0)); | 4684 Load(args->at(0)); |
4693 Load(args->at(1)); | 4685 Load(args->at(1)); |
4694 | 4686 |
4695 Register index = r1; | 4687 Register index = frame_->PopToRegister(); |
4696 Register object = r2; | 4688 Register object = frame_->PopToRegister(index); |
4697 | |
4698 frame_->EmitPop(r1); | |
4699 frame_->EmitPop(r2); | |
4700 | 4689 |
4701 // We need three extra registers. | 4690 // We need three extra registers. |
4702 Register scratch1 = r3; | 4691 Register scratch1 = VirtualFrame::scratch0(); |
4703 Register scratch2 = r4; | 4692 Register scratch2 = VirtualFrame::scratch1(); |
4704 Register result = r0; | 4693 // Use r6 without notifying the virtual frame. |
| 4694 Register result = r6; |
4705 | 4695 |
4706 DeferredStringCharAt* deferred = | 4696 DeferredStringCharAt* deferred = |
4707 new DeferredStringCharAt(object, | 4697 new DeferredStringCharAt(object, |
4708 index, | 4698 index, |
4709 scratch1, | 4699 scratch1, |
4710 scratch2, | 4700 scratch2, |
4711 result); | 4701 result); |
4712 deferred->fast_case_generator()->GenerateFast(masm_); | 4702 deferred->fast_case_generator()->GenerateFast(masm_); |
4713 deferred->BindExit(); | 4703 deferred->BindExit(); |
4714 frame_->EmitPush(result); | 4704 frame_->EmitPush(result); |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4873 // adaptor frame. | 4863 // adaptor frame. |
4874 __ ldr(tos, | 4864 __ ldr(tos, |
4875 MemOperand(scratch0, ArgumentsAdaptorFrameConstants::kLengthOffset), | 4865 MemOperand(scratch0, ArgumentsAdaptorFrameConstants::kLengthOffset), |
4876 eq); | 4866 eq); |
4877 | 4867 |
4878 frame_->EmitPush(tos); | 4868 frame_->EmitPush(tos); |
4879 } | 4869 } |
4880 | 4870 |
4881 | 4871 |
4882 void CodeGenerator::GenerateArguments(ZoneList<Expression*>* args) { | 4872 void CodeGenerator::GenerateArguments(ZoneList<Expression*>* args) { |
4883 VirtualFrame::SpilledScope spilled_scope(frame_); | |
4884 ASSERT(args->length() == 1); | 4873 ASSERT(args->length() == 1); |
4885 | 4874 |
4886 // Satisfy contract with ArgumentsAccessStub: | 4875 // Satisfy contract with ArgumentsAccessStub: |
4887 // Load the key into r1 and the formal parameters count into r0. | 4876 // Load the key into r1 and the formal parameters count into r0. |
4888 Load(args->at(0)); | 4877 Load(args->at(0)); |
4889 frame_->EmitPop(r1); | 4878 frame_->PopToR1(); |
| 4879 frame_->SpillAll(); |
4890 __ mov(r0, Operand(Smi::FromInt(scope()->num_parameters()))); | 4880 __ mov(r0, Operand(Smi::FromInt(scope()->num_parameters()))); |
4891 | 4881 |
4892 // Call the shared stub to get to arguments[key]. | 4882 // Call the shared stub to get to arguments[key]. |
4893 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); | 4883 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); |
4894 frame_->CallStub(&stub, 0); | 4884 frame_->CallStub(&stub, 0); |
4895 frame_->EmitPush(r0); | 4885 frame_->EmitPush(r0); |
4896 } | 4886 } |
4897 | 4887 |
4898 | 4888 |
4899 void CodeGenerator::GenerateRandomHeapNumber( | 4889 void CodeGenerator::GenerateRandomHeapNumber( |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5107 virtual void Generate(); | 5097 virtual void Generate(); |
5108 | 5098 |
5109 private: | 5099 private: |
5110 Register dst_, cache_, key_; | 5100 Register dst_, cache_, key_; |
5111 }; | 5101 }; |
5112 | 5102 |
5113 | 5103 |
5114 void DeferredSearchCache::Generate() { | 5104 void DeferredSearchCache::Generate() { |
5115 __ Push(cache_, key_); | 5105 __ Push(cache_, key_); |
5116 __ CallRuntime(Runtime::kGetFromCache, 2); | 5106 __ CallRuntime(Runtime::kGetFromCache, 2); |
5117 if (!dst_.is(r0)) { | 5107 __ Move(dst_, r0); |
5118 __ mov(dst_, r0); | |
5119 } | |
5120 } | 5108 } |
5121 | 5109 |
5122 | 5110 |
5123 void CodeGenerator::GenerateGetFromCache(ZoneList<Expression*>* args) { | 5111 void CodeGenerator::GenerateGetFromCache(ZoneList<Expression*>* args) { |
5124 ASSERT_EQ(2, args->length()); | 5112 ASSERT_EQ(2, args->length()); |
5125 | 5113 |
5126 ASSERT_NE(NULL, args->at(0)->AsLiteral()); | 5114 ASSERT_NE(NULL, args->at(0)->AsLiteral()); |
5127 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); | 5115 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); |
5128 | 5116 |
5129 Handle<FixedArray> jsfunction_result_caches( | 5117 Handle<FixedArray> jsfunction_result_caches( |
5130 Top::global_context()->jsfunction_result_caches()); | 5118 Top::global_context()->jsfunction_result_caches()); |
5131 if (jsfunction_result_caches->length() <= cache_id) { | 5119 if (jsfunction_result_caches->length() <= cache_id) { |
5132 __ Abort("Attempt to use undefined cache."); | 5120 __ Abort("Attempt to use undefined cache."); |
5133 frame_->EmitPushRoot(Heap::kUndefinedValueRootIndex); | 5121 frame_->EmitPushRoot(Heap::kUndefinedValueRootIndex); |
5134 return; | 5122 return; |
5135 } | 5123 } |
5136 | 5124 |
5137 Load(args->at(1)); | 5125 Load(args->at(1)); |
5138 | 5126 |
5139 VirtualFrame::SpilledScope spilled_scope(frame_); | 5127 frame_->PopToR1(); |
| 5128 frame_->SpillAll(); |
| 5129 Register key = r1; // Just poped to r1 |
| 5130 Register result = r0; // Free, as frame has just been spilled. |
| 5131 Register scratch1 = VirtualFrame::scratch0(); |
| 5132 Register scratch2 = VirtualFrame::scratch1(); |
5140 | 5133 |
5141 frame_->EmitPop(r2); | 5134 __ ldr(scratch1, ContextOperand(cp, Context::GLOBAL_INDEX)); |
| 5135 __ ldr(scratch1, |
| 5136 FieldMemOperand(scratch1, GlobalObject::kGlobalContextOffset)); |
| 5137 __ ldr(scratch1, |
| 5138 ContextOperand(scratch1, Context::JSFUNCTION_RESULT_CACHES_INDEX)); |
| 5139 __ ldr(scratch1, |
| 5140 FieldMemOperand(scratch1, FixedArray::OffsetOfElementAt(cache_id))); |
5142 | 5141 |
5143 __ ldr(r1, ContextOperand(cp, Context::GLOBAL_INDEX)); | 5142 DeferredSearchCache* deferred = |
5144 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalContextOffset)); | 5143 new DeferredSearchCache(result, scratch1, key); |
5145 __ ldr(r1, ContextOperand(r1, Context::JSFUNCTION_RESULT_CACHES_INDEX)); | |
5146 __ ldr(r1, FieldMemOperand(r1, FixedArray::OffsetOfElementAt(cache_id))); | |
5147 | |
5148 DeferredSearchCache* deferred = new DeferredSearchCache(r0, r1, r2); | |
5149 | 5144 |
5150 const int kFingerOffset = | 5145 const int kFingerOffset = |
5151 FixedArray::OffsetOfElementAt(JSFunctionResultCache::kFingerIndex); | 5146 FixedArray::OffsetOfElementAt(JSFunctionResultCache::kFingerIndex); |
5152 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); | 5147 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); |
5153 __ ldr(r0, FieldMemOperand(r1, kFingerOffset)); | 5148 __ ldr(result, FieldMemOperand(scratch1, kFingerOffset)); |
5154 // r0 now holds finger offset as a smi. | 5149 // result now holds finger offset as a smi. |
5155 __ add(r3, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 5150 __ add(scratch2, scratch1, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
5156 // r3 now points to the start of fixed array elements. | 5151 // scratch2 now points to the start of fixed array elements. |
5157 __ ldr(r0, MemOperand(r3, r0, LSL, kPointerSizeLog2 - kSmiTagSize, PreIndex)); | 5152 __ ldr(result, |
5158 // Note side effect of PreIndex: r3 now points to the key of the pair. | 5153 MemOperand( |
5159 __ cmp(r2, r0); | 5154 scratch2, result, LSL, kPointerSizeLog2 - kSmiTagSize, PreIndex)); |
| 5155 // Note side effect of PreIndex: scratch2 now points to the key of the pair. |
| 5156 __ cmp(key, result); |
5160 deferred->Branch(ne); | 5157 deferred->Branch(ne); |
5161 | 5158 |
5162 __ ldr(r0, MemOperand(r3, kPointerSize)); | 5159 __ ldr(result, MemOperand(scratch2, kPointerSize)); |
5163 | 5160 |
5164 deferred->BindExit(); | 5161 deferred->BindExit(); |
5165 frame_->EmitPush(r0); | 5162 frame_->EmitPush(result); |
5166 } | 5163 } |
5167 | 5164 |
5168 | 5165 |
5169 void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) { | 5166 void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) { |
5170 ASSERT_EQ(args->length(), 1); | 5167 ASSERT_EQ(args->length(), 1); |
5171 | 5168 |
5172 // Load the argument on the stack and jump to the runtime. | 5169 // Load the argument on the stack and jump to the runtime. |
5173 Load(args->at(0)); | 5170 Load(args->at(0)); |
5174 | 5171 |
5175 NumberToStringStub stub; | 5172 NumberToStringStub stub; |
(...skipping 5272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10448 call_helper.BeforeCall(masm); | 10445 call_helper.BeforeCall(masm); |
10449 __ Push(object_, index_); | 10446 __ Push(object_, index_); |
10450 __ push(index_); // Consumed by runtime conversion function. | 10447 __ push(index_); // Consumed by runtime conversion function. |
10451 if (index_flags_ == STRING_INDEX_IS_NUMBER) { | 10448 if (index_flags_ == STRING_INDEX_IS_NUMBER) { |
10452 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); | 10449 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); |
10453 } else { | 10450 } else { |
10454 ASSERT(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); | 10451 ASSERT(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); |
10455 // NumberToSmi discards numbers that are not exact integers. | 10452 // NumberToSmi discards numbers that are not exact integers. |
10456 __ CallRuntime(Runtime::kNumberToSmi, 1); | 10453 __ CallRuntime(Runtime::kNumberToSmi, 1); |
10457 } | 10454 } |
10458 if (!scratch_.is(r0)) { | 10455 // Save the conversion result before the pop instructions below |
10459 // Save the conversion result before the pop instructions below | 10456 // have a chance to overwrite it. |
10460 // have a chance to overwrite it. | 10457 __ Move(scratch_, r0); |
10461 __ mov(scratch_, r0); | |
10462 } | |
10463 __ pop(index_); | 10458 __ pop(index_); |
10464 __ pop(object_); | 10459 __ pop(object_); |
10465 // Reload the instance type. | 10460 // Reload the instance type. |
10466 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); | 10461 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); |
10467 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); | 10462 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); |
10468 call_helper.AfterCall(masm); | 10463 call_helper.AfterCall(masm); |
10469 // If index is still not a smi, it must be out of range. | 10464 // If index is still not a smi, it must be out of range. |
10470 __ BranchOnNotSmi(scratch_, index_out_of_range_); | 10465 __ BranchOnNotSmi(scratch_, index_out_of_range_); |
10471 // Otherwise, return to the fast path. | 10466 // Otherwise, return to the fast path. |
10472 __ jmp(&got_smi_index_); | 10467 __ jmp(&got_smi_index_); |
10473 | 10468 |
10474 // Call runtime. We get here when the receiver is a string and the | 10469 // Call runtime. We get here when the receiver is a string and the |
10475 // index is a number, but the code of getting the actual character | 10470 // index is a number, but the code of getting the actual character |
10476 // is too complex (e.g., when the string needs to be flattened). | 10471 // is too complex (e.g., when the string needs to be flattened). |
10477 __ bind(&call_runtime_); | 10472 __ bind(&call_runtime_); |
10478 call_helper.BeforeCall(masm); | 10473 call_helper.BeforeCall(masm); |
10479 __ Push(object_, index_); | 10474 __ Push(object_, index_); |
10480 __ CallRuntime(Runtime::kStringCharCodeAt, 2); | 10475 __ CallRuntime(Runtime::kStringCharCodeAt, 2); |
10481 if (!result_.is(r0)) { | 10476 __ Move(result_, r0); |
10482 __ mov(result_, r0); | |
10483 } | |
10484 call_helper.AfterCall(masm); | 10477 call_helper.AfterCall(masm); |
10485 __ jmp(&exit_); | 10478 __ jmp(&exit_); |
10486 | 10479 |
10487 __ Abort("Unexpected fallthrough from CharCodeAt slow case"); | 10480 __ Abort("Unexpected fallthrough from CharCodeAt slow case"); |
10488 } | 10481 } |
10489 | 10482 |
10490 | 10483 |
10491 // ------------------------------------------------------------------------- | 10484 // ------------------------------------------------------------------------- |
10492 // StringCharFromCodeGenerator | 10485 // StringCharFromCodeGenerator |
10493 | 10486 |
(...skipping 20 matching lines...) Expand all Loading... |
10514 | 10507 |
10515 | 10508 |
10516 void StringCharFromCodeGenerator::GenerateSlow( | 10509 void StringCharFromCodeGenerator::GenerateSlow( |
10517 MacroAssembler* masm, const RuntimeCallHelper& call_helper) { | 10510 MacroAssembler* masm, const RuntimeCallHelper& call_helper) { |
10518 __ Abort("Unexpected fallthrough to CharFromCode slow case"); | 10511 __ Abort("Unexpected fallthrough to CharFromCode slow case"); |
10519 | 10512 |
10520 __ bind(&slow_case_); | 10513 __ bind(&slow_case_); |
10521 call_helper.BeforeCall(masm); | 10514 call_helper.BeforeCall(masm); |
10522 __ push(code_); | 10515 __ push(code_); |
10523 __ CallRuntime(Runtime::kCharFromCode, 1); | 10516 __ CallRuntime(Runtime::kCharFromCode, 1); |
10524 if (!result_.is(r0)) { | 10517 __ Move(result_, r0); |
10525 __ mov(result_, r0); | |
10526 } | |
10527 call_helper.AfterCall(masm); | 10518 call_helper.AfterCall(masm); |
10528 __ jmp(&exit_); | 10519 __ jmp(&exit_); |
10529 | 10520 |
10530 __ Abort("Unexpected fallthrough from CharFromCode slow case"); | 10521 __ Abort("Unexpected fallthrough from CharFromCode slow case"); |
10531 } | 10522 } |
10532 | 10523 |
10533 | 10524 |
10534 // ------------------------------------------------------------------------- | 10525 // ------------------------------------------------------------------------- |
10535 // StringCharAtGenerator | 10526 // StringCharAtGenerator |
10536 | 10527 |
(...skipping 908 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11445 __ bind(&string_add_runtime); | 11436 __ bind(&string_add_runtime); |
11446 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | 11437 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); |
11447 } | 11438 } |
11448 | 11439 |
11449 | 11440 |
11450 #undef __ | 11441 #undef __ |
11451 | 11442 |
11452 } } // namespace v8::internal | 11443 } } // namespace v8::internal |
11453 | 11444 |
11454 #endif // V8_TARGET_ARCH_ARM | 11445 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |