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

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

Issue 6250027: Port lithium template classes to ARM.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
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/ia32/lithium-ia32.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 998 matching lines...) Expand 10 before | Expand all | Expand 10 after
1009 public: 1009 public:
1010 DeferredModI(LCodeGen* codegen, LModI* instr) 1010 DeferredModI(LCodeGen* codegen, LModI* instr)
1011 : LDeferredCode(codegen), instr_(instr) { } 1011 : LDeferredCode(codegen), instr_(instr) { }
1012 virtual void Generate() { 1012 virtual void Generate() {
1013 codegen()->DoDeferredGenericBinaryStub(instr_, Token::MOD); 1013 codegen()->DoDeferredGenericBinaryStub(instr_, Token::MOD);
1014 } 1014 }
1015 private: 1015 private:
1016 LModI* instr_; 1016 LModI* instr_;
1017 }; 1017 };
1018 // These registers hold untagged 32 bit values. 1018 // These registers hold untagged 32 bit values.
1019 Register left = ToRegister(instr->left()); 1019 Register left = ToRegister(instr->InputAt(0));
1020 Register right = ToRegister(instr->right()); 1020 Register right = ToRegister(instr->InputAt(1));
1021 Register result = ToRegister(instr->result()); 1021 Register result = ToRegister(instr->result());
1022 Register scratch = scratch0(); 1022 Register scratch = scratch0();
1023 1023
1024 Label deoptimize, done; 1024 Label deoptimize, done;
1025 // Check for x % 0. 1025 // Check for x % 0.
1026 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 1026 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
1027 __ tst(right, Operand(right)); 1027 __ tst(right, Operand(right));
1028 __ b(eq, &deoptimize); 1028 __ b(eq, &deoptimize);
1029 } 1029 }
1030 1030
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1095 public: 1095 public:
1096 DeferredDivI(LCodeGen* codegen, LDivI* instr) 1096 DeferredDivI(LCodeGen* codegen, LDivI* instr)
1097 : LDeferredCode(codegen), instr_(instr) { } 1097 : LDeferredCode(codegen), instr_(instr) { }
1098 virtual void Generate() { 1098 virtual void Generate() {
1099 codegen()->DoDeferredGenericBinaryStub(instr_, Token::DIV); 1099 codegen()->DoDeferredGenericBinaryStub(instr_, Token::DIV);
1100 } 1100 }
1101 private: 1101 private:
1102 LDivI* instr_; 1102 LDivI* instr_;
1103 }; 1103 };
1104 1104
1105 const Register left = ToRegister(instr->left()); 1105 const Register left = ToRegister(instr->InputAt(0));
1106 const Register right = ToRegister(instr->right()); 1106 const Register right = ToRegister(instr->InputAt(1));
1107 const Register scratch = scratch0(); 1107 const Register scratch = scratch0();
1108 const Register result = ToRegister(instr->result()); 1108 const Register result = ToRegister(instr->result());
1109 1109
1110 // Check for x / 0. 1110 // Check for x / 0.
1111 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 1111 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
1112 __ tst(right, right); 1112 __ tst(right, right);
1113 DeoptimizeIf(eq, instr->environment()); 1113 DeoptimizeIf(eq, instr->environment());
1114 } 1114 }
1115 1115
1116 // Check for (0 / -x) that will produce negative zero. 1116 // Check for (0 / -x) that will produce negative zero.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1163 __ BranchOnNotSmi(result, &deoptimize); 1163 __ BranchOnNotSmi(result, &deoptimize);
1164 __ SmiUntag(result); 1164 __ SmiUntag(result);
1165 __ b(&done); 1165 __ b(&done);
1166 1166
1167 __ bind(&deoptimize); 1167 __ bind(&deoptimize);
1168 DeoptimizeIf(al, instr->environment()); 1168 DeoptimizeIf(al, instr->environment());
1169 __ bind(&done); 1169 __ bind(&done);
1170 } 1170 }
1171 1171
1172 1172
1173 void LCodeGen::DoDeferredGenericBinaryStub(LBinaryOperation* instr, 1173 template<int T>
1174 void LCodeGen::DoDeferredGenericBinaryStub(LTemplateInstruction<1, 2, T>* instr,
1174 Token::Value op) { 1175 Token::Value op) {
1175 Register left = ToRegister(instr->left()); 1176 Register left = ToRegister(instr->InputAt(0));
1176 Register right = ToRegister(instr->right()); 1177 Register right = ToRegister(instr->InputAt(1));
1177 1178
1178 __ PushSafepointRegistersAndDoubles(); 1179 __ PushSafepointRegistersAndDoubles();
1179 GenericBinaryOpStub stub(op, OVERWRITE_LEFT, left, right); 1180 GenericBinaryOpStub stub(op, OVERWRITE_LEFT, left, right);
1180 __ CallStub(&stub); 1181 __ CallStub(&stub);
1181 RecordSafepointWithRegistersAndDoubles(instr->pointer_map(), 1182 RecordSafepointWithRegistersAndDoubles(instr->pointer_map(),
1182 0, 1183 0,
1183 Safepoint::kNoDeoptimizationIndex); 1184 Safepoint::kNoDeoptimizationIndex);
1184 // Overwrite the stored value of r0 with the result of the stub. 1185 // Overwrite the stored value of r0 with the result of the stub.
1185 __ str(r0, MemOperand(sp, DwVfpRegister::kNumAllocatableRegisters * 1186 __ str(r0, MemOperand(sp, DwVfpRegister::kNumAllocatableRegisters *
1186 kDoubleSize)); 1187 kDoubleSize));
1187 __ PopSafepointRegistersAndDoubles(); 1188 __ PopSafepointRegistersAndDoubles();
1188 } 1189 }
1189 1190
1190 1191
1191 void LCodeGen::DoMulI(LMulI* instr) { 1192 void LCodeGen::DoMulI(LMulI* instr) {
1192 Register scratch = scratch0(); 1193 Register scratch = scratch0();
1193 Register left = ToRegister(instr->left()); 1194 Register left = ToRegister(instr->InputAt(0));
1194 Register right = EmitLoadRegister(instr->right(), scratch); 1195 Register right = EmitLoadRegister(instr->InputAt(1), scratch);
1195 1196
1196 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero) && 1197 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero) &&
1197 !instr->right()->IsConstantOperand()) { 1198 !instr->InputAt(1)->IsConstantOperand()) {
1198 __ orr(ToRegister(instr->temp()), left, right); 1199 __ orr(ToRegister(instr->TempAt(0)), left, right);
1199 } 1200 }
1200 1201
1201 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1202 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1202 // scratch:left = left * right. 1203 // scratch:left = left * right.
1203 __ smull(scratch, left, left, right); 1204 __ smull(scratch, left, left, right);
1204 __ mov(ip, Operand(left, ASR, 31)); 1205 __ mov(ip, Operand(left, ASR, 31));
1205 __ cmp(ip, Operand(scratch)); 1206 __ cmp(ip, Operand(scratch));
1206 DeoptimizeIf(ne, instr->environment()); 1207 DeoptimizeIf(ne, instr->environment());
1207 } else { 1208 } else {
1208 __ mul(left, left, right); 1209 __ mul(left, left, right);
1209 } 1210 }
1210 1211
1211 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1212 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1212 // Bail out if the result is supposed to be negative zero. 1213 // Bail out if the result is supposed to be negative zero.
1213 Label done; 1214 Label done;
1214 __ tst(left, Operand(left)); 1215 __ tst(left, Operand(left));
1215 __ b(ne, &done); 1216 __ b(ne, &done);
1216 if (instr->right()->IsConstantOperand()) { 1217 if (instr->InputAt(1)->IsConstantOperand()) {
1217 if (ToInteger32(LConstantOperand::cast(instr->right())) < 0) { 1218 if (ToInteger32(LConstantOperand::cast(instr->InputAt(1))) < 0) {
1218 DeoptimizeIf(no_condition, instr->environment()); 1219 DeoptimizeIf(no_condition, instr->environment());
1219 } 1220 }
1220 } else { 1221 } else {
1221 // Test the non-zero operand for negative sign. 1222 // Test the non-zero operand for negative sign.
1222 __ cmp(ToRegister(instr->temp()), Operand(0)); 1223 __ cmp(ToRegister(instr->TempAt(0)), Operand(0));
1223 DeoptimizeIf(mi, instr->environment()); 1224 DeoptimizeIf(mi, instr->environment());
1224 } 1225 }
1225 __ bind(&done); 1226 __ bind(&done);
1226 } 1227 }
1227 } 1228 }
1228 1229
1229 1230
1230 void LCodeGen::DoBitI(LBitI* instr) { 1231 void LCodeGen::DoBitI(LBitI* instr) {
1231 LOperand* left = instr->left(); 1232 LOperand* left = instr->InputAt(0);
1232 LOperand* right = instr->right(); 1233 LOperand* right = instr->InputAt(1);
1233 ASSERT(left->Equals(instr->result())); 1234 ASSERT(left->Equals(instr->result()));
1234 ASSERT(left->IsRegister()); 1235 ASSERT(left->IsRegister());
1235 Register result = ToRegister(left); 1236 Register result = ToRegister(left);
1236 Register right_reg = EmitLoadRegister(right, ip); 1237 Register right_reg = EmitLoadRegister(right, ip);
1237 switch (instr->op()) { 1238 switch (instr->op()) {
1238 case Token::BIT_AND: 1239 case Token::BIT_AND:
1239 __ and_(result, ToRegister(left), Operand(right_reg)); 1240 __ and_(result, ToRegister(left), Operand(right_reg));
1240 break; 1241 break;
1241 case Token::BIT_OR: 1242 case Token::BIT_OR:
1242 __ orr(result, ToRegister(left), Operand(right_reg)); 1243 __ orr(result, ToRegister(left), Operand(right_reg));
1243 break; 1244 break;
1244 case Token::BIT_XOR: 1245 case Token::BIT_XOR:
1245 __ eor(result, ToRegister(left), Operand(right_reg)); 1246 __ eor(result, ToRegister(left), Operand(right_reg));
1246 break; 1247 break;
1247 default: 1248 default:
1248 UNREACHABLE(); 1249 UNREACHABLE();
1249 break; 1250 break;
1250 } 1251 }
1251 } 1252 }
1252 1253
1253 1254
1254 void LCodeGen::DoShiftI(LShiftI* instr) { 1255 void LCodeGen::DoShiftI(LShiftI* instr) {
1255 Register scratch = scratch0(); 1256 Register scratch = scratch0();
1256 LOperand* left = instr->left(); 1257 LOperand* left = instr->InputAt(0);
1257 LOperand* right = instr->right(); 1258 LOperand* right = instr->InputAt(1);
1258 ASSERT(left->Equals(instr->result())); 1259 ASSERT(left->Equals(instr->result()));
1259 ASSERT(left->IsRegister()); 1260 ASSERT(left->IsRegister());
1260 Register result = ToRegister(left); 1261 Register result = ToRegister(left);
1261 if (right->IsRegister()) { 1262 if (right->IsRegister()) {
1262 // Mask the right operand. 1263 // Mask the right operand.
1263 __ and_(scratch, ToRegister(right), Operand(0x1F)); 1264 __ and_(scratch, ToRegister(right), Operand(0x1F));
1264 switch (instr->op()) { 1265 switch (instr->op()) {
1265 case Token::SAR: 1266 case Token::SAR:
1266 __ mov(result, Operand(result, ASR, scratch)); 1267 __ mov(result, Operand(result, ASR, scratch));
1267 break; 1268 break;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1304 break; 1305 break;
1305 default: 1306 default:
1306 UNREACHABLE(); 1307 UNREACHABLE();
1307 break; 1308 break;
1308 } 1309 }
1309 } 1310 }
1310 } 1311 }
1311 1312
1312 1313
1313 void LCodeGen::DoSubI(LSubI* instr) { 1314 void LCodeGen::DoSubI(LSubI* instr) {
1314 Register left = ToRegister(instr->left()); 1315 Register left = ToRegister(instr->InputAt(0));
1315 Register right = EmitLoadRegister(instr->right(), ip); 1316 Register right = EmitLoadRegister(instr->InputAt(1), ip);
1316 ASSERT(instr->left()->Equals(instr->result())); 1317 ASSERT(instr->InputAt(0)->Equals(instr->result()));
1317 __ sub(left, left, right, SetCC); 1318 __ sub(left, left, right, SetCC);
1318 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1319 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1319 DeoptimizeIf(vs, instr->environment()); 1320 DeoptimizeIf(vs, instr->environment());
1320 } 1321 }
1321 } 1322 }
1322 1323
1323 1324
1324 void LCodeGen::DoConstantI(LConstantI* instr) { 1325 void LCodeGen::DoConstantI(LConstantI* instr) {
1325 ASSERT(instr->result()->IsRegister()); 1326 ASSERT(instr->result()->IsRegister());
1326 __ mov(ToRegister(instr->result()), Operand(instr->value())); 1327 __ mov(ToRegister(instr->result()), Operand(instr->value()));
1327 } 1328 }
1328 1329
1329 1330
1330 void LCodeGen::DoConstantD(LConstantD* instr) { 1331 void LCodeGen::DoConstantD(LConstantD* instr) {
1331 ASSERT(instr->result()->IsDoubleRegister()); 1332 ASSERT(instr->result()->IsDoubleRegister());
1332 DwVfpRegister result = ToDoubleRegister(instr->result()); 1333 DwVfpRegister result = ToDoubleRegister(instr->result());
1333 double v = instr->value(); 1334 double v = instr->value();
1334 __ vmov(result, v); 1335 __ vmov(result, v);
1335 } 1336 }
1336 1337
1337 1338
1338 void LCodeGen::DoConstantT(LConstantT* instr) { 1339 void LCodeGen::DoConstantT(LConstantT* instr) {
1339 ASSERT(instr->result()->IsRegister()); 1340 ASSERT(instr->result()->IsRegister());
1340 __ mov(ToRegister(instr->result()), Operand(instr->value())); 1341 __ mov(ToRegister(instr->result()), Operand(instr->value()));
1341 } 1342 }
1342 1343
1343 1344
1344 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { 1345 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
1345 Register result = ToRegister(instr->result()); 1346 Register result = ToRegister(instr->result());
1346 Register array = ToRegister(instr->input()); 1347 Register array = ToRegister(instr->InputAt(0));
1347 __ ldr(result, FieldMemOperand(array, JSArray::kLengthOffset)); 1348 __ ldr(result, FieldMemOperand(array, JSArray::kLengthOffset));
1348 } 1349 }
1349 1350
1350 1351
1351 void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) { 1352 void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) {
1352 Register result = ToRegister(instr->result()); 1353 Register result = ToRegister(instr->result());
1353 Register array = ToRegister(instr->input()); 1354 Register array = ToRegister(instr->InputAt(0));
1354 __ ldr(result, FieldMemOperand(array, FixedArray::kLengthOffset)); 1355 __ ldr(result, FieldMemOperand(array, FixedArray::kLengthOffset));
1355 } 1356 }
1356 1357
1357 1358
1358 void LCodeGen::DoValueOf(LValueOf* instr) { 1359 void LCodeGen::DoValueOf(LValueOf* instr) {
1359 Register input = ToRegister(instr->input()); 1360 Register input = ToRegister(instr->InputAt(0));
1360 Register result = ToRegister(instr->result()); 1361 Register result = ToRegister(instr->result());
1361 Register map = ToRegister(instr->temporary()); 1362 Register map = ToRegister(instr->TempAt(0));
1362 ASSERT(input.is(result)); 1363 ASSERT(input.is(result));
1363 Label done; 1364 Label done;
1364 1365
1365 // If the object is a smi return the object. 1366 // If the object is a smi return the object.
1366 __ tst(input, Operand(kSmiTagMask)); 1367 __ tst(input, Operand(kSmiTagMask));
1367 __ b(eq, &done); 1368 __ b(eq, &done);
1368 1369
1369 // If the object is not a value type, return the object. 1370 // If the object is not a value type, return the object.
1370 __ CompareObjectType(input, map, map, JS_VALUE_TYPE); 1371 __ CompareObjectType(input, map, map, JS_VALUE_TYPE);
1371 __ b(ne, &done); 1372 __ b(ne, &done);
1372 __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset)); 1373 __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset));
1373 1374
1374 __ bind(&done); 1375 __ bind(&done);
1375 } 1376 }
1376 1377
1377 1378
1378 void LCodeGen::DoBitNotI(LBitNotI* instr) { 1379 void LCodeGen::DoBitNotI(LBitNotI* instr) {
1379 LOperand* input = instr->input(); 1380 LOperand* input = instr->InputAt(0);
1380 ASSERT(input->Equals(instr->result())); 1381 ASSERT(input->Equals(instr->result()));
1381 __ mvn(ToRegister(input), Operand(ToRegister(input))); 1382 __ mvn(ToRegister(input), Operand(ToRegister(input)));
1382 } 1383 }
1383 1384
1384 1385
1385 void LCodeGen::DoThrow(LThrow* instr) { 1386 void LCodeGen::DoThrow(LThrow* instr) {
1386 Register input_reg = EmitLoadRegister(instr->input(), ip); 1387 Register input_reg = EmitLoadRegister(instr->InputAt(0), ip);
1387 __ push(input_reg); 1388 __ push(input_reg);
1388 CallRuntime(Runtime::kThrow, 1, instr); 1389 CallRuntime(Runtime::kThrow, 1, instr);
1389 1390
1390 if (FLAG_debug_code) { 1391 if (FLAG_debug_code) {
1391 __ stop("Unreachable code."); 1392 __ stop("Unreachable code.");
1392 } 1393 }
1393 } 1394 }
1394 1395
1395 1396
1396 void LCodeGen::DoAddI(LAddI* instr) { 1397 void LCodeGen::DoAddI(LAddI* instr) {
1397 LOperand* left = instr->left(); 1398 LOperand* left = instr->InputAt(0);
1398 LOperand* right = instr->right(); 1399 LOperand* right = instr->InputAt(1);
1399 ASSERT(left->Equals(instr->result())); 1400 ASSERT(left->Equals(instr->result()));
1400 1401
1401 Register right_reg = EmitLoadRegister(right, ip); 1402 Register right_reg = EmitLoadRegister(right, ip);
1402 __ add(ToRegister(left), ToRegister(left), Operand(right_reg), SetCC); 1403 __ add(ToRegister(left), ToRegister(left), Operand(right_reg), SetCC);
1403 1404
1404 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1405 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1405 DeoptimizeIf(vs, instr->environment()); 1406 DeoptimizeIf(vs, instr->environment());
1406 } 1407 }
1407 } 1408 }
1408 1409
1409 1410
1410 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { 1411 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
1411 DoubleRegister left = ToDoubleRegister(instr->left()); 1412 DoubleRegister left = ToDoubleRegister(instr->InputAt(0));
1412 DoubleRegister right = ToDoubleRegister(instr->right()); 1413 DoubleRegister right = ToDoubleRegister(instr->InputAt(1));
1413 switch (instr->op()) { 1414 switch (instr->op()) {
1414 case Token::ADD: 1415 case Token::ADD:
1415 __ vadd(left, left, right); 1416 __ vadd(left, left, right);
1416 break; 1417 break;
1417 case Token::SUB: 1418 case Token::SUB:
1418 __ vsub(left, left, right); 1419 __ vsub(left, left, right);
1419 break; 1420 break;
1420 case Token::MUL: 1421 case Token::MUL:
1421 __ vmul(left, left, right); 1422 __ vmul(left, left, right);
1422 break; 1423 break;
1423 case Token::DIV: 1424 case Token::DIV:
1424 __ vdiv(left, left, right); 1425 __ vdiv(left, left, right);
1425 break; 1426 break;
1426 case Token::MOD: { 1427 case Token::MOD: {
1427 Abort("DoArithmeticD unimplemented for MOD."); 1428 Abort("DoArithmeticD unimplemented for MOD.");
1428 break; 1429 break;
1429 } 1430 }
1430 default: 1431 default:
1431 UNREACHABLE(); 1432 UNREACHABLE();
1432 break; 1433 break;
1433 } 1434 }
1434 } 1435 }
1435 1436
1436 1437
1437 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { 1438 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
1438 ASSERT(ToRegister(instr->left()).is(r1)); 1439 ASSERT(ToRegister(instr->InputAt(0)).is(r1));
1439 ASSERT(ToRegister(instr->right()).is(r0)); 1440 ASSERT(ToRegister(instr->InputAt(1)).is(r0));
1440 ASSERT(ToRegister(instr->result()).is(r0)); 1441 ASSERT(ToRegister(instr->result()).is(r0));
1441 1442
1442 // TODO(regis): Implement TypeRecordingBinaryOpStub and replace current 1443 // TODO(regis): Implement TypeRecordingBinaryOpStub and replace current
1443 // GenericBinaryOpStub: 1444 // GenericBinaryOpStub:
1444 // TypeRecordingBinaryOpStub stub(instr->op(), NO_OVERWRITE); 1445 // TypeRecordingBinaryOpStub stub(instr->op(), NO_OVERWRITE);
1445 GenericBinaryOpStub stub(instr->op(), NO_OVERWRITE, r1, r0); 1446 GenericBinaryOpStub stub(instr->op(), NO_OVERWRITE, r1, r0);
1446 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 1447 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1447 } 1448 }
1448 1449
1449 1450
(...skipping 23 matching lines...) Expand all
1473 } 1474 }
1474 } 1475 }
1475 1476
1476 1477
1477 void LCodeGen::DoBranch(LBranch* instr) { 1478 void LCodeGen::DoBranch(LBranch* instr) {
1478 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1479 int true_block = chunk_->LookupDestination(instr->true_block_id());
1479 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1480 int false_block = chunk_->LookupDestination(instr->false_block_id());
1480 1481
1481 Representation r = instr->hydrogen()->representation(); 1482 Representation r = instr->hydrogen()->representation();
1482 if (r.IsInteger32()) { 1483 if (r.IsInteger32()) {
1483 Register reg = ToRegister(instr->input()); 1484 Register reg = ToRegister(instr->InputAt(0));
1484 __ cmp(reg, Operand(0)); 1485 __ cmp(reg, Operand(0));
1485 EmitBranch(true_block, false_block, nz); 1486 EmitBranch(true_block, false_block, nz);
1486 } else if (r.IsDouble()) { 1487 } else if (r.IsDouble()) {
1487 DoubleRegister reg = ToDoubleRegister(instr->input()); 1488 DoubleRegister reg = ToDoubleRegister(instr->InputAt(0));
1488 Register scratch = scratch0(); 1489 Register scratch = scratch0();
1489 1490
1490 // Test the double value. Zero and NaN are false. 1491 // Test the double value. Zero and NaN are false.
1491 __ VFPCompareAndLoadFlags(reg, 0.0, scratch); 1492 __ VFPCompareAndLoadFlags(reg, 0.0, scratch);
1492 __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit)); 1493 __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit));
1493 EmitBranch(true_block, false_block, ne); 1494 EmitBranch(true_block, false_block, ne);
1494 } else { 1495 } else {
1495 ASSERT(r.IsTagged()); 1496 ASSERT(r.IsTagged());
1496 Register reg = ToRegister(instr->input()); 1497 Register reg = ToRegister(instr->InputAt(0));
1497 if (instr->hydrogen()->type().IsBoolean()) { 1498 if (instr->hydrogen()->type().IsBoolean()) {
1498 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 1499 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
1499 __ cmp(reg, ip); 1500 __ cmp(reg, ip);
1500 EmitBranch(true_block, false_block, eq); 1501 EmitBranch(true_block, false_block, eq);
1501 } else { 1502 } else {
1502 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1503 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1503 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1504 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1504 1505
1505 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 1506 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
1506 __ cmp(reg, ip); 1507 __ cmp(reg, ip);
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1629 Abort("DoCmpID unimplemented."); 1630 Abort("DoCmpID unimplemented.");
1630 } 1631 }
1631 1632
1632 1633
1633 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { 1634 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
1634 Abort("DoCmpIDAndBranch unimplemented."); 1635 Abort("DoCmpIDAndBranch unimplemented.");
1635 } 1636 }
1636 1637
1637 1638
1638 void LCodeGen::DoCmpJSObjectEq(LCmpJSObjectEq* instr) { 1639 void LCodeGen::DoCmpJSObjectEq(LCmpJSObjectEq* instr) {
1639 Register left = ToRegister(instr->left()); 1640 Register left = ToRegister(instr->InputAt(0));
1640 Register right = ToRegister(instr->right()); 1641 Register right = ToRegister(instr->InputAt(1));
1641 Register result = ToRegister(instr->result()); 1642 Register result = ToRegister(instr->result());
1642 1643
1643 __ cmp(left, Operand(right)); 1644 __ cmp(left, Operand(right));
1644 __ LoadRoot(result, Heap::kTrueValueRootIndex, eq); 1645 __ LoadRoot(result, Heap::kTrueValueRootIndex, eq);
1645 __ LoadRoot(result, Heap::kFalseValueRootIndex, ne); 1646 __ LoadRoot(result, Heap::kFalseValueRootIndex, ne);
1646 } 1647 }
1647 1648
1648 1649
1649 void LCodeGen::DoCmpJSObjectEqAndBranch(LCmpJSObjectEqAndBranch* instr) { 1650 void LCodeGen::DoCmpJSObjectEqAndBranch(LCmpJSObjectEqAndBranch* instr) {
1650 Register left = ToRegister(instr->left()); 1651 Register left = ToRegister(instr->InputAt(0));
1651 Register right = ToRegister(instr->right()); 1652 Register right = ToRegister(instr->InputAt(1));
1652 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1653 int false_block = chunk_->LookupDestination(instr->false_block_id());
1653 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1654 int true_block = chunk_->LookupDestination(instr->true_block_id());
1654 1655
1655 __ cmp(left, Operand(right)); 1656 __ cmp(left, Operand(right));
1656 EmitBranch(true_block, false_block, eq); 1657 EmitBranch(true_block, false_block, eq);
1657 } 1658 }
1658 1659
1659 1660
1660 void LCodeGen::DoIsNull(LIsNull* instr) { 1661 void LCodeGen::DoIsNull(LIsNull* instr) {
1661 Register reg = ToRegister(instr->input()); 1662 Register reg = ToRegister(instr->InputAt(0));
1662 Register result = ToRegister(instr->result()); 1663 Register result = ToRegister(instr->result());
1663 1664
1664 __ LoadRoot(ip, Heap::kNullValueRootIndex); 1665 __ LoadRoot(ip, Heap::kNullValueRootIndex);
1665 __ cmp(reg, ip); 1666 __ cmp(reg, ip);
1666 if (instr->is_strict()) { 1667 if (instr->is_strict()) {
1667 __ LoadRoot(result, Heap::kTrueValueRootIndex, eq); 1668 __ LoadRoot(result, Heap::kTrueValueRootIndex, eq);
1668 __ LoadRoot(result, Heap::kFalseValueRootIndex, ne); 1669 __ LoadRoot(result, Heap::kFalseValueRootIndex, ne);
1669 } else { 1670 } else {
1670 Label true_value, false_value, done; 1671 Label true_value, false_value, done;
1671 __ b(eq, &true_value); 1672 __ b(eq, &true_value);
(...skipping 14 matching lines...) Expand all
1686 __ jmp(&done); 1687 __ jmp(&done);
1687 __ bind(&true_value); 1688 __ bind(&true_value);
1688 __ LoadRoot(result, Heap::kTrueValueRootIndex); 1689 __ LoadRoot(result, Heap::kTrueValueRootIndex);
1689 __ bind(&done); 1690 __ bind(&done);
1690 } 1691 }
1691 } 1692 }
1692 1693
1693 1694
1694 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) { 1695 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) {
1695 Register scratch = scratch0(); 1696 Register scratch = scratch0();
1696 Register reg = ToRegister(instr->input()); 1697 Register reg = ToRegister(instr->InputAt(0));
1697 1698
1698 // TODO(fsc): If the expression is known to be a smi, then it's 1699 // TODO(fsc): If the expression is known to be a smi, then it's
1699 // definitely not null. Jump to the false block. 1700 // definitely not null. Jump to the false block.
1700 1701
1701 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1702 int true_block = chunk_->LookupDestination(instr->true_block_id());
1702 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1703 int false_block = chunk_->LookupDestination(instr->false_block_id());
1703 1704
1704 __ LoadRoot(ip, Heap::kNullValueRootIndex); 1705 __ LoadRoot(ip, Heap::kNullValueRootIndex);
1705 __ cmp(reg, ip); 1706 __ cmp(reg, ip);
1706 if (instr->is_strict()) { 1707 if (instr->is_strict()) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1740 1741
1741 1742
1742 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { 1743 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
1743 Abort("DoIsObjectAndBranch unimplemented."); 1744 Abort("DoIsObjectAndBranch unimplemented.");
1744 } 1745 }
1745 1746
1746 1747
1747 void LCodeGen::DoIsSmi(LIsSmi* instr) { 1748 void LCodeGen::DoIsSmi(LIsSmi* instr) {
1748 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); 1749 ASSERT(instr->hydrogen()->value()->representation().IsTagged());
1749 Register result = ToRegister(instr->result()); 1750 Register result = ToRegister(instr->result());
1750 Register input_reg = EmitLoadRegister(instr->input(), ip); 1751 Register input_reg = EmitLoadRegister(instr->InputAt(0), ip);
1751 __ tst(input_reg, Operand(kSmiTagMask)); 1752 __ tst(input_reg, Operand(kSmiTagMask));
1752 __ LoadRoot(result, Heap::kTrueValueRootIndex); 1753 __ LoadRoot(result, Heap::kTrueValueRootIndex);
1753 Label done; 1754 Label done;
1754 __ b(eq, &done); 1755 __ b(eq, &done);
1755 __ LoadRoot(result, Heap::kFalseValueRootIndex); 1756 __ LoadRoot(result, Heap::kFalseValueRootIndex);
1756 __ bind(&done); 1757 __ bind(&done);
1757 } 1758 }
1758 1759
1759 1760
1760 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { 1761 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
1761 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1762 int true_block = chunk_->LookupDestination(instr->true_block_id());
1762 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1763 int false_block = chunk_->LookupDestination(instr->false_block_id());
1763 1764
1764 Register input_reg = EmitLoadRegister(instr->input(), ip); 1765 Register input_reg = EmitLoadRegister(instr->InputAt(0), ip);
1765 __ tst(input_reg, Operand(kSmiTagMask)); 1766 __ tst(input_reg, Operand(kSmiTagMask));
1766 EmitBranch(true_block, false_block, eq); 1767 EmitBranch(true_block, false_block, eq);
1767 } 1768 }
1768 1769
1769 1770
1770 InstanceType LHasInstanceType::TestType() {
1771 InstanceType from = hydrogen()->from();
1772 InstanceType to = hydrogen()->to();
1773 if (from == FIRST_TYPE) return to;
1774 ASSERT(from == to || to == LAST_TYPE);
1775 return from;
1776 }
1777
1778
1779 Condition LHasInstanceType::BranchCondition() {
1780 InstanceType from = hydrogen()->from();
1781 InstanceType to = hydrogen()->to();
1782 if (from == to) return eq;
1783 if (to == LAST_TYPE) return hs;
1784 if (from == FIRST_TYPE) return ls;
1785 UNREACHABLE();
1786 return eq;
1787 }
1788
1789
1790 static InstanceType TestType(HHasInstanceType* instr) { 1771 static InstanceType TestType(HHasInstanceType* instr) {
1791 InstanceType from = instr->from(); 1772 InstanceType from = instr->from();
1792 InstanceType to = instr->to(); 1773 InstanceType to = instr->to();
1793 if (from == FIRST_TYPE) return to; 1774 if (from == FIRST_TYPE) return to;
1794 ASSERT(from == to || to == LAST_TYPE); 1775 ASSERT(from == to || to == LAST_TYPE);
1795 return from; 1776 return from;
1796 } 1777 }
1797 1778
1798 1779
1799 static Condition BranchCondition(HHasInstanceType* instr) { 1780 static Condition BranchCondition(HHasInstanceType* instr) {
1800 InstanceType from = instr->from(); 1781 InstanceType from = instr->from();
1801 InstanceType to = instr->to(); 1782 InstanceType to = instr->to();
1802 if (from == to) return eq; 1783 if (from == to) return eq;
1803 if (to == LAST_TYPE) return hs; 1784 if (to == LAST_TYPE) return hs;
1804 if (from == FIRST_TYPE) return ls; 1785 if (from == FIRST_TYPE) return ls;
1805 UNREACHABLE(); 1786 UNREACHABLE();
1806 return eq; 1787 return eq;
1807 } 1788 }
1808 1789
1809 1790
1810 void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) { 1791 void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) {
1811 Register input = ToRegister(instr->input()); 1792 Register input = ToRegister(instr->InputAt(0));
1812 Register result = ToRegister(instr->result()); 1793 Register result = ToRegister(instr->result());
1813 1794
1814 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); 1795 ASSERT(instr->hydrogen()->value()->representation().IsTagged());
1815 Label done; 1796 Label done;
1816 __ tst(input, Operand(kSmiTagMask)); 1797 __ tst(input, Operand(kSmiTagMask));
1817 __ LoadRoot(result, Heap::kFalseValueRootIndex, eq); 1798 __ LoadRoot(result, Heap::kFalseValueRootIndex, eq);
1818 __ b(eq, &done); 1799 __ b(eq, &done);
1819 __ CompareObjectType(input, result, result, TestType(instr->hydrogen())); 1800 __ CompareObjectType(input, result, result, TestType(instr->hydrogen()));
1820 Condition cond = BranchCondition(instr->hydrogen()); 1801 Condition cond = BranchCondition(instr->hydrogen());
1821 __ LoadRoot(result, Heap::kTrueValueRootIndex, cond); 1802 __ LoadRoot(result, Heap::kTrueValueRootIndex, cond);
1822 __ LoadRoot(result, Heap::kFalseValueRootIndex, NegateCondition(cond)); 1803 __ LoadRoot(result, Heap::kFalseValueRootIndex, NegateCondition(cond));
1823 __ bind(&done); 1804 __ bind(&done);
1824 } 1805 }
1825 1806
1826 1807
1827 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { 1808 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
1828 Register scratch = scratch0(); 1809 Register scratch = scratch0();
1829 Register input = ToRegister(instr->input()); 1810 Register input = ToRegister(instr->InputAt(0));
1830 1811
1831 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1812 int true_block = chunk_->LookupDestination(instr->true_block_id());
1832 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1813 int false_block = chunk_->LookupDestination(instr->false_block_id());
1833 1814
1834 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1815 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1835 1816
1836 __ tst(input, Operand(kSmiTagMask)); 1817 __ tst(input, Operand(kSmiTagMask));
1837 __ b(eq, false_label); 1818 __ b(eq, false_label);
1838 1819
1839 __ CompareObjectType(input, scratch, scratch, instr->TestType()); 1820 __ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen()));
1840 EmitBranch(true_block, false_block, instr->BranchCondition()); 1821 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen()));
1841 } 1822 }
1842 1823
1843 1824
1844 void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) { 1825 void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) {
1845 Abort("DoHasCachedArrayIndex unimplemented."); 1826 Abort("DoHasCachedArrayIndex unimplemented.");
1846 } 1827 }
1847 1828
1848 1829
1849 void LCodeGen::DoHasCachedArrayIndexAndBranch( 1830 void LCodeGen::DoHasCachedArrayIndexAndBranch(
1850 LHasCachedArrayIndexAndBranch* instr) { 1831 LHasCachedArrayIndexAndBranch* instr) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1903 // booted. This routine isn't expected to work for random API-created 1884 // booted. This routine isn't expected to work for random API-created
1904 // classes and it doesn't have to because you can't access it with natives 1885 // classes and it doesn't have to because you can't access it with natives
1905 // syntax. Since both sides are symbols it is sufficient to use an identity 1886 // syntax. Since both sides are symbols it is sufficient to use an identity
1906 // comparison. 1887 // comparison.
1907 __ cmp(temp, Operand(class_name)); 1888 __ cmp(temp, Operand(class_name));
1908 // End with the answer in flags. 1889 // End with the answer in flags.
1909 } 1890 }
1910 1891
1911 1892
1912 void LCodeGen::DoClassOfTest(LClassOfTest* instr) { 1893 void LCodeGen::DoClassOfTest(LClassOfTest* instr) {
1913 Register input = ToRegister(instr->input()); 1894 Register input = ToRegister(instr->InputAt(0));
1914 Register result = ToRegister(instr->result()); 1895 Register result = ToRegister(instr->result());
1915 ASSERT(input.is(result)); 1896 ASSERT(input.is(result));
1916 Handle<String> class_name = instr->hydrogen()->class_name(); 1897 Handle<String> class_name = instr->hydrogen()->class_name();
1917 1898
1918 Label done, is_true, is_false; 1899 Label done, is_true, is_false;
1919 1900
1920 EmitClassOfTest(&is_true, &is_false, class_name, input, scratch0(), input); 1901 EmitClassOfTest(&is_true, &is_false, class_name, input, scratch0(), input);
1921 __ b(ne, &is_false); 1902 __ b(ne, &is_false);
1922 1903
1923 __ bind(&is_true); 1904 __ bind(&is_true);
1924 __ LoadRoot(result, Heap::kTrueValueRootIndex); 1905 __ LoadRoot(result, Heap::kTrueValueRootIndex);
1925 __ jmp(&done); 1906 __ jmp(&done);
1926 1907
1927 __ bind(&is_false); 1908 __ bind(&is_false);
1928 __ LoadRoot(result, Heap::kFalseValueRootIndex); 1909 __ LoadRoot(result, Heap::kFalseValueRootIndex);
1929 __ bind(&done); 1910 __ bind(&done);
1930 } 1911 }
1931 1912
1932 1913
1933 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 1914 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
1934 Register input = ToRegister(instr->input()); 1915 Register input = ToRegister(instr->InputAt(0));
1935 Register temp = scratch0(); 1916 Register temp = scratch0();
1936 Register temp2 = ToRegister(instr->temporary()); 1917 Register temp2 = ToRegister(instr->TempAt(0));
1937 Handle<String> class_name = instr->hydrogen()->class_name(); 1918 Handle<String> class_name = instr->hydrogen()->class_name();
1938 1919
1939 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1920 int true_block = chunk_->LookupDestination(instr->true_block_id());
1940 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1921 int false_block = chunk_->LookupDestination(instr->false_block_id());
1941 1922
1942 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1923 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1943 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1924 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1944 1925
1945 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2); 1926 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2);
1946 1927
1947 EmitBranch(true_block, false_block, eq); 1928 EmitBranch(true_block, false_block, eq);
1948 } 1929 }
1949 1930
1950 1931
1951 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { 1932 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
1952 Register reg = ToRegister(instr->input()); 1933 Register reg = ToRegister(instr->InputAt(0));
1953 Register temp = ToRegister(instr->temp()); 1934 Register temp = ToRegister(instr->TempAt(0));
1954 int true_block = instr->true_block_id(); 1935 int true_block = instr->true_block_id();
1955 int false_block = instr->false_block_id(); 1936 int false_block = instr->false_block_id();
1956 1937
1957 __ ldr(temp, FieldMemOperand(reg, HeapObject::kMapOffset)); 1938 __ ldr(temp, FieldMemOperand(reg, HeapObject::kMapOffset));
1958 __ cmp(temp, Operand(instr->map())); 1939 __ cmp(temp, Operand(instr->map()));
1959 EmitBranch(true_block, false_block, eq); 1940 EmitBranch(true_block, false_block, eq);
1960 } 1941 }
1961 1942
1962 1943
1963 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { 1944 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
1964 ASSERT(ToRegister(instr->left()).is(r0)); // Object is in r0. 1945 ASSERT(ToRegister(instr->InputAt(0)).is(r0)); // Object is in r0.
1965 ASSERT(ToRegister(instr->right()).is(r1)); // Function is in r1. 1946 ASSERT(ToRegister(instr->InputAt(1)).is(r1)); // Function is in r1.
1966 1947
1967 InstanceofStub stub(InstanceofStub::kArgsInRegisters); 1948 InstanceofStub stub(InstanceofStub::kArgsInRegisters);
1968 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 1949 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1969 1950
1970 Label true_value, done; 1951 Label true_value, done;
1971 __ tst(r0, r0); 1952 __ tst(r0, r0);
1972 __ mov(r0, Operand(Factory::false_value()), LeaveCC, ne); 1953 __ mov(r0, Operand(Factory::false_value()), LeaveCC, ne);
1973 __ mov(r0, Operand(Factory::true_value()), LeaveCC, eq); 1954 __ mov(r0, Operand(Factory::true_value()), LeaveCC, eq);
1974 } 1955 }
1975 1956
(...skipping 17 matching lines...) Expand all
1993 1974
1994 private: 1975 private:
1995 LInstanceOfKnownGlobal* instr_; 1976 LInstanceOfKnownGlobal* instr_;
1996 Label map_check_; 1977 Label map_check_;
1997 }; 1978 };
1998 1979
1999 DeferredInstanceOfKnownGlobal* deferred; 1980 DeferredInstanceOfKnownGlobal* deferred;
2000 deferred = new DeferredInstanceOfKnownGlobal(this, instr); 1981 deferred = new DeferredInstanceOfKnownGlobal(this, instr);
2001 1982
2002 Label done, false_result; 1983 Label done, false_result;
2003 Register object = ToRegister(instr->input()); 1984 Register object = ToRegister(instr->InputAt(0));
2004 Register temp = ToRegister(instr->temp()); 1985 Register temp = ToRegister(instr->TempAt(0));
2005 Register result = ToRegister(instr->result()); 1986 Register result = ToRegister(instr->result());
2006 1987
2007 ASSERT(object.is(r0)); 1988 ASSERT(object.is(r0));
2008 ASSERT(result.is(r0)); 1989 ASSERT(result.is(r0));
2009 1990
2010 // A Smi is not instance of anything. 1991 // A Smi is not instance of anything.
2011 __ BranchOnSmi(object, &false_result); 1992 __ BranchOnSmi(object, &false_result);
2012 1993
2013 // This is the inlined call site instanceof cache. The two occurences of the 1994 // This is the inlined call site instanceof cache. The two occurences of the
2014 // hole value will be patched to the last map/result pair generated by the 1995 // hole value will be patched to the last map/result pair generated by the
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2066 flags | InstanceofStub::kCallSiteInlineCheck); 2047 flags | InstanceofStub::kCallSiteInlineCheck);
2067 flags = static_cast<InstanceofStub::Flags>( 2048 flags = static_cast<InstanceofStub::Flags>(
2068 flags | InstanceofStub::kReturnTrueFalseObject); 2049 flags | InstanceofStub::kReturnTrueFalseObject);
2069 InstanceofStub stub(flags); 2050 InstanceofStub stub(flags);
2070 2051
2071 __ PushSafepointRegisters(); 2052 __ PushSafepointRegisters();
2072 2053
2073 // Get the temp register reserved by the instruction. This needs to be r4 as 2054 // Get the temp register reserved by the instruction. This needs to be r4 as
2074 // its slot of the pushing of safepoint registers is used to communicate the 2055 // its slot of the pushing of safepoint registers is used to communicate the
2075 // offset to the location of the map check. 2056 // offset to the location of the map check.
2076 Register temp = ToRegister(instr->temp()); 2057 Register temp = ToRegister(instr->TempAt(0));
2077 ASSERT(temp.is(r4)); 2058 ASSERT(temp.is(r4));
2078 __ mov(InstanceofStub::right(), Operand(instr->function())); 2059 __ mov(InstanceofStub::right(), Operand(instr->function()));
2079 static const int kAdditionalDelta = 4; 2060 static const int kAdditionalDelta = 4;
2080 int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta; 2061 int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta;
2081 Label before_push_delta; 2062 Label before_push_delta;
2082 __ bind(&before_push_delta); 2063 __ bind(&before_push_delta);
2083 __ BlockConstPoolFor(kAdditionalDelta); 2064 __ BlockConstPoolFor(kAdditionalDelta);
2084 __ mov(temp, Operand(delta * kPointerSize)); 2065 __ mov(temp, Operand(delta * kPointerSize));
2085 __ StoreToSafepointRegisterSlot(temp); 2066 __ StoreToSafepointRegisterSlot(temp);
2086 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); 2067 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
2162 __ ldr(result, FieldMemOperand(ip, JSGlobalPropertyCell::kValueOffset)); 2143 __ ldr(result, FieldMemOperand(ip, JSGlobalPropertyCell::kValueOffset));
2163 if (instr->hydrogen()->check_hole_value()) { 2144 if (instr->hydrogen()->check_hole_value()) {
2164 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 2145 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
2165 __ cmp(result, ip); 2146 __ cmp(result, ip);
2166 DeoptimizeIf(eq, instr->environment()); 2147 DeoptimizeIf(eq, instr->environment());
2167 } 2148 }
2168 } 2149 }
2169 2150
2170 2151
2171 void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) { 2152 void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) {
2172 Register value = ToRegister(instr->input()); 2153 Register value = ToRegister(instr->InputAt(0));
2173 __ mov(ip, Operand(Handle<Object>(instr->hydrogen()->cell()))); 2154 __ mov(ip, Operand(Handle<Object>(instr->hydrogen()->cell())));
2174 __ str(value, FieldMemOperand(ip, JSGlobalPropertyCell::kValueOffset)); 2155 __ str(value, FieldMemOperand(ip, JSGlobalPropertyCell::kValueOffset));
2175 } 2156 }
2176 2157
2177 2158
2178 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { 2159 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
2179 // TODO(antonm): load a context with a separate instruction. 2160 // TODO(antonm): load a context with a separate instruction.
2180 Register result = ToRegister(instr->result()); 2161 Register result = ToRegister(instr->result());
2181 __ LoadContext(result, instr->context_chain_length()); 2162 __ LoadContext(result, instr->context_chain_length());
2182 __ ldr(result, ContextOperand(result, instr->slot_index())); 2163 __ ldr(result, ContextOperand(result, instr->slot_index()));
2183 } 2164 }
2184 2165
2185 2166
2186 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { 2167 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
2187 Register object = ToRegister(instr->input()); 2168 Register object = ToRegister(instr->InputAt(0));
2188 Register result = ToRegister(instr->result()); 2169 Register result = ToRegister(instr->result());
2189 if (instr->hydrogen()->is_in_object()) { 2170 if (instr->hydrogen()->is_in_object()) {
2190 __ ldr(result, FieldMemOperand(object, instr->hydrogen()->offset())); 2171 __ ldr(result, FieldMemOperand(object, instr->hydrogen()->offset()));
2191 } else { 2172 } else {
2192 __ ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); 2173 __ ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
2193 __ ldr(result, FieldMemOperand(result, instr->hydrogen()->offset())); 2174 __ ldr(result, FieldMemOperand(result, instr->hydrogen()->offset()));
2194 } 2175 }
2195 } 2176 }
2196 2177
2197 2178
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2244 // in initial map. 2225 // in initial map.
2245 __ bind(&non_instance); 2226 __ bind(&non_instance);
2246 __ ldr(result, FieldMemOperand(result, Map::kConstructorOffset)); 2227 __ ldr(result, FieldMemOperand(result, Map::kConstructorOffset));
2247 2228
2248 // All done. 2229 // All done.
2249 __ bind(&done); 2230 __ bind(&done);
2250 } 2231 }
2251 2232
2252 2233
2253 void LCodeGen::DoLoadElements(LLoadElements* instr) { 2234 void LCodeGen::DoLoadElements(LLoadElements* instr) {
2254 ASSERT(instr->result()->Equals(instr->input())); 2235 ASSERT(instr->result()->Equals(instr->InputAt(0)));
2255 Register reg = ToRegister(instr->input()); 2236 Register reg = ToRegister(instr->InputAt(0));
2256 Register scratch = scratch0(); 2237 Register scratch = scratch0();
2257 2238
2258 __ ldr(reg, FieldMemOperand(reg, JSObject::kElementsOffset)); 2239 __ ldr(reg, FieldMemOperand(reg, JSObject::kElementsOffset));
2259 if (FLAG_debug_code) { 2240 if (FLAG_debug_code) {
2260 Label done; 2241 Label done;
2261 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); 2242 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset));
2262 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); 2243 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
2263 __ cmp(scratch, ip); 2244 __ cmp(scratch, ip);
2264 __ b(eq, &done); 2245 __ b(eq, &done);
2265 __ LoadRoot(ip, Heap::kFixedCOWArrayMapRootIndex); 2246 __ LoadRoot(ip, Heap::kFixedCOWArrayMapRootIndex);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2326 __ cmp(result, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 2307 __ cmp(result, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
2327 2308
2328 // Result is the frame pointer for the frame if not adapted and for the real 2309 // Result is the frame pointer for the frame if not adapted and for the real
2329 // frame below the adaptor frame if adapted. 2310 // frame below the adaptor frame if adapted.
2330 __ mov(result, fp, LeaveCC, ne); 2311 __ mov(result, fp, LeaveCC, ne);
2331 __ mov(result, scratch, LeaveCC, eq); 2312 __ mov(result, scratch, LeaveCC, eq);
2332 } 2313 }
2333 2314
2334 2315
2335 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { 2316 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
2336 Register elem = ToRegister(instr->input()); 2317 Register elem = ToRegister(instr->InputAt(0));
2337 Register result = ToRegister(instr->result()); 2318 Register result = ToRegister(instr->result());
2338 2319
2339 Label done; 2320 Label done;
2340 2321
2341 // If no arguments adaptor frame the number of arguments is fixed. 2322 // If no arguments adaptor frame the number of arguments is fixed.
2342 __ cmp(fp, elem); 2323 __ cmp(fp, elem);
2343 __ mov(result, Operand(scope()->num_parameters())); 2324 __ mov(result, Operand(scope()->num_parameters()));
2344 __ b(eq, &done); 2325 __ b(eq, &done);
2345 2326
2346 // Arguments adaptor frame present. Get argument length from there. 2327 // Arguments adaptor frame present. Get argument length from there.
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2411 // which is r0, as expected by InvokeFunction. 2392 // which is r0, as expected by InvokeFunction.
2412 v8::internal::ParameterCount actual(receiver); 2393 v8::internal::ParameterCount actual(receiver);
2413 SafepointGenerator safepoint_generator(this, 2394 SafepointGenerator safepoint_generator(this,
2414 instr->pointer_map(), 2395 instr->pointer_map(),
2415 Safepoint::kNoDeoptimizationIndex); 2396 Safepoint::kNoDeoptimizationIndex);
2416 __ InvokeFunction(function, actual, CALL_FUNCTION, &safepoint_generator); 2397 __ InvokeFunction(function, actual, CALL_FUNCTION, &safepoint_generator);
2417 } 2398 }
2418 2399
2419 2400
2420 void LCodeGen::DoPushArgument(LPushArgument* instr) { 2401 void LCodeGen::DoPushArgument(LPushArgument* instr) {
2421 LOperand* argument = instr->input(); 2402 LOperand* argument = instr->InputAt(0);
2422 if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) { 2403 if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) {
2423 Abort("DoPushArgument not implemented for double type."); 2404 Abort("DoPushArgument not implemented for double type.");
2424 } else { 2405 } else {
2425 Register argument_reg = EmitLoadRegister(argument, ip); 2406 Register argument_reg = EmitLoadRegister(argument, ip);
2426 __ push(argument_reg); 2407 __ push(argument_reg);
2427 } 2408 }
2428 } 2409 }
2429 2410
2430 2411
2431 void LCodeGen::DoGlobalObject(LGlobalObject* instr) { 2412 void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2475 2456
2476 2457
2477 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { 2458 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
2478 ASSERT(ToRegister(instr->result()).is(r0)); 2459 ASSERT(ToRegister(instr->result()).is(r0));
2479 __ mov(r1, Operand(instr->function())); 2460 __ mov(r1, Operand(instr->function()));
2480 CallKnownFunction(instr->function(), instr->arity(), instr); 2461 CallKnownFunction(instr->function(), instr->arity(), instr);
2481 } 2462 }
2482 2463
2483 2464
2484 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { 2465 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
2485 Register input = ToRegister(instr->input()); 2466 Register input = ToRegister(instr->InputAt(0));
2486 Register scratch = scratch0(); 2467 Register scratch = scratch0();
2487 2468
2488 // Deoptimize if not a heap number. 2469 // Deoptimize if not a heap number.
2489 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); 2470 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
2490 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 2471 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
2491 __ cmp(scratch, Operand(ip)); 2472 __ cmp(scratch, Operand(ip));
2492 DeoptimizeIf(ne, instr->environment()); 2473 DeoptimizeIf(ne, instr->environment());
2493 2474
2494 Label done; 2475 Label done;
2495 Register tmp = input.is(r0) ? r1 : r0; 2476 Register tmp = input.is(r0) ? r1 : r0;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2538 __ str(tmp, input_register_slot); 2519 __ str(tmp, input_register_slot);
2539 __ PopSafepointRegisters(); 2520 __ PopSafepointRegisters();
2540 2521
2541 __ bind(&done); 2522 __ bind(&done);
2542 } 2523 }
2543 2524
2544 2525
2545 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { 2526 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
2546 Label is_positive; 2527 Label is_positive;
2547 uint32_t kSignMask = 0x80000000u; 2528 uint32_t kSignMask = 0x80000000u;
2548 Register input = ToRegister(instr->input()); 2529 Register input = ToRegister(instr->InputAt(0));
2549 __ tst(input, Operand(kSignMask)); 2530 __ tst(input, Operand(kSignMask));
2550 __ b(eq, &is_positive); 2531 __ b(eq, &is_positive);
2551 __ rsb(input, input, Operand(0), SetCC); 2532 __ rsb(input, input, Operand(0), SetCC);
2552 // Deoptimize on overflow. 2533 // Deoptimize on overflow.
2553 DeoptimizeIf(vs, instr->environment()); 2534 DeoptimizeIf(vs, instr->environment());
2554 __ bind(&is_positive); 2535 __ bind(&is_positive);
2555 } 2536 }
2556 2537
2557 2538
2558 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { 2539 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
2559 // Class for deferred case. 2540 // Class for deferred case.
2560 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { 2541 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
2561 public: 2542 public:
2562 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, 2543 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen,
2563 LUnaryMathOperation* instr) 2544 LUnaryMathOperation* instr)
2564 : LDeferredCode(codegen), instr_(instr) { } 2545 : LDeferredCode(codegen), instr_(instr) { }
2565 virtual void Generate() { 2546 virtual void Generate() {
2566 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 2547 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
2567 } 2548 }
2568 private: 2549 private:
2569 LUnaryMathOperation* instr_; 2550 LUnaryMathOperation* instr_;
2570 }; 2551 };
2571 2552
2572 ASSERT(instr->input()->Equals(instr->result())); 2553 ASSERT(instr->InputAt(0)->Equals(instr->result()));
2573 Representation r = instr->hydrogen()->value()->representation(); 2554 Representation r = instr->hydrogen()->value()->representation();
2574 if (r.IsDouble()) { 2555 if (r.IsDouble()) {
2575 DwVfpRegister input = ToDoubleRegister(instr->input()); 2556 DwVfpRegister input = ToDoubleRegister(instr->InputAt(0));
2576 // __ vabs(input, input); 2557 // __ vabs(input, input);
2577 Abort("Double DoMathAbs unimplemented"); 2558 Abort("Double DoMathAbs unimplemented");
2578 } else if (r.IsInteger32()) { 2559 } else if (r.IsInteger32()) {
2579 EmitIntegerMathAbs(instr); 2560 EmitIntegerMathAbs(instr);
2580 } else { 2561 } else {
2581 // Representation is tagged. 2562 // Representation is tagged.
2582 DeferredMathAbsTaggedHeapNumber* deferred = 2563 DeferredMathAbsTaggedHeapNumber* deferred =
2583 new DeferredMathAbsTaggedHeapNumber(this, instr); 2564 new DeferredMathAbsTaggedHeapNumber(this, instr);
2584 Register input = ToRegister(instr->input()); 2565 Register input = ToRegister(instr->InputAt(0));
2585 // Smi check. 2566 // Smi check.
2586 __ BranchOnNotSmi(input, deferred->entry()); 2567 __ BranchOnNotSmi(input, deferred->entry());
2587 // If smi, handle it directly. 2568 // If smi, handle it directly.
2588 EmitIntegerMathAbs(instr); 2569 EmitIntegerMathAbs(instr);
2589 __ bind(deferred->exit()); 2570 __ bind(deferred->exit());
2590 } 2571 }
2591 } 2572 }
2592 2573
2593 2574
2594 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { 2575 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
2595 DoubleRegister input = ToDoubleRegister(instr->input()); 2576 DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
2596 Register result = ToRegister(instr->result()); 2577 Register result = ToRegister(instr->result());
2597 Register prev_fpscr = ToRegister(instr->temp()); 2578 Register prev_fpscr = ToRegister(instr->TempAt(0));
2598 SwVfpRegister single_scratch = double_scratch0().low(); 2579 SwVfpRegister single_scratch = double_scratch0().low();
2599 Register scratch = scratch0(); 2580 Register scratch = scratch0();
2600 2581
2601 // Set custom FPCSR: 2582 // Set custom FPCSR:
2602 // - Set rounding mode to "Round towards Minus Infinity". 2583 // - Set rounding mode to "Round towards Minus Infinity".
2603 // - Clear vfp cumulative exception flags. 2584 // - Clear vfp cumulative exception flags.
2604 // - Make sure Flush-to-zero mode control bit is unset. 2585 // - Make sure Flush-to-zero mode control bit is unset.
2605 __ vmrs(prev_fpscr); 2586 __ vmrs(prev_fpscr);
2606 __ bic(scratch, prev_fpscr, 2587 __ bic(scratch, prev_fpscr,
2607 Operand(kVFPExceptionMask | kVFPRoundingModeMask | kVFPFlushToZeroMask)); 2588 Operand(kVFPExceptionMask | kVFPRoundingModeMask | kVFPFlushToZeroMask));
(...skipping 21 matching lines...) Expand all
2629 __ cmp(result, Operand(0)); 2610 __ cmp(result, Operand(0));
2630 __ b(ne, &done); 2611 __ b(ne, &done);
2631 __ vmov(scratch, input.high()); 2612 __ vmov(scratch, input.high());
2632 __ tst(scratch, Operand(HeapNumber::kSignMask)); 2613 __ tst(scratch, Operand(HeapNumber::kSignMask));
2633 DeoptimizeIf(ne, instr->environment()); 2614 DeoptimizeIf(ne, instr->environment());
2634 __ bind(&done); 2615 __ bind(&done);
2635 } 2616 }
2636 2617
2637 2618
2638 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { 2619 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
2639 DoubleRegister input = ToDoubleRegister(instr->input()); 2620 DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
2640 ASSERT(ToDoubleRegister(instr->result()).is(input)); 2621 ASSERT(ToDoubleRegister(instr->result()).is(input));
2641 __ vsqrt(input, input); 2622 __ vsqrt(input, input);
2642 } 2623 }
2643 2624
2644 2625
2645 void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) { 2626 void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) {
2646 switch (instr->op()) { 2627 switch (instr->op()) {
2647 case kMathAbs: 2628 case kMathAbs:
2648 DoMathAbs(instr); 2629 DoMathAbs(instr);
2649 break; 2630 break;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2705 2686
2706 2687
2707 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { 2688 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
2708 ASSERT(ToRegister(instr->result()).is(r0)); 2689 ASSERT(ToRegister(instr->result()).is(r0));
2709 __ mov(r1, Operand(instr->target())); 2690 __ mov(r1, Operand(instr->target()));
2710 CallKnownFunction(instr->target(), instr->arity(), instr); 2691 CallKnownFunction(instr->target(), instr->arity(), instr);
2711 } 2692 }
2712 2693
2713 2694
2714 void LCodeGen::DoCallNew(LCallNew* instr) { 2695 void LCodeGen::DoCallNew(LCallNew* instr) {
2715 ASSERT(ToRegister(instr->input()).is(r1)); 2696 ASSERT(ToRegister(instr->InputAt(0)).is(r1));
2716 ASSERT(ToRegister(instr->result()).is(r0)); 2697 ASSERT(ToRegister(instr->result()).is(r0));
2717 2698
2718 Handle<Code> builtin(Builtins::builtin(Builtins::JSConstructCall)); 2699 Handle<Code> builtin(Builtins::builtin(Builtins::JSConstructCall));
2719 __ mov(r0, Operand(instr->arity())); 2700 __ mov(r0, Operand(instr->arity()));
2720 CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr); 2701 CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr);
2721 } 2702 }
2722 2703
2723 2704
2724 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { 2705 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
2725 CallRuntime(instr->function(), instr->arity(), instr); 2706 CallRuntime(instr->function(), instr->arity(), instr);
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
2947 __ AbortIfNotSmi(r0); 2928 __ AbortIfNotSmi(r0);
2948 } 2929 }
2949 __ SmiUntag(r0); 2930 __ SmiUntag(r0);
2950 MemOperand result_stack_slot = masm()->SafepointRegisterSlot(result); 2931 MemOperand result_stack_slot = masm()->SafepointRegisterSlot(result);
2951 __ str(r0, result_stack_slot); 2932 __ str(r0, result_stack_slot);
2952 __ PopSafepointRegisters(); 2933 __ PopSafepointRegisters();
2953 } 2934 }
2954 2935
2955 2936
2956 void LCodeGen::DoStringLength(LStringLength* instr) { 2937 void LCodeGen::DoStringLength(LStringLength* instr) {
2957 Register string = ToRegister(instr->input()); 2938 Register string = ToRegister(instr->InputAt(0));
2958 Register result = ToRegister(instr->result()); 2939 Register result = ToRegister(instr->result());
2959 __ ldr(result, FieldMemOperand(string, String::kLengthOffset)); 2940 __ ldr(result, FieldMemOperand(string, String::kLengthOffset));
2960 } 2941 }
2961 2942
2962 2943
2963 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 2944 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
2964 LOperand* input = instr->input(); 2945 LOperand* input = instr->InputAt(0);
2965 ASSERT(input->IsRegister() || input->IsStackSlot()); 2946 ASSERT(input->IsRegister() || input->IsStackSlot());
2966 LOperand* output = instr->result(); 2947 LOperand* output = instr->result();
2967 ASSERT(output->IsDoubleRegister()); 2948 ASSERT(output->IsDoubleRegister());
2968 SwVfpRegister single_scratch = double_scratch0().low(); 2949 SwVfpRegister single_scratch = double_scratch0().low();
2969 if (input->IsStackSlot()) { 2950 if (input->IsStackSlot()) {
2970 Register scratch = scratch0(); 2951 Register scratch = scratch0();
2971 __ ldr(scratch, ToMemOperand(input)); 2952 __ ldr(scratch, ToMemOperand(input));
2972 __ vmov(single_scratch, scratch); 2953 __ vmov(single_scratch, scratch);
2973 } else { 2954 } else {
2974 __ vmov(single_scratch, ToRegister(input)); 2955 __ vmov(single_scratch, ToRegister(input));
2975 } 2956 }
2976 __ vcvt_f64_s32(ToDoubleRegister(output), single_scratch); 2957 __ vcvt_f64_s32(ToDoubleRegister(output), single_scratch);
2977 } 2958 }
2978 2959
2979 2960
2980 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 2961 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
2981 class DeferredNumberTagI: public LDeferredCode { 2962 class DeferredNumberTagI: public LDeferredCode {
2982 public: 2963 public:
2983 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) 2964 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
2984 : LDeferredCode(codegen), instr_(instr) { } 2965 : LDeferredCode(codegen), instr_(instr) { }
2985 virtual void Generate() { codegen()->DoDeferredNumberTagI(instr_); } 2966 virtual void Generate() { codegen()->DoDeferredNumberTagI(instr_); }
2986 private: 2967 private:
2987 LNumberTagI* instr_; 2968 LNumberTagI* instr_;
2988 }; 2969 };
2989 2970
2990 LOperand* input = instr->input(); 2971 LOperand* input = instr->InputAt(0);
2991 ASSERT(input->IsRegister() && input->Equals(instr->result())); 2972 ASSERT(input->IsRegister() && input->Equals(instr->result()));
2992 Register reg = ToRegister(input); 2973 Register reg = ToRegister(input);
2993 2974
2994 DeferredNumberTagI* deferred = new DeferredNumberTagI(this, instr); 2975 DeferredNumberTagI* deferred = new DeferredNumberTagI(this, instr);
2995 __ SmiTag(reg, SetCC); 2976 __ SmiTag(reg, SetCC);
2996 __ b(vs, deferred->entry()); 2977 __ b(vs, deferred->entry());
2997 __ bind(deferred->exit()); 2978 __ bind(deferred->exit());
2998 } 2979 }
2999 2980
3000 2981
3001 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) { 2982 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
3002 Label slow; 2983 Label slow;
3003 Register reg = ToRegister(instr->input()); 2984 Register reg = ToRegister(instr->InputAt(0));
3004 DoubleRegister dbl_scratch = d0; 2985 DoubleRegister dbl_scratch = d0;
3005 SwVfpRegister flt_scratch = s0; 2986 SwVfpRegister flt_scratch = s0;
3006 2987
3007 // Preserve the value of all registers. 2988 // Preserve the value of all registers.
3008 __ PushSafepointRegisters(); 2989 __ PushSafepointRegisters();
3009 2990
3010 // There was overflow, so bits 30 and 31 of the original integer 2991 // There was overflow, so bits 30 and 31 of the original integer
3011 // disagree. Try to allocate a heap number in new space and store 2992 // disagree. Try to allocate a heap number in new space and store
3012 // the value in there. If that fails, call the runtime system. 2993 // the value in there. If that fails, call the runtime system.
3013 Label done; 2994 Label done;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
3050 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { 3031 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
3051 class DeferredNumberTagD: public LDeferredCode { 3032 class DeferredNumberTagD: public LDeferredCode {
3052 public: 3033 public:
3053 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 3034 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
3054 : LDeferredCode(codegen), instr_(instr) { } 3035 : LDeferredCode(codegen), instr_(instr) { }
3055 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } 3036 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); }
3056 private: 3037 private:
3057 LNumberTagD* instr_; 3038 LNumberTagD* instr_;
3058 }; 3039 };
3059 3040
3060 DoubleRegister input_reg = ToDoubleRegister(instr->input()); 3041 DoubleRegister input_reg = ToDoubleRegister(instr->InputAt(0));
3061 Register scratch = scratch0(); 3042 Register scratch = scratch0();
3062 Register reg = ToRegister(instr->result()); 3043 Register reg = ToRegister(instr->result());
3063 Register temp1 = ToRegister(instr->temp1()); 3044 Register temp1 = ToRegister(instr->TempAt(0));
3064 Register temp2 = ToRegister(instr->temp2()); 3045 Register temp2 = ToRegister(instr->TempAt(1));
3065 3046
3066 DeferredNumberTagD* deferred = new DeferredNumberTagD(this, instr); 3047 DeferredNumberTagD* deferred = new DeferredNumberTagD(this, instr);
3067 if (FLAG_inline_new) { 3048 if (FLAG_inline_new) {
3068 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); 3049 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex);
3069 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry()); 3050 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry());
3070 } else { 3051 } else {
3071 __ jmp(deferred->entry()); 3052 __ jmp(deferred->entry());
3072 } 3053 }
3073 __ bind(deferred->exit()); 3054 __ bind(deferred->exit());
3074 __ sub(ip, reg, Operand(kHeapObjectTag)); 3055 __ sub(ip, reg, Operand(kHeapObjectTag));
(...skipping 12 matching lines...) Expand all
3087 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 3068 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
3088 RecordSafepointWithRegisters( 3069 RecordSafepointWithRegisters(
3089 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex); 3070 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex);
3090 int reg_stack_index = __ SafepointRegisterStackIndex(reg.code()); 3071 int reg_stack_index = __ SafepointRegisterStackIndex(reg.code());
3091 __ str(r0, MemOperand(sp, reg_stack_index * kPointerSize)); 3072 __ str(r0, MemOperand(sp, reg_stack_index * kPointerSize));
3092 __ PopSafepointRegisters(); 3073 __ PopSafepointRegisters();
3093 } 3074 }
3094 3075
3095 3076
3096 void LCodeGen::DoSmiTag(LSmiTag* instr) { 3077 void LCodeGen::DoSmiTag(LSmiTag* instr) {
3097 LOperand* input = instr->input(); 3078 LOperand* input = instr->InputAt(0);
3098 ASSERT(input->IsRegister() && input->Equals(instr->result())); 3079 ASSERT(input->IsRegister() && input->Equals(instr->result()));
3099 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)); 3080 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
3100 __ SmiTag(ToRegister(input)); 3081 __ SmiTag(ToRegister(input));
3101 } 3082 }
3102 3083
3103 3084
3104 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { 3085 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
3105 LOperand* input = instr->input(); 3086 LOperand* input = instr->InputAt(0);
3106 ASSERT(input->IsRegister() && input->Equals(instr->result())); 3087 ASSERT(input->IsRegister() && input->Equals(instr->result()));
3107 if (instr->needs_check()) { 3088 if (instr->needs_check()) {
3108 __ tst(ToRegister(input), Operand(kSmiTagMask)); 3089 __ tst(ToRegister(input), Operand(kSmiTagMask));
3109 DeoptimizeIf(ne, instr->environment()); 3090 DeoptimizeIf(ne, instr->environment());
3110 } 3091 }
3111 __ SmiUntag(ToRegister(input)); 3092 __ SmiUntag(ToRegister(input));
3112 } 3093 }
3113 3094
3114 3095
3115 void LCodeGen::EmitNumberUntagD(Register input_reg, 3096 void LCodeGen::EmitNumberUntagD(Register input_reg,
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
3162 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) 3143 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
3163 : LDeferredCode(codegen), instr_(instr) { } 3144 : LDeferredCode(codegen), instr_(instr) { }
3164 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } 3145 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); }
3165 private: 3146 private:
3166 LTaggedToI* instr_; 3147 LTaggedToI* instr_;
3167 }; 3148 };
3168 3149
3169 3150
3170 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { 3151 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
3171 Label done; 3152 Label done;
3172 Register input_reg = ToRegister(instr->input()); 3153 Register input_reg = ToRegister(instr->InputAt(0));
3173 Register scratch = scratch0(); 3154 Register scratch = scratch0();
3174 DoubleRegister dbl_scratch = d0; 3155 DoubleRegister dbl_scratch = d0;
3175 SwVfpRegister flt_scratch = s0; 3156 SwVfpRegister flt_scratch = s0;
3176 DoubleRegister dbl_tmp = ToDoubleRegister(instr->temp()); 3157 DoubleRegister dbl_tmp = ToDoubleRegister(instr->TempAt(0));
3177 3158
3178 // Heap number map check. 3159 // Heap number map check.
3179 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 3160 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
3180 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 3161 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
3181 __ cmp(scratch, Operand(ip)); 3162 __ cmp(scratch, Operand(ip));
3182 3163
3183 if (instr->truncating()) { 3164 if (instr->truncating()) {
3184 Label heap_number; 3165 Label heap_number;
3185 __ b(eq, &heap_number); 3166 __ b(eq, &heap_number);
3186 // Check for undefined. Undefined is converted to zero for truncating 3167 // Check for undefined. Undefined is converted to zero for truncating
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
3223 __ vmov(lr, ip, dbl_tmp); 3204 __ vmov(lr, ip, dbl_tmp);
3224 __ tst(ip, Operand(1 << 31)); // Test sign bit. 3205 __ tst(ip, Operand(1 << 31)); // Test sign bit.
3225 DeoptimizeIf(ne, instr->environment()); 3206 DeoptimizeIf(ne, instr->environment());
3226 } 3207 }
3227 } 3208 }
3228 __ bind(&done); 3209 __ bind(&done);
3229 } 3210 }
3230 3211
3231 3212
3232 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { 3213 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
3233 LOperand* input = instr->input(); 3214 LOperand* input = instr->InputAt(0);
3234 ASSERT(input->IsRegister()); 3215 ASSERT(input->IsRegister());
3235 ASSERT(input->Equals(instr->result())); 3216 ASSERT(input->Equals(instr->result()));
3236 3217
3237 Register input_reg = ToRegister(input); 3218 Register input_reg = ToRegister(input);
3238 3219
3239 DeferredTaggedToI* deferred = new DeferredTaggedToI(this, instr); 3220 DeferredTaggedToI* deferred = new DeferredTaggedToI(this, instr);
3240 3221
3241 // Smi check. 3222 // Smi check.
3242 __ tst(input_reg, Operand(kSmiTagMask)); 3223 __ tst(input_reg, Operand(kSmiTagMask));
3243 __ b(ne, deferred->entry()); 3224 __ b(ne, deferred->entry());
3244 3225
3245 // Smi to int32 conversion 3226 // Smi to int32 conversion
3246 __ SmiUntag(input_reg); // Untag smi. 3227 __ SmiUntag(input_reg); // Untag smi.
3247 3228
3248 __ bind(deferred->exit()); 3229 __ bind(deferred->exit());
3249 } 3230 }
3250 3231
3251 3232
3252 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { 3233 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
3253 LOperand* input = instr->input(); 3234 LOperand* input = instr->InputAt(0);
3254 ASSERT(input->IsRegister()); 3235 ASSERT(input->IsRegister());
3255 LOperand* result = instr->result(); 3236 LOperand* result = instr->result();
3256 ASSERT(result->IsDoubleRegister()); 3237 ASSERT(result->IsDoubleRegister());
3257 3238
3258 Register input_reg = ToRegister(input); 3239 Register input_reg = ToRegister(input);
3259 DoubleRegister result_reg = ToDoubleRegister(result); 3240 DoubleRegister result_reg = ToDoubleRegister(result);
3260 3241
3261 EmitNumberUntagD(input_reg, result_reg, instr->environment()); 3242 EmitNumberUntagD(input_reg, result_reg, instr->environment());
3262 } 3243 }
3263 3244
3264 3245
3265 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { 3246 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
3266 Abort("DoDoubleToI unimplemented."); 3247 Abort("DoDoubleToI unimplemented.");
3267 } 3248 }
3268 3249
3269 3250
3270 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { 3251 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
3271 LOperand* input = instr->input(); 3252 LOperand* input = instr->InputAt(0);
3272 ASSERT(input->IsRegister()); 3253 ASSERT(input->IsRegister());
3273 __ tst(ToRegister(input), Operand(kSmiTagMask)); 3254 __ tst(ToRegister(input), Operand(kSmiTagMask));
3274 DeoptimizeIf(instr->condition(), instr->environment()); 3255 DeoptimizeIf(instr->condition(), instr->environment());
3275 } 3256 }
3276 3257
3277 3258
3278 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 3259 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
3279 Register input = ToRegister(instr->input()); 3260 Register input = ToRegister(instr->InputAt(0));
3280 Register scratch = scratch0(); 3261 Register scratch = scratch0();
3281 InstanceType first = instr->hydrogen()->first(); 3262 InstanceType first = instr->hydrogen()->first();
3282 InstanceType last = instr->hydrogen()->last(); 3263 InstanceType last = instr->hydrogen()->last();
3283 3264
3284 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); 3265 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
3285 __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset)); 3266 __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
3286 __ cmp(scratch, Operand(first)); 3267 __ cmp(scratch, Operand(first));
3287 3268
3288 // If there is only one type in the interval check for equality. 3269 // If there is only one type in the interval check for equality.
3289 if (first == last) { 3270 if (first == last) {
3290 DeoptimizeIf(ne, instr->environment()); 3271 DeoptimizeIf(ne, instr->environment());
3291 } else { 3272 } else {
3292 DeoptimizeIf(lo, instr->environment()); 3273 DeoptimizeIf(lo, instr->environment());
3293 // Omit check for the last type. 3274 // Omit check for the last type.
3294 if (last != LAST_TYPE) { 3275 if (last != LAST_TYPE) {
3295 __ cmp(scratch, Operand(last)); 3276 __ cmp(scratch, Operand(last));
3296 DeoptimizeIf(hi, instr->environment()); 3277 DeoptimizeIf(hi, instr->environment());
3297 } 3278 }
3298 } 3279 }
3299 } 3280 }
3300 3281
3301 3282
3302 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { 3283 void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
3303 ASSERT(instr->input()->IsRegister()); 3284 ASSERT(instr->InputAt(0)->IsRegister());
3304 Register reg = ToRegister(instr->input()); 3285 Register reg = ToRegister(instr->InputAt(0));
3305 __ cmp(reg, Operand(instr->hydrogen()->target())); 3286 __ cmp(reg, Operand(instr->hydrogen()->target()));
3306 DeoptimizeIf(ne, instr->environment()); 3287 DeoptimizeIf(ne, instr->environment());
3307 } 3288 }
3308 3289
3309 3290
3310 void LCodeGen::DoCheckMap(LCheckMap* instr) { 3291 void LCodeGen::DoCheckMap(LCheckMap* instr) {
3311 Register scratch = scratch0(); 3292 Register scratch = scratch0();
3312 LOperand* input = instr->input(); 3293 LOperand* input = instr->InputAt(0);
3313 ASSERT(input->IsRegister()); 3294 ASSERT(input->IsRegister());
3314 Register reg = ToRegister(input); 3295 Register reg = ToRegister(input);
3315 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); 3296 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset));
3316 __ cmp(scratch, Operand(instr->hydrogen()->map())); 3297 __ cmp(scratch, Operand(instr->hydrogen()->map()));
3317 DeoptimizeIf(ne, instr->environment()); 3298 DeoptimizeIf(ne, instr->environment());
3318 } 3299 }
3319 3300
3320 3301
3321 void LCodeGen::LoadHeapObject(Register result, 3302 void LCodeGen::LoadHeapObject(Register result,
3322 Handle<HeapObject> object) { 3303 Handle<HeapObject> object) {
3323 if (Heap::InNewSpace(*object)) { 3304 if (Heap::InNewSpace(*object)) {
3324 Handle<JSGlobalPropertyCell> cell = 3305 Handle<JSGlobalPropertyCell> cell =
3325 Factory::NewJSGlobalPropertyCell(object); 3306 Factory::NewJSGlobalPropertyCell(object);
3326 __ mov(result, Operand(cell)); 3307 __ mov(result, Operand(cell));
3327 __ ldr(result, FieldMemOperand(result, JSGlobalPropertyCell::kValueOffset)); 3308 __ ldr(result, FieldMemOperand(result, JSGlobalPropertyCell::kValueOffset));
3328 } else { 3309 } else {
3329 __ mov(result, Operand(object)); 3310 __ mov(result, Operand(object));
3330 } 3311 }
3331 } 3312 }
3332 3313
3333 3314
3334 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { 3315 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
3335 Register temp1 = ToRegister(instr->temp1()); 3316 Register temp1 = ToRegister(instr->TempAt(0));
3336 Register temp2 = ToRegister(instr->temp2()); 3317 Register temp2 = ToRegister(instr->TempAt(1));
3337 3318
3338 Handle<JSObject> holder = instr->holder(); 3319 Handle<JSObject> holder = instr->holder();
3339 Handle<JSObject> current_prototype = instr->prototype(); 3320 Handle<JSObject> current_prototype = instr->prototype();
3340 3321
3341 // Load prototype object. 3322 // Load prototype object.
3342 LoadHeapObject(temp1, current_prototype); 3323 LoadHeapObject(temp1, current_prototype);
3343 3324
3344 // Check prototype maps up to the holder. 3325 // Check prototype maps up to the holder.
3345 while (!current_prototype.is_identical_to(holder)) { 3326 while (!current_prototype.is_identical_to(holder)) {
3346 __ ldr(temp2, FieldMemOperand(temp1, HeapObject::kMapOffset)); 3327 __ ldr(temp2, FieldMemOperand(temp1, HeapObject::kMapOffset));
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
3474 __ mov(r1, Operand(pretenure 3455 __ mov(r1, Operand(pretenure
3475 ? Factory::true_value() 3456 ? Factory::true_value()
3476 : Factory::false_value())); 3457 : Factory::false_value()));
3477 __ Push(cp, r2, r1); 3458 __ Push(cp, r2, r1);
3478 CallRuntime(Runtime::kNewClosure, 3, instr); 3459 CallRuntime(Runtime::kNewClosure, 3, instr);
3479 } 3460 }
3480 } 3461 }
3481 3462
3482 3463
3483 void LCodeGen::DoTypeof(LTypeof* instr) { 3464 void LCodeGen::DoTypeof(LTypeof* instr) {
3484 Register input = ToRegister(instr->input()); 3465 Register input = ToRegister(instr->InputAt(0));
3485 __ push(input); 3466 __ push(input);
3486 CallRuntime(Runtime::kTypeof, 1, instr); 3467 CallRuntime(Runtime::kTypeof, 1, instr);
3487 } 3468 }
3488 3469
3489 3470
3490 void LCodeGen::DoTypeofIs(LTypeofIs* instr) { 3471 void LCodeGen::DoTypeofIs(LTypeofIs* instr) {
3491 Register input = ToRegister(instr->input()); 3472 Register input = ToRegister(instr->InputAt(0));
3492 Register result = ToRegister(instr->result()); 3473 Register result = ToRegister(instr->result());
3493 Label true_label; 3474 Label true_label;
3494 Label false_label; 3475 Label false_label;
3495 Label done; 3476 Label done;
3496 3477
3497 Condition final_branch_condition = EmitTypeofIs(&true_label, 3478 Condition final_branch_condition = EmitTypeofIs(&true_label,
3498 &false_label, 3479 &false_label,
3499 input, 3480 input,
3500 instr->type_literal()); 3481 instr->type_literal());
3501 __ b(final_branch_condition, &true_label); 3482 __ b(final_branch_condition, &true_label);
3502 __ bind(&false_label); 3483 __ bind(&false_label);
3503 __ LoadRoot(result, Heap::kFalseValueRootIndex); 3484 __ LoadRoot(result, Heap::kFalseValueRootIndex);
3504 __ b(&done); 3485 __ b(&done);
3505 3486
3506 __ bind(&true_label); 3487 __ bind(&true_label);
3507 __ LoadRoot(result, Heap::kTrueValueRootIndex); 3488 __ LoadRoot(result, Heap::kTrueValueRootIndex);
3508 3489
3509 __ bind(&done); 3490 __ bind(&done);
3510 } 3491 }
3511 3492
3512 3493
3513 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { 3494 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
3514 Register input = ToRegister(instr->input()); 3495 Register input = ToRegister(instr->InputAt(0));
3515 int true_block = chunk_->LookupDestination(instr->true_block_id()); 3496 int true_block = chunk_->LookupDestination(instr->true_block_id());
3516 int false_block = chunk_->LookupDestination(instr->false_block_id()); 3497 int false_block = chunk_->LookupDestination(instr->false_block_id());
3517 Label* true_label = chunk_->GetAssemblyLabel(true_block); 3498 Label* true_label = chunk_->GetAssemblyLabel(true_block);
3518 Label* false_label = chunk_->GetAssemblyLabel(false_block); 3499 Label* false_label = chunk_->GetAssemblyLabel(false_block);
3519 3500
3520 Condition final_branch_condition = EmitTypeofIs(true_label, 3501 Condition final_branch_condition = EmitTypeofIs(true_label,
3521 false_label, 3502 false_label,
3522 input, 3503 input,
3523 instr->type_literal()); 3504 instr->type_literal());
3524 3505
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
3644 3625
3645 3626
3646 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { 3627 void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
3647 Abort("DoOsrEntry unimplemented."); 3628 Abort("DoOsrEntry unimplemented.");
3648 } 3629 }
3649 3630
3650 3631
3651 #undef __ 3632 #undef __
3652 3633
3653 } } // namespace v8::internal 3634 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698