Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(143)

Side by Side Diff: src/arm/lithium-codegen-arm.cc

Issue 112863002: Merge bleeding_edge 18021:18297 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 GenerateDeferredCode() && 77 GenerateDeferredCode() &&
78 GenerateDeoptJumpTable() && 78 GenerateDeoptJumpTable() &&
79 GenerateSafepointTable(); 79 GenerateSafepointTable();
80 } 80 }
81 81
82 82
83 void LCodeGen::FinishCode(Handle<Code> code) { 83 void LCodeGen::FinishCode(Handle<Code> code) {
84 ASSERT(is_done()); 84 ASSERT(is_done());
85 code->set_stack_slots(GetStackSlotCount()); 85 code->set_stack_slots(GetStackSlotCount());
86 code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); 86 code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
87 if (FLAG_weak_embedded_maps_in_optimized_code) { 87 RegisterDependentCodeForEmbeddedMaps(code);
88 RegisterDependentCodeForEmbeddedMaps(code);
89 }
90 PopulateDeoptimizationData(code); 88 PopulateDeoptimizationData(code);
91 info()->CommitDependencies(code); 89 info()->CommitDependencies(code);
92 } 90 }
93 91
94 92
95 void LCodeGen::Abort(BailoutReason reason) { 93 void LCodeGen::Abort(BailoutReason reason) {
96 info()->set_bailout_reason(reason); 94 info()->set_bailout_reason(reason);
97 status_ = ABORTED; 95 status_ = ABORTED;
98 } 96 }
99 97
(...skipping 780 matching lines...) Expand 10 before | Expand all | Expand 10 after
880 878
881 void LCodeGen::DeoptimizeIf(Condition condition, 879 void LCodeGen::DeoptimizeIf(Condition condition,
882 LEnvironment* environment) { 880 LEnvironment* environment) {
883 Deoptimizer::BailoutType bailout_type = info()->IsStub() 881 Deoptimizer::BailoutType bailout_type = info()->IsStub()
884 ? Deoptimizer::LAZY 882 ? Deoptimizer::LAZY
885 : Deoptimizer::EAGER; 883 : Deoptimizer::EAGER;
886 DeoptimizeIf(condition, environment, bailout_type); 884 DeoptimizeIf(condition, environment, bailout_type);
887 } 885 }
888 886
889 887
890 void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) {
891 ZoneList<Handle<Map> > maps(1, zone());
892 ZoneList<Handle<JSObject> > objects(1, zone());
893 int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
894 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
895 if (Code::IsWeakEmbeddedObject(code->kind(), it.rinfo()->target_object())) {
896 if (it.rinfo()->target_object()->IsMap()) {
897 Handle<Map> map(Map::cast(it.rinfo()->target_object()));
898 maps.Add(map, zone());
899 } else if (it.rinfo()->target_object()->IsJSObject()) {
900 Handle<JSObject> object(JSObject::cast(it.rinfo()->target_object()));
901 objects.Add(object, zone());
902 }
903 }
904 }
905 #ifdef VERIFY_HEAP
906 // This disables verification of weak embedded objects after full GC.
907 // AddDependentCode can cause a GC, which would observe the state where
908 // this code is not yet in the depended code lists of the embedded maps.
909 NoWeakObjectVerificationScope disable_verification_of_embedded_objects;
910 #endif
911 for (int i = 0; i < maps.length(); i++) {
912 maps.at(i)->AddDependentCode(DependentCode::kWeaklyEmbeddedGroup, code);
913 }
914 for (int i = 0; i < objects.length(); i++) {
915 AddWeakObjectToCodeDependency(isolate()->heap(), objects.at(i), code);
916 }
917 }
918
919
920 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { 888 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
921 int length = deoptimizations_.length(); 889 int length = deoptimizations_.length();
922 if (length == 0) return; 890 if (length == 0) return;
923 Handle<DeoptimizationInputData> data = 891 Handle<DeoptimizationInputData> data =
924 factory()->NewDeoptimizationInputData(length, TENURED); 892 factory()->NewDeoptimizationInputData(length, TENURED);
925 893
926 Handle<ByteArray> translations = 894 Handle<ByteArray> translations =
927 translations_.CreateByteArray(isolate()->factory()); 895 translations_.CreateByteArray(isolate()->factory());
928 data->SetTranslationByteArray(*translations); 896 data->SetTranslationByteArray(*translations);
929 data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); 897 data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_));
(...skipping 1110 matching lines...) Expand 10 before | Expand all | Expand 10 after
2040 MemOperand operand = BuildSeqStringOperand(string, instr->index(), encoding); 2008 MemOperand operand = BuildSeqStringOperand(string, instr->index(), encoding);
2041 if (encoding == String::ONE_BYTE_ENCODING) { 2009 if (encoding == String::ONE_BYTE_ENCODING) {
2042 __ strb(value, operand); 2010 __ strb(value, operand);
2043 } else { 2011 } else {
2044 __ strh(value, operand); 2012 __ strh(value, operand);
2045 } 2013 }
2046 } 2014 }
2047 2015
2048 2016
2049 void LCodeGen::DoThrow(LThrow* instr) { 2017 void LCodeGen::DoThrow(LThrow* instr) {
2050 Register input_reg = EmitLoadRegister(instr->value(), ip); 2018 __ push(ToRegister(instr->value()));
2051 __ push(input_reg);
2052 ASSERT(ToRegister(instr->context()).is(cp)); 2019 ASSERT(ToRegister(instr->context()).is(cp));
2053 CallRuntime(Runtime::kThrow, 1, instr); 2020 CallRuntime(Runtime::kThrow, 1, instr);
2054 2021
2055 if (FLAG_debug_code) { 2022 if (FLAG_debug_code) {
2056 __ stop("Unreachable code."); 2023 __ stop("Unreachable code.");
2057 } 2024 }
2058 } 2025 }
2059 2026
2060 2027
2061 void LCodeGen::DoAddI(LAddI* instr) { 2028 void LCodeGen::DoAddI(LAddI* instr) {
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
2157 case Token::SUB: 2124 case Token::SUB:
2158 __ vsub(result, left, right); 2125 __ vsub(result, left, right);
2159 break; 2126 break;
2160 case Token::MUL: 2127 case Token::MUL:
2161 __ vmul(result, left, right); 2128 __ vmul(result, left, right);
2162 break; 2129 break;
2163 case Token::DIV: 2130 case Token::DIV:
2164 __ vdiv(result, left, right); 2131 __ vdiv(result, left, right);
2165 break; 2132 break;
2166 case Token::MOD: { 2133 case Token::MOD: {
2167 // Save r0-r3 on the stack.
2168 __ stm(db_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit());
2169
2170 __ PrepareCallCFunction(0, 2, scratch0()); 2134 __ PrepareCallCFunction(0, 2, scratch0());
2171 __ SetCallCDoubleArguments(left, right); 2135 __ SetCallCDoubleArguments(left, right);
2172 __ CallCFunction( 2136 __ CallCFunction(
2173 ExternalReference::double_fp_operation(Token::MOD, isolate()), 2137 ExternalReference::double_fp_operation(Token::MOD, isolate()),
2174 0, 2); 2138 0, 2);
2175 // Move the result in the double result register. 2139 // Move the result in the double result register.
2176 __ GetCFunctionDoubleResult(result); 2140 __ GetCFunctionDoubleResult(result);
2177
2178 // Restore r0-r3.
2179 __ ldm(ia_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit());
2180 break; 2141 break;
2181 } 2142 }
2182 default: 2143 default:
2183 UNREACHABLE(); 2144 UNREACHABLE();
2184 break; 2145 break;
2185 } 2146 }
2186 } 2147 }
2187 2148
2188 2149
2189 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { 2150 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
2190 ASSERT(ToRegister(instr->context()).is(cp)); 2151 ASSERT(ToRegister(instr->context()).is(cp));
2191 ASSERT(ToRegister(instr->left()).is(r1)); 2152 ASSERT(ToRegister(instr->left()).is(r1));
2192 ASSERT(ToRegister(instr->right()).is(r0)); 2153 ASSERT(ToRegister(instr->right()).is(r0));
2193 ASSERT(ToRegister(instr->result()).is(r0)); 2154 ASSERT(ToRegister(instr->result()).is(r0));
2194 2155
2195 BinaryOpStub stub(instr->op(), NO_OVERWRITE); 2156 BinaryOpICStub stub(instr->op(), NO_OVERWRITE);
2196 // Block literal pool emission to ensure nop indicating no inlined smi code 2157 // Block literal pool emission to ensure nop indicating no inlined smi code
2197 // is in the correct position. 2158 // is in the correct position.
2198 Assembler::BlockConstPoolScope block_const_pool(masm()); 2159 Assembler::BlockConstPoolScope block_const_pool(masm());
2199 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 2160 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
2200 __ nop(); // Signals no inlined code. 2161 __ nop(); // Signals no inlined code.
2201 } 2162 }
2202 2163
2203 2164
2204 template<class InstrType> 2165 template<class InstrType>
2205 void LCodeGen::EmitBranch(InstrType instr, Condition condition) { 2166 void LCodeGen::EmitBranch(InstrType instr, Condition condition) {
(...skipping 1289 matching lines...) Expand 10 before | Expand all | Expand 10 after
3495 __ SmiUntag(result); 3456 __ SmiUntag(result);
3496 3457
3497 // Argument length is in result register. 3458 // Argument length is in result register.
3498 __ bind(&done); 3459 __ bind(&done);
3499 } 3460 }
3500 3461
3501 3462
3502 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { 3463 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
3503 Register receiver = ToRegister(instr->receiver()); 3464 Register receiver = ToRegister(instr->receiver());
3504 Register function = ToRegister(instr->function()); 3465 Register function = ToRegister(instr->function());
3466 Register result = ToRegister(instr->result());
3505 Register scratch = scratch0(); 3467 Register scratch = scratch0();
3506 3468
3507 // If the receiver is null or undefined, we have to pass the global 3469 // If the receiver is null or undefined, we have to pass the global
3508 // object as a receiver to normal functions. Values have to be 3470 // object as a receiver to normal functions. Values have to be
3509 // passed unchanged to builtins and strict-mode functions. 3471 // passed unchanged to builtins and strict-mode functions.
3510 Label global_object, receiver_ok; 3472 Label global_object, result_in_receiver;
3511 3473
3512 // Do not transform the receiver to object for strict mode 3474 // Do not transform the receiver to object for strict mode
3513 // functions. 3475 // functions.
3514 __ ldr(scratch, 3476 __ ldr(scratch,
3515 FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset)); 3477 FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset));
3516 __ ldr(scratch, 3478 __ ldr(scratch,
3517 FieldMemOperand(scratch, SharedFunctionInfo::kCompilerHintsOffset)); 3479 FieldMemOperand(scratch, SharedFunctionInfo::kCompilerHintsOffset));
3518 __ tst(scratch, 3480 __ tst(scratch,
3519 Operand(1 << (SharedFunctionInfo::kStrictModeFunction + kSmiTagSize))); 3481 Operand(1 << (SharedFunctionInfo::kStrictModeFunction + kSmiTagSize)));
3520 __ b(ne, &receiver_ok); 3482 __ b(ne, &result_in_receiver);
3521 3483
3522 // Do not transform the receiver to object for builtins. 3484 // Do not transform the receiver to object for builtins.
3523 __ tst(scratch, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize))); 3485 __ tst(scratch, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
3524 __ b(ne, &receiver_ok); 3486 __ b(ne, &result_in_receiver);
3525 3487
3526 // Normal function. Replace undefined or null with global receiver. 3488 // Normal function. Replace undefined or null with global receiver.
3527 __ LoadRoot(scratch, Heap::kNullValueRootIndex); 3489 __ LoadRoot(scratch, Heap::kNullValueRootIndex);
3528 __ cmp(receiver, scratch); 3490 __ cmp(receiver, scratch);
3529 __ b(eq, &global_object); 3491 __ b(eq, &global_object);
3530 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); 3492 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
3531 __ cmp(receiver, scratch); 3493 __ cmp(receiver, scratch);
3532 __ b(eq, &global_object); 3494 __ b(eq, &global_object);
3533 3495
3534 // Deoptimize if the receiver is not a JS object. 3496 // Deoptimize if the receiver is not a JS object.
3535 __ SmiTst(receiver); 3497 __ SmiTst(receiver);
3536 DeoptimizeIf(eq, instr->environment()); 3498 DeoptimizeIf(eq, instr->environment());
3537 __ CompareObjectType(receiver, scratch, scratch, FIRST_SPEC_OBJECT_TYPE); 3499 __ CompareObjectType(receiver, scratch, scratch, FIRST_SPEC_OBJECT_TYPE);
3538 DeoptimizeIf(lt, instr->environment()); 3500 DeoptimizeIf(lt, instr->environment());
3539 __ jmp(&receiver_ok); 3501 __ b(&result_in_receiver);
3540 3502
3541 __ bind(&global_object); 3503 __ bind(&global_object);
3542 __ ldr(receiver, GlobalObjectOperand()); 3504 __ ldr(result, GlobalObjectOperand());
3543 __ ldr(receiver, 3505 __ ldr(result,
3544 FieldMemOperand(receiver, JSGlobalObject::kGlobalReceiverOffset)); 3506 FieldMemOperand(result, JSGlobalObject::kGlobalReceiverOffset));
3545 __ bind(&receiver_ok); 3507 if (result.is(receiver)) {
3508 __ bind(&result_in_receiver);
3509 } else {
3510 Label result_ok;
3511 __ b(&result_ok);
3512 __ bind(&result_in_receiver);
3513 __ mov(result, receiver);
3514 __ bind(&result_ok);
3515 }
3546 } 3516 }
3547 3517
3548 3518
3549 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { 3519 void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
3550 Register receiver = ToRegister(instr->receiver()); 3520 Register receiver = ToRegister(instr->receiver());
3551 Register function = ToRegister(instr->function()); 3521 Register function = ToRegister(instr->function());
3552 Register length = ToRegister(instr->length()); 3522 Register length = ToRegister(instr->length());
3553 Register elements = ToRegister(instr->elements()); 3523 Register elements = ToRegister(instr->elements());
3554 Register scratch = scratch0(); 3524 Register scratch = scratch0();
3555 ASSERT(receiver.is(r0)); // Used for parameter count. 3525 ASSERT(receiver.is(r0)); // Used for parameter count.
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
3896 void LCodeGen::DoMathSqrt(LMathSqrt* instr) { 3866 void LCodeGen::DoMathSqrt(LMathSqrt* instr) {
3897 DwVfpRegister input = ToDoubleRegister(instr->value()); 3867 DwVfpRegister input = ToDoubleRegister(instr->value());
3898 DwVfpRegister result = ToDoubleRegister(instr->result()); 3868 DwVfpRegister result = ToDoubleRegister(instr->result());
3899 __ vsqrt(result, input); 3869 __ vsqrt(result, input);
3900 } 3870 }
3901 3871
3902 3872
3903 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) { 3873 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
3904 DwVfpRegister input = ToDoubleRegister(instr->value()); 3874 DwVfpRegister input = ToDoubleRegister(instr->value());
3905 DwVfpRegister result = ToDoubleRegister(instr->result()); 3875 DwVfpRegister result = ToDoubleRegister(instr->result());
3906 DwVfpRegister temp = ToDoubleRegister(instr->temp()); 3876 DwVfpRegister temp = double_scratch0();
3907 3877
3908 // Note that according to ECMA-262 15.8.2.13: 3878 // Note that according to ECMA-262 15.8.2.13:
3909 // Math.pow(-Infinity, 0.5) == Infinity 3879 // Math.pow(-Infinity, 0.5) == Infinity
3910 // Math.sqrt(-Infinity) == NaN 3880 // Math.sqrt(-Infinity) == NaN
3911 Label done; 3881 Label done;
3912 __ vmov(temp, -V8_INFINITY, scratch0()); 3882 __ vmov(temp, -V8_INFINITY, scratch0());
3913 __ VFPCompareAndSetFlags(input, temp); 3883 __ VFPCompareAndSetFlags(input, temp);
3914 __ vneg(result, temp, eq); 3884 __ vneg(result, temp, eq);
3915 __ b(&done, eq); 3885 __ b(&done, eq);
3916 3886
3917 // Add +0 to convert -0 to +0. 3887 // Add +0 to convert -0 to +0.
3918 __ vadd(result, input, kDoubleRegZero); 3888 __ vadd(result, input, kDoubleRegZero);
3919 __ vsqrt(result, result); 3889 __ vsqrt(result, result);
3920 __ bind(&done); 3890 __ bind(&done);
3921 } 3891 }
3922 3892
3923 3893
3924 void LCodeGen::DoPower(LPower* instr) { 3894 void LCodeGen::DoPower(LPower* instr) {
3925 Representation exponent_type = instr->hydrogen()->right()->representation(); 3895 Representation exponent_type = instr->hydrogen()->right()->representation();
3926 // Having marked this as a call, we can use any registers. 3896 // Having marked this as a call, we can use any registers.
3927 // Just make sure that the input/output registers are the expected ones. 3897 // Just make sure that the input/output registers are the expected ones.
3928 ASSERT(!instr->right()->IsDoubleRegister() || 3898 ASSERT(!instr->right()->IsDoubleRegister() ||
3929 ToDoubleRegister(instr->right()).is(d2)); 3899 ToDoubleRegister(instr->right()).is(d1));
3930 ASSERT(!instr->right()->IsRegister() || 3900 ASSERT(!instr->right()->IsRegister() ||
3931 ToRegister(instr->right()).is(r2)); 3901 ToRegister(instr->right()).is(r2));
3932 ASSERT(ToDoubleRegister(instr->left()).is(d1)); 3902 ASSERT(ToDoubleRegister(instr->left()).is(d0));
3933 ASSERT(ToDoubleRegister(instr->result()).is(d3)); 3903 ASSERT(ToDoubleRegister(instr->result()).is(d2));
3934 3904
3935 if (exponent_type.IsSmi()) { 3905 if (exponent_type.IsSmi()) {
3936 MathPowStub stub(MathPowStub::TAGGED); 3906 MathPowStub stub(MathPowStub::TAGGED);
3937 __ CallStub(&stub); 3907 __ CallStub(&stub);
3938 } else if (exponent_type.IsTagged()) { 3908 } else if (exponent_type.IsTagged()) {
3939 Label no_deopt; 3909 Label no_deopt;
3940 __ JumpIfSmi(r2, &no_deopt); 3910 __ JumpIfSmi(r2, &no_deopt);
3941 __ ldr(r6, FieldMemOperand(r2, HeapObject::kMapOffset)); 3911 __ ldr(r6, FieldMemOperand(r2, HeapObject::kMapOffset));
3942 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 3912 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
3943 __ cmp(r6, Operand(ip)); 3913 __ cmp(r6, Operand(ip));
(...skipping 30 matching lines...) Expand all
3974 ASSERT(ToDoubleRegister(instr->result()).is(d2)); 3944 ASSERT(ToDoubleRegister(instr->result()).is(d2));
3975 // Set the context register to a GC-safe fake value. Clobbering it is 3945 // Set the context register to a GC-safe fake value. Clobbering it is
3976 // OK because this instruction is marked as a call. 3946 // OK because this instruction is marked as a call.
3977 __ mov(cp, Operand::Zero()); 3947 __ mov(cp, Operand::Zero());
3978 TranscendentalCacheStub stub(TranscendentalCache::LOG, 3948 TranscendentalCacheStub stub(TranscendentalCache::LOG,
3979 TranscendentalCacheStub::UNTAGGED); 3949 TranscendentalCacheStub::UNTAGGED);
3980 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 3950 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3981 } 3951 }
3982 3952
3983 3953
3984 void LCodeGen::DoMathTan(LMathTan* instr) {
3985 ASSERT(ToDoubleRegister(instr->result()).is(d2));
3986 // Set the context register to a GC-safe fake value. Clobbering it is
3987 // OK because this instruction is marked as a call.
3988 __ mov(cp, Operand::Zero());
3989 TranscendentalCacheStub stub(TranscendentalCache::TAN,
3990 TranscendentalCacheStub::UNTAGGED);
3991 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3992 }
3993
3994
3995 void LCodeGen::DoMathCos(LMathCos* instr) {
3996 ASSERT(ToDoubleRegister(instr->result()).is(d2));
3997 // Set the context register to a GC-safe fake value. Clobbering it is
3998 // OK because this instruction is marked as a call.
3999 __ mov(cp, Operand::Zero());
4000 TranscendentalCacheStub stub(TranscendentalCache::COS,
4001 TranscendentalCacheStub::UNTAGGED);
4002 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4003 }
4004
4005
4006 void LCodeGen::DoMathSin(LMathSin* instr) {
4007 ASSERT(ToDoubleRegister(instr->result()).is(d2));
4008 // Set the context register to a GC-safe fake value. Clobbering it is
4009 // OK because this instruction is marked as a call.
4010 __ mov(cp, Operand::Zero());
4011 TranscendentalCacheStub stub(TranscendentalCache::SIN,
4012 TranscendentalCacheStub::UNTAGGED);
4013 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4014 }
4015
4016
4017 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { 3954 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
4018 ASSERT(ToRegister(instr->context()).is(cp)); 3955 ASSERT(ToRegister(instr->context()).is(cp));
4019 ASSERT(ToRegister(instr->function()).is(r1)); 3956 ASSERT(ToRegister(instr->function()).is(r1));
4020 ASSERT(instr->HasPointerMap()); 3957 ASSERT(instr->HasPointerMap());
4021 3958
4022 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); 3959 Handle<JSFunction> known_function = instr->hydrogen()->known_function();
4023 if (known_function.is_null()) { 3960 if (known_function.is_null()) {
4024 LPointerMap* pointers = instr->pointer_map(); 3961 LPointerMap* pointers = instr->pointer_map();
4025 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); 3962 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
4026 ParameterCount count(instr->arity()); 3963 ParameterCount count(instr->arity());
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
4169 Register code_object = ToRegister(instr->code_object()); 4106 Register code_object = ToRegister(instr->code_object());
4170 __ add(code_object, code_object, Operand(Code::kHeaderSize - kHeapObjectTag)); 4107 __ add(code_object, code_object, Operand(Code::kHeaderSize - kHeapObjectTag));
4171 __ str(code_object, 4108 __ str(code_object,
4172 FieldMemOperand(function, JSFunction::kCodeEntryOffset)); 4109 FieldMemOperand(function, JSFunction::kCodeEntryOffset));
4173 } 4110 }
4174 4111
4175 4112
4176 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { 4113 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
4177 Register result = ToRegister(instr->result()); 4114 Register result = ToRegister(instr->result());
4178 Register base = ToRegister(instr->base_object()); 4115 Register base = ToRegister(instr->base_object());
4179 __ add(result, base, Operand(instr->offset())); 4116 if (instr->offset()->IsConstantOperand()) {
4117 LConstantOperand* offset = LConstantOperand::cast(instr->offset());
4118 __ add(result, base, Operand(ToInteger32(offset)));
4119 } else {
4120 Register offset = ToRegister(instr->offset());
4121 __ add(result, base, offset);
4122 }
4180 } 4123 }
4181 4124
4182 4125
4183 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { 4126 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
4184 Representation representation = instr->representation(); 4127 Representation representation = instr->representation();
4185 4128
4186 Register object = ToRegister(instr->object()); 4129 Register object = ToRegister(instr->object());
4187 Register scratch = scratch0(); 4130 Register scratch = scratch0();
4188 HObjectAccess access = instr->hydrogen()->access(); 4131 HObjectAccess access = instr->hydrogen()->access();
4189 int offset = access.offset(); 4132 int offset = access.offset();
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after
4688 } else { 4631 } else {
4689 __ vmov(single_scratch, ToRegister(input)); 4632 __ vmov(single_scratch, ToRegister(input));
4690 } 4633 }
4691 __ vcvt_f64_s32(ToDoubleRegister(output), single_scratch); 4634 __ vcvt_f64_s32(ToDoubleRegister(output), single_scratch);
4692 } 4635 }
4693 4636
4694 4637
4695 void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) { 4638 void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) {
4696 LOperand* input = instr->value(); 4639 LOperand* input = instr->value();
4697 LOperand* output = instr->result(); 4640 LOperand* output = instr->result();
4698 __ SmiTag(ToRegister(output), ToRegister(input), SetCC); 4641 ASSERT(output->IsRegister());
4699 if (!instr->hydrogen()->value()->HasRange() || 4642 if (!instr->hydrogen()->value()->HasRange() ||
4700 !instr->hydrogen()->value()->range()->IsInSmiRange()) { 4643 !instr->hydrogen()->value()->range()->IsInSmiRange()) {
4644 __ SmiTag(ToRegister(output), ToRegister(input), SetCC);
4701 DeoptimizeIf(vs, instr->environment()); 4645 DeoptimizeIf(vs, instr->environment());
4646 } else {
4647 __ SmiTag(ToRegister(output), ToRegister(input));
4702 } 4648 }
4703 } 4649 }
4704 4650
4705 4651
4706 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { 4652 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4707 LOperand* input = instr->value(); 4653 LOperand* input = instr->value();
4708 LOperand* output = instr->result(); 4654 LOperand* output = instr->result();
4709 4655
4710 SwVfpRegister flt_scratch = double_scratch0().low(); 4656 SwVfpRegister flt_scratch = double_scratch0().low();
4711 __ vmov(flt_scratch, ToRegister(input)); 4657 __ vmov(flt_scratch, ToRegister(input));
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
4758 virtual void Generate() V8_OVERRIDE { 4704 virtual void Generate() V8_OVERRIDE {
4759 codegen()->DoDeferredNumberTagI(instr_, 4705 codegen()->DoDeferredNumberTagI(instr_,
4760 instr_->value(), 4706 instr_->value(),
4761 UNSIGNED_INT32); 4707 UNSIGNED_INT32);
4762 } 4708 }
4763 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } 4709 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4764 private: 4710 private:
4765 LNumberTagU* instr_; 4711 LNumberTagU* instr_;
4766 }; 4712 };
4767 4713
4768 LOperand* input = instr->value(); 4714 Register input = ToRegister(instr->value());
4769 ASSERT(input->IsRegister() && input->Equals(instr->result())); 4715 Register result = ToRegister(instr->result());
4770 Register reg = ToRegister(input);
4771 4716
4772 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); 4717 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
4773 __ cmp(reg, Operand(Smi::kMaxValue)); 4718 __ cmp(input, Operand(Smi::kMaxValue));
4774 __ b(hi, deferred->entry()); 4719 __ b(hi, deferred->entry());
4775 __ SmiTag(reg, reg); 4720 __ SmiTag(result, input);
4776 __ bind(deferred->exit()); 4721 __ bind(deferred->exit());
4777 } 4722 }
4778 4723
4779 4724
4780 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, 4725 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
4781 LOperand* value, 4726 LOperand* value,
4782 IntegerSignedness signedness) { 4727 IntegerSignedness signedness) {
4783 Label slow; 4728 Label slow;
4784 Register src = ToRegister(value); 4729 Register src = ToRegister(value);
4785 Register dst = ToRegister(instr->result()); 4730 Register dst = ToRegister(instr->result());
(...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after
5550 5495
5551 5496
5552 Condition LCodeGen::EmitTypeofIs(Label* true_label, 5497 Condition LCodeGen::EmitTypeofIs(Label* true_label,
5553 Label* false_label, 5498 Label* false_label,
5554 Register input, 5499 Register input,
5555 Handle<String> type_name) { 5500 Handle<String> type_name) {
5556 Condition final_branch_condition = kNoCondition; 5501 Condition final_branch_condition = kNoCondition;
5557 Register scratch = scratch0(); 5502 Register scratch = scratch0();
5558 if (type_name->Equals(heap()->number_string())) { 5503 if (type_name->Equals(heap()->number_string())) {
5559 __ JumpIfSmi(input, true_label); 5504 __ JumpIfSmi(input, true_label);
5560 __ ldr(input, FieldMemOperand(input, HeapObject::kMapOffset)); 5505 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
5561 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 5506 __ CompareRoot(scratch, Heap::kHeapNumberMapRootIndex);
5562 __ cmp(input, Operand(ip));
5563 final_branch_condition = eq; 5507 final_branch_condition = eq;
5564 5508
5565 } else if (type_name->Equals(heap()->string_string())) { 5509 } else if (type_name->Equals(heap()->string_string())) {
5566 __ JumpIfSmi(input, false_label); 5510 __ JumpIfSmi(input, false_label);
5567 __ CompareObjectType(input, input, scratch, FIRST_NONSTRING_TYPE); 5511 __ CompareObjectType(input, scratch, no_reg, FIRST_NONSTRING_TYPE);
5568 __ b(ge, false_label); 5512 __ b(ge, false_label);
5569 __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset)); 5513 __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset));
5570 __ tst(ip, Operand(1 << Map::kIsUndetectable)); 5514 __ tst(scratch, Operand(1 << Map::kIsUndetectable));
5571 final_branch_condition = eq; 5515 final_branch_condition = eq;
5572 5516
5573 } else if (type_name->Equals(heap()->symbol_string())) { 5517 } else if (type_name->Equals(heap()->symbol_string())) {
5574 __ JumpIfSmi(input, false_label); 5518 __ JumpIfSmi(input, false_label);
5575 __ CompareObjectType(input, input, scratch, SYMBOL_TYPE); 5519 __ CompareObjectType(input, scratch, no_reg, SYMBOL_TYPE);
5576 final_branch_condition = eq; 5520 final_branch_condition = eq;
5577 5521
5578 } else if (type_name->Equals(heap()->boolean_string())) { 5522 } else if (type_name->Equals(heap()->boolean_string())) {
5579 __ CompareRoot(input, Heap::kTrueValueRootIndex); 5523 __ CompareRoot(input, Heap::kTrueValueRootIndex);
5580 __ b(eq, true_label); 5524 __ b(eq, true_label);
5581 __ CompareRoot(input, Heap::kFalseValueRootIndex); 5525 __ CompareRoot(input, Heap::kFalseValueRootIndex);
5582 final_branch_condition = eq; 5526 final_branch_condition = eq;
5583 5527
5584 } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_string())) { 5528 } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_string())) {
5585 __ CompareRoot(input, Heap::kNullValueRootIndex); 5529 __ CompareRoot(input, Heap::kNullValueRootIndex);
5586 final_branch_condition = eq; 5530 final_branch_condition = eq;
5587 5531
5588 } else if (type_name->Equals(heap()->undefined_string())) { 5532 } else if (type_name->Equals(heap()->undefined_string())) {
5589 __ CompareRoot(input, Heap::kUndefinedValueRootIndex); 5533 __ CompareRoot(input, Heap::kUndefinedValueRootIndex);
5590 __ b(eq, true_label); 5534 __ b(eq, true_label);
5591 __ JumpIfSmi(input, false_label); 5535 __ JumpIfSmi(input, false_label);
5592 // Check for undetectable objects => true. 5536 // Check for undetectable objects => true.
5593 __ ldr(input, FieldMemOperand(input, HeapObject::kMapOffset)); 5537 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
5594 __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset)); 5538 __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset));
5595 __ tst(ip, Operand(1 << Map::kIsUndetectable)); 5539 __ tst(scratch, Operand(1 << Map::kIsUndetectable));
5596 final_branch_condition = ne; 5540 final_branch_condition = ne;
5597 5541
5598 } else if (type_name->Equals(heap()->function_string())) { 5542 } else if (type_name->Equals(heap()->function_string())) {
5599 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); 5543 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
5544 Register type_reg = scratch;
5600 __ JumpIfSmi(input, false_label); 5545 __ JumpIfSmi(input, false_label);
5601 __ CompareObjectType(input, scratch, input, JS_FUNCTION_TYPE); 5546 __ CompareObjectType(input, scratch, type_reg, JS_FUNCTION_TYPE);
5602 __ b(eq, true_label); 5547 __ b(eq, true_label);
5603 __ cmp(input, Operand(JS_FUNCTION_PROXY_TYPE)); 5548 __ cmp(type_reg, Operand(JS_FUNCTION_PROXY_TYPE));
5604 final_branch_condition = eq; 5549 final_branch_condition = eq;
5605 5550
5606 } else if (type_name->Equals(heap()->object_string())) { 5551 } else if (type_name->Equals(heap()->object_string())) {
5552 Register map = scratch;
5607 __ JumpIfSmi(input, false_label); 5553 __ JumpIfSmi(input, false_label);
5608 if (!FLAG_harmony_typeof) { 5554 if (!FLAG_harmony_typeof) {
5609 __ CompareRoot(input, Heap::kNullValueRootIndex); 5555 __ CompareRoot(input, Heap::kNullValueRootIndex);
5610 __ b(eq, true_label); 5556 __ b(eq, true_label);
5611 } 5557 }
5612 __ CompareObjectType(input, input, scratch, 5558 __ CheckObjectTypeRange(input,
5613 FIRST_NONCALLABLE_SPEC_OBJECT_TYPE); 5559 map,
5614 __ b(lt, false_label); 5560 FIRST_NONCALLABLE_SPEC_OBJECT_TYPE,
5615 __ CompareInstanceType(input, scratch, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); 5561 LAST_NONCALLABLE_SPEC_OBJECT_TYPE,
5616 __ b(gt, false_label); 5562 false_label);
5617 // Check for undetectable objects => false. 5563 // Check for undetectable objects => false.
5618 __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset)); 5564 __ ldrb(scratch, FieldMemOperand(map, Map::kBitFieldOffset));
5619 __ tst(ip, Operand(1 << Map::kIsUndetectable)); 5565 __ tst(scratch, Operand(1 << Map::kIsUndetectable));
5620 final_branch_condition = eq; 5566 final_branch_condition = eq;
5621 5567
5622 } else { 5568 } else {
5623 __ b(false_label); 5569 __ b(false_label);
5624 } 5570 }
5625 5571
5626 return final_branch_condition; 5572 return final_branch_condition;
5627 } 5573 }
5628 5574
5629 5575
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
5878 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); 5824 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index));
5879 __ ldr(result, FieldMemOperand(scratch, 5825 __ ldr(result, FieldMemOperand(scratch,
5880 FixedArray::kHeaderSize - kPointerSize)); 5826 FixedArray::kHeaderSize - kPointerSize));
5881 __ bind(&done); 5827 __ bind(&done);
5882 } 5828 }
5883 5829
5884 5830
5885 #undef __ 5831 #undef __
5886 5832
5887 } } // namespace v8::internal 5833 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698