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

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

Issue 11109003: MIPS: Consistently use named getters for Lithium operands on ARM. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 2 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 | « no previous file | src/mips/lithium-mips.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 893 matching lines...) Expand 10 before | Expand all | Expand 10 after
904 } 904 }
905 905
906 906
907 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 907 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
908 // Nothing to do. 908 // Nothing to do.
909 } 909 }
910 910
911 911
912 void LCodeGen::DoModI(LModI* instr) { 912 void LCodeGen::DoModI(LModI* instr) {
913 Register scratch = scratch0(); 913 Register scratch = scratch0();
914 const Register left = ToRegister(instr->InputAt(0)); 914 const Register left = ToRegister(instr->left());
915 const Register result = ToRegister(instr->result()); 915 const Register result = ToRegister(instr->result());
916 916
917 Label done; 917 Label done;
918 918
919 if (instr->hydrogen()->HasPowerOf2Divisor()) { 919 if (instr->hydrogen()->HasPowerOf2Divisor()) {
920 Register scratch = scratch0(); 920 Register scratch = scratch0();
921 ASSERT(!left.is(scratch)); 921 ASSERT(!left.is(scratch));
922 __ mov(scratch, left); 922 __ mov(scratch, left);
923 int32_t p2constant = HConstant::cast( 923 int32_t p2constant = HConstant::cast(
924 instr->hydrogen()->right())->Integer32Value(); 924 instr->hydrogen()->right())->Integer32Value();
925 ASSERT(p2constant != 0); 925 ASSERT(p2constant != 0);
926 // Result always takes the sign of the dividend (left). 926 // Result always takes the sign of the dividend (left).
927 p2constant = abs(p2constant); 927 p2constant = abs(p2constant);
928 928
929 Label positive_dividend; 929 Label positive_dividend;
930 __ Branch(USE_DELAY_SLOT, &positive_dividend, ge, left, Operand(zero_reg)); 930 __ Branch(USE_DELAY_SLOT, &positive_dividend, ge, left, Operand(zero_reg));
931 __ subu(result, zero_reg, left); 931 __ subu(result, zero_reg, left);
932 __ And(result, result, p2constant - 1); 932 __ And(result, result, p2constant - 1);
933 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 933 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
934 DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg)); 934 DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg));
935 } 935 }
936 __ Branch(USE_DELAY_SLOT, &done); 936 __ Branch(USE_DELAY_SLOT, &done);
937 __ subu(result, zero_reg, result); 937 __ subu(result, zero_reg, result);
938 __ bind(&positive_dividend); 938 __ bind(&positive_dividend);
939 __ And(result, scratch, p2constant - 1); 939 __ And(result, scratch, p2constant - 1);
940 } else { 940 } else {
941 // div runs in the background while we check for special cases. 941 // div runs in the background while we check for special cases.
942 Register right = EmitLoadRegister(instr->InputAt(1), scratch); 942 Register right = EmitLoadRegister(instr->right(), scratch);
943 __ div(left, right); 943 __ div(left, right);
944 944
945 // Check for x % 0. 945 // Check for x % 0.
946 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 946 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
947 DeoptimizeIf(eq, instr->environment(), right, Operand(zero_reg)); 947 DeoptimizeIf(eq, instr->environment(), right, Operand(zero_reg));
948 } 948 }
949 949
950 __ Branch(USE_DELAY_SLOT, &done, ge, left, Operand(zero_reg)); 950 __ Branch(USE_DELAY_SLOT, &done, ge, left, Operand(zero_reg));
951 __ mfhi(result); 951 __ mfhi(result);
952 952
953 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 953 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
954 DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg)); 954 DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg));
955 } 955 }
956 } 956 }
957 __ bind(&done); 957 __ bind(&done);
958 } 958 }
959 959
960 960
961 void LCodeGen::DoDivI(LDivI* instr) { 961 void LCodeGen::DoDivI(LDivI* instr) {
962 const Register left = ToRegister(instr->InputAt(0)); 962 const Register left = ToRegister(instr->left());
963 const Register right = ToRegister(instr->InputAt(1)); 963 const Register right = ToRegister(instr->right());
964 const Register result = ToRegister(instr->result()); 964 const Register result = ToRegister(instr->result());
965 965
966 // On MIPS div is asynchronous - it will run in the background while we 966 // On MIPS div is asynchronous - it will run in the background while we
967 // check for special cases. 967 // check for special cases.
968 __ div(left, right); 968 __ div(left, right);
969 969
970 // Check for x / 0. 970 // Check for x / 0.
971 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 971 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
972 DeoptimizeIf(eq, instr->environment(), right, Operand(zero_reg)); 972 DeoptimizeIf(eq, instr->environment(), right, Operand(zero_reg));
973 } 973 }
(...skipping 17 matching lines...) Expand all
991 __ mfhi(result); 991 __ mfhi(result);
992 DeoptimizeIf(ne, instr->environment(), result, Operand(zero_reg)); 992 DeoptimizeIf(ne, instr->environment(), result, Operand(zero_reg));
993 __ mflo(result); 993 __ mflo(result);
994 } 994 }
995 995
996 996
997 void LCodeGen::DoMulI(LMulI* instr) { 997 void LCodeGen::DoMulI(LMulI* instr) {
998 Register scratch = scratch0(); 998 Register scratch = scratch0();
999 Register result = ToRegister(instr->result()); 999 Register result = ToRegister(instr->result());
1000 // Note that result may alias left. 1000 // Note that result may alias left.
1001 Register left = ToRegister(instr->InputAt(0)); 1001 Register left = ToRegister(instr->left());
1002 LOperand* right_op = instr->InputAt(1); 1002 LOperand* right_op = instr->right();
1003 1003
1004 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1004 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1005 bool bailout_on_minus_zero = 1005 bool bailout_on_minus_zero =
1006 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); 1006 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
1007 1007
1008 if (right_op->IsConstantOperand() && !can_overflow) { 1008 if (right_op->IsConstantOperand() && !can_overflow) {
1009 // Use optimized code for specific constants. 1009 // Use optimized code for specific constants.
1010 int32_t constant = ToInteger32(LConstantOperand::cast(right_op)); 1010 int32_t constant = ToInteger32(LConstantOperand::cast(right_op));
1011 1011
1012 if (bailout_on_minus_zero && (constant < 0)) { 1012 if (bailout_on_minus_zero && (constant < 0)) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1062 } else { 1062 } else {
1063 // Generate standard code. 1063 // Generate standard code.
1064 __ li(at, constant); 1064 __ li(at, constant);
1065 __ Mul(result, left, at); 1065 __ Mul(result, left, at);
1066 } 1066 }
1067 } 1067 }
1068 1068
1069 } else { 1069 } else {
1070 Register right = EmitLoadRegister(right_op, scratch); 1070 Register right = EmitLoadRegister(right_op, scratch);
1071 if (bailout_on_minus_zero) { 1071 if (bailout_on_minus_zero) {
1072 __ Or(ToRegister(instr->TempAt(0)), left, right); 1072 __ Or(ToRegister(instr->temp()), left, right);
1073 } 1073 }
1074 1074
1075 if (can_overflow) { 1075 if (can_overflow) {
1076 // hi:lo = left * right. 1076 // hi:lo = left * right.
1077 __ mult(left, right); 1077 __ mult(left, right);
1078 __ mfhi(scratch); 1078 __ mfhi(scratch);
1079 __ mflo(result); 1079 __ mflo(result);
1080 __ sra(at, result, 31); 1080 __ sra(at, result, 31);
1081 DeoptimizeIf(ne, instr->environment(), scratch, Operand(at)); 1081 DeoptimizeIf(ne, instr->environment(), scratch, Operand(at));
1082 } else { 1082 } else {
1083 __ Mul(result, left, right); 1083 __ Mul(result, left, right);
1084 } 1084 }
1085 1085
1086 if (bailout_on_minus_zero) { 1086 if (bailout_on_minus_zero) {
1087 // Bail out if the result is supposed to be negative zero. 1087 // Bail out if the result is supposed to be negative zero.
1088 Label done; 1088 Label done;
1089 __ Branch(&done, ne, result, Operand(zero_reg)); 1089 __ Branch(&done, ne, result, Operand(zero_reg));
1090 DeoptimizeIf(lt, 1090 DeoptimizeIf(lt,
1091 instr->environment(), 1091 instr->environment(),
1092 ToRegister(instr->TempAt(0)), 1092 ToRegister(instr->temp()),
1093 Operand(zero_reg)); 1093 Operand(zero_reg));
1094 __ bind(&done); 1094 __ bind(&done);
1095 } 1095 }
1096 } 1096 }
1097 } 1097 }
1098 1098
1099 1099
1100 void LCodeGen::DoBitI(LBitI* instr) { 1100 void LCodeGen::DoBitI(LBitI* instr) {
1101 LOperand* left_op = instr->InputAt(0); 1101 LOperand* left_op = instr->left();
1102 LOperand* right_op = instr->InputAt(1); 1102 LOperand* right_op = instr->right();
1103 ASSERT(left_op->IsRegister()); 1103 ASSERT(left_op->IsRegister());
1104 Register left = ToRegister(left_op); 1104 Register left = ToRegister(left_op);
1105 Register result = ToRegister(instr->result()); 1105 Register result = ToRegister(instr->result());
1106 Operand right(no_reg); 1106 Operand right(no_reg);
1107 1107
1108 if (right_op->IsStackSlot() || right_op->IsArgument()) { 1108 if (right_op->IsStackSlot() || right_op->IsArgument()) {
1109 right = Operand(EmitLoadRegister(right_op, at)); 1109 right = Operand(EmitLoadRegister(right_op, at));
1110 } else { 1110 } else {
1111 ASSERT(right_op->IsRegister() || right_op->IsConstantOperand()); 1111 ASSERT(right_op->IsRegister() || right_op->IsConstantOperand());
1112 right = ToOperand(right_op); 1112 right = ToOperand(right_op);
(...skipping 12 matching lines...) Expand all
1125 default: 1125 default:
1126 UNREACHABLE(); 1126 UNREACHABLE();
1127 break; 1127 break;
1128 } 1128 }
1129 } 1129 }
1130 1130
1131 1131
1132 void LCodeGen::DoShiftI(LShiftI* instr) { 1132 void LCodeGen::DoShiftI(LShiftI* instr) {
1133 // Both 'left' and 'right' are "used at start" (see LCodeGen::DoShift), so 1133 // Both 'left' and 'right' are "used at start" (see LCodeGen::DoShift), so
1134 // result may alias either of them. 1134 // result may alias either of them.
1135 LOperand* right_op = instr->InputAt(1); 1135 LOperand* right_op = instr->right();
1136 Register left = ToRegister(instr->InputAt(0)); 1136 Register left = ToRegister(instr->left());
1137 Register result = ToRegister(instr->result()); 1137 Register result = ToRegister(instr->result());
1138 1138
1139 if (right_op->IsRegister()) { 1139 if (right_op->IsRegister()) {
1140 // No need to mask the right operand on MIPS, it is built into the variable 1140 // No need to mask the right operand on MIPS, it is built into the variable
1141 // shift instructions. 1141 // shift instructions.
1142 switch (instr->op()) { 1142 switch (instr->op()) {
1143 case Token::SAR: 1143 case Token::SAR:
1144 __ srav(result, left, ToRegister(right_op)); 1144 __ srav(result, left, ToRegister(right_op));
1145 break; 1145 break;
1146 case Token::SHR: 1146 case Token::SHR:
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1188 break; 1188 break;
1189 default: 1189 default:
1190 UNREACHABLE(); 1190 UNREACHABLE();
1191 break; 1191 break;
1192 } 1192 }
1193 } 1193 }
1194 } 1194 }
1195 1195
1196 1196
1197 void LCodeGen::DoSubI(LSubI* instr) { 1197 void LCodeGen::DoSubI(LSubI* instr) {
1198 LOperand* left = instr->InputAt(0); 1198 LOperand* left = instr->left();
1199 LOperand* right = instr->InputAt(1); 1199 LOperand* right = instr->right();
1200 LOperand* result = instr->result(); 1200 LOperand* result = instr->result();
1201 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1201 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1202 1202
1203 if (!can_overflow) { 1203 if (!can_overflow) {
1204 if (right->IsStackSlot() || right->IsArgument()) { 1204 if (right->IsStackSlot() || right->IsArgument()) {
1205 Register right_reg = EmitLoadRegister(right, at); 1205 Register right_reg = EmitLoadRegister(right, at);
1206 __ Subu(ToRegister(result), ToRegister(left), Operand(right_reg)); 1206 __ Subu(ToRegister(result), ToRegister(left), Operand(right_reg));
1207 } else { 1207 } else {
1208 ASSERT(right->IsRegister() || right->IsConstantOperand()); 1208 ASSERT(right->IsRegister() || right->IsConstantOperand());
1209 __ Subu(ToRegister(result), ToRegister(left), ToOperand(right)); 1209 __ Subu(ToRegister(result), ToRegister(left), ToOperand(right));
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1253 __ li(ToRegister(instr->result()), Operand(value)); 1253 __ li(ToRegister(instr->result()), Operand(value));
1254 } else { 1254 } else {
1255 __ LoadHeapObject(ToRegister(instr->result()), 1255 __ LoadHeapObject(ToRegister(instr->result()),
1256 Handle<HeapObject>::cast(value)); 1256 Handle<HeapObject>::cast(value));
1257 } 1257 }
1258 } 1258 }
1259 1259
1260 1260
1261 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { 1261 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
1262 Register result = ToRegister(instr->result()); 1262 Register result = ToRegister(instr->result());
1263 Register array = ToRegister(instr->InputAt(0)); 1263 Register array = ToRegister(instr->value());
1264 __ lw(result, FieldMemOperand(array, JSArray::kLengthOffset)); 1264 __ lw(result, FieldMemOperand(array, JSArray::kLengthOffset));
1265 } 1265 }
1266 1266
1267 1267
1268 void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) { 1268 void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) {
1269 Register result = ToRegister(instr->result()); 1269 Register result = ToRegister(instr->result());
1270 Register array = ToRegister(instr->InputAt(0)); 1270 Register array = ToRegister(instr->value());
1271 __ lw(result, FieldMemOperand(array, FixedArrayBase::kLengthOffset)); 1271 __ lw(result, FieldMemOperand(array, FixedArrayBase::kLengthOffset));
1272 } 1272 }
1273 1273
1274 1274
1275 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { 1275 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
1276 Register result = ToRegister(instr->result()); 1276 Register result = ToRegister(instr->result());
1277 Register map = ToRegister(instr->InputAt(0)); 1277 Register map = ToRegister(instr->value());
1278 __ EnumLength(result, map); 1278 __ EnumLength(result, map);
1279 } 1279 }
1280 1280
1281 1281
1282 void LCodeGen::DoElementsKind(LElementsKind* instr) { 1282 void LCodeGen::DoElementsKind(LElementsKind* instr) {
1283 Register result = ToRegister(instr->result()); 1283 Register result = ToRegister(instr->result());
1284 Register input = ToRegister(instr->InputAt(0)); 1284 Register input = ToRegister(instr->value());
1285 1285
1286 // Load map into |result|. 1286 // Load map into |result|.
1287 __ lw(result, FieldMemOperand(input, HeapObject::kMapOffset)); 1287 __ lw(result, FieldMemOperand(input, HeapObject::kMapOffset));
1288 // Load the map's "bit field 2" into |result|. We only need the first byte, 1288 // Load the map's "bit field 2" into |result|. We only need the first byte,
1289 // but the following bit field extraction takes care of that anyway. 1289 // but the following bit field extraction takes care of that anyway.
1290 __ lbu(result, FieldMemOperand(result, Map::kBitField2Offset)); 1290 __ lbu(result, FieldMemOperand(result, Map::kBitField2Offset));
1291 // Retrieve elements_kind from bit field 2. 1291 // Retrieve elements_kind from bit field 2.
1292 __ Ext(result, result, Map::kElementsKindShift, Map::kElementsKindBitCount); 1292 __ Ext(result, result, Map::kElementsKindShift, Map::kElementsKindBitCount);
1293 } 1293 }
1294 1294
1295 1295
1296 void LCodeGen::DoValueOf(LValueOf* instr) { 1296 void LCodeGen::DoValueOf(LValueOf* instr) {
1297 Register input = ToRegister(instr->InputAt(0)); 1297 Register input = ToRegister(instr->value());
1298 Register result = ToRegister(instr->result()); 1298 Register result = ToRegister(instr->result());
1299 Register map = ToRegister(instr->TempAt(0)); 1299 Register map = ToRegister(instr->temp());
1300 Label done; 1300 Label done;
1301 1301
1302 // If the object is a smi return the object. 1302 // If the object is a smi return the object.
1303 __ Move(result, input); 1303 __ Move(result, input);
1304 __ JumpIfSmi(input, &done); 1304 __ JumpIfSmi(input, &done);
1305 1305
1306 // If the object is not a value type, return the object. 1306 // If the object is not a value type, return the object.
1307 __ GetObjectType(input, map, map); 1307 __ GetObjectType(input, map, map);
1308 __ Branch(&done, ne, map, Operand(JS_VALUE_TYPE)); 1308 __ Branch(&done, ne, map, Operand(JS_VALUE_TYPE));
1309 __ lw(result, FieldMemOperand(input, JSValue::kValueOffset)); 1309 __ lw(result, FieldMemOperand(input, JSValue::kValueOffset));
1310 1310
1311 __ bind(&done); 1311 __ bind(&done);
1312 } 1312 }
1313 1313
1314 1314
1315 void LCodeGen::DoDateField(LDateField* instr) { 1315 void LCodeGen::DoDateField(LDateField* instr) {
1316 Register object = ToRegister(instr->InputAt(0)); 1316 Register object = ToRegister(instr->date());
1317 Register result = ToRegister(instr->result()); 1317 Register result = ToRegister(instr->result());
1318 Register scratch = ToRegister(instr->TempAt(0)); 1318 Register scratch = ToRegister(instr->temp());
1319 Smi* index = instr->index(); 1319 Smi* index = instr->index();
1320 Label runtime, done; 1320 Label runtime, done;
1321 ASSERT(object.is(a0)); 1321 ASSERT(object.is(a0));
1322 ASSERT(result.is(v0)); 1322 ASSERT(result.is(v0));
1323 ASSERT(!scratch.is(scratch0())); 1323 ASSERT(!scratch.is(scratch0()));
1324 ASSERT(!scratch.is(object)); 1324 ASSERT(!scratch.is(object));
1325 1325
1326 __ And(at, object, Operand(kSmiTagMask)); 1326 __ And(at, object, Operand(kSmiTagMask));
1327 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); 1327 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
1328 __ GetObjectType(object, scratch, scratch); 1328 __ GetObjectType(object, scratch, scratch);
(...skipping 15 matching lines...) Expand all
1344 __ bind(&runtime); 1344 __ bind(&runtime);
1345 __ PrepareCallCFunction(2, scratch); 1345 __ PrepareCallCFunction(2, scratch);
1346 __ li(a1, Operand(index)); 1346 __ li(a1, Operand(index));
1347 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); 1347 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
1348 __ bind(&done); 1348 __ bind(&done);
1349 } 1349 }
1350 } 1350 }
1351 1351
1352 1352
1353 void LCodeGen::DoBitNotI(LBitNotI* instr) { 1353 void LCodeGen::DoBitNotI(LBitNotI* instr) {
1354 Register input = ToRegister(instr->InputAt(0)); 1354 Register input = ToRegister(instr->value());
1355 Register result = ToRegister(instr->result()); 1355 Register result = ToRegister(instr->result());
1356 __ Nor(result, zero_reg, Operand(input)); 1356 __ Nor(result, zero_reg, Operand(input));
1357 } 1357 }
1358 1358
1359 1359
1360 void LCodeGen::DoThrow(LThrow* instr) { 1360 void LCodeGen::DoThrow(LThrow* instr) {
1361 Register input_reg = EmitLoadRegister(instr->InputAt(0), at); 1361 Register input_reg = EmitLoadRegister(instr->value(), at);
1362 __ push(input_reg); 1362 __ push(input_reg);
1363 CallRuntime(Runtime::kThrow, 1, instr); 1363 CallRuntime(Runtime::kThrow, 1, instr);
1364 1364
1365 if (FLAG_debug_code) { 1365 if (FLAG_debug_code) {
1366 __ stop("Unreachable code."); 1366 __ stop("Unreachable code.");
1367 } 1367 }
1368 } 1368 }
1369 1369
1370 1370
1371 void LCodeGen::DoAddI(LAddI* instr) { 1371 void LCodeGen::DoAddI(LAddI* instr) {
1372 LOperand* left = instr->InputAt(0); 1372 LOperand* left = instr->left();
1373 LOperand* right = instr->InputAt(1); 1373 LOperand* right = instr->right();
1374 LOperand* result = instr->result(); 1374 LOperand* result = instr->result();
1375 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1375 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1376 1376
1377 if (!can_overflow) { 1377 if (!can_overflow) {
1378 if (right->IsStackSlot() || right->IsArgument()) { 1378 if (right->IsStackSlot() || right->IsArgument()) {
1379 Register right_reg = EmitLoadRegister(right, at); 1379 Register right_reg = EmitLoadRegister(right, at);
1380 __ Addu(ToRegister(result), ToRegister(left), Operand(right_reg)); 1380 __ Addu(ToRegister(result), ToRegister(left), Operand(right_reg));
1381 } else { 1381 } else {
1382 ASSERT(right->IsRegister() || right->IsConstantOperand()); 1382 ASSERT(right->IsRegister() || right->IsConstantOperand());
1383 __ Addu(ToRegister(result), ToRegister(left), ToOperand(right)); 1383 __ Addu(ToRegister(result), ToRegister(left), ToOperand(right));
(...skipping 17 matching lines...) Expand all
1401 ToRegister(left), 1401 ToRegister(left),
1402 ToRegister(right), 1402 ToRegister(right),
1403 overflow); // Reg at also used as scratch. 1403 overflow); // Reg at also used as scratch.
1404 } 1404 }
1405 DeoptimizeIf(lt, instr->environment(), overflow, Operand(zero_reg)); 1405 DeoptimizeIf(lt, instr->environment(), overflow, Operand(zero_reg));
1406 } 1406 }
1407 } 1407 }
1408 1408
1409 1409
1410 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { 1410 void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
1411 LOperand* left = instr->InputAt(0); 1411 LOperand* left = instr->left();
1412 LOperand* right = instr->InputAt(1); 1412 LOperand* right = instr->right();
1413 HMathMinMax::Operation operation = instr->hydrogen()->operation(); 1413 HMathMinMax::Operation operation = instr->hydrogen()->operation();
1414 Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge; 1414 Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge;
1415 if (instr->hydrogen()->representation().IsInteger32()) { 1415 if (instr->hydrogen()->representation().IsInteger32()) {
1416 Register left_reg = ToRegister(left); 1416 Register left_reg = ToRegister(left);
1417 Operand right_op = (right->IsRegister() || right->IsConstantOperand()) 1417 Operand right_op = (right->IsRegister() || right->IsConstantOperand())
1418 ? ToOperand(right) 1418 ? ToOperand(right)
1419 : Operand(EmitLoadRegister(right, at)); 1419 : Operand(EmitLoadRegister(right, at));
1420 Register result_reg = ToRegister(instr->result()); 1420 Register result_reg = ToRegister(instr->result());
1421 Label return_right, done; 1421 Label return_right, done;
1422 if (!result_reg.is(left_reg)) { 1422 if (!result_reg.is(left_reg)) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1463 __ bind(&return_left); 1463 __ bind(&return_left);
1464 if (!left_reg.is(result_reg)) { 1464 if (!left_reg.is(result_reg)) {
1465 __ mov_d(result_reg, left_reg); 1465 __ mov_d(result_reg, left_reg);
1466 } 1466 }
1467 __ bind(&done); 1467 __ bind(&done);
1468 } 1468 }
1469 } 1469 }
1470 1470
1471 1471
1472 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { 1472 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
1473 DoubleRegister left = ToDoubleRegister(instr->InputAt(0)); 1473 DoubleRegister left = ToDoubleRegister(instr->left());
1474 DoubleRegister right = ToDoubleRegister(instr->InputAt(1)); 1474 DoubleRegister right = ToDoubleRegister(instr->right());
1475 DoubleRegister result = ToDoubleRegister(instr->result()); 1475 DoubleRegister result = ToDoubleRegister(instr->result());
1476 switch (instr->op()) { 1476 switch (instr->op()) {
1477 case Token::ADD: 1477 case Token::ADD:
1478 __ add_d(result, left, right); 1478 __ add_d(result, left, right);
1479 break; 1479 break;
1480 case Token::SUB: 1480 case Token::SUB:
1481 __ sub_d(result, left, right); 1481 __ sub_d(result, left, right);
1482 break; 1482 break;
1483 case Token::MUL: 1483 case Token::MUL:
1484 __ mul_d(result, left, right); 1484 __ mul_d(result, left, right);
(...skipping 19 matching lines...) Expand all
1504 break; 1504 break;
1505 } 1505 }
1506 default: 1506 default:
1507 UNREACHABLE(); 1507 UNREACHABLE();
1508 break; 1508 break;
1509 } 1509 }
1510 } 1510 }
1511 1511
1512 1512
1513 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { 1513 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
1514 ASSERT(ToRegister(instr->InputAt(0)).is(a1)); 1514 ASSERT(ToRegister(instr->left()).is(a1));
1515 ASSERT(ToRegister(instr->InputAt(1)).is(a0)); 1515 ASSERT(ToRegister(instr->right()).is(a0));
1516 ASSERT(ToRegister(instr->result()).is(v0)); 1516 ASSERT(ToRegister(instr->result()).is(v0));
1517 1517
1518 BinaryOpStub stub(instr->op(), NO_OVERWRITE); 1518 BinaryOpStub stub(instr->op(), NO_OVERWRITE);
1519 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 1519 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1520 // Other arch use a nop here, to signal that there is no inlined 1520 // Other arch use a nop here, to signal that there is no inlined
1521 // patchable code. Mips does not need the nop, since our marker 1521 // patchable code. Mips does not need the nop, since our marker
1522 // instruction (andi zero_reg) will never be used in normal code. 1522 // instruction (andi zero_reg) will never be used in normal code.
1523 } 1523 }
1524 1524
1525 1525
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1569 } 1569 }
1570 } 1570 }
1571 1571
1572 1572
1573 void LCodeGen::DoBranch(LBranch* instr) { 1573 void LCodeGen::DoBranch(LBranch* instr) {
1574 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1574 int true_block = chunk_->LookupDestination(instr->true_block_id());
1575 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1575 int false_block = chunk_->LookupDestination(instr->false_block_id());
1576 1576
1577 Representation r = instr->hydrogen()->value()->representation(); 1577 Representation r = instr->hydrogen()->value()->representation();
1578 if (r.IsInteger32()) { 1578 if (r.IsInteger32()) {
1579 Register reg = ToRegister(instr->InputAt(0)); 1579 Register reg = ToRegister(instr->value());
1580 EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg)); 1580 EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg));
1581 } else if (r.IsDouble()) { 1581 } else if (r.IsDouble()) {
1582 DoubleRegister reg = ToDoubleRegister(instr->InputAt(0)); 1582 DoubleRegister reg = ToDoubleRegister(instr->value());
1583 // Test the double value. Zero and NaN are false. 1583 // Test the double value. Zero and NaN are false.
1584 EmitBranchF(true_block, false_block, ne, reg, kDoubleRegZero); 1584 EmitBranchF(true_block, false_block, ne, reg, kDoubleRegZero);
1585 } else { 1585 } else {
1586 ASSERT(r.IsTagged()); 1586 ASSERT(r.IsTagged());
1587 Register reg = ToRegister(instr->InputAt(0)); 1587 Register reg = ToRegister(instr->value());
1588 HType type = instr->hydrogen()->value()->type(); 1588 HType type = instr->hydrogen()->value()->type();
1589 if (type.IsBoolean()) { 1589 if (type.IsBoolean()) {
1590 __ LoadRoot(at, Heap::kTrueValueRootIndex); 1590 __ LoadRoot(at, Heap::kTrueValueRootIndex);
1591 EmitBranch(true_block, false_block, eq, reg, Operand(at)); 1591 EmitBranch(true_block, false_block, eq, reg, Operand(at));
1592 } else if (type.IsSmi()) { 1592 } else if (type.IsSmi()) {
1593 EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg)); 1593 EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg));
1594 } else { 1594 } else {
1595 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1595 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1596 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1596 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1597 1597
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1711 case Token::IN: 1711 case Token::IN:
1712 case Token::INSTANCEOF: 1712 case Token::INSTANCEOF:
1713 default: 1713 default:
1714 UNREACHABLE(); 1714 UNREACHABLE();
1715 } 1715 }
1716 return cond; 1716 return cond;
1717 } 1717 }
1718 1718
1719 1719
1720 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { 1720 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
1721 LOperand* left = instr->InputAt(0); 1721 LOperand* left = instr->left();
1722 LOperand* right = instr->InputAt(1); 1722 LOperand* right = instr->right();
1723 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1723 int false_block = chunk_->LookupDestination(instr->false_block_id());
1724 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1724 int true_block = chunk_->LookupDestination(instr->true_block_id());
1725 1725
1726 Condition cond = TokenToCondition(instr->op(), false); 1726 Condition cond = TokenToCondition(instr->op(), false);
1727 1727
1728 if (left->IsConstantOperand() && right->IsConstantOperand()) { 1728 if (left->IsConstantOperand() && right->IsConstantOperand()) {
1729 // We can statically evaluate the comparison. 1729 // We can statically evaluate the comparison.
1730 double left_val = ToDouble(LConstantOperand::cast(left)); 1730 double left_val = ToDouble(LConstantOperand::cast(left));
1731 double right_val = ToDouble(LConstantOperand::cast(right)); 1731 double right_val = ToDouble(LConstantOperand::cast(right));
1732 int next_block = 1732 int next_block =
(...skipping 30 matching lines...) Expand all
1763 cmp_right = Operand(ToRegister(right)); 1763 cmp_right = Operand(ToRegister(right));
1764 } 1764 }
1765 1765
1766 EmitBranch(true_block, false_block, cond, cmp_left, cmp_right); 1766 EmitBranch(true_block, false_block, cond, cmp_left, cmp_right);
1767 } 1767 }
1768 } 1768 }
1769 } 1769 }
1770 1770
1771 1771
1772 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { 1772 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
1773 Register left = ToRegister(instr->InputAt(0)); 1773 Register left = ToRegister(instr->left());
1774 Register right = ToRegister(instr->InputAt(1)); 1774 Register right = ToRegister(instr->right());
1775 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1775 int false_block = chunk_->LookupDestination(instr->false_block_id());
1776 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1776 int true_block = chunk_->LookupDestination(instr->true_block_id());
1777 1777
1778 EmitBranch(true_block, false_block, eq, left, Operand(right)); 1778 EmitBranch(true_block, false_block, eq, left, Operand(right));
1779 } 1779 }
1780 1780
1781 1781
1782 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) { 1782 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
1783 Register left = ToRegister(instr->InputAt(0)); 1783 Register left = ToRegister(instr->left());
1784 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1784 int true_block = chunk_->LookupDestination(instr->true_block_id());
1785 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1785 int false_block = chunk_->LookupDestination(instr->false_block_id());
1786 1786
1787 EmitBranch(true_block, false_block, eq, left, 1787 EmitBranch(true_block, false_block, eq, left,
1788 Operand(instr->hydrogen()->right())); 1788 Operand(instr->hydrogen()->right()));
1789 } 1789 }
1790 1790
1791 1791
1792 1792
1793 void LCodeGen::DoIsNilAndBranch(LIsNilAndBranch* instr) { 1793 void LCodeGen::DoIsNilAndBranch(LIsNilAndBranch* instr) {
1794 Register scratch = scratch0(); 1794 Register scratch = scratch0();
1795 Register reg = ToRegister(instr->InputAt(0)); 1795 Register reg = ToRegister(instr->value());
1796 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1796 int false_block = chunk_->LookupDestination(instr->false_block_id());
1797 1797
1798 // If the expression is known to be untagged or a smi, then it's definitely 1798 // If the expression is known to be untagged or a smi, then it's definitely
1799 // not null, and it can't be a an undetectable object. 1799 // not null, and it can't be a an undetectable object.
1800 if (instr->hydrogen()->representation().IsSpecialization() || 1800 if (instr->hydrogen()->representation().IsSpecialization() ||
1801 instr->hydrogen()->type().IsSmi()) { 1801 instr->hydrogen()->type().IsSmi()) {
1802 EmitGoto(false_block); 1802 EmitGoto(false_block);
1803 return; 1803 return;
1804 } 1804 }
1805 1805
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1851 // Load instance type and check that it is in object type range. 1851 // Load instance type and check that it is in object type range.
1852 __ lbu(temp2, FieldMemOperand(temp1, Map::kInstanceTypeOffset)); 1852 __ lbu(temp2, FieldMemOperand(temp1, Map::kInstanceTypeOffset));
1853 __ Branch(is_not_object, 1853 __ Branch(is_not_object,
1854 lt, temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 1854 lt, temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
1855 1855
1856 return le; 1856 return le;
1857 } 1857 }
1858 1858
1859 1859
1860 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { 1860 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
1861 Register reg = ToRegister(instr->InputAt(0)); 1861 Register reg = ToRegister(instr->value());
1862 Register temp1 = ToRegister(instr->TempAt(0)); 1862 Register temp1 = ToRegister(instr->temp());
1863 Register temp2 = scratch0(); 1863 Register temp2 = scratch0();
1864 1864
1865 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1865 int true_block = chunk_->LookupDestination(instr->true_block_id());
1866 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1866 int false_block = chunk_->LookupDestination(instr->false_block_id());
1867 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1867 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1868 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1868 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1869 1869
1870 Condition true_cond = 1870 Condition true_cond =
1871 EmitIsObject(reg, temp1, temp2, false_label, true_label); 1871 EmitIsObject(reg, temp1, temp2, false_label, true_label);
1872 1872
1873 EmitBranch(true_block, false_block, true_cond, temp2, 1873 EmitBranch(true_block, false_block, true_cond, temp2,
1874 Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); 1874 Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
1875 } 1875 }
1876 1876
1877 1877
1878 Condition LCodeGen::EmitIsString(Register input, 1878 Condition LCodeGen::EmitIsString(Register input,
1879 Register temp1, 1879 Register temp1,
1880 Label* is_not_string) { 1880 Label* is_not_string) {
1881 __ JumpIfSmi(input, is_not_string); 1881 __ JumpIfSmi(input, is_not_string);
1882 __ GetObjectType(input, temp1, temp1); 1882 __ GetObjectType(input, temp1, temp1);
1883 1883
1884 return lt; 1884 return lt;
1885 } 1885 }
1886 1886
1887 1887
1888 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { 1888 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
1889 Register reg = ToRegister(instr->InputAt(0)); 1889 Register reg = ToRegister(instr->value());
1890 Register temp1 = ToRegister(instr->TempAt(0)); 1890 Register temp1 = ToRegister(instr->temp());
1891 1891
1892 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1892 int true_block = chunk_->LookupDestination(instr->true_block_id());
1893 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1893 int false_block = chunk_->LookupDestination(instr->false_block_id());
1894 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1894 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1895 1895
1896 Condition true_cond = 1896 Condition true_cond =
1897 EmitIsString(reg, temp1, false_label); 1897 EmitIsString(reg, temp1, false_label);
1898 1898
1899 EmitBranch(true_block, false_block, true_cond, temp1, 1899 EmitBranch(true_block, false_block, true_cond, temp1,
1900 Operand(FIRST_NONSTRING_TYPE)); 1900 Operand(FIRST_NONSTRING_TYPE));
1901 } 1901 }
1902 1902
1903 1903
1904 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { 1904 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
1905 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1905 int true_block = chunk_->LookupDestination(instr->true_block_id());
1906 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1906 int false_block = chunk_->LookupDestination(instr->false_block_id());
1907 1907
1908 Register input_reg = EmitLoadRegister(instr->InputAt(0), at); 1908 Register input_reg = EmitLoadRegister(instr->value(), at);
1909 __ And(at, input_reg, kSmiTagMask); 1909 __ And(at, input_reg, kSmiTagMask);
1910 EmitBranch(true_block, false_block, eq, at, Operand(zero_reg)); 1910 EmitBranch(true_block, false_block, eq, at, Operand(zero_reg));
1911 } 1911 }
1912 1912
1913 1913
1914 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { 1914 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
1915 Register input = ToRegister(instr->InputAt(0)); 1915 Register input = ToRegister(instr->value());
1916 Register temp = ToRegister(instr->TempAt(0)); 1916 Register temp = ToRegister(instr->temp());
1917 1917
1918 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1918 int true_block = chunk_->LookupDestination(instr->true_block_id());
1919 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1919 int false_block = chunk_->LookupDestination(instr->false_block_id());
1920 1920
1921 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block)); 1921 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block));
1922 __ lw(temp, FieldMemOperand(input, HeapObject::kMapOffset)); 1922 __ lw(temp, FieldMemOperand(input, HeapObject::kMapOffset));
1923 __ lbu(temp, FieldMemOperand(temp, Map::kBitFieldOffset)); 1923 __ lbu(temp, FieldMemOperand(temp, Map::kBitFieldOffset));
1924 __ And(at, temp, Operand(1 << Map::kIsUndetectable)); 1924 __ And(at, temp, Operand(1 << Map::kIsUndetectable));
1925 EmitBranch(true_block, false_block, ne, at, Operand(zero_reg)); 1925 EmitBranch(true_block, false_block, ne, at, Operand(zero_reg));
1926 } 1926 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1975 if (from == to) return eq; 1975 if (from == to) return eq;
1976 if (to == LAST_TYPE) return hs; 1976 if (to == LAST_TYPE) return hs;
1977 if (from == FIRST_TYPE) return ls; 1977 if (from == FIRST_TYPE) return ls;
1978 UNREACHABLE(); 1978 UNREACHABLE();
1979 return eq; 1979 return eq;
1980 } 1980 }
1981 1981
1982 1982
1983 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { 1983 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
1984 Register scratch = scratch0(); 1984 Register scratch = scratch0();
1985 Register input = ToRegister(instr->InputAt(0)); 1985 Register input = ToRegister(instr->value());
1986 1986
1987 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1987 int true_block = chunk_->LookupDestination(instr->true_block_id());
1988 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1988 int false_block = chunk_->LookupDestination(instr->false_block_id());
1989 1989
1990 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1990 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1991 1991
1992 __ JumpIfSmi(input, false_label); 1992 __ JumpIfSmi(input, false_label);
1993 1993
1994 __ GetObjectType(input, scratch, scratch); 1994 __ GetObjectType(input, scratch, scratch);
1995 EmitBranch(true_block, 1995 EmitBranch(true_block,
1996 false_block, 1996 false_block,
1997 BranchCondition(instr->hydrogen()), 1997 BranchCondition(instr->hydrogen()),
1998 scratch, 1998 scratch,
1999 Operand(TestType(instr->hydrogen()))); 1999 Operand(TestType(instr->hydrogen())));
2000 } 2000 }
2001 2001
2002 2002
2003 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { 2003 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
2004 Register input = ToRegister(instr->InputAt(0)); 2004 Register input = ToRegister(instr->value());
2005 Register result = ToRegister(instr->result()); 2005 Register result = ToRegister(instr->result());
2006 2006
2007 __ AbortIfNotString(input); 2007 __ AbortIfNotString(input);
2008 2008
2009 __ lw(result, FieldMemOperand(input, String::kHashFieldOffset)); 2009 __ lw(result, FieldMemOperand(input, String::kHashFieldOffset));
2010 __ IndexFromHash(result, result); 2010 __ IndexFromHash(result, result);
2011 } 2011 }
2012 2012
2013 2013
2014 void LCodeGen::DoHasCachedArrayIndexAndBranch( 2014 void LCodeGen::DoHasCachedArrayIndexAndBranch(
2015 LHasCachedArrayIndexAndBranch* instr) { 2015 LHasCachedArrayIndexAndBranch* instr) {
2016 Register input = ToRegister(instr->InputAt(0)); 2016 Register input = ToRegister(instr->value());
2017 Register scratch = scratch0(); 2017 Register scratch = scratch0();
2018 2018
2019 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2019 int true_block = chunk_->LookupDestination(instr->true_block_id());
2020 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2020 int false_block = chunk_->LookupDestination(instr->false_block_id());
2021 2021
2022 __ lw(scratch, 2022 __ lw(scratch,
2023 FieldMemOperand(input, String::kHashFieldOffset)); 2023 FieldMemOperand(input, String::kHashFieldOffset));
2024 __ And(at, scratch, Operand(String::kContainsCachedArrayIndexMask)); 2024 __ And(at, scratch, Operand(String::kContainsCachedArrayIndexMask));
2025 EmitBranch(true_block, false_block, eq, at, Operand(zero_reg)); 2025 EmitBranch(true_block, false_block, eq, at, Operand(zero_reg));
2026 } 2026 }
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2086 // classes and it doesn't have to because you can't access it with natives 2086 // classes and it doesn't have to because you can't access it with natives
2087 // syntax. Since both sides are symbols it is sufficient to use an identity 2087 // syntax. Since both sides are symbols it is sufficient to use an identity
2088 // comparison. 2088 // comparison.
2089 2089
2090 // End with the address of this class_name instance in temp register. 2090 // End with the address of this class_name instance in temp register.
2091 // On MIPS, the caller must do the comparison with Handle<String>class_name. 2091 // On MIPS, the caller must do the comparison with Handle<String>class_name.
2092 } 2092 }
2093 2093
2094 2094
2095 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 2095 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
2096 Register input = ToRegister(instr->InputAt(0)); 2096 Register input = ToRegister(instr->value());
2097 Register temp = scratch0(); 2097 Register temp = scratch0();
2098 Register temp2 = ToRegister(instr->TempAt(0)); 2098 Register temp2 = ToRegister(instr->temp());
2099 Handle<String> class_name = instr->hydrogen()->class_name(); 2099 Handle<String> class_name = instr->hydrogen()->class_name();
2100 2100
2101 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2101 int true_block = chunk_->LookupDestination(instr->true_block_id());
2102 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2102 int false_block = chunk_->LookupDestination(instr->false_block_id());
2103 2103
2104 Label* true_label = chunk_->GetAssemblyLabel(true_block); 2104 Label* true_label = chunk_->GetAssemblyLabel(true_block);
2105 Label* false_label = chunk_->GetAssemblyLabel(false_block); 2105 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2106 2106
2107 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2); 2107 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2);
2108 2108
2109 EmitBranch(true_block, false_block, eq, temp, Operand(class_name)); 2109 EmitBranch(true_block, false_block, eq, temp, Operand(class_name));
2110 } 2110 }
2111 2111
2112 2112
2113 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { 2113 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
2114 Register reg = ToRegister(instr->InputAt(0)); 2114 Register reg = ToRegister(instr->value());
2115 Register temp = ToRegister(instr->TempAt(0)); 2115 Register temp = ToRegister(instr->temp());
2116 int true_block = instr->true_block_id(); 2116 int true_block = instr->true_block_id();
2117 int false_block = instr->false_block_id(); 2117 int false_block = instr->false_block_id();
2118 2118
2119 __ lw(temp, FieldMemOperand(reg, HeapObject::kMapOffset)); 2119 __ lw(temp, FieldMemOperand(reg, HeapObject::kMapOffset));
2120 EmitBranch(true_block, false_block, eq, temp, Operand(instr->map())); 2120 EmitBranch(true_block, false_block, eq, temp, Operand(instr->map()));
2121 } 2121 }
2122 2122
2123 2123
2124 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { 2124 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
2125 Label true_label, done; 2125 Label true_label, done;
2126 ASSERT(ToRegister(instr->InputAt(0)).is(a0)); // Object is in a0. 2126 ASSERT(ToRegister(instr->left()).is(a0)); // Object is in a0.
2127 ASSERT(ToRegister(instr->InputAt(1)).is(a1)); // Function is in a1. 2127 ASSERT(ToRegister(instr->right()).is(a1)); // Function is in a1.
2128 Register result = ToRegister(instr->result()); 2128 Register result = ToRegister(instr->result());
2129 ASSERT(result.is(v0)); 2129 ASSERT(result.is(v0));
2130 2130
2131 InstanceofStub stub(InstanceofStub::kArgsInRegisters); 2131 InstanceofStub stub(InstanceofStub::kArgsInRegisters);
2132 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 2132 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2133 2133
2134 __ Branch(&true_label, eq, result, Operand(zero_reg)); 2134 __ Branch(&true_label, eq, result, Operand(zero_reg));
2135 __ li(result, Operand(factory()->false_value())); 2135 __ li(result, Operand(factory()->false_value()));
2136 __ Branch(&done); 2136 __ Branch(&done);
2137 __ bind(&true_label); 2137 __ bind(&true_label);
(...skipping 16 matching lines...) Expand all
2154 2154
2155 private: 2155 private:
2156 LInstanceOfKnownGlobal* instr_; 2156 LInstanceOfKnownGlobal* instr_;
2157 Label map_check_; 2157 Label map_check_;
2158 }; 2158 };
2159 2159
2160 DeferredInstanceOfKnownGlobal* deferred; 2160 DeferredInstanceOfKnownGlobal* deferred;
2161 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr); 2161 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr);
2162 2162
2163 Label done, false_result; 2163 Label done, false_result;
2164 Register object = ToRegister(instr->InputAt(0)); 2164 Register object = ToRegister(instr->value());
2165 Register temp = ToRegister(instr->TempAt(0)); 2165 Register temp = ToRegister(instr->temp());
2166 Register result = ToRegister(instr->result()); 2166 Register result = ToRegister(instr->result());
2167 2167
2168 ASSERT(object.is(a0)); 2168 ASSERT(object.is(a0));
2169 ASSERT(result.is(v0)); 2169 ASSERT(result.is(v0));
2170 2170
2171 // A Smi is not instance of anything. 2171 // A Smi is not instance of anything.
2172 __ JumpIfSmi(object, &false_result); 2172 __ JumpIfSmi(object, &false_result);
2173 2173
2174 // This is the inlined call site instanceof cache. The two occurences of the 2174 // This is the inlined call site instanceof cache. The two occurences of the
2175 // hole value will be patched to the last map/result pair generated by the 2175 // hole value will be patched to the last map/result pair generated by the
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
2230 flags | InstanceofStub::kCallSiteInlineCheck); 2230 flags | InstanceofStub::kCallSiteInlineCheck);
2231 flags = static_cast<InstanceofStub::Flags>( 2231 flags = static_cast<InstanceofStub::Flags>(
2232 flags | InstanceofStub::kReturnTrueFalseObject); 2232 flags | InstanceofStub::kReturnTrueFalseObject);
2233 InstanceofStub stub(flags); 2233 InstanceofStub stub(flags);
2234 2234
2235 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 2235 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
2236 2236
2237 // Get the temp register reserved by the instruction. This needs to be t0 as 2237 // Get the temp register reserved by the instruction. This needs to be t0 as
2238 // its slot of the pushing of safepoint registers is used to communicate the 2238 // its slot of the pushing of safepoint registers is used to communicate the
2239 // offset to the location of the map check. 2239 // offset to the location of the map check.
2240 Register temp = ToRegister(instr->TempAt(0)); 2240 Register temp = ToRegister(instr->temp());
2241 ASSERT(temp.is(t0)); 2241 ASSERT(temp.is(t0));
2242 __ LoadHeapObject(InstanceofStub::right(), instr->function()); 2242 __ LoadHeapObject(InstanceofStub::right(), instr->function());
2243 static const int kAdditionalDelta = 7; 2243 static const int kAdditionalDelta = 7;
2244 int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta; 2244 int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta;
2245 Label before_push_delta; 2245 Label before_push_delta;
2246 __ bind(&before_push_delta); 2246 __ bind(&before_push_delta);
2247 { 2247 {
2248 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); 2248 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
2249 __ li(temp, Operand(delta * kPointerSize), CONSTANT_SIZE); 2249 __ li(temp, Operand(delta * kPointerSize), CONSTANT_SIZE);
2250 __ StoreToSafepointRegisterSlot(temp, temp); 2250 __ StoreToSafepointRegisterSlot(temp, temp);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2325 2325
2326 // Load the cell. 2326 // Load the cell.
2327 __ li(cell, Operand(instr->hydrogen()->cell())); 2327 __ li(cell, Operand(instr->hydrogen()->cell()));
2328 2328
2329 // If the cell we are storing to contains the hole it could have 2329 // If the cell we are storing to contains the hole it could have
2330 // been deleted from the property dictionary. In that case, we need 2330 // been deleted from the property dictionary. In that case, we need
2331 // to update the property details in the property dictionary to mark 2331 // to update the property details in the property dictionary to mark
2332 // it as no longer deleted. 2332 // it as no longer deleted.
2333 if (instr->hydrogen()->RequiresHoleCheck()) { 2333 if (instr->hydrogen()->RequiresHoleCheck()) {
2334 // We use a temp to check the payload. 2334 // We use a temp to check the payload.
2335 Register payload = ToRegister(instr->TempAt(0)); 2335 Register payload = ToRegister(instr->temp());
2336 __ lw(payload, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset)); 2336 __ lw(payload, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset));
2337 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2337 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2338 DeoptimizeIf(eq, instr->environment(), payload, Operand(at)); 2338 DeoptimizeIf(eq, instr->environment(), payload, Operand(at));
2339 } 2339 }
2340 2340
2341 // Store the value. 2341 // Store the value.
2342 __ sw(value, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset)); 2342 __ sw(value, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset));
2343 // Cells are always rescanned, so no write barrier here. 2343 // Cells are always rescanned, so no write barrier here.
2344 } 2344 }
2345 2345
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2408 kSaveFPRegs, 2408 kSaveFPRegs,
2409 EMIT_REMEMBERED_SET, 2409 EMIT_REMEMBERED_SET,
2410 check_needed); 2410 check_needed);
2411 } 2411 }
2412 2412
2413 __ bind(&skip_assignment); 2413 __ bind(&skip_assignment);
2414 } 2414 }
2415 2415
2416 2416
2417 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { 2417 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
2418 Register object = ToRegister(instr->InputAt(0)); 2418 Register object = ToRegister(instr->object());
2419 Register result = ToRegister(instr->result()); 2419 Register result = ToRegister(instr->result());
2420 if (instr->hydrogen()->is_in_object()) { 2420 if (instr->hydrogen()->is_in_object()) {
2421 __ lw(result, FieldMemOperand(object, instr->hydrogen()->offset())); 2421 __ lw(result, FieldMemOperand(object, instr->hydrogen()->offset()));
2422 } else { 2422 } else {
2423 __ lw(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); 2423 __ lw(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
2424 __ lw(result, FieldMemOperand(result, instr->hydrogen()->offset())); 2424 __ lw(result, FieldMemOperand(result, instr->hydrogen()->offset()));
2425 } 2425 }
2426 } 2426 }
2427 2427
2428 2428
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
2561 __ bind(&non_instance); 2561 __ bind(&non_instance);
2562 __ lw(result, FieldMemOperand(result, Map::kConstructorOffset)); 2562 __ lw(result, FieldMemOperand(result, Map::kConstructorOffset));
2563 2563
2564 // All done. 2564 // All done.
2565 __ bind(&done); 2565 __ bind(&done);
2566 } 2566 }
2567 2567
2568 2568
2569 void LCodeGen::DoLoadElements(LLoadElements* instr) { 2569 void LCodeGen::DoLoadElements(LLoadElements* instr) {
2570 Register result = ToRegister(instr->result()); 2570 Register result = ToRegister(instr->result());
2571 Register input = ToRegister(instr->InputAt(0)); 2571 Register input = ToRegister(instr->object());
2572 Register scratch = scratch0(); 2572 Register scratch = scratch0();
2573 2573
2574 __ lw(result, FieldMemOperand(input, JSObject::kElementsOffset)); 2574 __ lw(result, FieldMemOperand(input, JSObject::kElementsOffset));
2575 if (FLAG_debug_code) { 2575 if (FLAG_debug_code) {
2576 Label done, fail; 2576 Label done, fail;
2577 __ lw(scratch, FieldMemOperand(result, HeapObject::kMapOffset)); 2577 __ lw(scratch, FieldMemOperand(result, HeapObject::kMapOffset));
2578 __ LoadRoot(at, Heap::kFixedArrayMapRootIndex); 2578 __ LoadRoot(at, Heap::kFixedArrayMapRootIndex);
2579 __ Branch(USE_DELAY_SLOT, &done, eq, scratch, Operand(at)); 2579 __ Branch(USE_DELAY_SLOT, &done, eq, scratch, Operand(at));
2580 __ LoadRoot(at, Heap::kFixedCOWArrayMapRootIndex); // In the delay slot. 2580 __ LoadRoot(at, Heap::kFixedCOWArrayMapRootIndex); // In the delay slot.
2581 __ Branch(&done, eq, scratch, Operand(at)); 2581 __ Branch(&done, eq, scratch, Operand(at));
(...skipping 12 matching lines...) Expand all
2594 __ bind(&fail); 2594 __ bind(&fail);
2595 __ Abort("Check for fast or external elements failed."); 2595 __ Abort("Check for fast or external elements failed.");
2596 __ bind(&done); 2596 __ bind(&done);
2597 } 2597 }
2598 } 2598 }
2599 2599
2600 2600
2601 void LCodeGen::DoLoadExternalArrayPointer( 2601 void LCodeGen::DoLoadExternalArrayPointer(
2602 LLoadExternalArrayPointer* instr) { 2602 LLoadExternalArrayPointer* instr) {
2603 Register to_reg = ToRegister(instr->result()); 2603 Register to_reg = ToRegister(instr->result());
2604 Register from_reg = ToRegister(instr->InputAt(0)); 2604 Register from_reg = ToRegister(instr->object());
2605 __ lw(to_reg, FieldMemOperand(from_reg, 2605 __ lw(to_reg, FieldMemOperand(from_reg,
2606 ExternalArray::kExternalPointerOffset)); 2606 ExternalArray::kExternalPointerOffset));
2607 } 2607 }
2608 2608
2609 2609
2610 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { 2610 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
2611 Register arguments = ToRegister(instr->arguments()); 2611 Register arguments = ToRegister(instr->arguments());
2612 Register length = ToRegister(instr->length()); 2612 Register length = ToRegister(instr->length());
2613 Register index = ToRegister(instr->index()); 2613 Register index = ToRegister(instr->index());
2614 Register result = ToRegister(instr->result()); 2614 Register result = ToRegister(instr->result());
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
2867 2867
2868 // Result is the frame pointer for the frame if not adapted and for the real 2868 // Result is the frame pointer for the frame if not adapted and for the real
2869 // frame below the adaptor frame if adapted. 2869 // frame below the adaptor frame if adapted.
2870 __ Movn(result, fp, temp); // Move only if temp is not equal to zero (ne). 2870 __ Movn(result, fp, temp); // Move only if temp is not equal to zero (ne).
2871 __ Movz(result, scratch, temp); // Move only if temp is equal to zero (eq). 2871 __ Movz(result, scratch, temp); // Move only if temp is equal to zero (eq).
2872 } 2872 }
2873 } 2873 }
2874 2874
2875 2875
2876 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { 2876 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
2877 Register elem = ToRegister(instr->InputAt(0)); 2877 Register elem = ToRegister(instr->elements());
2878 Register result = ToRegister(instr->result()); 2878 Register result = ToRegister(instr->result());
2879 2879
2880 Label done; 2880 Label done;
2881 2881
2882 // If no arguments adaptor frame the number of arguments is fixed. 2882 // If no arguments adaptor frame the number of arguments is fixed.
2883 __ Addu(result, zero_reg, Operand(scope()->num_parameters())); 2883 __ Addu(result, zero_reg, Operand(scope()->num_parameters()));
2884 __ Branch(&done, eq, fp, Operand(elem)); 2884 __ Branch(&done, eq, fp, Operand(elem));
2885 2885
2886 // Arguments adaptor frame present. Get argument length from there. 2886 // Arguments adaptor frame present. Get argument length from there.
2887 __ lw(result, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 2887 __ lw(result, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
2985 // The number of arguments is stored in receiver which is a0, as expected 2985 // The number of arguments is stored in receiver which is a0, as expected
2986 // by InvokeFunction. 2986 // by InvokeFunction.
2987 ParameterCount actual(receiver); 2987 ParameterCount actual(receiver);
2988 __ InvokeFunction(function, actual, CALL_FUNCTION, 2988 __ InvokeFunction(function, actual, CALL_FUNCTION,
2989 safepoint_generator, CALL_AS_METHOD); 2989 safepoint_generator, CALL_AS_METHOD);
2990 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2990 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2991 } 2991 }
2992 2992
2993 2993
2994 void LCodeGen::DoPushArgument(LPushArgument* instr) { 2994 void LCodeGen::DoPushArgument(LPushArgument* instr) {
2995 LOperand* argument = instr->InputAt(0); 2995 LOperand* argument = instr->value();
2996 if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) { 2996 if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) {
2997 Abort("DoPushArgument not implemented for double type."); 2997 Abort("DoPushArgument not implemented for double type.");
2998 } else { 2998 } else {
2999 Register argument_reg = EmitLoadRegister(argument, at); 2999 Register argument_reg = EmitLoadRegister(argument, at);
3000 __ push(argument_reg); 3000 __ push(argument_reg);
3001 } 3001 }
3002 } 3002 }
3003 3003
3004 3004
3005 void LCodeGen::DoDrop(LDrop* instr) { 3005 void LCodeGen::DoDrop(LDrop* instr) {
(...skipping 30 matching lines...) Expand all
3036 } 3036 }
3037 3037
3038 3038
3039 void LCodeGen::DoGlobalObject(LGlobalObject* instr) { 3039 void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
3040 Register result = ToRegister(instr->result()); 3040 Register result = ToRegister(instr->result());
3041 __ lw(result, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); 3041 __ lw(result, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
3042 } 3042 }
3043 3043
3044 3044
3045 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { 3045 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) {
3046 Register global = ToRegister(instr->global()); 3046 Register global = ToRegister(instr->global_object());
3047 Register result = ToRegister(instr->result()); 3047 Register result = ToRegister(instr->result());
3048 __ lw(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset)); 3048 __ lw(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset));
3049 } 3049 }
3050 3050
3051 3051
3052 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, 3052 void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
3053 int arity, 3053 int arity,
3054 LInstruction* instr, 3054 LInstruction* instr,
3055 CallKind call_kind, 3055 CallKind call_kind,
3056 A1State a1_state) { 3056 A1State a1_state) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
3097 __ mov(a0, v0); 3097 __ mov(a0, v0);
3098 CallKnownFunction(instr->function(), 3098 CallKnownFunction(instr->function(),
3099 instr->arity(), 3099 instr->arity(),
3100 instr, 3100 instr,
3101 CALL_AS_METHOD, 3101 CALL_AS_METHOD,
3102 A1_UNINITIALIZED); 3102 A1_UNINITIALIZED);
3103 } 3103 }
3104 3104
3105 3105
3106 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { 3106 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
3107 Register input = ToRegister(instr->InputAt(0)); 3107 Register input = ToRegister(instr->value());
3108 Register result = ToRegister(instr->result()); 3108 Register result = ToRegister(instr->result());
3109 Register scratch = scratch0(); 3109 Register scratch = scratch0();
3110 3110
3111 // Deoptimize if not a heap number. 3111 // Deoptimize if not a heap number.
3112 __ lw(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); 3112 __ lw(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
3113 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 3113 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
3114 DeoptimizeIf(ne, instr->environment(), scratch, Operand(at)); 3114 DeoptimizeIf(ne, instr->environment(), scratch, Operand(at));
3115 3115
3116 Label done; 3116 Label done;
3117 Register exponent = scratch0(); 3117 Register exponent = scratch0();
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
3162 __ sw(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset)); 3162 __ sw(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset));
3163 3163
3164 __ StoreToSafepointRegisterSlot(tmp1, result); 3164 __ StoreToSafepointRegisterSlot(tmp1, result);
3165 } 3165 }
3166 3166
3167 __ bind(&done); 3167 __ bind(&done);
3168 } 3168 }
3169 3169
3170 3170
3171 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { 3171 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
3172 Register input = ToRegister(instr->InputAt(0)); 3172 Register input = ToRegister(instr->value());
3173 Register result = ToRegister(instr->result()); 3173 Register result = ToRegister(instr->result());
3174 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); 3174 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
3175 Label done; 3175 Label done;
3176 __ Branch(USE_DELAY_SLOT, &done, ge, input, Operand(zero_reg)); 3176 __ Branch(USE_DELAY_SLOT, &done, ge, input, Operand(zero_reg));
3177 __ mov(result, input); 3177 __ mov(result, input);
3178 ASSERT_EQ(2, masm()->InstructionsGeneratedSince(&done)); 3178 ASSERT_EQ(2, masm()->InstructionsGeneratedSince(&done));
3179 __ subu(result, zero_reg, input); 3179 __ subu(result, zero_reg, input);
3180 // Overflow if result is still negative, i.e. 0x80000000. 3180 // Overflow if result is still negative, i.e. 0x80000000.
3181 DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg)); 3181 DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg));
3182 __ bind(&done); 3182 __ bind(&done);
(...skipping 10 matching lines...) Expand all
3193 virtual void Generate() { 3193 virtual void Generate() {
3194 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 3194 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
3195 } 3195 }
3196 virtual LInstruction* instr() { return instr_; } 3196 virtual LInstruction* instr() { return instr_; }
3197 private: 3197 private:
3198 LUnaryMathOperation* instr_; 3198 LUnaryMathOperation* instr_;
3199 }; 3199 };
3200 3200
3201 Representation r = instr->hydrogen()->value()->representation(); 3201 Representation r = instr->hydrogen()->value()->representation();
3202 if (r.IsDouble()) { 3202 if (r.IsDouble()) {
3203 FPURegister input = ToDoubleRegister(instr->InputAt(0)); 3203 FPURegister input = ToDoubleRegister(instr->value());
3204 FPURegister result = ToDoubleRegister(instr->result()); 3204 FPURegister result = ToDoubleRegister(instr->result());
3205 __ abs_d(result, input); 3205 __ abs_d(result, input);
3206 } else if (r.IsInteger32()) { 3206 } else if (r.IsInteger32()) {
3207 EmitIntegerMathAbs(instr); 3207 EmitIntegerMathAbs(instr);
3208 } else { 3208 } else {
3209 // Representation is tagged. 3209 // Representation is tagged.
3210 DeferredMathAbsTaggedHeapNumber* deferred = 3210 DeferredMathAbsTaggedHeapNumber* deferred =
3211 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr); 3211 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
3212 Register input = ToRegister(instr->InputAt(0)); 3212 Register input = ToRegister(instr->value());
3213 // Smi check. 3213 // Smi check.
3214 __ JumpIfNotSmi(input, deferred->entry()); 3214 __ JumpIfNotSmi(input, deferred->entry());
3215 // If smi, handle it directly. 3215 // If smi, handle it directly.
3216 EmitIntegerMathAbs(instr); 3216 EmitIntegerMathAbs(instr);
3217 __ bind(deferred->exit()); 3217 __ bind(deferred->exit());
3218 } 3218 }
3219 } 3219 }
3220 3220
3221 3221
3222 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { 3222 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
3223 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); 3223 DoubleRegister input = ToDoubleRegister(instr->value());
3224 Register result = ToRegister(instr->result()); 3224 Register result = ToRegister(instr->result());
3225 FPURegister single_scratch = double_scratch0().low(); 3225 FPURegister single_scratch = double_scratch0().low();
3226 Register scratch1 = scratch0(); 3226 Register scratch1 = scratch0();
3227 Register except_flag = ToRegister(instr->TempAt(0)); 3227 Register except_flag = ToRegister(instr->temp());
3228 3228
3229 __ EmitFPUTruncate(kRoundToMinusInf, 3229 __ EmitFPUTruncate(kRoundToMinusInf,
3230 single_scratch, 3230 single_scratch,
3231 input, 3231 input,
3232 scratch1, 3232 scratch1,
3233 except_flag); 3233 except_flag);
3234 3234
3235 // Deopt if the operation did not succeed. 3235 // Deopt if the operation did not succeed.
3236 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); 3236 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg));
3237 3237
3238 // Load the result. 3238 // Load the result.
3239 __ mfc1(result, single_scratch); 3239 __ mfc1(result, single_scratch);
3240 3240
3241 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3241 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3242 // Test for -0. 3242 // Test for -0.
3243 Label done; 3243 Label done;
3244 __ Branch(&done, ne, result, Operand(zero_reg)); 3244 __ Branch(&done, ne, result, Operand(zero_reg));
3245 __ mfc1(scratch1, input.high()); 3245 __ mfc1(scratch1, input.high());
3246 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); 3246 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
3247 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); 3247 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg));
3248 __ bind(&done); 3248 __ bind(&done);
3249 } 3249 }
3250 } 3250 }
3251 3251
3252 3252
3253 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { 3253 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
3254 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); 3254 DoubleRegister input = ToDoubleRegister(instr->value());
3255 Register result = ToRegister(instr->result()); 3255 Register result = ToRegister(instr->result());
3256 Register scratch = scratch0(); 3256 Register scratch = scratch0();
3257 Label done, check_sign_on_zero; 3257 Label done, check_sign_on_zero;
3258 3258
3259 // Extract exponent bits. 3259 // Extract exponent bits.
3260 __ mfc1(result, input.high()); 3260 __ mfc1(result, input.high());
3261 __ Ext(scratch, 3261 __ Ext(scratch,
3262 result, 3262 result,
3263 HeapNumber::kExponentShift, 3263 HeapNumber::kExponentShift,
3264 HeapNumber::kExponentBits); 3264 HeapNumber::kExponentBits);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
3321 __ bind(&check_sign_on_zero); 3321 __ bind(&check_sign_on_zero);
3322 __ mfc1(scratch, input.high()); 3322 __ mfc1(scratch, input.high());
3323 __ And(scratch, scratch, Operand(HeapNumber::kSignMask)); 3323 __ And(scratch, scratch, Operand(HeapNumber::kSignMask));
3324 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); 3324 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg));
3325 } 3325 }
3326 __ bind(&done); 3326 __ bind(&done);
3327 } 3327 }
3328 3328
3329 3329
3330 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { 3330 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
3331 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); 3331 DoubleRegister input = ToDoubleRegister(instr->value());
3332 DoubleRegister result = ToDoubleRegister(instr->result()); 3332 DoubleRegister result = ToDoubleRegister(instr->result());
3333 __ sqrt_d(result, input); 3333 __ sqrt_d(result, input);
3334 } 3334 }
3335 3335
3336 3336
3337 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { 3337 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
3338 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); 3338 DoubleRegister input = ToDoubleRegister(instr->value());
3339 DoubleRegister result = ToDoubleRegister(instr->result()); 3339 DoubleRegister result = ToDoubleRegister(instr->result());
3340 DoubleRegister temp = ToDoubleRegister(instr->TempAt(0)); 3340 DoubleRegister temp = ToDoubleRegister(instr->temp());
3341 3341
3342 ASSERT(!input.is(result)); 3342 ASSERT(!input.is(result));
3343 3343
3344 // Note that according to ECMA-262 15.8.2.13: 3344 // Note that according to ECMA-262 15.8.2.13:
3345 // Math.pow(-Infinity, 0.5) == Infinity 3345 // Math.pow(-Infinity, 0.5) == Infinity
3346 // Math.sqrt(-Infinity) == NaN 3346 // Math.sqrt(-Infinity) == NaN
3347 Label done; 3347 Label done;
3348 __ Move(temp, -V8_INFINITY); 3348 __ Move(temp, -V8_INFINITY);
3349 __ BranchF(USE_DELAY_SLOT, &done, NULL, eq, temp, input); 3349 __ BranchF(USE_DELAY_SLOT, &done, NULL, eq, temp, input);
3350 // Set up Infinity in the delay slot. 3350 // Set up Infinity in the delay slot.
3351 // result is overwritten if the branch is not taken. 3351 // result is overwritten if the branch is not taken.
3352 __ neg_d(result, temp); 3352 __ neg_d(result, temp);
3353 3353
3354 // Add +0 to convert -0 to +0. 3354 // Add +0 to convert -0 to +0.
3355 __ add_d(result, input, kDoubleRegZero); 3355 __ add_d(result, input, kDoubleRegZero);
3356 __ sqrt_d(result, result); 3356 __ sqrt_d(result, result);
3357 __ bind(&done); 3357 __ bind(&done);
3358 } 3358 }
3359 3359
3360 3360
3361 void LCodeGen::DoPower(LPower* instr) { 3361 void LCodeGen::DoPower(LPower* instr) {
3362 Representation exponent_type = instr->hydrogen()->right()->representation(); 3362 Representation exponent_type = instr->hydrogen()->right()->representation();
3363 // Having marked this as a call, we can use any registers. 3363 // Having marked this as a call, we can use any registers.
3364 // Just make sure that the input/output registers are the expected ones. 3364 // Just make sure that the input/output registers are the expected ones.
3365 ASSERT(!instr->InputAt(1)->IsDoubleRegister() || 3365 ASSERT(!instr->InputAt(1)->IsDoubleRegister() ||
3366 ToDoubleRegister(instr->InputAt(1)).is(f4)); 3366 ToDoubleRegister(instr->right()).is(f4));
3367 ASSERT(!instr->InputAt(1)->IsRegister() || 3367 ASSERT(!instr->InputAt(1)->IsRegister() ||
3368 ToRegister(instr->InputAt(1)).is(a2)); 3368 ToRegister(instr->right()).is(a2));
3369 ASSERT(ToDoubleRegister(instr->InputAt(0)).is(f2)); 3369 ASSERT(ToDoubleRegister(instr->left()).is(f2));
3370 ASSERT(ToDoubleRegister(instr->result()).is(f0)); 3370 ASSERT(ToDoubleRegister(instr->result()).is(f0));
3371 3371
3372 if (exponent_type.IsTagged()) { 3372 if (exponent_type.IsTagged()) {
3373 Label no_deopt; 3373 Label no_deopt;
3374 __ JumpIfSmi(a2, &no_deopt); 3374 __ JumpIfSmi(a2, &no_deopt);
3375 __ lw(t3, FieldMemOperand(a2, HeapObject::kMapOffset)); 3375 __ lw(t3, FieldMemOperand(a2, HeapObject::kMapOffset));
3376 DeoptimizeIf(ne, instr->environment(), t3, Operand(at)); 3376 DeoptimizeIf(ne, instr->environment(), t3, Operand(at));
3377 __ bind(&no_deopt); 3377 __ bind(&no_deopt);
3378 MathPowStub stub(MathPowStub::TAGGED); 3378 MathPowStub stub(MathPowStub::TAGGED);
3379 __ CallStub(&stub); 3379 __ CallStub(&stub);
(...skipping 16 matching lines...) Expand all
3396 virtual void Generate() { codegen()->DoDeferredRandom(instr_); } 3396 virtual void Generate() { codegen()->DoDeferredRandom(instr_); }
3397 virtual LInstruction* instr() { return instr_; } 3397 virtual LInstruction* instr() { return instr_; }
3398 private: 3398 private:
3399 LRandom* instr_; 3399 LRandom* instr_;
3400 }; 3400 };
3401 3401
3402 DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr); 3402 DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr);
3403 // Having marked this instruction as a call we can use any 3403 // Having marked this instruction as a call we can use any
3404 // registers. 3404 // registers.
3405 ASSERT(ToDoubleRegister(instr->result()).is(f0)); 3405 ASSERT(ToDoubleRegister(instr->result()).is(f0));
3406 ASSERT(ToRegister(instr->InputAt(0)).is(a0)); 3406 ASSERT(ToRegister(instr->global_object()).is(a0));
3407 3407
3408 static const int kSeedSize = sizeof(uint32_t); 3408 static const int kSeedSize = sizeof(uint32_t);
3409 STATIC_ASSERT(kPointerSize == kSeedSize); 3409 STATIC_ASSERT(kPointerSize == kSeedSize);
3410 3410
3411 __ lw(a0, FieldMemOperand(a0, GlobalObject::kNativeContextOffset)); 3411 __ lw(a0, FieldMemOperand(a0, GlobalObject::kNativeContextOffset));
3412 static const int kRandomSeedOffset = 3412 static const int kRandomSeedOffset =
3413 FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize; 3413 FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize;
3414 __ lw(a2, FieldMemOperand(a0, kRandomSeedOffset)); 3414 __ lw(a2, FieldMemOperand(a0, kRandomSeedOffset));
3415 // a2: FixedArray of the native context's random seeds 3415 // a2: FixedArray of the native context's random seeds
3416 3416
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
3606 ASSERT(ToRegister(instr->result()).is(v0)); 3606 ASSERT(ToRegister(instr->result()).is(v0));
3607 CallKnownFunction(instr->target(), 3607 CallKnownFunction(instr->target(),
3608 instr->arity(), 3608 instr->arity(),
3609 instr, 3609 instr,
3610 CALL_AS_FUNCTION, 3610 CALL_AS_FUNCTION,
3611 A1_UNINITIALIZED); 3611 A1_UNINITIALIZED);
3612 } 3612 }
3613 3613
3614 3614
3615 void LCodeGen::DoCallNew(LCallNew* instr) { 3615 void LCodeGen::DoCallNew(LCallNew* instr) {
3616 ASSERT(ToRegister(instr->InputAt(0)).is(a1)); 3616 ASSERT(ToRegister(instr->constructor()).is(a1));
3617 ASSERT(ToRegister(instr->result()).is(v0)); 3617 ASSERT(ToRegister(instr->result()).is(v0));
3618 3618
3619 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); 3619 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
3620 __ li(a0, Operand(instr->arity())); 3620 __ li(a0, Operand(instr->arity()));
3621 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 3621 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
3622 } 3622 }
3623 3623
3624 3624
3625 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { 3625 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
3626 CallRuntime(instr->function(), instr->arity(), instr); 3626 CallRuntime(instr->function(), instr->arity(), instr);
3627 } 3627 }
3628 3628
3629 3629
3630 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { 3630 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
3631 Register object = ToRegister(instr->object()); 3631 Register object = ToRegister(instr->object());
3632 Register value = ToRegister(instr->value()); 3632 Register value = ToRegister(instr->value());
3633 Register scratch = scratch0(); 3633 Register scratch = scratch0();
3634 int offset = instr->offset(); 3634 int offset = instr->offset();
3635 3635
3636 ASSERT(!object.is(value)); 3636 ASSERT(!object.is(value));
3637 3637
3638 if (!instr->transition().is_null()) { 3638 if (!instr->transition().is_null()) {
3639 __ li(scratch, Operand(instr->transition())); 3639 __ li(scratch, Operand(instr->transition()));
3640 __ sw(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); 3640 __ sw(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
3641 if (instr->hydrogen()->NeedsWriteBarrierForMap()) { 3641 if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
3642 Register temp = ToRegister(instr->TempAt(0)); 3642 Register temp = ToRegister(instr->temp());
3643 // Update the write barrier for the map field. 3643 // Update the write barrier for the map field.
3644 __ RecordWriteField(object, 3644 __ RecordWriteField(object,
3645 HeapObject::kMapOffset, 3645 HeapObject::kMapOffset,
3646 scratch, 3646 scratch,
3647 temp, 3647 temp,
3648 kRAHasBeenSaved, 3648 kRAHasBeenSaved,
3649 kSaveFPRegs, 3649 kSaveFPRegs,
3650 OMIT_REMEMBERED_SET, 3650 OMIT_REMEMBERED_SET,
3651 OMIT_SMI_CHECK); 3651 OMIT_SMI_CHECK);
3652 } 3652 }
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
3924 3924
3925 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 3925 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
3926 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3926 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
3927 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3927 : isolate()->builtins()->KeyedStoreIC_Initialize();
3928 CallCode(ic, RelocInfo::CODE_TARGET, instr); 3928 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3929 } 3929 }
3930 3930
3931 3931
3932 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { 3932 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
3933 Register object_reg = ToRegister(instr->object()); 3933 Register object_reg = ToRegister(instr->object());
3934 Register new_map_reg = ToRegister(instr->new_map_reg()); 3934 Register new_map_reg = ToRegister(instr->new_map_temp());
3935 Register scratch = scratch0(); 3935 Register scratch = scratch0();
3936 3936
3937 Handle<Map> from_map = instr->original_map(); 3937 Handle<Map> from_map = instr->original_map();
3938 Handle<Map> to_map = instr->transitioned_map(); 3938 Handle<Map> to_map = instr->transitioned_map();
3939 ElementsKind from_kind = from_map->elements_kind(); 3939 ElementsKind from_kind = from_map->elements_kind();
3940 ElementsKind to_kind = to_map->elements_kind(); 3940 ElementsKind to_kind = to_map->elements_kind();
3941 3941
3942 __ mov(ToRegister(instr->result()), object_reg); 3942 __ mov(ToRegister(instr->result()), object_reg);
3943 3943
3944 Label not_applicable; 3944 Label not_applicable;
3945 __ lw(scratch, FieldMemOperand(object_reg, HeapObject::kMapOffset)); 3945 __ lw(scratch, FieldMemOperand(object_reg, HeapObject::kMapOffset));
3946 __ Branch(&not_applicable, ne, scratch, Operand(from_map)); 3946 __ Branch(&not_applicable, ne, scratch, Operand(from_map));
3947 3947
3948 __ li(new_map_reg, Operand(to_map)); 3948 __ li(new_map_reg, Operand(to_map));
3949 if (IsFastSmiElementsKind(from_kind) && IsFastObjectElementsKind(to_kind)) { 3949 if (IsFastSmiElementsKind(from_kind) && IsFastObjectElementsKind(to_kind)) {
3950 __ sw(new_map_reg, FieldMemOperand(object_reg, HeapObject::kMapOffset)); 3950 __ sw(new_map_reg, FieldMemOperand(object_reg, HeapObject::kMapOffset));
3951 // Write barrier. 3951 // Write barrier.
3952 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg, 3952 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg,
3953 scratch, kRAHasBeenSaved, kDontSaveFPRegs); 3953 scratch, kRAHasBeenSaved, kDontSaveFPRegs);
3954 } else if (IsFastSmiElementsKind(from_kind) && 3954 } else if (IsFastSmiElementsKind(from_kind) &&
3955 IsFastDoubleElementsKind(to_kind)) { 3955 IsFastDoubleElementsKind(to_kind)) {
3956 Register fixed_object_reg = ToRegister(instr->temp_reg()); 3956 Register fixed_object_reg = ToRegister(instr->temp());
3957 ASSERT(fixed_object_reg.is(a2)); 3957 ASSERT(fixed_object_reg.is(a2));
3958 ASSERT(new_map_reg.is(a3)); 3958 ASSERT(new_map_reg.is(a3));
3959 __ mov(fixed_object_reg, object_reg); 3959 __ mov(fixed_object_reg, object_reg);
3960 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(), 3960 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(),
3961 RelocInfo::CODE_TARGET, instr); 3961 RelocInfo::CODE_TARGET, instr);
3962 } else if (IsFastDoubleElementsKind(from_kind) && 3962 } else if (IsFastDoubleElementsKind(from_kind) &&
3963 IsFastObjectElementsKind(to_kind)) { 3963 IsFastObjectElementsKind(to_kind)) {
3964 Register fixed_object_reg = ToRegister(instr->temp_reg()); 3964 Register fixed_object_reg = ToRegister(instr->temp());
3965 ASSERT(fixed_object_reg.is(a2)); 3965 ASSERT(fixed_object_reg.is(a2));
3966 ASSERT(new_map_reg.is(a3)); 3966 ASSERT(new_map_reg.is(a3));
3967 __ mov(fixed_object_reg, object_reg); 3967 __ mov(fixed_object_reg, object_reg);
3968 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(), 3968 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(),
3969 RelocInfo::CODE_TARGET, instr); 3969 RelocInfo::CODE_TARGET, instr);
3970 } else { 3970 } else {
3971 UNREACHABLE(); 3971 UNREACHABLE();
3972 } 3972 }
3973 __ bind(&not_applicable); 3973 __ bind(&not_applicable);
3974 } 3974 }
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
4079 4079
4080 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 4080 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
4081 __ SmiTag(char_code); 4081 __ SmiTag(char_code);
4082 __ push(char_code); 4082 __ push(char_code);
4083 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr); 4083 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr);
4084 __ StoreToSafepointRegisterSlot(v0, result); 4084 __ StoreToSafepointRegisterSlot(v0, result);
4085 } 4085 }
4086 4086
4087 4087
4088 void LCodeGen::DoStringLength(LStringLength* instr) { 4088 void LCodeGen::DoStringLength(LStringLength* instr) {
4089 Register string = ToRegister(instr->InputAt(0)); 4089 Register string = ToRegister(instr->string());
4090 Register result = ToRegister(instr->result()); 4090 Register result = ToRegister(instr->result());
4091 __ lw(result, FieldMemOperand(string, String::kLengthOffset)); 4091 __ lw(result, FieldMemOperand(string, String::kLengthOffset));
4092 } 4092 }
4093 4093
4094 4094
4095 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 4095 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4096 LOperand* input = instr->InputAt(0); 4096 LOperand* input = instr->value();
4097 ASSERT(input->IsRegister() || input->IsStackSlot()); 4097 ASSERT(input->IsRegister() || input->IsStackSlot());
4098 LOperand* output = instr->result(); 4098 LOperand* output = instr->result();
4099 ASSERT(output->IsDoubleRegister()); 4099 ASSERT(output->IsDoubleRegister());
4100 FPURegister single_scratch = double_scratch0().low(); 4100 FPURegister single_scratch = double_scratch0().low();
4101 if (input->IsStackSlot()) { 4101 if (input->IsStackSlot()) {
4102 Register scratch = scratch0(); 4102 Register scratch = scratch0();
4103 __ lw(scratch, ToMemOperand(input)); 4103 __ lw(scratch, ToMemOperand(input));
4104 __ mtc1(scratch, single_scratch); 4104 __ mtc1(scratch, single_scratch);
4105 } else { 4105 } else {
4106 __ mtc1(ToRegister(input), single_scratch); 4106 __ mtc1(ToRegister(input), single_scratch);
4107 } 4107 }
4108 __ cvt_d_w(ToDoubleRegister(output), single_scratch); 4108 __ cvt_d_w(ToDoubleRegister(output), single_scratch);
4109 } 4109 }
4110 4110
4111 4111
4112 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { 4112 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4113 LOperand* input = instr->InputAt(0); 4113 LOperand* input = instr->value();
4114 LOperand* output = instr->result(); 4114 LOperand* output = instr->result();
4115 4115
4116 FPURegister dbl_scratch = double_scratch0(); 4116 FPURegister dbl_scratch = double_scratch0();
4117 __ mtc1(ToRegister(input), dbl_scratch); 4117 __ mtc1(ToRegister(input), dbl_scratch);
4118 __ Cvt_d_uw(ToDoubleRegister(output), dbl_scratch, f22); 4118 __ Cvt_d_uw(ToDoubleRegister(output), dbl_scratch, f22);
4119 } 4119 }
4120 4120
4121 4121
4122 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 4122 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
4123 class DeferredNumberTagI: public LDeferredCode { 4123 class DeferredNumberTagI: public LDeferredCode {
4124 public: 4124 public:
4125 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) 4125 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
4126 : LDeferredCode(codegen), instr_(instr) { } 4126 : LDeferredCode(codegen), instr_(instr) { }
4127 virtual void Generate() { 4127 virtual void Generate() {
4128 codegen()->DoDeferredNumberTagI(instr_, 4128 codegen()->DoDeferredNumberTagI(instr_,
4129 instr_->InputAt(0), 4129 instr_->value(),
4130 SIGNED_INT32); 4130 SIGNED_INT32);
4131 } 4131 }
4132 virtual LInstruction* instr() { return instr_; } 4132 virtual LInstruction* instr() { return instr_; }
4133 private: 4133 private:
4134 LNumberTagI* instr_; 4134 LNumberTagI* instr_;
4135 }; 4135 };
4136 4136
4137 Register src = ToRegister(instr->InputAt(0)); 4137 Register src = ToRegister(instr->value());
4138 Register dst = ToRegister(instr->result()); 4138 Register dst = ToRegister(instr->result());
4139 Register overflow = scratch0(); 4139 Register overflow = scratch0();
4140 4140
4141 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr); 4141 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr);
4142 __ SmiTagCheckOverflow(dst, src, overflow); 4142 __ SmiTagCheckOverflow(dst, src, overflow);
4143 __ BranchOnOverflow(deferred->entry(), overflow); 4143 __ BranchOnOverflow(deferred->entry(), overflow);
4144 __ bind(deferred->exit()); 4144 __ bind(deferred->exit());
4145 } 4145 }
4146 4146
4147 4147
4148 void LCodeGen::DoNumberTagU(LNumberTagU* instr) { 4148 void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
4149 class DeferredNumberTagU: public LDeferredCode { 4149 class DeferredNumberTagU: public LDeferredCode {
4150 public: 4150 public:
4151 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) 4151 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
4152 : LDeferredCode(codegen), instr_(instr) { } 4152 : LDeferredCode(codegen), instr_(instr) { }
4153 virtual void Generate() { 4153 virtual void Generate() {
4154 codegen()->DoDeferredNumberTagI(instr_, 4154 codegen()->DoDeferredNumberTagI(instr_,
4155 instr_->InputAt(0), 4155 instr_->value(),
4156 UNSIGNED_INT32); 4156 UNSIGNED_INT32);
4157 } 4157 }
4158 virtual LInstruction* instr() { return instr_; } 4158 virtual LInstruction* instr() { return instr_; }
4159 private: 4159 private:
4160 LNumberTagU* instr_; 4160 LNumberTagU* instr_;
4161 }; 4161 };
4162 4162
4163 LOperand* input = instr->InputAt(0); 4163 LOperand* input = instr->value();
4164 ASSERT(input->IsRegister() && input->Equals(instr->result())); 4164 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4165 Register reg = ToRegister(input); 4165 Register reg = ToRegister(input);
4166 4166
4167 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); 4167 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
4168 __ Branch(deferred->entry(), hi, reg, Operand(Smi::kMaxValue)); 4168 __ Branch(deferred->entry(), hi, reg, Operand(Smi::kMaxValue));
4169 __ SmiTag(reg, reg); 4169 __ SmiTag(reg, reg);
4170 __ bind(deferred->exit()); 4170 __ bind(deferred->exit());
4171 } 4171 }
4172 4172
4173 4173
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
4227 class DeferredNumberTagD: public LDeferredCode { 4227 class DeferredNumberTagD: public LDeferredCode {
4228 public: 4228 public:
4229 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 4229 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
4230 : LDeferredCode(codegen), instr_(instr) { } 4230 : LDeferredCode(codegen), instr_(instr) { }
4231 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } 4231 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); }
4232 virtual LInstruction* instr() { return instr_; } 4232 virtual LInstruction* instr() { return instr_; }
4233 private: 4233 private:
4234 LNumberTagD* instr_; 4234 LNumberTagD* instr_;
4235 }; 4235 };
4236 4236
4237 DoubleRegister input_reg = ToDoubleRegister(instr->InputAt(0)); 4237 DoubleRegister input_reg = ToDoubleRegister(instr->value());
4238 Register scratch = scratch0(); 4238 Register scratch = scratch0();
4239 Register reg = ToRegister(instr->result()); 4239 Register reg = ToRegister(instr->result());
4240 Register temp1 = ToRegister(instr->TempAt(0)); 4240 Register temp1 = ToRegister(instr->temp());
4241 Register temp2 = ToRegister(instr->TempAt(1)); 4241 Register temp2 = ToRegister(instr->temp2());
4242 4242
4243 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); 4243 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
4244 if (FLAG_inline_new) { 4244 if (FLAG_inline_new) {
4245 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); 4245 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex);
4246 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry()); 4246 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry());
4247 } else { 4247 } else {
4248 __ Branch(deferred->entry()); 4248 __ Branch(deferred->entry());
4249 } 4249 }
4250 __ bind(deferred->exit()); 4250 __ bind(deferred->exit());
4251 __ sdc1(input_reg, FieldMemOperand(reg, HeapNumber::kValueOffset)); 4251 __ sdc1(input_reg, FieldMemOperand(reg, HeapNumber::kValueOffset));
4252 } 4252 }
4253 4253
4254 4254
4255 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 4255 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
4256 // TODO(3095996): Get rid of this. For now, we need to make the 4256 // TODO(3095996): Get rid of this. For now, we need to make the
4257 // result register contain a valid pointer because it is already 4257 // result register contain a valid pointer because it is already
4258 // contained in the register pointer map. 4258 // contained in the register pointer map.
4259 Register reg = ToRegister(instr->result()); 4259 Register reg = ToRegister(instr->result());
4260 __ mov(reg, zero_reg); 4260 __ mov(reg, zero_reg);
4261 4261
4262 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 4262 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
4263 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); 4263 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
4264 __ StoreToSafepointRegisterSlot(v0, reg); 4264 __ StoreToSafepointRegisterSlot(v0, reg);
4265 } 4265 }
4266 4266
4267 4267
4268 void LCodeGen::DoSmiTag(LSmiTag* instr) { 4268 void LCodeGen::DoSmiTag(LSmiTag* instr) {
4269 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)); 4269 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
4270 __ SmiTag(ToRegister(instr->result()), ToRegister(instr->InputAt(0))); 4270 __ SmiTag(ToRegister(instr->result()), ToRegister(instr->value()));
4271 } 4271 }
4272 4272
4273 4273
4274 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { 4274 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
4275 Register scratch = scratch0(); 4275 Register scratch = scratch0();
4276 Register input = ToRegister(instr->InputAt(0)); 4276 Register input = ToRegister(instr->value());
4277 Register result = ToRegister(instr->result()); 4277 Register result = ToRegister(instr->result());
4278 if (instr->needs_check()) { 4278 if (instr->needs_check()) {
4279 STATIC_ASSERT(kHeapObjectTag == 1); 4279 STATIC_ASSERT(kHeapObjectTag == 1);
4280 // If the input is a HeapObject, value of scratch won't be zero. 4280 // If the input is a HeapObject, value of scratch won't be zero.
4281 __ And(scratch, input, Operand(kHeapObjectTag)); 4281 __ And(scratch, input, Operand(kHeapObjectTag));
4282 __ SmiUntag(result, input); 4282 __ SmiUntag(result, input);
4283 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); 4283 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg));
4284 } else { 4284 } else {
4285 __ SmiUntag(result, input); 4285 __ SmiUntag(result, input);
4286 } 4286 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
4331 // Smi to double register conversion 4331 // Smi to double register conversion
4332 __ bind(&load_smi); 4332 __ bind(&load_smi);
4333 // scratch: untagged value of input_reg 4333 // scratch: untagged value of input_reg
4334 __ mtc1(scratch, result_reg); 4334 __ mtc1(scratch, result_reg);
4335 __ cvt_d_w(result_reg, result_reg); 4335 __ cvt_d_w(result_reg, result_reg);
4336 __ bind(&done); 4336 __ bind(&done);
4337 } 4337 }
4338 4338
4339 4339
4340 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { 4340 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
4341 Register input_reg = ToRegister(instr->InputAt(0)); 4341 Register input_reg = ToRegister(instr->value());
4342 Register scratch1 = scratch0(); 4342 Register scratch1 = scratch0();
4343 Register scratch2 = ToRegister(instr->TempAt(0)); 4343 Register scratch2 = ToRegister(instr->temp());
4344 DoubleRegister double_scratch = double_scratch0(); 4344 DoubleRegister double_scratch = double_scratch0();
4345 FPURegister single_scratch = double_scratch.low(); 4345 FPURegister single_scratch = double_scratch.low();
4346 4346
4347 ASSERT(!scratch1.is(input_reg) && !scratch1.is(scratch2)); 4347 ASSERT(!scratch1.is(input_reg) && !scratch1.is(scratch2));
4348 ASSERT(!scratch2.is(input_reg) && !scratch2.is(scratch1)); 4348 ASSERT(!scratch2.is(input_reg) && !scratch2.is(scratch1));
4349 4349
4350 Label done; 4350 Label done;
4351 4351
4352 // The input is a tagged HeapObject. 4352 // The input is a tagged HeapObject.
4353 // Heap number map check. 4353 // Heap number map check.
4354 __ lw(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 4354 __ lw(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset));
4355 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 4355 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
4356 // This 'at' value and scratch1 map value are used for tests in both clauses 4356 // This 'at' value and scratch1 map value are used for tests in both clauses
4357 // of the if. 4357 // of the if.
4358 4358
4359 if (instr->truncating()) { 4359 if (instr->truncating()) {
4360 Register scratch3 = ToRegister(instr->TempAt(1)); 4360 Register scratch3 = ToRegister(instr->temp2());
4361 DoubleRegister double_scratch2 = ToDoubleRegister(instr->TempAt(2)); 4361 DoubleRegister double_scratch2 = ToDoubleRegister(instr->temp3());
4362 ASSERT(!scratch3.is(input_reg) && 4362 ASSERT(!scratch3.is(input_reg) &&
4363 !scratch3.is(scratch1) && 4363 !scratch3.is(scratch1) &&
4364 !scratch3.is(scratch2)); 4364 !scratch3.is(scratch2));
4365 // Performs a truncating conversion of a floating point number as used by 4365 // Performs a truncating conversion of a floating point number as used by
4366 // the JS bitwise operations. 4366 // the JS bitwise operations.
4367 Label heap_number; 4367 Label heap_number;
4368 __ Branch(&heap_number, eq, scratch1, Operand(at)); // HeapNumber map? 4368 __ Branch(&heap_number, eq, scratch1, Operand(at)); // HeapNumber map?
4369 // Check for undefined. Undefined is converted to zero for truncating 4369 // Check for undefined. Undefined is converted to zero for truncating
4370 // conversions. 4370 // conversions.
4371 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 4371 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
4421 class DeferredTaggedToI: public LDeferredCode { 4421 class DeferredTaggedToI: public LDeferredCode {
4422 public: 4422 public:
4423 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) 4423 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
4424 : LDeferredCode(codegen), instr_(instr) { } 4424 : LDeferredCode(codegen), instr_(instr) { }
4425 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } 4425 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); }
4426 virtual LInstruction* instr() { return instr_; } 4426 virtual LInstruction* instr() { return instr_; }
4427 private: 4427 private:
4428 LTaggedToI* instr_; 4428 LTaggedToI* instr_;
4429 }; 4429 };
4430 4430
4431 LOperand* input = instr->InputAt(0); 4431 LOperand* input = instr->value();
4432 ASSERT(input->IsRegister()); 4432 ASSERT(input->IsRegister());
4433 ASSERT(input->Equals(instr->result())); 4433 ASSERT(input->Equals(instr->result()));
4434 4434
4435 Register input_reg = ToRegister(input); 4435 Register input_reg = ToRegister(input);
4436 4436
4437 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr); 4437 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
4438 4438
4439 // Let the deferred code handle the HeapObject case. 4439 // Let the deferred code handle the HeapObject case.
4440 __ JumpIfNotSmi(input_reg, deferred->entry()); 4440 __ JumpIfNotSmi(input_reg, deferred->entry());
4441 4441
4442 // Smi to int32 conversion. 4442 // Smi to int32 conversion.
4443 __ SmiUntag(input_reg); 4443 __ SmiUntag(input_reg);
4444 __ bind(deferred->exit()); 4444 __ bind(deferred->exit());
4445 } 4445 }
4446 4446
4447 4447
4448 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { 4448 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
4449 LOperand* input = instr->InputAt(0); 4449 LOperand* input = instr->value();
4450 ASSERT(input->IsRegister()); 4450 ASSERT(input->IsRegister());
4451 LOperand* result = instr->result(); 4451 LOperand* result = instr->result();
4452 ASSERT(result->IsDoubleRegister()); 4452 ASSERT(result->IsDoubleRegister());
4453 4453
4454 Register input_reg = ToRegister(input); 4454 Register input_reg = ToRegister(input);
4455 DoubleRegister result_reg = ToDoubleRegister(result); 4455 DoubleRegister result_reg = ToDoubleRegister(result);
4456 4456
4457 EmitNumberUntagD(input_reg, result_reg, 4457 EmitNumberUntagD(input_reg, result_reg,
4458 instr->hydrogen()->deoptimize_on_undefined(), 4458 instr->hydrogen()->deoptimize_on_undefined(),
4459 instr->hydrogen()->deoptimize_on_minus_zero(), 4459 instr->hydrogen()->deoptimize_on_minus_zero(),
4460 instr->environment()); 4460 instr->environment());
4461 } 4461 }
4462 4462
4463 4463
4464 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { 4464 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
4465 Register result_reg = ToRegister(instr->result()); 4465 Register result_reg = ToRegister(instr->result());
4466 Register scratch1 = scratch0(); 4466 Register scratch1 = scratch0();
4467 Register scratch2 = ToRegister(instr->TempAt(0)); 4467 Register scratch2 = ToRegister(instr->temp());
4468 DoubleRegister double_input = ToDoubleRegister(instr->InputAt(0)); 4468 DoubleRegister double_input = ToDoubleRegister(instr->value());
4469 FPURegister single_scratch = double_scratch0().low(); 4469 FPURegister single_scratch = double_scratch0().low();
4470 4470
4471 if (instr->truncating()) { 4471 if (instr->truncating()) {
4472 Register scratch3 = ToRegister(instr->TempAt(1)); 4472 Register scratch3 = ToRegister(instr->temp2());
4473 __ EmitECMATruncate(result_reg, 4473 __ EmitECMATruncate(result_reg,
4474 double_input, 4474 double_input,
4475 single_scratch, 4475 single_scratch,
4476 scratch1, 4476 scratch1,
4477 scratch2, 4477 scratch2,
4478 scratch3); 4478 scratch3);
4479 } else { 4479 } else {
4480 Register except_flag = scratch2; 4480 Register except_flag = scratch2;
4481 4481
4482 __ EmitFPUTruncate(kRoundToMinusInf, 4482 __ EmitFPUTruncate(kRoundToMinusInf,
4483 single_scratch, 4483 single_scratch,
4484 double_input, 4484 double_input,
4485 scratch1, 4485 scratch1,
4486 except_flag, 4486 except_flag,
4487 kCheckForInexactConversion); 4487 kCheckForInexactConversion);
4488 4488
4489 // Deopt if the operation did not succeed (except_flag != 0). 4489 // Deopt if the operation did not succeed (except_flag != 0).
4490 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); 4490 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg));
4491 4491
4492 // Load the result. 4492 // Load the result.
4493 __ mfc1(result_reg, single_scratch); 4493 __ mfc1(result_reg, single_scratch);
4494 } 4494 }
4495 } 4495 }
4496 4496
4497 4497
4498 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { 4498 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
4499 LOperand* input = instr->InputAt(0); 4499 LOperand* input = instr->value();
4500 __ And(at, ToRegister(input), Operand(kSmiTagMask)); 4500 __ And(at, ToRegister(input), Operand(kSmiTagMask));
4501 DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg)); 4501 DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg));
4502 } 4502 }
4503 4503
4504 4504
4505 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { 4505 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
4506 LOperand* input = instr->InputAt(0); 4506 LOperand* input = instr->value();
4507 __ And(at, ToRegister(input), Operand(kSmiTagMask)); 4507 __ And(at, ToRegister(input), Operand(kSmiTagMask));
4508 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); 4508 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
4509 } 4509 }
4510 4510
4511 4511
4512 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 4512 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
4513 Register input = ToRegister(instr->InputAt(0)); 4513 Register input = ToRegister(instr->value());
4514 Register scratch = scratch0(); 4514 Register scratch = scratch0();
4515 4515
4516 __ GetObjectType(input, scratch, scratch); 4516 __ GetObjectType(input, scratch, scratch);
4517 4517
4518 if (instr->hydrogen()->is_interval_check()) { 4518 if (instr->hydrogen()->is_interval_check()) {
4519 InstanceType first; 4519 InstanceType first;
4520 InstanceType last; 4520 InstanceType last;
4521 instr->hydrogen()->GetCheckInterval(&first, &last); 4521 instr->hydrogen()->GetCheckInterval(&first, &last);
4522 4522
4523 // If there is only one type in the interval check for equality. 4523 // If there is only one type in the interval check for equality.
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
4573 LEnvironment* env) { 4573 LEnvironment* env) {
4574 Label success; 4574 Label success;
4575 __ CompareMapAndBranch(reg, scratch, map, &success, eq, &success, mode); 4575 __ CompareMapAndBranch(reg, scratch, map, &success, eq, &success, mode);
4576 DeoptimizeIf(al, env); 4576 DeoptimizeIf(al, env);
4577 __ bind(&success); 4577 __ bind(&success);
4578 } 4578 }
4579 4579
4580 4580
4581 void LCodeGen::DoCheckMaps(LCheckMaps* instr) { 4581 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
4582 Register scratch = scratch0(); 4582 Register scratch = scratch0();
4583 LOperand* input = instr->InputAt(0); 4583 LOperand* input = instr->value();
4584 ASSERT(input->IsRegister()); 4584 ASSERT(input->IsRegister());
4585 Register reg = ToRegister(input); 4585 Register reg = ToRegister(input);
4586 Label success; 4586 Label success;
4587 SmallMapList* map_set = instr->hydrogen()->map_set(); 4587 SmallMapList* map_set = instr->hydrogen()->map_set();
4588 for (int i = 0; i < map_set->length() - 1; i++) { 4588 for (int i = 0; i < map_set->length() - 1; i++) {
4589 Handle<Map> map = map_set->at(i); 4589 Handle<Map> map = map_set->at(i);
4590 __ CompareMapAndBranch( 4590 __ CompareMapAndBranch(
4591 reg, scratch, map, &success, eq, &success, REQUIRE_EXACT_MAP); 4591 reg, scratch, map, &success, eq, &success, REQUIRE_EXACT_MAP);
4592 } 4592 }
4593 Handle<Map> map = map_set->last(); 4593 Handle<Map> map = map_set->last();
4594 DoCheckMapCommon(reg, scratch, map, REQUIRE_EXACT_MAP, instr->environment()); 4594 DoCheckMapCommon(reg, scratch, map, REQUIRE_EXACT_MAP, instr->environment());
4595 __ bind(&success); 4595 __ bind(&success);
4596 } 4596 }
4597 4597
4598 4598
4599 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { 4599 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
4600 DoubleRegister value_reg = ToDoubleRegister(instr->unclamped()); 4600 DoubleRegister value_reg = ToDoubleRegister(instr->unclamped());
4601 Register result_reg = ToRegister(instr->result()); 4601 Register result_reg = ToRegister(instr->result());
4602 DoubleRegister temp_reg = ToDoubleRegister(instr->TempAt(0)); 4602 DoubleRegister temp_reg = ToDoubleRegister(instr->temp());
4603 __ ClampDoubleToUint8(result_reg, value_reg, temp_reg); 4603 __ ClampDoubleToUint8(result_reg, value_reg, temp_reg);
4604 } 4604 }
4605 4605
4606 4606
4607 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { 4607 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
4608 Register unclamped_reg = ToRegister(instr->unclamped()); 4608 Register unclamped_reg = ToRegister(instr->unclamped());
4609 Register result_reg = ToRegister(instr->result()); 4609 Register result_reg = ToRegister(instr->result());
4610 __ ClampUint8(result_reg, unclamped_reg); 4610 __ ClampUint8(result_reg, unclamped_reg);
4611 } 4611 }
4612 4612
4613 4613
4614 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { 4614 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
4615 Register scratch = scratch0(); 4615 Register scratch = scratch0();
4616 Register input_reg = ToRegister(instr->unclamped()); 4616 Register input_reg = ToRegister(instr->unclamped());
4617 Register result_reg = ToRegister(instr->result()); 4617 Register result_reg = ToRegister(instr->result());
4618 DoubleRegister temp_reg = ToDoubleRegister(instr->TempAt(0)); 4618 DoubleRegister temp_reg = ToDoubleRegister(instr->temp());
4619 Label is_smi, done, heap_number; 4619 Label is_smi, done, heap_number;
4620 4620
4621 // Both smi and heap number cases are handled. 4621 // Both smi and heap number cases are handled.
4622 __ UntagAndJumpIfSmi(scratch, input_reg, &is_smi); 4622 __ UntagAndJumpIfSmi(scratch, input_reg, &is_smi);
4623 4623
4624 // Check for heap number 4624 // Check for heap number
4625 __ lw(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 4625 __ lw(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
4626 __ Branch(&heap_number, eq, scratch, Operand(factory()->heap_number_map())); 4626 __ Branch(&heap_number, eq, scratch, Operand(factory()->heap_number_map()));
4627 4627
4628 // Check for undefined. Undefined is converted to zero for clamping 4628 // Check for undefined. Undefined is converted to zero for clamping
(...skipping 11 matching lines...) Expand all
4640 __ jmp(&done); 4640 __ jmp(&done);
4641 4641
4642 __ bind(&is_smi); 4642 __ bind(&is_smi);
4643 __ ClampUint8(result_reg, scratch); 4643 __ ClampUint8(result_reg, scratch);
4644 4644
4645 __ bind(&done); 4645 __ bind(&done);
4646 } 4646 }
4647 4647
4648 4648
4649 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { 4649 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
4650 Register temp1 = ToRegister(instr->TempAt(0)); 4650 Register temp1 = ToRegister(instr->temp());
4651 Register temp2 = ToRegister(instr->TempAt(1)); 4651 Register temp2 = ToRegister(instr->temp2());
4652 4652
4653 Handle<JSObject> holder = instr->holder(); 4653 Handle<JSObject> holder = instr->holder();
4654 Handle<JSObject> current_prototype = instr->prototype(); 4654 Handle<JSObject> current_prototype = instr->prototype();
4655 4655
4656 // Load prototype object. 4656 // Load prototype object.
4657 __ LoadHeapObject(temp1, current_prototype); 4657 __ LoadHeapObject(temp1, current_prototype);
4658 4658
4659 // Check prototype maps up to the holder. 4659 // Check prototype maps up to the holder.
4660 while (!current_prototype.is_identical_to(holder)) { 4660 while (!current_prototype.is_identical_to(holder)) {
4661 DoCheckMapCommon(temp1, temp2, 4661 DoCheckMapCommon(temp1, temp2,
(...skipping 20 matching lines...) Expand all
4682 virtual void Generate() { codegen()->DoDeferredAllocateObject(instr_); } 4682 virtual void Generate() { codegen()->DoDeferredAllocateObject(instr_); }
4683 virtual LInstruction* instr() { return instr_; } 4683 virtual LInstruction* instr() { return instr_; }
4684 private: 4684 private:
4685 LAllocateObject* instr_; 4685 LAllocateObject* instr_;
4686 }; 4686 };
4687 4687
4688 DeferredAllocateObject* deferred = 4688 DeferredAllocateObject* deferred =
4689 new(zone()) DeferredAllocateObject(this, instr); 4689 new(zone()) DeferredAllocateObject(this, instr);
4690 4690
4691 Register result = ToRegister(instr->result()); 4691 Register result = ToRegister(instr->result());
4692 Register scratch = ToRegister(instr->TempAt(0)); 4692 Register scratch = ToRegister(instr->temp());
4693 Register scratch2 = ToRegister(instr->TempAt(1)); 4693 Register scratch2 = ToRegister(instr->temp2());
4694 Handle<JSFunction> constructor = instr->hydrogen()->constructor(); 4694 Handle<JSFunction> constructor = instr->hydrogen()->constructor();
4695 Handle<Map> initial_map(constructor->initial_map()); 4695 Handle<Map> initial_map(constructor->initial_map());
4696 int instance_size = initial_map->instance_size(); 4696 int instance_size = initial_map->instance_size();
4697 ASSERT(initial_map->pre_allocated_property_fields() + 4697 ASSERT(initial_map->pre_allocated_property_fields() +
4698 initial_map->unused_property_fields() - 4698 initial_map->unused_property_fields() -
4699 initial_map->inobject_properties() == 0); 4699 initial_map->inobject_properties() == 0);
4700 4700
4701 // Allocate memory for the object. The initial map might change when 4701 // Allocate memory for the object. The initial map might change when
4702 // the constructor's prototype changes, but instance size and property 4702 // the constructor's prototype changes, but instance size and property
4703 // counts remain unchanged (if slack tracking finished). 4703 // counts remain unchanged (if slack tracking finished).
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
4979 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { 4979 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) {
4980 CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr); 4980 CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr);
4981 } else { 4981 } else {
4982 FastCloneShallowObjectStub stub(properties_count); 4982 FastCloneShallowObjectStub stub(properties_count);
4983 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 4983 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
4984 } 4984 }
4985 } 4985 }
4986 4986
4987 4987
4988 void LCodeGen::DoToFastProperties(LToFastProperties* instr) { 4988 void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
4989 ASSERT(ToRegister(instr->InputAt(0)).is(a0)); 4989 ASSERT(ToRegister(instr->value()).is(a0));
4990 ASSERT(ToRegister(instr->result()).is(v0)); 4990 ASSERT(ToRegister(instr->result()).is(v0));
4991 __ push(a0); 4991 __ push(a0);
4992 CallRuntime(Runtime::kToFastProperties, 1, instr); 4992 CallRuntime(Runtime::kToFastProperties, 1, instr);
4993 } 4993 }
4994 4994
4995 4995
4996 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { 4996 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
4997 Label materialized; 4997 Label materialized;
4998 // Registers will be used as follows: 4998 // Registers will be used as follows:
4999 // t3 = literals array. 4999 // t3 = literals array.
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
5061 ? factory()->true_value() 5061 ? factory()->true_value()
5062 : factory()->false_value())); 5062 : factory()->false_value()));
5063 __ Push(cp, a2, a1); 5063 __ Push(cp, a2, a1);
5064 CallRuntime(Runtime::kNewClosure, 3, instr); 5064 CallRuntime(Runtime::kNewClosure, 3, instr);
5065 } 5065 }
5066 } 5066 }
5067 5067
5068 5068
5069 void LCodeGen::DoTypeof(LTypeof* instr) { 5069 void LCodeGen::DoTypeof(LTypeof* instr) {
5070 ASSERT(ToRegister(instr->result()).is(v0)); 5070 ASSERT(ToRegister(instr->result()).is(v0));
5071 Register input = ToRegister(instr->InputAt(0)); 5071 Register input = ToRegister(instr->value());
5072 __ push(input); 5072 __ push(input);
5073 CallRuntime(Runtime::kTypeof, 1, instr); 5073 CallRuntime(Runtime::kTypeof, 1, instr);
5074 } 5074 }
5075 5075
5076 5076
5077 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { 5077 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
5078 Register input = ToRegister(instr->InputAt(0)); 5078 Register input = ToRegister(instr->value());
5079 int true_block = chunk_->LookupDestination(instr->true_block_id()); 5079 int true_block = chunk_->LookupDestination(instr->true_block_id());
5080 int false_block = chunk_->LookupDestination(instr->false_block_id()); 5080 int false_block = chunk_->LookupDestination(instr->false_block_id());
5081 Label* true_label = chunk_->GetAssemblyLabel(true_block); 5081 Label* true_label = chunk_->GetAssemblyLabel(true_block);
5082 Label* false_label = chunk_->GetAssemblyLabel(false_block); 5082 Label* false_label = chunk_->GetAssemblyLabel(false_block);
5083 5083
5084 Register cmp1 = no_reg; 5084 Register cmp1 = no_reg;
5085 Operand cmp2 = Operand(no_reg); 5085 Operand cmp2 = Operand(no_reg);
5086 5086
5087 Condition final_branch_condition = EmitTypeofIs(true_label, 5087 Condition final_branch_condition = EmitTypeofIs(true_label,
5088 false_label, 5088 false_label,
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
5195 cmp1 = at; 5195 cmp1 = at;
5196 cmp2 = Operand(zero_reg); // Set to valid regs, to avoid caller assertion. 5196 cmp2 = Operand(zero_reg); // Set to valid regs, to avoid caller assertion.
5197 __ Branch(false_label); 5197 __ Branch(false_label);
5198 } 5198 }
5199 5199
5200 return final_branch_condition; 5200 return final_branch_condition;
5201 } 5201 }
5202 5202
5203 5203
5204 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { 5204 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
5205 Register temp1 = ToRegister(instr->TempAt(0)); 5205 Register temp1 = ToRegister(instr->temp());
5206 int true_block = chunk_->LookupDestination(instr->true_block_id()); 5206 int true_block = chunk_->LookupDestination(instr->true_block_id());
5207 int false_block = chunk_->LookupDestination(instr->false_block_id()); 5207 int false_block = chunk_->LookupDestination(instr->false_block_id());
5208 5208
5209 EmitIsConstructCall(temp1, scratch0()); 5209 EmitIsConstructCall(temp1, scratch0());
5210 5210
5211 EmitBranch(true_block, false_block, eq, temp1, 5211 EmitBranch(true_block, false_block, eq, temp1,
5212 Operand(Smi::FromInt(StackFrame::CONSTRUCT))); 5212 Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
5213 } 5213 }
5214 5214
5215 5215
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
5450 __ Subu(scratch, result, scratch); 5450 __ Subu(scratch, result, scratch);
5451 __ lw(result, FieldMemOperand(scratch, 5451 __ lw(result, FieldMemOperand(scratch,
5452 FixedArray::kHeaderSize - kPointerSize)); 5452 FixedArray::kHeaderSize - kPointerSize));
5453 __ bind(&done); 5453 __ bind(&done);
5454 } 5454 }
5455 5455
5456 5456
5457 #undef __ 5457 #undef __
5458 5458
5459 } } // namespace v8::internal 5459 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/mips/lithium-mips.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698