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

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

Issue 6066010: Merge 6095:6198 from bleeding_edge to experimental/gc. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 11 months 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/ast.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 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 580 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 current_block_ = label->block_id(); 591 current_block_ = label->block_id();
592 LCodeGen::DoGap(label); 592 LCodeGen::DoGap(label);
593 } 593 }
594 594
595 595
596 void LCodeGen::DoParallelMove(LParallelMove* move) { 596 void LCodeGen::DoParallelMove(LParallelMove* move) {
597 // d0 must always be a scratch register. 597 // d0 must always be a scratch register.
598 DoubleRegister dbl_scratch = d0; 598 DoubleRegister dbl_scratch = d0;
599 LUnallocated marker_operand(LUnallocated::NONE); 599 LUnallocated marker_operand(LUnallocated::NONE);
600 600
601 Register core_scratch = r9; 601 Register core_scratch = scratch0();
602 bool destroys_core_scratch = false; 602 bool destroys_core_scratch = false;
603 603
604 LGapResolver resolver(move->move_operands(), &marker_operand); 604 LGapResolver resolver(move->move_operands(), &marker_operand);
605 const ZoneList<LMoveOperands>* moves = resolver.ResolveInReverseOrder(); 605 const ZoneList<LMoveOperands>* moves = resolver.ResolveInReverseOrder();
606 for (int i = moves->length() - 1; i >= 0; --i) { 606 for (int i = moves->length() - 1; i >= 0; --i) {
607 LMoveOperands move = moves->at(i); 607 LMoveOperands move = moves->at(i);
608 LOperand* from = move.from(); 608 LOperand* from = move.from();
609 LOperand* to = move.to(); 609 LOperand* to = move.to();
610 ASSERT(!from->IsDoubleRegister() || 610 ASSERT(!from->IsDoubleRegister() ||
611 !ToDoubleRegister(from).is(dbl_scratch)); 611 !ToDoubleRegister(from).is(dbl_scratch));
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
723 } 723 }
724 } 724 }
725 725
726 726
727 void LCodeGen::DoParameter(LParameter* instr) { 727 void LCodeGen::DoParameter(LParameter* instr) {
728 // Nothing to do. 728 // Nothing to do.
729 } 729 }
730 730
731 731
732 void LCodeGen::DoCallStub(LCallStub* instr) { 732 void LCodeGen::DoCallStub(LCallStub* instr) {
733 Abort("DoCallStub unimplemented."); 733 ASSERT(ToRegister(instr->result()).is(r0));
734 switch (instr->hydrogen()->major_key()) {
735 case CodeStub::RegExpConstructResult: {
736 RegExpConstructResultStub stub;
737 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
738 break;
739 }
740 case CodeStub::RegExpExec: {
741 RegExpExecStub stub;
742 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
743 break;
744 }
745 case CodeStub::SubString: {
746 SubStringStub stub;
747 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
748 break;
749 }
750 case CodeStub::StringCharAt: {
751 Abort("StringCharAtStub unimplemented.");
752 break;
753 }
754 case CodeStub::MathPow: {
755 Abort("MathPowStub unimplemented.");
756 break;
757 }
758 case CodeStub::NumberToString: {
759 NumberToStringStub stub;
760 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
761 break;
762 }
763 case CodeStub::StringAdd: {
764 StringAddStub stub(NO_STRING_ADD_FLAGS);
765 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
766 break;
767 }
768 case CodeStub::StringCompare: {
769 StringCompareStub stub;
770 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
771 break;
772 }
773 case CodeStub::TranscendentalCache: {
774 Abort("TranscendentalCache unimplemented.");
775 break;
776 }
777 default:
778 UNREACHABLE();
779 }
734 } 780 }
735 781
736 782
737 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 783 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
738 // Nothing to do. 784 // Nothing to do.
739 } 785 }
740 786
741 787
742 void LCodeGen::DoModI(LModI* instr) { 788 void LCodeGen::DoModI(LModI* instr) {
743 Abort("DoModI unimplemented."); 789 Abort("DoModI unimplemented.");
744 } 790 }
745 791
746 792
747 void LCodeGen::DoDivI(LDivI* instr) { 793 void LCodeGen::DoDivI(LDivI* instr) {
748 Abort("DoDivI unimplemented."); 794 Abort("DoDivI unimplemented.");
749 } 795 }
750 796
751 797
752 void LCodeGen::DoMulI(LMulI* instr) { 798 void LCodeGen::DoMulI(LMulI* instr) {
799 Register scratch = scratch0();
753 Register left = ToRegister(instr->left()); 800 Register left = ToRegister(instr->left());
754 Register scratch = r9;
755 Register right = EmitLoadRegister(instr->right(), scratch); 801 Register right = EmitLoadRegister(instr->right(), scratch);
756 802
757 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero) && 803 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero) &&
758 !instr->right()->IsConstantOperand()) { 804 !instr->right()->IsConstantOperand()) {
759 __ orr(ToRegister(instr->temp()), left, right); 805 __ orr(ToRegister(instr->temp()), left, right);
760 } 806 }
761 807
762 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 808 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
763 // scratch:left = left * right. 809 // scratch:left = left * right.
764 __ smull(scratch, left, left, right); 810 __ smull(scratch, left, left, right);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 __ eor(result, ToRegister(left), Operand(right_reg)); 852 __ eor(result, ToRegister(left), Operand(right_reg));
807 break; 853 break;
808 default: 854 default:
809 UNREACHABLE(); 855 UNREACHABLE();
810 break; 856 break;
811 } 857 }
812 } 858 }
813 859
814 860
815 void LCodeGen::DoShiftI(LShiftI* instr) { 861 void LCodeGen::DoShiftI(LShiftI* instr) {
862 Register scratch = scratch0();
816 LOperand* left = instr->left(); 863 LOperand* left = instr->left();
817 LOperand* right = instr->right(); 864 LOperand* right = instr->right();
818 ASSERT(left->Equals(instr->result())); 865 ASSERT(left->Equals(instr->result()));
819 ASSERT(left->IsRegister()); 866 ASSERT(left->IsRegister());
820 Register result = ToRegister(left); 867 Register result = ToRegister(left);
821 if (right->IsRegister()) { 868 if (right->IsRegister()) {
822 // Mask the right operand. 869 // Mask the right operand.
823 __ and_(r9, ToRegister(right), Operand(0x1F)); 870 __ and_(scratch, ToRegister(right), Operand(0x1F));
824 switch (instr->op()) { 871 switch (instr->op()) {
825 case Token::SAR: 872 case Token::SAR:
826 __ mov(result, Operand(result, ASR, r9)); 873 __ mov(result, Operand(result, ASR, scratch));
827 break; 874 break;
828 case Token::SHR: 875 case Token::SHR:
829 if (instr->can_deopt()) { 876 if (instr->can_deopt()) {
830 __ mov(result, Operand(result, LSR, r9), SetCC); 877 __ mov(result, Operand(result, LSR, scratch), SetCC);
831 DeoptimizeIf(mi, instr->environment()); 878 DeoptimizeIf(mi, instr->environment());
832 } else { 879 } else {
833 __ mov(result, Operand(result, LSR, r9)); 880 __ mov(result, Operand(result, LSR, scratch));
834 } 881 }
835 break; 882 break;
836 case Token::SHL: 883 case Token::SHL:
837 __ mov(result, Operand(result, LSL, r9)); 884 __ mov(result, Operand(result, LSL, scratch));
838 break; 885 break;
839 default: 886 default:
840 UNREACHABLE(); 887 UNREACHABLE();
841 break; 888 break;
842 } 889 }
843 } else { 890 } else {
844 int value = ToInteger32(LConstantOperand::cast(right)); 891 int value = ToInteger32(LConstantOperand::cast(right));
845 uint8_t shift_count = static_cast<uint8_t>(value & 0x1F); 892 uint8_t shift_count = static_cast<uint8_t>(value & 0x1F);
846 switch (instr->op()) { 893 switch (instr->op()) {
847 case Token::SAR: 894 case Token::SAR:
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 Abort("DoConstantD unimplemented."); 938 Abort("DoConstantD unimplemented.");
892 } 939 }
893 940
894 941
895 void LCodeGen::DoConstantT(LConstantT* instr) { 942 void LCodeGen::DoConstantT(LConstantT* instr) {
896 ASSERT(instr->result()->IsRegister()); 943 ASSERT(instr->result()->IsRegister());
897 __ mov(ToRegister(instr->result()), Operand(instr->value())); 944 __ mov(ToRegister(instr->result()), Operand(instr->value()));
898 } 945 }
899 946
900 947
901 void LCodeGen::DoArrayLength(LArrayLength* instr) { 948 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
902 Register result = ToRegister(instr->result()); 949 Register result = ToRegister(instr->result());
903 950 Register array = ToRegister(instr->input());
904 if (instr->hydrogen()->value()->IsLoadElements()) { 951 __ ldr(result, FieldMemOperand(array, JSArray::kLengthOffset));
905 // We load the length directly from the elements array.
906 Register elements = ToRegister(instr->input());
907 __ ldr(result, FieldMemOperand(elements, FixedArray::kLengthOffset));
908 } else {
909 // Check that the receiver really is an array.
910 Register array = ToRegister(instr->input());
911 Register temporary = ToRegister(instr->temporary());
912 __ CompareObjectType(array, temporary, temporary, JS_ARRAY_TYPE);
913 DeoptimizeIf(ne, instr->environment());
914
915 // Load length directly from the array.
916 __ ldr(result, FieldMemOperand(array, JSArray::kLengthOffset));
917 }
918 Abort("DoArrayLength untested.");
919 } 952 }
920 953
921 954
955 void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) {
956 Register result = ToRegister(instr->result());
957 Register array = ToRegister(instr->input());
958 __ ldr(result, FieldMemOperand(array, FixedArray::kLengthOffset));
959 Abort("DoFixedArrayLength untested.");
960 }
961
962
922 void LCodeGen::DoValueOf(LValueOf* instr) { 963 void LCodeGen::DoValueOf(LValueOf* instr) {
923 Abort("DoValueOf unimplemented."); 964 Abort("DoValueOf unimplemented.");
924 } 965 }
925 966
926 967
927 void LCodeGen::DoBitNotI(LBitNotI* instr) { 968 void LCodeGen::DoBitNotI(LBitNotI* instr) {
928 LOperand* input = instr->input(); 969 LOperand* input = instr->input();
929 ASSERT(input->Equals(instr->result())); 970 ASSERT(input->Equals(instr->result()));
930 __ mvn(ToRegister(input), Operand(ToRegister(input))); 971 __ mvn(ToRegister(input), Operand(ToRegister(input)));
931 Abort("DoBitNotI untested."); 972 Abort("DoBitNotI untested.");
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1058 __ cmp(reg, ip); 1099 __ cmp(reg, ip);
1059 __ b(eq, false_label); 1100 __ b(eq, false_label);
1060 __ cmp(reg, Operand(0)); 1101 __ cmp(reg, Operand(0));
1061 __ b(eq, false_label); 1102 __ b(eq, false_label);
1062 __ tst(reg, Operand(kSmiTagMask)); 1103 __ tst(reg, Operand(kSmiTagMask));
1063 __ b(eq, true_label); 1104 __ b(eq, true_label);
1064 1105
1065 // Test for double values. Zero is false. 1106 // Test for double values. Zero is false.
1066 Label call_stub; 1107 Label call_stub;
1067 DoubleRegister dbl_scratch = d0; 1108 DoubleRegister dbl_scratch = d0;
1068 Register core_scratch = r9; 1109 Register scratch = scratch0();
1069 ASSERT(!reg.is(core_scratch)); 1110 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset));
1070 __ ldr(core_scratch, FieldMemOperand(reg, HeapObject::kMapOffset));
1071 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 1111 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
1072 __ cmp(core_scratch, Operand(ip)); 1112 __ cmp(scratch, Operand(ip));
1073 __ b(ne, &call_stub); 1113 __ b(ne, &call_stub);
1074 __ sub(ip, reg, Operand(kHeapObjectTag)); 1114 __ sub(ip, reg, Operand(kHeapObjectTag));
1075 __ vldr(dbl_scratch, ip, HeapNumber::kValueOffset); 1115 __ vldr(dbl_scratch, ip, HeapNumber::kValueOffset);
1076 __ vcmp(dbl_scratch, 0.0); 1116 __ vcmp(dbl_scratch, 0.0);
1077 __ b(eq, false_label); 1117 __ b(eq, false_label);
1078 __ b(true_label); 1118 __ b(true_label);
1079 1119
1080 // The conversion stub doesn't cause garbage collections so it's 1120 // The conversion stub doesn't cause garbage collections so it's
1081 // safe to not record a safepoint after the call. 1121 // safe to not record a safepoint after the call.
1082 __ bind(&call_stub); 1122 __ bind(&call_stub);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1169 Abort("DoCmpJSObjectEq untested."); 1209 Abort("DoCmpJSObjectEq untested.");
1170 } 1210 }
1171 1211
1172 1212
1173 void LCodeGen::DoCmpJSObjectEqAndBranch(LCmpJSObjectEqAndBranch* instr) { 1213 void LCodeGen::DoCmpJSObjectEqAndBranch(LCmpJSObjectEqAndBranch* instr) {
1174 Abort("DoCmpJSObjectEqAndBranch unimplemented."); 1214 Abort("DoCmpJSObjectEqAndBranch unimplemented.");
1175 } 1215 }
1176 1216
1177 1217
1178 void LCodeGen::DoIsNull(LIsNull* instr) { 1218 void LCodeGen::DoIsNull(LIsNull* instr) {
1179 Abort("DoIsNull unimplemented."); 1219 Register reg = ToRegister(instr->input());
1220 Register result = ToRegister(instr->result());
1221
1222 __ LoadRoot(ip, Heap::kNullValueRootIndex);
1223 __ cmp(reg, ip);
1224 if (instr->is_strict()) {
1225 __ LoadRoot(result, Heap::kTrueValueRootIndex, eq);
1226 __ LoadRoot(result, Heap::kFalseValueRootIndex, ne);
1227 } else {
1228 Label true_value, false_value, done;
1229 __ b(eq, &true_value);
1230 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
1231 __ cmp(ip, reg);
1232 __ b(eq, &true_value);
1233 __ tst(reg, Operand(kSmiTagMask));
1234 __ b(eq, &false_value);
1235 // Check for undetectable objects by looking in the bit field in
1236 // the map. The object has already been smi checked.
1237 Register scratch = result;
1238 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset));
1239 __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset));
1240 __ tst(scratch, Operand(1 << Map::kIsUndetectable));
1241 __ b(ne, &true_value);
1242 __ bind(&false_value);
1243 __ LoadRoot(result, Heap::kFalseValueRootIndex);
1244 __ jmp(&done);
1245 __ bind(&true_value);
1246 __ LoadRoot(result, Heap::kTrueValueRootIndex);
1247 __ bind(&done);
1248 }
1180 } 1249 }
1181 1250
1182 1251
1183 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) { 1252 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) {
1253 Register scratch = scratch0();
1184 Register reg = ToRegister(instr->input()); 1254 Register reg = ToRegister(instr->input());
1185 1255
1186 // TODO(fsc): If the expression is known to be a smi, then it's 1256 // TODO(fsc): If the expression is known to be a smi, then it's
1187 // definitely not null. Jump to the false block. 1257 // definitely not null. Jump to the false block.
1188 1258
1189 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1259 int true_block = chunk_->LookupDestination(instr->true_block_id());
1190 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1260 int false_block = chunk_->LookupDestination(instr->false_block_id());
1191 1261
1192 __ LoadRoot(ip, Heap::kNullValueRootIndex); 1262 __ LoadRoot(ip, Heap::kNullValueRootIndex);
1193 __ cmp(reg, ip); 1263 __ cmp(reg, ip);
1194 if (instr->is_strict()) { 1264 if (instr->is_strict()) {
1195 EmitBranch(true_block, false_block, eq); 1265 EmitBranch(true_block, false_block, eq);
1196 } else { 1266 } else {
1197 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1267 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1198 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1268 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1199 __ b(eq, true_label); 1269 __ b(eq, true_label);
1200 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 1270 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
1201 __ cmp(reg, ip); 1271 __ cmp(reg, ip);
1202 __ b(eq, true_label); 1272 __ b(eq, true_label);
1203 __ tst(reg, Operand(kSmiTagMask)); 1273 __ tst(reg, Operand(kSmiTagMask));
1204 __ b(eq, false_label); 1274 __ b(eq, false_label);
1205 // Check for undetectable objects by looking in the bit field in 1275 // Check for undetectable objects by looking in the bit field in
1206 // the map. The object has already been smi checked. 1276 // the map. The object has already been smi checked.
1207 Register scratch = ToRegister(instr->temp());
1208 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); 1277 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset));
1209 __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset)); 1278 __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset));
1210 __ tst(scratch, Operand(1 << Map::kIsUndetectable)); 1279 __ tst(scratch, Operand(1 << Map::kIsUndetectable));
1211 EmitBranch(true_block, false_block, ne); 1280 EmitBranch(true_block, false_block, ne);
1212 } 1281 }
1213 } 1282 }
1214 1283
1215 1284
1216 Condition LCodeGen::EmitIsObject(Register input, 1285 Condition LCodeGen::EmitIsObject(Register input,
1217 Register temp1, 1286 Register temp1,
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1275 return eq; 1344 return eq;
1276 } 1345 }
1277 1346
1278 1347
1279 void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) { 1348 void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) {
1280 Abort("DoHasInstanceType unimplemented."); 1349 Abort("DoHasInstanceType unimplemented.");
1281 } 1350 }
1282 1351
1283 1352
1284 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { 1353 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
1354 Register scratch = scratch0();
1285 Register input = ToRegister(instr->input()); 1355 Register input = ToRegister(instr->input());
1286 Register temp = ToRegister(instr->temp());
1287 1356
1288 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1357 int true_block = chunk_->LookupDestination(instr->true_block_id());
1289 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1358 int false_block = chunk_->LookupDestination(instr->false_block_id());
1290 1359
1291 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1360 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1292 1361
1293 __ tst(input, Operand(kSmiTagMask)); 1362 __ tst(input, Operand(kSmiTagMask));
1294 __ b(eq, false_label); 1363 __ b(eq, false_label);
1295 1364
1296 __ CompareObjectType(input, temp, temp, instr->TestType()); 1365 __ CompareObjectType(input, scratch, scratch, instr->TestType());
1297 EmitBranch(true_block, false_block, instr->BranchCondition()); 1366 EmitBranch(true_block, false_block, instr->BranchCondition());
1298 } 1367 }
1299 1368
1300 1369
1301 void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) { 1370 void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) {
1302 Abort("DoHasCachedArrayIndex unimplemented."); 1371 Abort("DoHasCachedArrayIndex unimplemented.");
1303 } 1372 }
1304 1373
1305 1374
1306 void LCodeGen::DoHasCachedArrayIndexAndBranch( 1375 void LCodeGen::DoHasCachedArrayIndexAndBranch(
(...skipping 18 matching lines...) Expand all
1325 Abort("DoClassOfTest unimplemented."); 1394 Abort("DoClassOfTest unimplemented.");
1326 } 1395 }
1327 1396
1328 1397
1329 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 1398 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
1330 Abort("DoClassOfTestAndBranch unimplemented."); 1399 Abort("DoClassOfTestAndBranch unimplemented.");
1331 } 1400 }
1332 1401
1333 1402
1334 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { 1403 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
1335 Abort("DoCmpMapAndBranch unimplemented."); 1404 Register reg = ToRegister(instr->input());
1405 Register temp = ToRegister(instr->temp());
1406 int true_block = instr->true_block_id();
1407 int false_block = instr->false_block_id();
1408
1409 __ ldr(temp, FieldMemOperand(reg, HeapObject::kMapOffset));
1410 __ cmp(temp, Operand(instr->map()));
1411 EmitBranch(true_block, false_block, eq);
1336 } 1412 }
1337 1413
1338 1414
1339 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { 1415 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
1340 // We expect object and function in registers r1 and r0. 1416 ASSERT(ToRegister(instr->left()).is(r0)); // Object is in r0.
1417 ASSERT(ToRegister(instr->right()).is(r1)); // Function is in r1.
1418
1341 InstanceofStub stub(InstanceofStub::kArgsInRegisters); 1419 InstanceofStub stub(InstanceofStub::kArgsInRegisters);
1342 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 1420 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1343 1421
1344 Label true_value, done; 1422 Label true_value, done;
1345 __ tst(r0, r0); 1423 __ tst(r0, r0);
1346 __ mov(r0, Operand(Factory::false_value()), LeaveCC, eq); 1424 __ mov(r0, Operand(Factory::false_value()), LeaveCC, ne);
1347 __ mov(r0, Operand(Factory::true_value()), LeaveCC, ne); 1425 __ mov(r0, Operand(Factory::true_value()), LeaveCC, eq);
1348 } 1426 }
1349 1427
1350 1428
1351 void LCodeGen::DoInstanceOfAndBranch(LInstanceOfAndBranch* instr) { 1429 void LCodeGen::DoInstanceOfAndBranch(LInstanceOfAndBranch* instr) {
1352 Abort("DoInstanceOfAndBranch unimplemented."); 1430 Abort("DoInstanceOfAndBranch unimplemented.");
1353 } 1431 }
1354 1432
1355 1433
1356 1434
1357 static Condition ComputeCompareCondition(Token::Value op) { 1435 static Condition ComputeCompareCondition(Token::Value op) {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1425 1503
1426 1504
1427 void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) { 1505 void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) {
1428 Register value = ToRegister(instr->input()); 1506 Register value = ToRegister(instr->input());
1429 __ mov(ip, Operand(Handle<Object>(instr->hydrogen()->cell()))); 1507 __ mov(ip, Operand(Handle<Object>(instr->hydrogen()->cell())));
1430 __ str(value, FieldMemOperand(ip, JSGlobalPropertyCell::kValueOffset)); 1508 __ str(value, FieldMemOperand(ip, JSGlobalPropertyCell::kValueOffset));
1431 } 1509 }
1432 1510
1433 1511
1434 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { 1512 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
1435 Abort("DoLoadNamedField unimplemented."); 1513 Register object = ToRegister(instr->input());
1514 Register result = ToRegister(instr->result());
1515 if (instr->hydrogen()->is_in_object()) {
1516 __ ldr(result, FieldMemOperand(object, instr->hydrogen()->offset()));
1517 } else {
1518 __ ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
1519 __ ldr(result, FieldMemOperand(result, instr->hydrogen()->offset()));
1520 }
1436 } 1521 }
1437 1522
1438 1523
1439 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { 1524 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
1440 ASSERT(ToRegister(instr->object()).is(r0)); 1525 ASSERT(ToRegister(instr->object()).is(r0));
1441 ASSERT(ToRegister(instr->result()).is(r0)); 1526 ASSERT(ToRegister(instr->result()).is(r0));
1442 1527
1443 // Name is always in r2. 1528 // Name is always in r2.
1444 __ mov(r2, Operand(instr->name())); 1529 __ mov(r2, Operand(instr->name()));
1445 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 1530 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1446 CallCode(ic, RelocInfo::CODE_TARGET, instr); 1531 CallCode(ic, RelocInfo::CODE_TARGET, instr);
1447 } 1532 }
1448 1533
1449 1534
1535 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
1536 Register scratch = scratch0();
1537 Register function = ToRegister(instr->function());
1538 Register result = ToRegister(instr->result());
1539
1540 // Check that the function really is a function. Load map into the
1541 // result register.
1542 __ CompareObjectType(function, result, scratch, JS_FUNCTION_TYPE);
1543 DeoptimizeIf(ne, instr->environment());
1544
1545 // Make sure that the function has an instance prototype.
1546 Label non_instance;
1547 __ ldrb(scratch, FieldMemOperand(result, Map::kBitFieldOffset));
1548 __ tst(scratch, Operand(1 << Map::kHasNonInstancePrototype));
1549 __ b(ne, &non_instance);
1550
1551 // Get the prototype or initial map from the function.
1552 __ ldr(result,
1553 FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
1554
1555 // Check that the function has a prototype or an initial map.
1556 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
1557 __ cmp(result, ip);
1558 DeoptimizeIf(eq, instr->environment());
1559
1560 // If the function does not have an initial map, we're done.
1561 Label done;
1562 __ CompareObjectType(result, scratch, scratch, MAP_TYPE);
1563 __ b(ne, &done);
1564
1565 // Get the prototype from the initial map.
1566 __ ldr(result, FieldMemOperand(result, Map::kPrototypeOffset));
1567 __ jmp(&done);
1568
1569 // Non-instance prototype: Fetch prototype from constructor field
1570 // in initial map.
1571 __ bind(&non_instance);
1572 __ ldr(result, FieldMemOperand(result, Map::kConstructorOffset));
1573
1574 // All done.
1575 __ bind(&done);
1576 }
1577
1578
1450 void LCodeGen::DoLoadElements(LLoadElements* instr) { 1579 void LCodeGen::DoLoadElements(LLoadElements* instr) {
1451 Abort("DoLoadElements unimplemented."); 1580 Abort("DoLoadElements unimplemented.");
1452 } 1581 }
1453 1582
1454 1583
1455 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { 1584 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
1456 Abort("DoAccessArgumentsAt unimplemented."); 1585 Abort("DoAccessArgumentsAt unimplemented.");
1457 } 1586 }
1458 1587
1459 1588
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1537 1666
1538 // Setup deoptimization. 1667 // Setup deoptimization.
1539 RegisterLazyDeoptimization(instr); 1668 RegisterLazyDeoptimization(instr);
1540 1669
1541 // Restore context. 1670 // Restore context.
1542 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1671 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1543 } 1672 }
1544 1673
1545 1674
1546 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { 1675 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
1547 Abort("DoCallConstantFunction unimplemented."); 1676 ASSERT(ToRegister(instr->result()).is(r0));
1677 __ mov(r1, Operand(instr->function()));
1678 CallKnownFunction(instr->function(), instr->arity(), instr);
1548 } 1679 }
1549 1680
1550 1681
1551 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { 1682 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
1552 Abort("DoDeferredMathAbsTaggedHeapNumber unimplemented."); 1683 Abort("DoDeferredMathAbsTaggedHeapNumber unimplemented.");
1553 } 1684 }
1554 1685
1555 1686
1556 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { 1687 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
1557 Abort("DoMathAbs unimplemented."); 1688 Abort("DoMathAbs unimplemented.");
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1597 int arity = instr->arity(); 1728 int arity = instr->arity();
1598 Handle<Code> ic = StubCache::ComputeCallInitialize(arity, NOT_IN_LOOP); 1729 Handle<Code> ic = StubCache::ComputeCallInitialize(arity, NOT_IN_LOOP);
1599 __ mov(r2, Operand(instr->name())); 1730 __ mov(r2, Operand(instr->name()));
1600 CallCode(ic, RelocInfo::CODE_TARGET, instr); 1731 CallCode(ic, RelocInfo::CODE_TARGET, instr);
1601 // Restore context register. 1732 // Restore context register.
1602 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1733 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1603 } 1734 }
1604 1735
1605 1736
1606 void LCodeGen::DoCallFunction(LCallFunction* instr) { 1737 void LCodeGen::DoCallFunction(LCallFunction* instr) {
1607 Abort("DoCallFunction unimplemented."); 1738 ASSERT(ToRegister(instr->result()).is(r0));
1739
1740 int arity = instr->arity();
1741 CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_VALUE);
1742 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1743 __ Drop(1);
1744 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1608 } 1745 }
1609 1746
1610 1747
1611 void LCodeGen::DoCallGlobal(LCallGlobal* instr) { 1748 void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
1612 Abort("DoCallGlobal unimplemented."); 1749 Abort("DoCallGlobal unimplemented.");
1613 } 1750 }
1614 1751
1615 1752
1616 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { 1753 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
1617 ASSERT(ToRegister(instr->result()).is(r0)); 1754 ASSERT(ToRegister(instr->result()).is(r0));
(...skipping 27 matching lines...) Expand all
1645 ASSERT(ToRegister(instr->value()).is(r0)); 1782 ASSERT(ToRegister(instr->value()).is(r0));
1646 1783
1647 // Name is always in r2. 1784 // Name is always in r2.
1648 __ mov(r2, Operand(instr->name())); 1785 __ mov(r2, Operand(instr->name()));
1649 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 1786 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
1650 CallCode(ic, RelocInfo::CODE_TARGET, instr); 1787 CallCode(ic, RelocInfo::CODE_TARGET, instr);
1651 } 1788 }
1652 1789
1653 1790
1654 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { 1791 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
1655 Abort("DoBoundsCheck unimplemented."); 1792 __ cmp(ToRegister(instr->index()), ToOperand(instr->length()));
1793 DeoptimizeIf(hs, instr->environment());
1656 } 1794 }
1657 1795
1658 1796
1659 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { 1797 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
1660 Abort("DoStoreKeyedFastElement unimplemented."); 1798 Abort("DoStoreKeyedFastElement unimplemented.");
1661 } 1799 }
1662 1800
1663 1801
1664 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 1802 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
1665 ASSERT(ToRegister(instr->object()).is(r2)); 1803 ASSERT(ToRegister(instr->object()).is(r2));
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1750 class DeferredNumberTagD: public LDeferredCode { 1888 class DeferredNumberTagD: public LDeferredCode {
1751 public: 1889 public:
1752 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 1890 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
1753 : LDeferredCode(codegen), instr_(instr) { } 1891 : LDeferredCode(codegen), instr_(instr) { }
1754 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } 1892 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); }
1755 private: 1893 private:
1756 LNumberTagD* instr_; 1894 LNumberTagD* instr_;
1757 }; 1895 };
1758 1896
1759 DoubleRegister input_reg = ToDoubleRegister(instr->input()); 1897 DoubleRegister input_reg = ToDoubleRegister(instr->input());
1898 Register scratch = scratch0();
1760 Register reg = ToRegister(instr->result()); 1899 Register reg = ToRegister(instr->result());
1761 Register temp1 = ToRegister(instr->temp1()); 1900 Register temp1 = ToRegister(instr->temp1());
1762 Register temp2 = ToRegister(instr->temp2()); 1901 Register temp2 = ToRegister(instr->temp2());
1763 Register scratch = r9;
1764 1902
1765 DeferredNumberTagD* deferred = new DeferredNumberTagD(this, instr); 1903 DeferredNumberTagD* deferred = new DeferredNumberTagD(this, instr);
1766 if (FLAG_inline_new) { 1904 if (FLAG_inline_new) {
1767 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); 1905 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex);
1768 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry()); 1906 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry());
1769 } else { 1907 } else {
1770 __ jmp(deferred->entry()); 1908 __ jmp(deferred->entry());
1771 } 1909 }
1772 __ bind(deferred->exit()); 1910 __ bind(deferred->exit());
1773 __ sub(ip, reg, Operand(kHeapObjectTag)); 1911 __ sub(ip, reg, Operand(kHeapObjectTag));
(...skipping 27 matching lines...) Expand all
1801 1939
1802 1940
1803 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { 1941 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
1804 Abort("DoSmiUntag unimplemented."); 1942 Abort("DoSmiUntag unimplemented.");
1805 } 1943 }
1806 1944
1807 1945
1808 void LCodeGen::EmitNumberUntagD(Register input_reg, 1946 void LCodeGen::EmitNumberUntagD(Register input_reg,
1809 DoubleRegister result_reg, 1947 DoubleRegister result_reg,
1810 LEnvironment* env) { 1948 LEnvironment* env) {
1811 Register core_scratch = r9; 1949 Register scratch = scratch0();
1812 ASSERT(!input_reg.is(core_scratch));
1813 SwVfpRegister flt_scratch = s0; 1950 SwVfpRegister flt_scratch = s0;
1814 ASSERT(!result_reg.is(d0)); 1951 ASSERT(!result_reg.is(d0));
1815 1952
1816 Label load_smi, heap_number, done; 1953 Label load_smi, heap_number, done;
1817 1954
1818 // Smi check. 1955 // Smi check.
1819 __ tst(input_reg, Operand(kSmiTagMask)); 1956 __ tst(input_reg, Operand(kSmiTagMask));
1820 __ b(eq, &load_smi); 1957 __ b(eq, &load_smi);
1821 1958
1822 // Heap number map check. 1959 // Heap number map check.
1823 __ ldr(core_scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 1960 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
1824 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 1961 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
1825 __ cmp(core_scratch, Operand(ip)); 1962 __ cmp(scratch, Operand(ip));
1826 __ b(eq, &heap_number); 1963 __ b(eq, &heap_number);
1827 1964
1828 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 1965 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
1829 __ cmp(input_reg, Operand(ip)); 1966 __ cmp(input_reg, Operand(ip));
1830 DeoptimizeIf(ne, env); 1967 DeoptimizeIf(ne, env);
1831 1968
1832 // Convert undefined to NaN. 1969 // Convert undefined to NaN.
1833 __ LoadRoot(ip, Heap::kNanValueRootIndex); 1970 __ LoadRoot(ip, Heap::kNanValueRootIndex);
1834 __ sub(ip, ip, Operand(kHeapObjectTag)); 1971 __ sub(ip, ip, Operand(kHeapObjectTag));
1835 __ vldr(result_reg, ip, HeapNumber::kValueOffset); 1972 __ vldr(result_reg, ip, HeapNumber::kValueOffset);
(...skipping 21 matching lines...) Expand all
1857 : LDeferredCode(codegen), instr_(instr) { } 1994 : LDeferredCode(codegen), instr_(instr) { }
1858 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } 1995 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); }
1859 private: 1996 private:
1860 LTaggedToI* instr_; 1997 LTaggedToI* instr_;
1861 }; 1998 };
1862 1999
1863 2000
1864 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { 2001 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
1865 Label done; 2002 Label done;
1866 Register input_reg = ToRegister(instr->input()); 2003 Register input_reg = ToRegister(instr->input());
1867 Register core_scratch = r9; 2004 Register scratch = scratch0();
1868 ASSERT(!input_reg.is(core_scratch));
1869 DoubleRegister dbl_scratch = d0; 2005 DoubleRegister dbl_scratch = d0;
1870 SwVfpRegister flt_scratch = s0; 2006 SwVfpRegister flt_scratch = s0;
1871 DoubleRegister dbl_tmp = ToDoubleRegister(instr->temp()); 2007 DoubleRegister dbl_tmp = ToDoubleRegister(instr->temp());
1872 2008
1873 // Heap number map check. 2009 // Heap number map check.
1874 __ ldr(core_scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 2010 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
1875 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 2011 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
1876 __ cmp(core_scratch, Operand(ip)); 2012 __ cmp(scratch, Operand(ip));
1877 2013
1878 if (instr->truncating()) { 2014 if (instr->truncating()) {
1879 Label heap_number; 2015 Label heap_number;
1880 __ b(eq, &heap_number); 2016 __ b(eq, &heap_number);
1881 // Check for undefined. Undefined is converted to zero for truncating 2017 // Check for undefined. Undefined is converted to zero for truncating
1882 // conversions. 2018 // conversions.
1883 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 2019 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
1884 __ cmp(input_reg, Operand(ip)); 2020 __ cmp(input_reg, Operand(ip));
1885 DeoptimizeIf(ne, instr->environment()); 2021 DeoptimizeIf(ne, instr->environment());
1886 __ mov(input_reg, Operand(0)); 2022 __ mov(input_reg, Operand(0));
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1978 2114
1979 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { 2115 void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
1980 ASSERT(instr->input()->IsRegister()); 2116 ASSERT(instr->input()->IsRegister());
1981 Register reg = ToRegister(instr->input()); 2117 Register reg = ToRegister(instr->input());
1982 __ cmp(reg, Operand(instr->hydrogen()->target())); 2118 __ cmp(reg, Operand(instr->hydrogen()->target()));
1983 DeoptimizeIf(ne, instr->environment()); 2119 DeoptimizeIf(ne, instr->environment());
1984 } 2120 }
1985 2121
1986 2122
1987 void LCodeGen::DoCheckMap(LCheckMap* instr) { 2123 void LCodeGen::DoCheckMap(LCheckMap* instr) {
2124 Register scratch = scratch0();
1988 LOperand* input = instr->input(); 2125 LOperand* input = instr->input();
1989 ASSERT(input->IsRegister()); 2126 ASSERT(input->IsRegister());
1990 Register reg = ToRegister(input); 2127 Register reg = ToRegister(input);
1991 __ ldr(r9, FieldMemOperand(reg, HeapObject::kMapOffset)); 2128 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset));
1992 __ cmp(r9, Operand(instr->hydrogen()->map())); 2129 __ cmp(scratch, Operand(instr->hydrogen()->map()));
1993 DeoptimizeIf(ne, instr->environment()); 2130 DeoptimizeIf(ne, instr->environment());
1994 } 2131 }
1995 2132
1996 2133
1997 void LCodeGen::LoadPrototype(Register result, 2134 void LCodeGen::LoadPrototype(Register result,
1998 Handle<JSObject> prototype) { 2135 Handle<JSObject> prototype) {
1999 Abort("LoadPrototype unimplemented."); 2136 if (Heap::InNewSpace(*prototype)) {
2137 Handle<JSGlobalPropertyCell> cell =
2138 Factory::NewJSGlobalPropertyCell(prototype);
2139 __ mov(result, Operand(cell));
2140 } else {
2141 __ mov(result, Operand(prototype));
2142 }
2000 } 2143 }
2001 2144
2002 2145
2003 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { 2146 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
2004 Abort("DoCheckPrototypeMaps unimplemented."); 2147 Register temp1 = ToRegister(instr->temp1());
2148 Register temp2 = ToRegister(instr->temp2());
2149
2150 Handle<JSObject> holder = instr->holder();
2151 Handle<Map> receiver_map = instr->receiver_map();
2152 Handle<JSObject> current_prototype(JSObject::cast(receiver_map->prototype()));
2153
2154 // Load prototype object.
2155 LoadPrototype(temp1, current_prototype);
2156
2157 // Check prototype maps up to the holder.
2158 while (!current_prototype.is_identical_to(holder)) {
2159 __ ldr(temp2, FieldMemOperand(temp1, HeapObject::kMapOffset));
2160 __ cmp(temp2, Operand(Handle<Map>(current_prototype->map())));
2161 DeoptimizeIf(ne, instr->environment());
2162 current_prototype =
2163 Handle<JSObject>(JSObject::cast(current_prototype->GetPrototype()));
2164 // Load next prototype object.
2165 LoadPrototype(temp1, current_prototype);
2166 }
2167
2168 // Check the holder map.
2169 __ ldr(temp2, FieldMemOperand(temp1, HeapObject::kMapOffset));
2170 __ cmp(temp2, Operand(Handle<Map>(current_prototype->map())));
2171 DeoptimizeIf(ne, instr->environment());
2005 } 2172 }
2006 2173
2007 2174
2008 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { 2175 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
2009 Abort("DoArrayLiteral unimplemented."); 2176 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
2177 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset));
2178 __ mov(r2, Operand(Smi::FromInt(instr->hydrogen()->literal_index())));
2179 __ mov(r1, Operand(instr->hydrogen()->constant_elements()));
2180 __ Push(r3, r2, r1);
2181
2182 // Pick the right runtime function or stub to call.
2183 int length = instr->hydrogen()->length();
2184 if (instr->hydrogen()->IsCopyOnWrite()) {
2185 ASSERT(instr->hydrogen()->depth() == 1);
2186 FastCloneShallowArrayStub::Mode mode =
2187 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS;
2188 FastCloneShallowArrayStub stub(mode, length);
2189 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2190 } else if (instr->hydrogen()->depth() > 1) {
2191 CallRuntime(Runtime::kCreateArrayLiteral, 3, instr);
2192 } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) {
2193 CallRuntime(Runtime::kCreateArrayLiteralShallow, 3, instr);
2194 } else {
2195 FastCloneShallowArrayStub::Mode mode =
2196 FastCloneShallowArrayStub::CLONE_ELEMENTS;
2197 FastCloneShallowArrayStub stub(mode, length);
2198 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2199 }
2010 } 2200 }
2011 2201
2012 2202
2013 void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { 2203 void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) {
2014 Abort("DoObjectLiteral unimplemented."); 2204 __ ldr(r4, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
2205 __ ldr(r4, FieldMemOperand(r4, JSFunction::kLiteralsOffset));
2206 __ mov(r3, Operand(Smi::FromInt(instr->hydrogen()->literal_index())));
2207 __ mov(r2, Operand(instr->hydrogen()->constant_properties()));
2208 __ mov(r1, Operand(Smi::FromInt(instr->hydrogen()->fast_elements() ? 1 : 0)));
2209 __ Push(r4, r3, r2, r1);
2210
2211 // Pick the right runtime function to call.
2212 if (instr->hydrogen()->depth() > 1) {
2213 CallRuntime(Runtime::kCreateObjectLiteral, 4, instr);
2214 } else {
2215 CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr);
2216 }
2015 } 2217 }
2016 2218
2017 2219
2018 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { 2220 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
2019 Abort("DoRegExpLiteral unimplemented."); 2221 Abort("DoRegExpLiteral unimplemented.");
2020 } 2222 }
2021 2223
2022 2224
2023 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { 2225 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
2024 Abort("DoFunctionLiteral unimplemented."); 2226 Abort("DoFunctionLiteral unimplemented.");
(...skipping 24 matching lines...) Expand all
2049 2251
2050 EmitBranch(true_block, false_block, final_branch_condition); 2252 EmitBranch(true_block, false_block, final_branch_condition);
2051 } 2253 }
2052 2254
2053 2255
2054 Condition LCodeGen::EmitTypeofIs(Label* true_label, 2256 Condition LCodeGen::EmitTypeofIs(Label* true_label,
2055 Label* false_label, 2257 Label* false_label,
2056 Register input, 2258 Register input,
2057 Handle<String> type_name) { 2259 Handle<String> type_name) {
2058 Condition final_branch_condition = no_condition; 2260 Condition final_branch_condition = no_condition;
2059 Register core_scratch = r9; 2261 Register scratch = scratch0();
2060 ASSERT(!input.is(core_scratch));
2061 if (type_name->Equals(Heap::number_symbol())) { 2262 if (type_name->Equals(Heap::number_symbol())) {
2062 __ tst(input, Operand(kSmiTagMask)); 2263 __ tst(input, Operand(kSmiTagMask));
2063 __ b(eq, true_label); 2264 __ b(eq, true_label);
2064 __ ldr(input, FieldMemOperand(input, HeapObject::kMapOffset)); 2265 __ ldr(input, FieldMemOperand(input, HeapObject::kMapOffset));
2065 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 2266 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
2066 __ cmp(input, Operand(ip)); 2267 __ cmp(input, Operand(ip));
2067 final_branch_condition = eq; 2268 final_branch_condition = eq;
2068 2269
2069 } else if (type_name->Equals(Heap::string_symbol())) { 2270 } else if (type_name->Equals(Heap::string_symbol())) {
2070 __ tst(input, Operand(kSmiTagMask)); 2271 __ tst(input, Operand(kSmiTagMask));
2071 __ b(eq, false_label); 2272 __ b(eq, false_label);
2072 __ ldr(input, FieldMemOperand(input, HeapObject::kMapOffset)); 2273 __ ldr(input, FieldMemOperand(input, HeapObject::kMapOffset));
2073 __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset)); 2274 __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset));
2074 __ tst(ip, Operand(1 << Map::kIsUndetectable)); 2275 __ tst(ip, Operand(1 << Map::kIsUndetectable));
2075 __ b(ne, false_label); 2276 __ b(ne, false_label);
2076 __ CompareInstanceType(input, core_scratch, FIRST_NONSTRING_TYPE); 2277 __ CompareInstanceType(input, scratch, FIRST_NONSTRING_TYPE);
2077 final_branch_condition = lo; 2278 final_branch_condition = lo;
2078 2279
2079 } else if (type_name->Equals(Heap::boolean_symbol())) { 2280 } else if (type_name->Equals(Heap::boolean_symbol())) {
2080 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 2281 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
2081 __ cmp(input, ip); 2282 __ cmp(input, ip);
2082 __ b(eq, true_label); 2283 __ b(eq, true_label);
2083 __ LoadRoot(ip, Heap::kFalseValueRootIndex); 2284 __ LoadRoot(ip, Heap::kFalseValueRootIndex);
2084 __ cmp(input, ip); 2285 __ cmp(input, ip);
2085 final_branch_condition = eq; 2286 final_branch_condition = eq;
2086 2287
2087 } else if (type_name->Equals(Heap::undefined_symbol())) { 2288 } else if (type_name->Equals(Heap::undefined_symbol())) {
2088 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 2289 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
2089 __ cmp(input, ip); 2290 __ cmp(input, ip);
2090 __ b(eq, true_label); 2291 __ b(eq, true_label);
2091 __ tst(input, Operand(kSmiTagMask)); 2292 __ tst(input, Operand(kSmiTagMask));
2092 __ b(eq, false_label); 2293 __ b(eq, false_label);
2093 // Check for undetectable objects => true. 2294 // Check for undetectable objects => true.
2094 __ ldr(input, FieldMemOperand(input, HeapObject::kMapOffset)); 2295 __ ldr(input, FieldMemOperand(input, HeapObject::kMapOffset));
2095 __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset)); 2296 __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset));
2096 __ tst(ip, Operand(1 << Map::kIsUndetectable)); 2297 __ tst(ip, Operand(1 << Map::kIsUndetectable));
2097 final_branch_condition = ne; 2298 final_branch_condition = ne;
2098 2299
2099 } else if (type_name->Equals(Heap::function_symbol())) { 2300 } else if (type_name->Equals(Heap::function_symbol())) {
2100 __ tst(input, Operand(kSmiTagMask)); 2301 __ tst(input, Operand(kSmiTagMask));
2101 __ b(eq, false_label); 2302 __ b(eq, false_label);
2102 __ CompareObjectType(input, input, core_scratch, JS_FUNCTION_TYPE); 2303 __ CompareObjectType(input, input, scratch, JS_FUNCTION_TYPE);
2103 __ b(eq, true_label); 2304 __ b(eq, true_label);
2104 // Regular expressions => 'function' (they are callable). 2305 // Regular expressions => 'function' (they are callable).
2105 __ CompareInstanceType(input, core_scratch, JS_REGEXP_TYPE); 2306 __ CompareInstanceType(input, scratch, JS_REGEXP_TYPE);
2106 final_branch_condition = eq; 2307 final_branch_condition = eq;
2107 2308
2108 } else if (type_name->Equals(Heap::object_symbol())) { 2309 } else if (type_name->Equals(Heap::object_symbol())) {
2109 __ tst(input, Operand(kSmiTagMask)); 2310 __ tst(input, Operand(kSmiTagMask));
2110 __ b(eq, false_label); 2311 __ b(eq, false_label);
2111 __ LoadRoot(ip, Heap::kNullValueRootIndex); 2312 __ LoadRoot(ip, Heap::kNullValueRootIndex);
2112 __ cmp(input, ip); 2313 __ cmp(input, ip);
2113 __ b(eq, true_label); 2314 __ b(eq, true_label);
2114 // Regular expressions => 'function', not 'object'. 2315 // Regular expressions => 'function', not 'object'.
2115 __ CompareObjectType(input, input, core_scratch, JS_REGEXP_TYPE); 2316 __ CompareObjectType(input, input, scratch, JS_REGEXP_TYPE);
2116 __ b(eq, false_label); 2317 __ b(eq, false_label);
2117 // Check for undetectable objects => false. 2318 // Check for undetectable objects => false.
2118 __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset)); 2319 __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset));
2119 __ tst(ip, Operand(1 << Map::kIsUndetectable)); 2320 __ tst(ip, Operand(1 << Map::kIsUndetectable));
2120 __ b(ne, false_label); 2321 __ b(ne, false_label);
2121 // Check for JS objects => true. 2322 // Check for JS objects => true.
2122 __ CompareInstanceType(input, core_scratch, FIRST_JS_OBJECT_TYPE); 2323 __ CompareInstanceType(input, scratch, FIRST_JS_OBJECT_TYPE);
2123 __ b(lo, false_label); 2324 __ b(lo, false_label);
2124 __ CompareInstanceType(input, core_scratch, LAST_JS_OBJECT_TYPE); 2325 __ CompareInstanceType(input, scratch, LAST_JS_OBJECT_TYPE);
2125 final_branch_condition = ls; 2326 final_branch_condition = ls;
2126 2327
2127 } else { 2328 } else {
2128 final_branch_condition = ne; 2329 final_branch_condition = ne;
2129 __ b(false_label); 2330 __ b(false_label);
2130 // A dead branch instruction will be generated after this point. 2331 // A dead branch instruction will be generated after this point.
2131 } 2332 }
2132 2333
2133 return final_branch_condition; 2334 return final_branch_condition;
2134 } 2335 }
(...skipping 28 matching lines...) Expand all
2163 2364
2164 2365
2165 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { 2366 void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
2166 Abort("DoOsrEntry unimplemented."); 2367 Abort("DoOsrEntry unimplemented.");
2167 } 2368 }
2168 2369
2169 2370
2170 #undef __ 2371 #undef __
2171 2372
2172 } } // namespace v8::internal 2373 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/ast.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698