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

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

Issue 7281009: Version 3.4.8... (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 5 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/arm/macro-assembler-arm.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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 855 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 866
867 867
868 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 868 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
869 // Nothing to do. 869 // Nothing to do.
870 } 870 }
871 871
872 872
873 void LCodeGen::DoModI(LModI* instr) { 873 void LCodeGen::DoModI(LModI* instr) {
874 if (instr->hydrogen()->HasPowerOf2Divisor()) { 874 if (instr->hydrogen()->HasPowerOf2Divisor()) {
875 Register dividend = ToRegister(instr->InputAt(0)); 875 Register dividend = ToRegister(instr->InputAt(0));
876 Register result = ToRegister(instr->result());
876 877
877 int32_t divisor = 878 int32_t divisor =
878 HConstant::cast(instr->hydrogen()->right())->Integer32Value(); 879 HConstant::cast(instr->hydrogen()->right())->Integer32Value();
879 880
880 if (divisor < 0) divisor = -divisor; 881 if (divisor < 0) divisor = -divisor;
881 882
882 Label positive_dividend, done; 883 Label positive_dividend, done;
883 __ cmp(dividend, Operand(0)); 884 __ cmp(dividend, Operand(0));
884 __ b(pl, &positive_dividend); 885 __ b(pl, &positive_dividend);
885 __ rsb(dividend, dividend, Operand(0)); 886 __ rsb(result, dividend, Operand(0));
886 __ and_(dividend, dividend, Operand(divisor - 1)); 887 __ and_(result, result, Operand(divisor - 1), SetCC);
887 __ rsb(dividend, dividend, Operand(0), SetCC);
888 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 888 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
889 __ b(ne, &done); 889 DeoptimizeIf(eq, instr->environment());
890 DeoptimizeIf(al, instr->environment());
891 } else {
892 __ b(&done);
893 } 890 }
891 __ rsb(result, result, Operand(0));
892 __ b(&done);
894 __ bind(&positive_dividend); 893 __ bind(&positive_dividend);
895 __ and_(dividend, dividend, Operand(divisor - 1)); 894 __ and_(result, dividend, Operand(divisor - 1));
896 __ bind(&done); 895 __ bind(&done);
897 return; 896 return;
898 } 897 }
899 898
900 // These registers hold untagged 32 bit values. 899 // These registers hold untagged 32 bit values.
901 Register left = ToRegister(instr->InputAt(0)); 900 Register left = ToRegister(instr->InputAt(0));
902 Register right = ToRegister(instr->InputAt(1)); 901 Register right = ToRegister(instr->InputAt(1));
903 Register result = ToRegister(instr->result()); 902 Register result = ToRegister(instr->result());
904 903
905 Register scratch = scratch0(); 904 Register scratch = scratch0();
906 Register scratch2 = ToRegister(instr->TempAt(0)); 905 Register scratch2 = ToRegister(instr->TempAt(0));
907 DwVfpRegister dividend = ToDoubleRegister(instr->TempAt(1)); 906 DwVfpRegister dividend = ToDoubleRegister(instr->TempAt(1));
908 DwVfpRegister divisor = ToDoubleRegister(instr->TempAt(2)); 907 DwVfpRegister divisor = ToDoubleRegister(instr->TempAt(2));
909 DwVfpRegister quotient = double_scratch0(); 908 DwVfpRegister quotient = double_scratch0();
910 909
911 ASSERT(result.is(left));
912
913 ASSERT(!dividend.is(divisor)); 910 ASSERT(!dividend.is(divisor));
914 ASSERT(!dividend.is(quotient)); 911 ASSERT(!dividend.is(quotient));
915 ASSERT(!divisor.is(quotient)); 912 ASSERT(!divisor.is(quotient));
916 ASSERT(!scratch.is(left)); 913 ASSERT(!scratch.is(left));
917 ASSERT(!scratch.is(right)); 914 ASSERT(!scratch.is(right));
918 ASSERT(!scratch.is(result)); 915 ASSERT(!scratch.is(result));
919 916
920 Label done, vfp_modulo, both_positive, right_negative; 917 Label done, vfp_modulo, both_positive, right_negative;
921 918
922 // Check for x % 0. 919 // Check for x % 0.
923 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 920 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
924 __ cmp(right, Operand(0)); 921 __ cmp(right, Operand(0));
925 DeoptimizeIf(eq, instr->environment()); 922 DeoptimizeIf(eq, instr->environment());
926 } 923 }
927 924
925 __ Move(result, left);
926
928 // (0 % x) must yield 0 (if x is finite, which is the case here). 927 // (0 % x) must yield 0 (if x is finite, which is the case here).
929 __ cmp(left, Operand(0)); 928 __ cmp(left, Operand(0));
930 __ b(eq, &done); 929 __ b(eq, &done);
931 // Preload right in a vfp register. 930 // Preload right in a vfp register.
932 __ vmov(divisor.low(), right); 931 __ vmov(divisor.low(), right);
933 __ b(lt, &vfp_modulo); 932 __ b(lt, &vfp_modulo);
934 933
935 __ cmp(left, Operand(right)); 934 __ cmp(left, Operand(right));
936 __ b(lt, &done); 935 __ b(lt, &done);
937 936
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
1113 __ CallStub(&stub); 1112 __ CallStub(&stub);
1114 RecordSafepointWithRegistersAndDoubles(instr->pointer_map(), 1113 RecordSafepointWithRegistersAndDoubles(instr->pointer_map(),
1115 0, 1114 0,
1116 Safepoint::kNoDeoptimizationIndex); 1115 Safepoint::kNoDeoptimizationIndex);
1117 // Overwrite the stored value of r0 with the result of the stub. 1116 // Overwrite the stored value of r0 with the result of the stub.
1118 __ StoreToSafepointRegistersAndDoublesSlot(r0, r0); 1117 __ StoreToSafepointRegistersAndDoublesSlot(r0, r0);
1119 } 1118 }
1120 1119
1121 1120
1122 void LCodeGen::DoMulI(LMulI* instr) { 1121 void LCodeGen::DoMulI(LMulI* instr) {
1123 ASSERT(instr->result()->Equals(instr->InputAt(0)));
1124 Register scratch = scratch0(); 1122 Register scratch = scratch0();
1125 Register result = ToRegister(instr->result()); 1123 Register result = ToRegister(instr->result());
1124 // Note that result may alias left.
1126 Register left = ToRegister(instr->InputAt(0)); 1125 Register left = ToRegister(instr->InputAt(0));
1127 LOperand* right_op = instr->InputAt(1); 1126 LOperand* right_op = instr->InputAt(1);
1128 1127
1129 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1128 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1130 bool bailout_on_minus_zero = 1129 bool bailout_on_minus_zero =
1131 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); 1130 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
1132 1131
1133 if (right_op->IsConstantOperand() && !can_overflow) { 1132 if (right_op->IsConstantOperand() && !can_overflow) {
1134 // Use optimized code for specific constants. 1133 // Use optimized code for specific constants.
1135 int32_t constant = ToInteger32(LConstantOperand::cast(right_op)); 1134 int32_t constant = ToInteger32(LConstantOperand::cast(right_op));
(...skipping 12 matching lines...) Expand all
1148 case 0: 1147 case 0:
1149 if (bailout_on_minus_zero) { 1148 if (bailout_on_minus_zero) {
1150 // If left is strictly negative and the constant is null, the 1149 // If left is strictly negative and the constant is null, the
1151 // result is -0. Deoptimize if required, otherwise return 0. 1150 // result is -0. Deoptimize if required, otherwise return 0.
1152 __ cmp(left, Operand(0)); 1151 __ cmp(left, Operand(0));
1153 DeoptimizeIf(mi, instr->environment()); 1152 DeoptimizeIf(mi, instr->environment());
1154 } 1153 }
1155 __ mov(result, Operand(0)); 1154 __ mov(result, Operand(0));
1156 break; 1155 break;
1157 case 1: 1156 case 1:
1158 // Nothing to do. 1157 __ Move(result, left);
1159 break; 1158 break;
1160 default: 1159 default:
1161 // Multiplying by powers of two and powers of two plus or minus 1160 // Multiplying by powers of two and powers of two plus or minus
1162 // one can be done faster with shifted operands. 1161 // one can be done faster with shifted operands.
1163 // For other constants we emit standard code. 1162 // For other constants we emit standard code.
1164 int32_t mask = constant >> 31; 1163 int32_t mask = constant >> 31;
1165 uint32_t constant_abs = (constant + mask) ^ mask; 1164 uint32_t constant_abs = (constant + mask) ^ mask;
1166 1165
1167 if (IsPowerOf2(constant_abs) || 1166 if (IsPowerOf2(constant_abs) ||
1168 IsPowerOf2(constant_abs - 1) || 1167 IsPowerOf2(constant_abs - 1) ||
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1210 __ b(ne, &done); 1209 __ b(ne, &done);
1211 __ cmp(ToRegister(instr->TempAt(0)), Operand(0)); 1210 __ cmp(ToRegister(instr->TempAt(0)), Operand(0));
1212 DeoptimizeIf(mi, instr->environment()); 1211 DeoptimizeIf(mi, instr->environment());
1213 __ bind(&done); 1212 __ bind(&done);
1214 } 1213 }
1215 } 1214 }
1216 } 1215 }
1217 1216
1218 1217
1219 void LCodeGen::DoBitI(LBitI* instr) { 1218 void LCodeGen::DoBitI(LBitI* instr) {
1220 LOperand* left = instr->InputAt(0); 1219 LOperand* left_op = instr->InputAt(0);
1221 LOperand* right = instr->InputAt(1); 1220 LOperand* right_op = instr->InputAt(1);
1222 ASSERT(left->Equals(instr->result())); 1221 ASSERT(left_op->IsRegister());
1223 ASSERT(left->IsRegister()); 1222 Register left = ToRegister(left_op);
1224 Register result = ToRegister(left); 1223 Register result = ToRegister(instr->result());
1225 Operand right_operand(no_reg); 1224 Operand right(no_reg);
1226 1225
1227 if (right->IsStackSlot() || right->IsArgument()) { 1226 if (right_op->IsStackSlot() || right_op->IsArgument()) {
1228 Register right_reg = EmitLoadRegister(right, ip); 1227 right = Operand(EmitLoadRegister(right_op, ip));
1229 right_operand = Operand(right_reg);
1230 } else { 1228 } else {
1231 ASSERT(right->IsRegister() || right->IsConstantOperand()); 1229 ASSERT(right_op->IsRegister() || right_op->IsConstantOperand());
1232 right_operand = ToOperand(right); 1230 right = ToOperand(right_op);
1233 } 1231 }
1234 1232
1235 switch (instr->op()) { 1233 switch (instr->op()) {
1236 case Token::BIT_AND: 1234 case Token::BIT_AND:
1237 __ and_(result, ToRegister(left), right_operand); 1235 __ and_(result, left, right);
1238 break; 1236 break;
1239 case Token::BIT_OR: 1237 case Token::BIT_OR:
1240 __ orr(result, ToRegister(left), right_operand); 1238 __ orr(result, left, right);
1241 break; 1239 break;
1242 case Token::BIT_XOR: 1240 case Token::BIT_XOR:
1243 __ eor(result, ToRegister(left), right_operand); 1241 __ eor(result, left, right);
1244 break; 1242 break;
1245 default: 1243 default:
1246 UNREACHABLE(); 1244 UNREACHABLE();
1247 break; 1245 break;
1248 } 1246 }
1249 } 1247 }
1250 1248
1251 1249
1252 void LCodeGen::DoShiftI(LShiftI* instr) { 1250 void LCodeGen::DoShiftI(LShiftI* instr) {
1251 // Both 'left' and 'right' are "used at start" (see LCodeGen::DoShift), so
1252 // result may alias either of them.
1253 LOperand* right_op = instr->InputAt(1);
1254 Register left = ToRegister(instr->InputAt(0));
1255 Register result = ToRegister(instr->result());
1253 Register scratch = scratch0(); 1256 Register scratch = scratch0();
1254 LOperand* left = instr->InputAt(0); 1257 if (right_op->IsRegister()) {
1255 LOperand* right = instr->InputAt(1); 1258 // Mask the right_op operand.
1256 ASSERT(left->Equals(instr->result())); 1259 __ and_(scratch, ToRegister(right_op), Operand(0x1F));
1257 ASSERT(left->IsRegister());
1258 Register result = ToRegister(left);
1259 if (right->IsRegister()) {
1260 // Mask the right operand.
1261 __ and_(scratch, ToRegister(right), Operand(0x1F));
1262 switch (instr->op()) { 1260 switch (instr->op()) {
1263 case Token::SAR: 1261 case Token::SAR:
1264 __ mov(result, Operand(result, ASR, scratch)); 1262 __ mov(result, Operand(left, ASR, scratch));
1265 break; 1263 break;
1266 case Token::SHR: 1264 case Token::SHR:
1267 if (instr->can_deopt()) { 1265 if (instr->can_deopt()) {
1268 __ mov(result, Operand(result, LSR, scratch), SetCC); 1266 __ mov(result, Operand(left, LSR, scratch), SetCC);
1269 DeoptimizeIf(mi, instr->environment()); 1267 DeoptimizeIf(mi, instr->environment());
1270 } else { 1268 } else {
1271 __ mov(result, Operand(result, LSR, scratch)); 1269 __ mov(result, Operand(left, LSR, scratch));
1272 } 1270 }
1273 break; 1271 break;
1274 case Token::SHL: 1272 case Token::SHL:
1275 __ mov(result, Operand(result, LSL, scratch)); 1273 __ mov(result, Operand(left, LSL, scratch));
1276 break; 1274 break;
1277 default: 1275 default:
1278 UNREACHABLE(); 1276 UNREACHABLE();
1279 break; 1277 break;
1280 } 1278 }
1281 } else { 1279 } else {
1282 int value = ToInteger32(LConstantOperand::cast(right)); 1280 // Mask the right_op operand.
1281 int value = ToInteger32(LConstantOperand::cast(right_op));
1283 uint8_t shift_count = static_cast<uint8_t>(value & 0x1F); 1282 uint8_t shift_count = static_cast<uint8_t>(value & 0x1F);
1284 switch (instr->op()) { 1283 switch (instr->op()) {
1285 case Token::SAR: 1284 case Token::SAR:
1286 if (shift_count != 0) { 1285 if (shift_count != 0) {
1287 __ mov(result, Operand(result, ASR, shift_count)); 1286 __ mov(result, Operand(left, ASR, shift_count));
1287 } else {
1288 __ Move(result, left);
1288 } 1289 }
1289 break; 1290 break;
1290 case Token::SHR: 1291 case Token::SHR:
1291 if (shift_count == 0 && instr->can_deopt()) { 1292 if (shift_count != 0) {
1292 __ tst(result, Operand(0x80000000)); 1293 __ mov(result, Operand(left, LSR, shift_count));
1293 DeoptimizeIf(ne, instr->environment());
1294 } else { 1294 } else {
1295 __ mov(result, Operand(result, LSR, shift_count)); 1295 if (instr->can_deopt()) {
1296 __ tst(left, Operand(0x80000000));
1297 DeoptimizeIf(ne, instr->environment());
1298 }
1299 __ Move(result, left);
1296 } 1300 }
1297 break; 1301 break;
1298 case Token::SHL: 1302 case Token::SHL:
1299 if (shift_count != 0) { 1303 if (shift_count != 0) {
1300 __ mov(result, Operand(result, LSL, shift_count)); 1304 __ mov(result, Operand(left, LSL, shift_count));
1305 } else {
1306 __ Move(result, left);
1301 } 1307 }
1302 break; 1308 break;
1303 default: 1309 default:
1304 UNREACHABLE(); 1310 UNREACHABLE();
1305 break; 1311 break;
1306 } 1312 }
1307 } 1313 }
1308 } 1314 }
1309 1315
1310 1316
1311 void LCodeGen::DoSubI(LSubI* instr) { 1317 void LCodeGen::DoSubI(LSubI* instr) {
1312 LOperand* left = instr->InputAt(0); 1318 LOperand* left = instr->InputAt(0);
1313 LOperand* right = instr->InputAt(1); 1319 LOperand* right = instr->InputAt(1);
1314 ASSERT(left->Equals(instr->result())); 1320 LOperand* result = instr->result();
1315 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1321 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1316 SBit set_cond = can_overflow ? SetCC : LeaveCC; 1322 SBit set_cond = can_overflow ? SetCC : LeaveCC;
1317 1323
1318 if (right->IsStackSlot() || right->IsArgument()) { 1324 if (right->IsStackSlot() || right->IsArgument()) {
1319 Register right_reg = EmitLoadRegister(right, ip); 1325 Register right_reg = EmitLoadRegister(right, ip);
1320 __ sub(ToRegister(left), ToRegister(left), Operand(right_reg), set_cond); 1326 __ sub(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond);
1321 } else { 1327 } else {
1322 ASSERT(right->IsRegister() || right->IsConstantOperand()); 1328 ASSERT(right->IsRegister() || right->IsConstantOperand());
1323 __ sub(ToRegister(left), ToRegister(left), ToOperand(right), set_cond); 1329 __ sub(ToRegister(result), ToRegister(left), ToOperand(right), set_cond);
1324 } 1330 }
1325 1331
1326 if (can_overflow) { 1332 if (can_overflow) {
1327 DeoptimizeIf(vs, instr->environment()); 1333 DeoptimizeIf(vs, instr->environment());
1328 } 1334 }
1329 } 1335 }
1330 1336
1331 1337
1332 void LCodeGen::DoConstantI(LConstantI* instr) { 1338 void LCodeGen::DoConstantI(LConstantI* instr) {
1333 ASSERT(instr->result()->IsRegister()); 1339 ASSERT(instr->result()->IsRegister());
1334 __ mov(ToRegister(instr->result()), Operand(instr->value())); 1340 __ mov(ToRegister(instr->result()), Operand(instr->value()));
1335 } 1341 }
1336 1342
1337 1343
1338 void LCodeGen::DoConstantD(LConstantD* instr) { 1344 void LCodeGen::DoConstantD(LConstantD* instr) {
1339 ASSERT(instr->result()->IsDoubleRegister()); 1345 ASSERT(instr->result()->IsDoubleRegister());
1340 DwVfpRegister result = ToDoubleRegister(instr->result()); 1346 DwVfpRegister result = ToDoubleRegister(instr->result());
1341 double v = instr->value(); 1347 double v = instr->value();
1342 __ vmov(result, v); 1348 __ Vmov(result, v);
1343 } 1349 }
1344 1350
1345 1351
1346 void LCodeGen::DoConstantT(LConstantT* instr) { 1352 void LCodeGen::DoConstantT(LConstantT* instr) {
1347 ASSERT(instr->result()->IsRegister()); 1353 ASSERT(instr->result()->IsRegister());
1348 __ mov(ToRegister(instr->result()), Operand(instr->value())); 1354 __ mov(ToRegister(instr->result()), Operand(instr->value()));
1349 } 1355 }
1350 1356
1351 1357
1352 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { 1358 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
(...skipping 28 matching lines...) Expand all
1381 __ ldr(result, FieldMemOperand(result, Map::kBitField2Offset)); 1387 __ ldr(result, FieldMemOperand(result, Map::kBitField2Offset));
1382 // Retrieve elements_kind from bit field 2. 1388 // Retrieve elements_kind from bit field 2.
1383 __ ubfx(result, result, Map::kElementsKindShift, Map::kElementsKindBitCount); 1389 __ ubfx(result, result, Map::kElementsKindShift, Map::kElementsKindBitCount);
1384 } 1390 }
1385 1391
1386 1392
1387 void LCodeGen::DoValueOf(LValueOf* instr) { 1393 void LCodeGen::DoValueOf(LValueOf* instr) {
1388 Register input = ToRegister(instr->InputAt(0)); 1394 Register input = ToRegister(instr->InputAt(0));
1389 Register result = ToRegister(instr->result()); 1395 Register result = ToRegister(instr->result());
1390 Register map = ToRegister(instr->TempAt(0)); 1396 Register map = ToRegister(instr->TempAt(0));
1391 ASSERT(input.is(result));
1392 Label done; 1397 Label done;
1393 1398
1394 // If the object is a smi return the object. 1399 // If the object is a smi return the object.
1395 __ JumpIfSmi(input, &done); 1400 __ tst(input, Operand(kSmiTagMask));
1401 __ Move(result, input, eq);
1402 __ b(eq, &done);
1396 1403
1397 // If the object is not a value type, return the object. 1404 // If the object is not a value type, return the object.
1398 __ CompareObjectType(input, map, map, JS_VALUE_TYPE); 1405 __ CompareObjectType(input, map, map, JS_VALUE_TYPE);
1406 __ Move(result, input, ne);
1399 __ b(ne, &done); 1407 __ b(ne, &done);
1400 __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset)); 1408 __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset));
1401 1409
1402 __ bind(&done); 1410 __ bind(&done);
1403 } 1411 }
1404 1412
1405 1413
1406 void LCodeGen::DoBitNotI(LBitNotI* instr) { 1414 void LCodeGen::DoBitNotI(LBitNotI* instr) {
1407 LOperand* input = instr->InputAt(0); 1415 Register input = ToRegister(instr->InputAt(0));
1408 ASSERT(input->Equals(instr->result())); 1416 Register result = ToRegister(instr->result());
1409 __ mvn(ToRegister(input), Operand(ToRegister(input))); 1417 __ mvn(result, Operand(input));
1410 } 1418 }
1411 1419
1412 1420
1413 void LCodeGen::DoThrow(LThrow* instr) { 1421 void LCodeGen::DoThrow(LThrow* instr) {
1414 Register input_reg = EmitLoadRegister(instr->InputAt(0), ip); 1422 Register input_reg = EmitLoadRegister(instr->InputAt(0), ip);
1415 __ push(input_reg); 1423 __ push(input_reg);
1416 CallRuntime(Runtime::kThrow, 1, instr); 1424 CallRuntime(Runtime::kThrow, 1, instr);
1417 1425
1418 if (FLAG_debug_code) { 1426 if (FLAG_debug_code) {
1419 __ stop("Unreachable code."); 1427 __ stop("Unreachable code.");
1420 } 1428 }
1421 } 1429 }
1422 1430
1423 1431
1424 void LCodeGen::DoAddI(LAddI* instr) { 1432 void LCodeGen::DoAddI(LAddI* instr) {
1425 LOperand* left = instr->InputAt(0); 1433 LOperand* left = instr->InputAt(0);
1426 LOperand* right = instr->InputAt(1); 1434 LOperand* right = instr->InputAt(1);
1427 ASSERT(left->Equals(instr->result())); 1435 LOperand* result = instr->result();
1428 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1436 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1429 SBit set_cond = can_overflow ? SetCC : LeaveCC; 1437 SBit set_cond = can_overflow ? SetCC : LeaveCC;
1430 1438
1431 if (right->IsStackSlot() || right->IsArgument()) { 1439 if (right->IsStackSlot() || right->IsArgument()) {
1432 Register right_reg = EmitLoadRegister(right, ip); 1440 Register right_reg = EmitLoadRegister(right, ip);
1433 __ add(ToRegister(left), ToRegister(left), Operand(right_reg), set_cond); 1441 __ add(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond);
1434 } else { 1442 } else {
1435 ASSERT(right->IsRegister() || right->IsConstantOperand()); 1443 ASSERT(right->IsRegister() || right->IsConstantOperand());
1436 __ add(ToRegister(left), ToRegister(left), ToOperand(right), set_cond); 1444 __ add(ToRegister(result), ToRegister(left), ToOperand(right), set_cond);
1437 } 1445 }
1438 1446
1439 if (can_overflow) { 1447 if (can_overflow) {
1440 DeoptimizeIf(vs, instr->environment()); 1448 DeoptimizeIf(vs, instr->environment());
1441 } 1449 }
1442 } 1450 }
1443 1451
1444 1452
1445 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { 1453 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
1446 DoubleRegister left = ToDoubleRegister(instr->InputAt(0)); 1454 DoubleRegister left = ToDoubleRegister(instr->InputAt(0));
1447 DoubleRegister right = ToDoubleRegister(instr->InputAt(1)); 1455 DoubleRegister right = ToDoubleRegister(instr->InputAt(1));
1456 DoubleRegister result = ToDoubleRegister(instr->result());
1448 switch (instr->op()) { 1457 switch (instr->op()) {
1449 case Token::ADD: 1458 case Token::ADD:
1450 __ vadd(left, left, right); 1459 __ vadd(result, left, right);
1451 break; 1460 break;
1452 case Token::SUB: 1461 case Token::SUB:
1453 __ vsub(left, left, right); 1462 __ vsub(result, left, right);
1454 break; 1463 break;
1455 case Token::MUL: 1464 case Token::MUL:
1456 __ vmul(left, left, right); 1465 __ vmul(result, left, right);
1457 break; 1466 break;
1458 case Token::DIV: 1467 case Token::DIV:
1459 __ vdiv(left, left, right); 1468 __ vdiv(result, left, right);
1460 break; 1469 break;
1461 case Token::MOD: { 1470 case Token::MOD: {
1462 // Save r0-r3 on the stack. 1471 // Save r0-r3 on the stack.
1463 __ stm(db_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit()); 1472 __ stm(db_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit());
1464 1473
1465 __ PrepareCallCFunction(0, 2, scratch0()); 1474 __ PrepareCallCFunction(0, 2, scratch0());
1466 __ SetCallCDoubleArguments(left, right); 1475 __ SetCallCDoubleArguments(left, right);
1467 __ CallCFunction( 1476 __ CallCFunction(
1468 ExternalReference::double_fp_operation(Token::MOD, isolate()), 1477 ExternalReference::double_fp_operation(Token::MOD, isolate()),
1469 0, 2); 1478 0, 2);
1470 // Move the result in the double result register. 1479 // Move the result in the double result register.
1471 __ GetCFunctionDoubleResult(ToDoubleRegister(instr->result())); 1480 __ GetCFunctionDoubleResult(result);
1472 1481
1473 // Restore r0-r3. 1482 // Restore r0-r3.
1474 __ ldm(ia_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit()); 1483 __ ldm(ia_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit());
1475 break; 1484 break;
1476 } 1485 }
1477 default: 1486 default:
1478 UNREACHABLE(); 1487 UNREACHABLE();
1479 break; 1488 break;
1480 } 1489 }
1481 } 1490 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1554 __ b(eq, true_label); 1563 __ b(eq, true_label);
1555 __ LoadRoot(ip, Heap::kFalseValueRootIndex); 1564 __ LoadRoot(ip, Heap::kFalseValueRootIndex);
1556 __ cmp(reg, ip); 1565 __ cmp(reg, ip);
1557 __ b(eq, false_label); 1566 __ b(eq, false_label);
1558 __ cmp(reg, Operand(0)); 1567 __ cmp(reg, Operand(0));
1559 __ b(eq, false_label); 1568 __ b(eq, false_label);
1560 __ JumpIfSmi(reg, true_label); 1569 __ JumpIfSmi(reg, true_label);
1561 1570
1562 // Test double values. Zero and NaN are false. 1571 // Test double values. Zero and NaN are false.
1563 Label call_stub; 1572 Label call_stub;
1564 DoubleRegister dbl_scratch = d0; 1573 DoubleRegister dbl_scratch = double_scratch0();
1565 Register scratch = scratch0(); 1574 Register scratch = scratch0();
1566 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); 1575 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset));
1567 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 1576 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
1568 __ cmp(scratch, Operand(ip)); 1577 __ cmp(scratch, Operand(ip));
1569 __ b(ne, &call_stub); 1578 __ b(ne, &call_stub);
1570 __ sub(ip, reg, Operand(kHeapObjectTag)); 1579 __ sub(ip, reg, Operand(kHeapObjectTag));
1571 __ vldr(dbl_scratch, ip, HeapNumber::kValueOffset); 1580 __ vldr(dbl_scratch, ip, HeapNumber::kValueOffset);
1572 __ VFPCompareAndLoadFlags(dbl_scratch, 0.0, scratch); 1581 __ VFPCompareAndLoadFlags(dbl_scratch, 0.0, scratch);
1573 __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit)); 1582 __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit));
1574 __ b(ne, false_label); 1583 __ b(ne, false_label);
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
1789 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); 1798 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset));
1790 __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset)); 1799 __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset));
1791 __ tst(scratch, Operand(1 << Map::kIsUndetectable)); 1800 __ tst(scratch, Operand(1 << Map::kIsUndetectable));
1792 EmitBranch(true_block, false_block, ne); 1801 EmitBranch(true_block, false_block, ne);
1793 } 1802 }
1794 } 1803 }
1795 1804
1796 1805
1797 Condition LCodeGen::EmitIsObject(Register input, 1806 Condition LCodeGen::EmitIsObject(Register input,
1798 Register temp1, 1807 Register temp1,
1799 Register temp2,
1800 Label* is_not_object, 1808 Label* is_not_object,
1801 Label* is_object) { 1809 Label* is_object) {
1810 Register temp2 = scratch0();
1802 __ JumpIfSmi(input, is_not_object); 1811 __ JumpIfSmi(input, is_not_object);
1803 1812
1804 __ LoadRoot(temp1, Heap::kNullValueRootIndex); 1813 __ LoadRoot(temp2, Heap::kNullValueRootIndex);
1805 __ cmp(input, temp1); 1814 __ cmp(input, temp2);
1806 __ b(eq, is_object); 1815 __ b(eq, is_object);
1807 1816
1808 // Load map. 1817 // Load map.
1809 __ ldr(temp1, FieldMemOperand(input, HeapObject::kMapOffset)); 1818 __ ldr(temp1, FieldMemOperand(input, HeapObject::kMapOffset));
1810 // Undetectable objects behave like undefined. 1819 // Undetectable objects behave like undefined.
1811 __ ldrb(temp2, FieldMemOperand(temp1, Map::kBitFieldOffset)); 1820 __ ldrb(temp2, FieldMemOperand(temp1, Map::kBitFieldOffset));
1812 __ tst(temp2, Operand(1 << Map::kIsUndetectable)); 1821 __ tst(temp2, Operand(1 << Map::kIsUndetectable));
1813 __ b(ne, is_not_object); 1822 __ b(ne, is_not_object);
1814 1823
1815 // Load instance type and check that it is in object type range. 1824 // Load instance type and check that it is in object type range.
1816 __ ldrb(temp2, FieldMemOperand(temp1, Map::kInstanceTypeOffset)); 1825 __ ldrb(temp2, FieldMemOperand(temp1, Map::kInstanceTypeOffset));
1817 __ cmp(temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 1826 __ cmp(temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
1818 __ b(lt, is_not_object); 1827 __ b(lt, is_not_object);
1819 __ cmp(temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); 1828 __ cmp(temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
1820 return le; 1829 return le;
1821 } 1830 }
1822 1831
1823 1832
1824 void LCodeGen::DoIsObject(LIsObject* instr) { 1833 void LCodeGen::DoIsObject(LIsObject* instr) {
1825 Register reg = ToRegister(instr->InputAt(0)); 1834 Register reg = ToRegister(instr->InputAt(0));
1826 Register result = ToRegister(instr->result()); 1835 Register result = ToRegister(instr->result());
1827 Register temp = scratch0();
1828 Label is_false, is_true, done; 1836 Label is_false, is_true, done;
1829 1837
1830 Condition true_cond = EmitIsObject(reg, result, temp, &is_false, &is_true); 1838 Condition true_cond = EmitIsObject(reg, result, &is_false, &is_true);
1831 __ b(true_cond, &is_true); 1839 __ b(true_cond, &is_true);
1832 1840
1833 __ bind(&is_false); 1841 __ bind(&is_false);
1834 __ LoadRoot(result, Heap::kFalseValueRootIndex); 1842 __ LoadRoot(result, Heap::kFalseValueRootIndex);
1835 __ b(&done); 1843 __ b(&done);
1836 1844
1837 __ bind(&is_true); 1845 __ bind(&is_true);
1838 __ LoadRoot(result, Heap::kTrueValueRootIndex); 1846 __ LoadRoot(result, Heap::kTrueValueRootIndex);
1839 1847
1840 __ bind(&done); 1848 __ bind(&done);
1841 } 1849 }
1842 1850
1843 1851
1844 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { 1852 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
1845 Register reg = ToRegister(instr->InputAt(0)); 1853 Register reg = ToRegister(instr->InputAt(0));
1846 Register temp1 = ToRegister(instr->TempAt(0)); 1854 Register temp1 = ToRegister(instr->TempAt(0));
1847 Register temp2 = scratch0(); 1855 Register temp2 = scratch0();
1848 1856
1849 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1857 int true_block = chunk_->LookupDestination(instr->true_block_id());
1850 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1858 int false_block = chunk_->LookupDestination(instr->false_block_id());
1851 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1859 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1852 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1860 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1853 1861
1854 Condition true_cond = 1862 Condition true_cond =
1855 EmitIsObject(reg, temp1, temp2, false_label, true_label); 1863 EmitIsObject(reg, temp1, false_label, true_label);
1856 1864
1857 EmitBranch(true_block, false_block, true_cond); 1865 EmitBranch(true_block, false_block, true_cond);
1858 } 1866 }
1859 1867
1860 1868
1861 void LCodeGen::DoIsSmi(LIsSmi* instr) { 1869 void LCodeGen::DoIsSmi(LIsSmi* instr) {
1862 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); 1870 ASSERT(instr->hydrogen()->value()->representation().IsTagged());
1863 Register result = ToRegister(instr->result()); 1871 Register result = ToRegister(instr->result());
1864 Register input_reg = EmitLoadRegister(instr->InputAt(0), ip); 1872 Register input_reg = EmitLoadRegister(instr->InputAt(0), ip);
1865 Label done; 1873 Label done;
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after
2572 __ add(length, length, Operand(1)); 2580 __ add(length, length, Operand(1));
2573 __ ldr(result, MemOperand(arguments, length, LSL, kPointerSizeLog2)); 2581 __ ldr(result, MemOperand(arguments, length, LSL, kPointerSizeLog2));
2574 } 2582 }
2575 2583
2576 2584
2577 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { 2585 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
2578 Register elements = ToRegister(instr->elements()); 2586 Register elements = ToRegister(instr->elements());
2579 Register key = EmitLoadRegister(instr->key(), scratch0()); 2587 Register key = EmitLoadRegister(instr->key(), scratch0());
2580 Register result = ToRegister(instr->result()); 2588 Register result = ToRegister(instr->result());
2581 Register scratch = scratch0(); 2589 Register scratch = scratch0();
2582 ASSERT(result.is(elements));
2583 2590
2584 // Load the result. 2591 // Load the result.
2585 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); 2592 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
2586 __ ldr(result, FieldMemOperand(scratch, FixedArray::kHeaderSize)); 2593 __ ldr(result, FieldMemOperand(scratch, FixedArray::kHeaderSize));
2587 2594
2588 // Check for the hole value. 2595 // Check for the hole value.
2589 if (instr->hydrogen()->RequiresHoleCheck()) { 2596 if (instr->hydrogen()->RequiresHoleCheck()) {
2590 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); 2597 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
2591 __ cmp(result, scratch); 2598 __ cmp(result, scratch);
2592 DeoptimizeIf(eq, instr->environment()); 2599 DeoptimizeIf(eq, instr->environment());
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
2892 ASSERT(ToRegister(instr->result()).is(r0)); 2899 ASSERT(ToRegister(instr->result()).is(r0));
2893 __ mov(r1, Operand(instr->function())); 2900 __ mov(r1, Operand(instr->function()));
2894 CallKnownFunction(instr->function(), 2901 CallKnownFunction(instr->function(),
2895 instr->arity(), 2902 instr->arity(),
2896 instr, 2903 instr,
2897 CALL_AS_METHOD); 2904 CALL_AS_METHOD);
2898 } 2905 }
2899 2906
2900 2907
2901 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { 2908 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
2902 ASSERT(instr->InputAt(0)->Equals(instr->result()));
2903 Register input = ToRegister(instr->InputAt(0)); 2909 Register input = ToRegister(instr->InputAt(0));
2910 Register result = ToRegister(instr->result());
2904 Register scratch = scratch0(); 2911 Register scratch = scratch0();
2905 2912
2906 // Deoptimize if not a heap number. 2913 // Deoptimize if not a heap number.
2907 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); 2914 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
2908 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 2915 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
2909 __ cmp(scratch, Operand(ip)); 2916 __ cmp(scratch, Operand(ip));
2910 DeoptimizeIf(ne, instr->environment()); 2917 DeoptimizeIf(ne, instr->environment());
2911 2918
2912 Label done; 2919 Label done;
2913 Register exponent = scratch0(); 2920 Register exponent = scratch0();
2914 scratch = no_reg; 2921 scratch = no_reg;
2915 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset)); 2922 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset));
2916 // Check the sign of the argument. If the argument is positive, just 2923 // Check the sign of the argument. If the argument is positive, just
2917 // return it. We do not need to patch the stack since |input| and 2924 // return it.
2918 // |result| are the same register and |input| would be restored
2919 // unchanged by popping safepoint registers.
2920 __ tst(exponent, Operand(HeapNumber::kSignMask)); 2925 __ tst(exponent, Operand(HeapNumber::kSignMask));
2926 // Move the input to the result if necessary.
2927 __ Move(result, input);
2921 __ b(eq, &done); 2928 __ b(eq, &done);
2922 2929
2923 // Input is negative. Reverse its sign. 2930 // Input is negative. Reverse its sign.
2924 // Preserve the value of all registers. 2931 // Preserve the value of all registers.
2925 { 2932 {
2926 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 2933 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
2927 2934
2928 // Registers were saved at the safepoint, so we can use 2935 // Registers were saved at the safepoint, so we can use
2929 // many scratch registers. 2936 // many scratch registers.
2930 Register tmp1 = input.is(r1) ? r0 : r1; 2937 Register tmp1 = input.is(r1) ? r0 : r1;
(...skipping 19 matching lines...) Expand all
2950 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset)); 2957 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset));
2951 2958
2952 __ bind(&allocated); 2959 __ bind(&allocated);
2953 // exponent: floating point exponent value. 2960 // exponent: floating point exponent value.
2954 // tmp1: allocated heap number. 2961 // tmp1: allocated heap number.
2955 __ bic(exponent, exponent, Operand(HeapNumber::kSignMask)); 2962 __ bic(exponent, exponent, Operand(HeapNumber::kSignMask));
2956 __ str(exponent, FieldMemOperand(tmp1, HeapNumber::kExponentOffset)); 2963 __ str(exponent, FieldMemOperand(tmp1, HeapNumber::kExponentOffset));
2957 __ ldr(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset)); 2964 __ ldr(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset));
2958 __ str(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset)); 2965 __ str(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset));
2959 2966
2960 __ StoreToSafepointRegisterSlot(tmp1, input); 2967 __ StoreToSafepointRegisterSlot(tmp1, result);
2961 } 2968 }
2962 2969
2963 __ bind(&done); 2970 __ bind(&done);
2964 } 2971 }
2965 2972
2966 2973
2967 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { 2974 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
2968 Register input = ToRegister(instr->InputAt(0)); 2975 Register input = ToRegister(instr->InputAt(0));
2976 Register result = ToRegister(instr->result());
2969 __ cmp(input, Operand(0)); 2977 __ cmp(input, Operand(0));
2978 __ Move(result, input, pl);
2970 // We can make rsb conditional because the previous cmp instruction 2979 // We can make rsb conditional because the previous cmp instruction
2971 // will clear the V (overflow) flag and rsb won't set this flag 2980 // will clear the V (overflow) flag and rsb won't set this flag
2972 // if input is positive. 2981 // if input is positive.
2973 __ rsb(input, input, Operand(0), SetCC, mi); 2982 __ rsb(result, input, Operand(0), SetCC, mi);
2974 // Deoptimize on overflow. 2983 // Deoptimize on overflow.
2975 DeoptimizeIf(vs, instr->environment()); 2984 DeoptimizeIf(vs, instr->environment());
2976 } 2985 }
2977 2986
2978 2987
2979 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { 2988 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
2980 // Class for deferred case. 2989 // Class for deferred case.
2981 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { 2990 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
2982 public: 2991 public:
2983 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, 2992 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen,
2984 LUnaryMathOperation* instr) 2993 LUnaryMathOperation* instr)
2985 : LDeferredCode(codegen), instr_(instr) { } 2994 : LDeferredCode(codegen), instr_(instr) { }
2986 virtual void Generate() { 2995 virtual void Generate() {
2987 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 2996 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
2988 } 2997 }
2989 private: 2998 private:
2990 LUnaryMathOperation* instr_; 2999 LUnaryMathOperation* instr_;
2991 }; 3000 };
2992 3001
2993 ASSERT(instr->InputAt(0)->Equals(instr->result()));
2994 Representation r = instr->hydrogen()->value()->representation(); 3002 Representation r = instr->hydrogen()->value()->representation();
2995 if (r.IsDouble()) { 3003 if (r.IsDouble()) {
2996 DwVfpRegister input = ToDoubleRegister(instr->InputAt(0)); 3004 DwVfpRegister input = ToDoubleRegister(instr->InputAt(0));
2997 __ vabs(input, input); 3005 DwVfpRegister result = ToDoubleRegister(instr->result());
3006 __ vabs(result, input);
2998 } else if (r.IsInteger32()) { 3007 } else if (r.IsInteger32()) {
2999 EmitIntegerMathAbs(instr); 3008 EmitIntegerMathAbs(instr);
3000 } else { 3009 } else {
3001 // Representation is tagged. 3010 // Representation is tagged.
3002 DeferredMathAbsTaggedHeapNumber* deferred = 3011 DeferredMathAbsTaggedHeapNumber* deferred =
3003 new DeferredMathAbsTaggedHeapNumber(this, instr); 3012 new DeferredMathAbsTaggedHeapNumber(this, instr);
3004 Register input = ToRegister(instr->InputAt(0)); 3013 Register input = ToRegister(instr->InputAt(0));
3005 // Smi check. 3014 // Smi check.
3006 __ JumpIfNotSmi(input, deferred->entry()); 3015 __ JumpIfNotSmi(input, deferred->entry());
3007 // If smi, handle it directly. 3016 // If smi, handle it directly.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
3065 } 3074 }
3066 3075
3067 // The following conversion will not work with numbers 3076 // The following conversion will not work with numbers
3068 // outside of ]-2^32, 2^32[. 3077 // outside of ]-2^32, 2^32[.
3069 __ cmp(scratch2, Operand(HeapNumber::kExponentBias + 32)); 3078 __ cmp(scratch2, Operand(HeapNumber::kExponentBias + 32));
3070 DeoptimizeIf(ge, instr->environment()); 3079 DeoptimizeIf(ge, instr->environment());
3071 3080
3072 // Save the original sign for later comparison. 3081 // Save the original sign for later comparison.
3073 __ and_(scratch2, scratch1, Operand(HeapNumber::kSignMask)); 3082 __ and_(scratch2, scratch1, Operand(HeapNumber::kSignMask));
3074 3083
3075 __ vmov(double_scratch0(), 0.5); 3084 __ Vmov(double_scratch0(), 0.5);
3076 __ vadd(input, input, double_scratch0()); 3085 __ vadd(input, input, double_scratch0());
3077 3086
3078 // Check sign of the result: if the sign changed, the input 3087 // Check sign of the result: if the sign changed, the input
3079 // value was in ]0.5, 0[ and the result should be -0. 3088 // value was in ]0.5, 0[ and the result should be -0.
3080 __ vmov(scratch1, input.high()); 3089 __ vmov(scratch1, input.high());
3081 __ eor(scratch1, scratch1, Operand(scratch2), SetCC); 3090 __ eor(scratch1, scratch1, Operand(scratch2), SetCC);
3082 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3091 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3083 DeoptimizeIf(mi, instr->environment()); 3092 DeoptimizeIf(mi, instr->environment());
3084 } else { 3093 } else {
3085 __ mov(result, Operand(0), LeaveCC, mi); 3094 __ mov(result, Operand(0), LeaveCC, mi);
(...skipping 16 matching lines...) Expand all
3102 __ vmov(scratch1, input.high()); 3111 __ vmov(scratch1, input.high());
3103 __ tst(scratch1, Operand(HeapNumber::kSignMask)); 3112 __ tst(scratch1, Operand(HeapNumber::kSignMask));
3104 DeoptimizeIf(ne, instr->environment()); 3113 DeoptimizeIf(ne, instr->environment());
3105 } 3114 }
3106 __ bind(&done); 3115 __ bind(&done);
3107 } 3116 }
3108 3117
3109 3118
3110 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { 3119 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
3111 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); 3120 DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
3112 ASSERT(ToDoubleRegister(instr->result()).is(input)); 3121 DoubleRegister result = ToDoubleRegister(instr->result());
3113 __ vsqrt(input, input); 3122 __ vsqrt(result, input);
3114 } 3123 }
3115 3124
3116 3125
3117 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { 3126 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
3118 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); 3127 DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
3119 Register scratch = scratch0(); 3128 DoubleRegister result = ToDoubleRegister(instr->result());
3120 SwVfpRegister single_scratch = double_scratch0().low();
3121 DoubleRegister double_scratch = double_scratch0();
3122 ASSERT(ToDoubleRegister(instr->result()).is(input));
3123
3124 // Add +0 to convert -0 to +0. 3129 // Add +0 to convert -0 to +0.
3125 __ mov(scratch, Operand(0)); 3130 __ vadd(result, input, kDoubleRegZero);
3126 __ vmov(single_scratch, scratch); 3131 __ vsqrt(result, result);
3127 __ vcvt_f64_s32(double_scratch, single_scratch);
3128 __ vadd(input, input, double_scratch);
3129 __ vsqrt(input, input);
3130 } 3132 }
3131 3133
3132 3134
3133 void LCodeGen::DoPower(LPower* instr) { 3135 void LCodeGen::DoPower(LPower* instr) {
3134 LOperand* left = instr->InputAt(0); 3136 LOperand* left = instr->InputAt(0);
3135 LOperand* right = instr->InputAt(1); 3137 LOperand* right = instr->InputAt(1);
3136 Register scratch = scratch0(); 3138 Register scratch = scratch0();
3137 DoubleRegister result_reg = ToDoubleRegister(instr->result()); 3139 DoubleRegister result_reg = ToDoubleRegister(instr->result());
3138 Representation exponent_type = instr->hydrogen()->right()->representation(); 3140 Representation exponent_type = instr->hydrogen()->right()->representation();
3139 if (exponent_type.IsDouble()) { 3141 if (exponent_type.IsDouble()) {
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after
3718 DeferredNumberTagI* deferred = new DeferredNumberTagI(this, instr); 3720 DeferredNumberTagI* deferred = new DeferredNumberTagI(this, instr);
3719 __ SmiTag(reg, SetCC); 3721 __ SmiTag(reg, SetCC);
3720 __ b(vs, deferred->entry()); 3722 __ b(vs, deferred->entry());
3721 __ bind(deferred->exit()); 3723 __ bind(deferred->exit());
3722 } 3724 }
3723 3725
3724 3726
3725 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) { 3727 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
3726 Label slow; 3728 Label slow;
3727 Register reg = ToRegister(instr->InputAt(0)); 3729 Register reg = ToRegister(instr->InputAt(0));
3728 DoubleRegister dbl_scratch = d0; 3730 DoubleRegister dbl_scratch = double_scratch0();
3729 SwVfpRegister flt_scratch = s0; 3731 SwVfpRegister flt_scratch = dbl_scratch.low();
3730 3732
3731 // Preserve the value of all registers. 3733 // Preserve the value of all registers.
3732 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 3734 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
3733 3735
3734 // There was overflow, so bits 30 and 31 of the original integer 3736 // There was overflow, so bits 30 and 31 of the original integer
3735 // disagree. Try to allocate a heap number in new space and store 3737 // disagree. Try to allocate a heap number in new space and store
3736 // the value in there. If that fails, call the runtime system. 3738 // the value in there. If that fails, call the runtime system.
3737 Label done; 3739 Label done;
3738 __ SmiUntag(reg); 3740 __ SmiUntag(reg);
3739 __ eor(reg, reg, Operand(0x80000000)); 3741 __ eor(reg, reg, Operand(0x80000000));
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
3828 __ SmiUntag(ToRegister(input)); 3830 __ SmiUntag(ToRegister(input));
3829 } 3831 }
3830 } 3832 }
3831 3833
3832 3834
3833 void LCodeGen::EmitNumberUntagD(Register input_reg, 3835 void LCodeGen::EmitNumberUntagD(Register input_reg,
3834 DoubleRegister result_reg, 3836 DoubleRegister result_reg,
3835 bool deoptimize_on_undefined, 3837 bool deoptimize_on_undefined,
3836 LEnvironment* env) { 3838 LEnvironment* env) {
3837 Register scratch = scratch0(); 3839 Register scratch = scratch0();
3838 SwVfpRegister flt_scratch = s0; 3840 SwVfpRegister flt_scratch = double_scratch0().low();
3839 ASSERT(!result_reg.is(d0)); 3841 ASSERT(!result_reg.is(double_scratch0()));
3840 3842
3841 Label load_smi, heap_number, done; 3843 Label load_smi, heap_number, done;
3842 3844
3843 // Smi check. 3845 // Smi check.
3844 __ JumpIfSmi(input_reg, &load_smi); 3846 __ JumpIfSmi(input_reg, &load_smi);
3845 3847
3846 // Heap number map check. 3848 // Heap number map check.
3847 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 3849 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
3848 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 3850 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
3849 __ cmp(scratch, Operand(ip)); 3851 __ cmp(scratch, Operand(ip));
(...skipping 751 matching lines...) Expand 10 before | Expand all | Expand 10 after
4601 ASSERT(osr_pc_offset_ == -1); 4603 ASSERT(osr_pc_offset_ == -1);
4602 osr_pc_offset_ = masm()->pc_offset(); 4604 osr_pc_offset_ = masm()->pc_offset();
4603 } 4605 }
4604 4606
4605 4607
4606 4608
4607 4609
4608 #undef __ 4610 #undef __
4609 4611
4610 } } // namespace v8::internal 4612 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698