OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 return Immediate(0); | 45 return Immediate(0); |
46 } | 46 } |
47 if (constant.rmode() == RelocInfo::WASM_MEMORY_REFERENCE || | 47 if (constant.rmode() == RelocInfo::WASM_MEMORY_REFERENCE || |
48 constant.rmode() == RelocInfo::WASM_MEMORY_SIZE_REFERENCE) { | 48 constant.rmode() == RelocInfo::WASM_MEMORY_SIZE_REFERENCE) { |
49 return Immediate(constant.ToInt32(), constant.rmode()); | 49 return Immediate(constant.ToInt32(), constant.rmode()); |
50 } | 50 } |
51 return Immediate(constant.ToInt32()); | 51 return Immediate(constant.ToInt32()); |
52 } | 52 } |
53 | 53 |
54 Operand ToOperand(InstructionOperand* op, int extra = 0) { | 54 Operand ToOperand(InstructionOperand* op, int extra = 0) { |
55 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); | 55 DCHECK(op->IsStackSlot() || op->IsFPStackSlot()); |
56 return SlotToOperand(AllocatedOperand::cast(op)->index(), extra); | 56 return SlotToOperand(AllocatedOperand::cast(op)->index(), extra); |
57 } | 57 } |
58 | 58 |
59 Operand SlotToOperand(int slot_index, int extra = 0) { | 59 Operand SlotToOperand(int slot_index, int extra = 0) { |
60 FrameOffset offset = frame_access_state()->GetFrameOffset(slot_index); | 60 FrameOffset offset = frame_access_state()->GetFrameOffset(slot_index); |
61 return Operand(offset.from_stack_pointer() ? rsp : rbp, | 61 return Operand(offset.from_stack_pointer() ? rsp : rbp, |
62 offset.offset() + extra); | 62 offset.offset() + extra); |
63 } | 63 } |
64 | 64 |
65 static size_t NextOffset(size_t* offset) { | 65 static size_t NextOffset(size_t* offset) { |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 do { \ | 338 do { \ |
339 if (instr->addressing_mode() != kMode_None) { \ | 339 if (instr->addressing_mode() != kMode_None) { \ |
340 __ asm_instr(i.OutputRegister(), i.MemoryOperand()); \ | 340 __ asm_instr(i.OutputRegister(), i.MemoryOperand()); \ |
341 } else if (instr->InputAt(0)->IsRegister()) { \ | 341 } else if (instr->InputAt(0)->IsRegister()) { \ |
342 __ asm_instr(i.OutputRegister(), i.InputRegister(0)); \ | 342 __ asm_instr(i.OutputRegister(), i.InputRegister(0)); \ |
343 } else { \ | 343 } else { \ |
344 __ asm_instr(i.OutputRegister(), i.InputOperand(0)); \ | 344 __ asm_instr(i.OutputRegister(), i.InputOperand(0)); \ |
345 } \ | 345 } \ |
346 } while (0) | 346 } while (0) |
347 | 347 |
348 | |
349 #define ASSEMBLE_SSE_BINOP(asm_instr) \ | 348 #define ASSEMBLE_SSE_BINOP(asm_instr) \ |
350 do { \ | 349 do { \ |
351 if (instr->InputAt(1)->IsDoubleRegister()) { \ | 350 if (instr->InputAt(1)->IsFPRegister()) { \ |
352 __ asm_instr(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); \ | 351 __ asm_instr(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); \ |
353 } else { \ | 352 } else { \ |
354 __ asm_instr(i.InputDoubleRegister(0), i.InputOperand(1)); \ | 353 __ asm_instr(i.InputDoubleRegister(0), i.InputOperand(1)); \ |
355 } \ | 354 } \ |
356 } while (0) | 355 } while (0) |
357 | 356 |
358 | |
359 #define ASSEMBLE_SSE_UNOP(asm_instr) \ | 357 #define ASSEMBLE_SSE_UNOP(asm_instr) \ |
360 do { \ | 358 do { \ |
361 if (instr->InputAt(0)->IsDoubleRegister()) { \ | 359 if (instr->InputAt(0)->IsFPRegister()) { \ |
362 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ | 360 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ |
363 } else { \ | 361 } else { \ |
364 __ asm_instr(i.OutputDoubleRegister(), i.InputOperand(0)); \ | 362 __ asm_instr(i.OutputDoubleRegister(), i.InputOperand(0)); \ |
365 } \ | 363 } \ |
366 } while (0) | 364 } while (0) |
367 | 365 |
368 | |
369 #define ASSEMBLE_AVX_BINOP(asm_instr) \ | 366 #define ASSEMBLE_AVX_BINOP(asm_instr) \ |
370 do { \ | 367 do { \ |
371 CpuFeatureScope avx_scope(masm(), AVX); \ | 368 CpuFeatureScope avx_scope(masm(), AVX); \ |
372 if (instr->InputAt(1)->IsDoubleRegister()) { \ | 369 if (instr->InputAt(1)->IsFPRegister()) { \ |
373 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \ | 370 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \ |
374 i.InputDoubleRegister(1)); \ | 371 i.InputDoubleRegister(1)); \ |
375 } else { \ | 372 } else { \ |
376 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \ | 373 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \ |
377 i.InputOperand(1)); \ | 374 i.InputOperand(1)); \ |
378 } \ | 375 } \ |
379 } while (0) | 376 } while (0) |
380 | 377 |
381 #define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr) \ | 378 #define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr) \ |
382 do { \ | 379 do { \ |
(...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1052 ASSEMBLE_SSE_UNOP(Cvtss2sd); | 1049 ASSEMBLE_SSE_UNOP(Cvtss2sd); |
1053 break; | 1050 break; |
1054 case kSSEFloat32Round: { | 1051 case kSSEFloat32Round: { |
1055 CpuFeatureScope sse_scope(masm(), SSE4_1); | 1052 CpuFeatureScope sse_scope(masm(), SSE4_1); |
1056 RoundingMode const mode = | 1053 RoundingMode const mode = |
1057 static_cast<RoundingMode>(MiscField::decode(instr->opcode())); | 1054 static_cast<RoundingMode>(MiscField::decode(instr->opcode())); |
1058 __ Roundss(i.OutputDoubleRegister(), i.InputDoubleRegister(0), mode); | 1055 __ Roundss(i.OutputDoubleRegister(), i.InputDoubleRegister(0), mode); |
1059 break; | 1056 break; |
1060 } | 1057 } |
1061 case kSSEFloat32ToInt32: | 1058 case kSSEFloat32ToInt32: |
1062 if (instr->InputAt(0)->IsDoubleRegister()) { | 1059 if (instr->InputAt(0)->IsFPRegister()) { |
1063 __ Cvttss2si(i.OutputRegister(), i.InputDoubleRegister(0)); | 1060 __ Cvttss2si(i.OutputRegister(), i.InputDoubleRegister(0)); |
1064 } else { | 1061 } else { |
1065 __ Cvttss2si(i.OutputRegister(), i.InputOperand(0)); | 1062 __ Cvttss2si(i.OutputRegister(), i.InputOperand(0)); |
1066 } | 1063 } |
1067 break; | 1064 break; |
1068 case kSSEFloat32ToUint32: { | 1065 case kSSEFloat32ToUint32: { |
1069 if (instr->InputAt(0)->IsDoubleRegister()) { | 1066 if (instr->InputAt(0)->IsFPRegister()) { |
1070 __ Cvttss2siq(i.OutputRegister(), i.InputDoubleRegister(0)); | 1067 __ Cvttss2siq(i.OutputRegister(), i.InputDoubleRegister(0)); |
1071 } else { | 1068 } else { |
1072 __ Cvttss2siq(i.OutputRegister(), i.InputOperand(0)); | 1069 __ Cvttss2siq(i.OutputRegister(), i.InputOperand(0)); |
1073 } | 1070 } |
1074 break; | 1071 break; |
1075 } | 1072 } |
1076 case kSSEFloat64Cmp: | 1073 case kSSEFloat64Cmp: |
1077 ASSEMBLE_SSE_BINOP(Ucomisd); | 1074 ASSEMBLE_SSE_BINOP(Ucomisd); |
1078 break; | 1075 break; |
1079 case kSSEFloat64Add: | 1076 case kSSEFloat64Add: |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1150 CpuFeatureScope sse_scope(masm(), SSE4_1); | 1147 CpuFeatureScope sse_scope(masm(), SSE4_1); |
1151 RoundingMode const mode = | 1148 RoundingMode const mode = |
1152 static_cast<RoundingMode>(MiscField::decode(instr->opcode())); | 1149 static_cast<RoundingMode>(MiscField::decode(instr->opcode())); |
1153 __ Roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0), mode); | 1150 __ Roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0), mode); |
1154 break; | 1151 break; |
1155 } | 1152 } |
1156 case kSSEFloat64ToFloat32: | 1153 case kSSEFloat64ToFloat32: |
1157 ASSEMBLE_SSE_UNOP(Cvtsd2ss); | 1154 ASSEMBLE_SSE_UNOP(Cvtsd2ss); |
1158 break; | 1155 break; |
1159 case kSSEFloat64ToInt32: | 1156 case kSSEFloat64ToInt32: |
1160 if (instr->InputAt(0)->IsDoubleRegister()) { | 1157 if (instr->InputAt(0)->IsFPRegister()) { |
1161 __ Cvttsd2si(i.OutputRegister(), i.InputDoubleRegister(0)); | 1158 __ Cvttsd2si(i.OutputRegister(), i.InputDoubleRegister(0)); |
1162 } else { | 1159 } else { |
1163 __ Cvttsd2si(i.OutputRegister(), i.InputOperand(0)); | 1160 __ Cvttsd2si(i.OutputRegister(), i.InputOperand(0)); |
1164 } | 1161 } |
1165 break; | 1162 break; |
1166 case kSSEFloat64ToUint32: { | 1163 case kSSEFloat64ToUint32: { |
1167 if (instr->InputAt(0)->IsDoubleRegister()) { | 1164 if (instr->InputAt(0)->IsFPRegister()) { |
1168 __ Cvttsd2siq(i.OutputRegister(), i.InputDoubleRegister(0)); | 1165 __ Cvttsd2siq(i.OutputRegister(), i.InputDoubleRegister(0)); |
1169 } else { | 1166 } else { |
1170 __ Cvttsd2siq(i.OutputRegister(), i.InputOperand(0)); | 1167 __ Cvttsd2siq(i.OutputRegister(), i.InputOperand(0)); |
1171 } | 1168 } |
1172 if (MiscField::decode(instr->opcode())) { | 1169 if (MiscField::decode(instr->opcode())) { |
1173 __ AssertZeroExtended(i.OutputRegister()); | 1170 __ AssertZeroExtended(i.OutputRegister()); |
1174 } | 1171 } |
1175 break; | 1172 break; |
1176 } | 1173 } |
1177 case kSSEFloat32ToInt64: | 1174 case kSSEFloat32ToInt64: |
1178 if (instr->InputAt(0)->IsDoubleRegister()) { | 1175 if (instr->InputAt(0)->IsFPRegister()) { |
1179 __ Cvttss2siq(i.OutputRegister(), i.InputDoubleRegister(0)); | 1176 __ Cvttss2siq(i.OutputRegister(), i.InputDoubleRegister(0)); |
1180 } else { | 1177 } else { |
1181 __ Cvttss2siq(i.OutputRegister(), i.InputOperand(0)); | 1178 __ Cvttss2siq(i.OutputRegister(), i.InputOperand(0)); |
1182 } | 1179 } |
1183 if (instr->OutputCount() > 1) { | 1180 if (instr->OutputCount() > 1) { |
1184 __ Set(i.OutputRegister(1), 1); | 1181 __ Set(i.OutputRegister(1), 1); |
1185 Label done; | 1182 Label done; |
1186 Label fail; | 1183 Label fail; |
1187 __ Move(kScratchDoubleReg, static_cast<float>(INT64_MIN)); | 1184 __ Move(kScratchDoubleReg, static_cast<float>(INT64_MIN)); |
1188 if (instr->InputAt(0)->IsDoubleRegister()) { | 1185 if (instr->InputAt(0)->IsFPRegister()) { |
1189 __ Ucomiss(kScratchDoubleReg, i.InputDoubleRegister(0)); | 1186 __ Ucomiss(kScratchDoubleReg, i.InputDoubleRegister(0)); |
1190 } else { | 1187 } else { |
1191 __ Ucomiss(kScratchDoubleReg, i.InputOperand(0)); | 1188 __ Ucomiss(kScratchDoubleReg, i.InputOperand(0)); |
1192 } | 1189 } |
1193 // If the input is NaN, then the conversion fails. | 1190 // If the input is NaN, then the conversion fails. |
1194 __ j(parity_even, &fail); | 1191 __ j(parity_even, &fail); |
1195 // If the input is INT64_MIN, then the conversion succeeds. | 1192 // If the input is INT64_MIN, then the conversion succeeds. |
1196 __ j(equal, &done); | 1193 __ j(equal, &done); |
1197 __ cmpq(i.OutputRegister(0), Immediate(1)); | 1194 __ cmpq(i.OutputRegister(0), Immediate(1)); |
1198 // If the conversion results in INT64_MIN, but the input was not | 1195 // If the conversion results in INT64_MIN, but the input was not |
1199 // INT64_MIN, then the conversion fails. | 1196 // INT64_MIN, then the conversion fails. |
1200 __ j(no_overflow, &done); | 1197 __ j(no_overflow, &done); |
1201 __ bind(&fail); | 1198 __ bind(&fail); |
1202 __ Set(i.OutputRegister(1), 0); | 1199 __ Set(i.OutputRegister(1), 0); |
1203 __ bind(&done); | 1200 __ bind(&done); |
1204 } | 1201 } |
1205 break; | 1202 break; |
1206 case kSSEFloat64ToInt64: | 1203 case kSSEFloat64ToInt64: |
1207 if (instr->InputAt(0)->IsDoubleRegister()) { | 1204 if (instr->InputAt(0)->IsFPRegister()) { |
1208 __ Cvttsd2siq(i.OutputRegister(0), i.InputDoubleRegister(0)); | 1205 __ Cvttsd2siq(i.OutputRegister(0), i.InputDoubleRegister(0)); |
1209 } else { | 1206 } else { |
1210 __ Cvttsd2siq(i.OutputRegister(0), i.InputOperand(0)); | 1207 __ Cvttsd2siq(i.OutputRegister(0), i.InputOperand(0)); |
1211 } | 1208 } |
1212 if (instr->OutputCount() > 1) { | 1209 if (instr->OutputCount() > 1) { |
1213 __ Set(i.OutputRegister(1), 1); | 1210 __ Set(i.OutputRegister(1), 1); |
1214 Label done; | 1211 Label done; |
1215 Label fail; | 1212 Label fail; |
1216 __ Move(kScratchDoubleReg, static_cast<double>(INT64_MIN)); | 1213 __ Move(kScratchDoubleReg, static_cast<double>(INT64_MIN)); |
1217 if (instr->InputAt(0)->IsDoubleRegister()) { | 1214 if (instr->InputAt(0)->IsFPRegister()) { |
1218 __ Ucomisd(kScratchDoubleReg, i.InputDoubleRegister(0)); | 1215 __ Ucomisd(kScratchDoubleReg, i.InputDoubleRegister(0)); |
1219 } else { | 1216 } else { |
1220 __ Ucomisd(kScratchDoubleReg, i.InputOperand(0)); | 1217 __ Ucomisd(kScratchDoubleReg, i.InputOperand(0)); |
1221 } | 1218 } |
1222 // If the input is NaN, then the conversion fails. | 1219 // If the input is NaN, then the conversion fails. |
1223 __ j(parity_even, &fail); | 1220 __ j(parity_even, &fail); |
1224 // If the input is INT64_MIN, then the conversion succeeds. | 1221 // If the input is INT64_MIN, then the conversion succeeds. |
1225 __ j(equal, &done); | 1222 __ j(equal, &done); |
1226 __ cmpq(i.OutputRegister(0), Immediate(1)); | 1223 __ cmpq(i.OutputRegister(0), Immediate(1)); |
1227 // If the conversion results in INT64_MIN, but the input was not | 1224 // If the conversion results in INT64_MIN, but the input was not |
1228 // INT64_MIN, then the conversion fails. | 1225 // INT64_MIN, then the conversion fails. |
1229 __ j(no_overflow, &done); | 1226 __ j(no_overflow, &done); |
1230 __ bind(&fail); | 1227 __ bind(&fail); |
1231 __ Set(i.OutputRegister(1), 0); | 1228 __ Set(i.OutputRegister(1), 0); |
1232 __ bind(&done); | 1229 __ bind(&done); |
1233 } | 1230 } |
1234 break; | 1231 break; |
1235 case kSSEFloat32ToUint64: { | 1232 case kSSEFloat32ToUint64: { |
1236 Label done; | 1233 Label done; |
1237 Label success; | 1234 Label success; |
1238 if (instr->OutputCount() > 1) { | 1235 if (instr->OutputCount() > 1) { |
1239 __ Set(i.OutputRegister(1), 0); | 1236 __ Set(i.OutputRegister(1), 0); |
1240 } | 1237 } |
1241 // There does not exist a Float32ToUint64 instruction, so we have to use | 1238 // There does not exist a Float32ToUint64 instruction, so we have to use |
1242 // the Float32ToInt64 instruction. | 1239 // the Float32ToInt64 instruction. |
1243 if (instr->InputAt(0)->IsDoubleRegister()) { | 1240 if (instr->InputAt(0)->IsFPRegister()) { |
1244 __ Cvttss2siq(i.OutputRegister(), i.InputDoubleRegister(0)); | 1241 __ Cvttss2siq(i.OutputRegister(), i.InputDoubleRegister(0)); |
1245 } else { | 1242 } else { |
1246 __ Cvttss2siq(i.OutputRegister(), i.InputOperand(0)); | 1243 __ Cvttss2siq(i.OutputRegister(), i.InputOperand(0)); |
1247 } | 1244 } |
1248 // Check if the result of the Float32ToInt64 conversion is positive, we | 1245 // Check if the result of the Float32ToInt64 conversion is positive, we |
1249 // are already done. | 1246 // are already done. |
1250 __ testq(i.OutputRegister(), i.OutputRegister()); | 1247 __ testq(i.OutputRegister(), i.OutputRegister()); |
1251 __ j(positive, &success); | 1248 __ j(positive, &success); |
1252 // The result of the first conversion was negative, which means that the | 1249 // The result of the first conversion was negative, which means that the |
1253 // input value was not within the positive int64 range. We subtract 2^64 | 1250 // input value was not within the positive int64 range. We subtract 2^64 |
1254 // and convert it again to see if it is within the uint64 range. | 1251 // and convert it again to see if it is within the uint64 range. |
1255 __ Move(kScratchDoubleReg, -9223372036854775808.0f); | 1252 __ Move(kScratchDoubleReg, -9223372036854775808.0f); |
1256 if (instr->InputAt(0)->IsDoubleRegister()) { | 1253 if (instr->InputAt(0)->IsFPRegister()) { |
1257 __ addss(kScratchDoubleReg, i.InputDoubleRegister(0)); | 1254 __ addss(kScratchDoubleReg, i.InputDoubleRegister(0)); |
1258 } else { | 1255 } else { |
1259 __ addss(kScratchDoubleReg, i.InputOperand(0)); | 1256 __ addss(kScratchDoubleReg, i.InputOperand(0)); |
1260 } | 1257 } |
1261 __ Cvttss2siq(i.OutputRegister(), kScratchDoubleReg); | 1258 __ Cvttss2siq(i.OutputRegister(), kScratchDoubleReg); |
1262 __ testq(i.OutputRegister(), i.OutputRegister()); | 1259 __ testq(i.OutputRegister(), i.OutputRegister()); |
1263 // The only possible negative value here is 0x80000000000000000, which is | 1260 // The only possible negative value here is 0x80000000000000000, which is |
1264 // used on x64 to indicate an integer overflow. | 1261 // used on x64 to indicate an integer overflow. |
1265 __ j(negative, &done); | 1262 __ j(negative, &done); |
1266 // The input value is within uint64 range and the second conversion worked | 1263 // The input value is within uint64 range and the second conversion worked |
1267 // successfully, but we still have to undo the subtraction we did | 1264 // successfully, but we still have to undo the subtraction we did |
1268 // earlier. | 1265 // earlier. |
1269 __ Set(kScratchRegister, 0x8000000000000000); | 1266 __ Set(kScratchRegister, 0x8000000000000000); |
1270 __ orq(i.OutputRegister(), kScratchRegister); | 1267 __ orq(i.OutputRegister(), kScratchRegister); |
1271 __ bind(&success); | 1268 __ bind(&success); |
1272 if (instr->OutputCount() > 1) { | 1269 if (instr->OutputCount() > 1) { |
1273 __ Set(i.OutputRegister(1), 1); | 1270 __ Set(i.OutputRegister(1), 1); |
1274 } | 1271 } |
1275 __ bind(&done); | 1272 __ bind(&done); |
1276 break; | 1273 break; |
1277 } | 1274 } |
1278 case kSSEFloat64ToUint64: { | 1275 case kSSEFloat64ToUint64: { |
1279 Label done; | 1276 Label done; |
1280 Label success; | 1277 Label success; |
1281 if (instr->OutputCount() > 1) { | 1278 if (instr->OutputCount() > 1) { |
1282 __ Set(i.OutputRegister(1), 0); | 1279 __ Set(i.OutputRegister(1), 0); |
1283 } | 1280 } |
1284 // There does not exist a Float64ToUint64 instruction, so we have to use | 1281 // There does not exist a Float64ToUint64 instruction, so we have to use |
1285 // the Float64ToInt64 instruction. | 1282 // the Float64ToInt64 instruction. |
1286 if (instr->InputAt(0)->IsDoubleRegister()) { | 1283 if (instr->InputAt(0)->IsFPRegister()) { |
1287 __ Cvttsd2siq(i.OutputRegister(), i.InputDoubleRegister(0)); | 1284 __ Cvttsd2siq(i.OutputRegister(), i.InputDoubleRegister(0)); |
1288 } else { | 1285 } else { |
1289 __ Cvttsd2siq(i.OutputRegister(), i.InputOperand(0)); | 1286 __ Cvttsd2siq(i.OutputRegister(), i.InputOperand(0)); |
1290 } | 1287 } |
1291 // Check if the result of the Float64ToInt64 conversion is positive, we | 1288 // Check if the result of the Float64ToInt64 conversion is positive, we |
1292 // are already done. | 1289 // are already done. |
1293 __ testq(i.OutputRegister(), i.OutputRegister()); | 1290 __ testq(i.OutputRegister(), i.OutputRegister()); |
1294 __ j(positive, &success); | 1291 __ j(positive, &success); |
1295 // The result of the first conversion was negative, which means that the | 1292 // The result of the first conversion was negative, which means that the |
1296 // input value was not within the positive int64 range. We subtract 2^64 | 1293 // input value was not within the positive int64 range. We subtract 2^64 |
1297 // and convert it again to see if it is within the uint64 range. | 1294 // and convert it again to see if it is within the uint64 range. |
1298 __ Move(kScratchDoubleReg, -9223372036854775808.0); | 1295 __ Move(kScratchDoubleReg, -9223372036854775808.0); |
1299 if (instr->InputAt(0)->IsDoubleRegister()) { | 1296 if (instr->InputAt(0)->IsFPRegister()) { |
1300 __ addsd(kScratchDoubleReg, i.InputDoubleRegister(0)); | 1297 __ addsd(kScratchDoubleReg, i.InputDoubleRegister(0)); |
1301 } else { | 1298 } else { |
1302 __ addsd(kScratchDoubleReg, i.InputOperand(0)); | 1299 __ addsd(kScratchDoubleReg, i.InputOperand(0)); |
1303 } | 1300 } |
1304 __ Cvttsd2siq(i.OutputRegister(), kScratchDoubleReg); | 1301 __ Cvttsd2siq(i.OutputRegister(), kScratchDoubleReg); |
1305 __ testq(i.OutputRegister(), i.OutputRegister()); | 1302 __ testq(i.OutputRegister(), i.OutputRegister()); |
1306 // The only possible negative value here is 0x80000000000000000, which is | 1303 // The only possible negative value here is 0x80000000000000000, which is |
1307 // used on x64 to indicate an integer overflow. | 1304 // used on x64 to indicate an integer overflow. |
1308 __ j(negative, &done); | 1305 __ j(negative, &done); |
1309 // The input value is within uint64 range and the second conversion worked | 1306 // The input value is within uint64 range and the second conversion worked |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1374 break; | 1371 break; |
1375 case kSSEUint32ToFloat32: | 1372 case kSSEUint32ToFloat32: |
1376 if (instr->InputAt(0)->IsRegister()) { | 1373 if (instr->InputAt(0)->IsRegister()) { |
1377 __ movl(kScratchRegister, i.InputRegister(0)); | 1374 __ movl(kScratchRegister, i.InputRegister(0)); |
1378 } else { | 1375 } else { |
1379 __ movl(kScratchRegister, i.InputOperand(0)); | 1376 __ movl(kScratchRegister, i.InputOperand(0)); |
1380 } | 1377 } |
1381 __ Cvtqsi2ss(i.OutputDoubleRegister(), kScratchRegister); | 1378 __ Cvtqsi2ss(i.OutputDoubleRegister(), kScratchRegister); |
1382 break; | 1379 break; |
1383 case kSSEFloat64ExtractLowWord32: | 1380 case kSSEFloat64ExtractLowWord32: |
1384 if (instr->InputAt(0)->IsDoubleStackSlot()) { | 1381 if (instr->InputAt(0)->IsFPStackSlot()) { |
1385 __ movl(i.OutputRegister(), i.InputOperand(0)); | 1382 __ movl(i.OutputRegister(), i.InputOperand(0)); |
1386 } else { | 1383 } else { |
1387 __ Movd(i.OutputRegister(), i.InputDoubleRegister(0)); | 1384 __ Movd(i.OutputRegister(), i.InputDoubleRegister(0)); |
1388 } | 1385 } |
1389 break; | 1386 break; |
1390 case kSSEFloat64ExtractHighWord32: | 1387 case kSSEFloat64ExtractHighWord32: |
1391 if (instr->InputAt(0)->IsDoubleStackSlot()) { | 1388 if (instr->InputAt(0)->IsFPStackSlot()) { |
1392 __ movl(i.OutputRegister(), i.InputOperand(0, kDoubleSize / 2)); | 1389 __ movl(i.OutputRegister(), i.InputOperand(0, kDoubleSize / 2)); |
1393 } else { | 1390 } else { |
1394 __ Pextrd(i.OutputRegister(), i.InputDoubleRegister(0), 1); | 1391 __ Pextrd(i.OutputRegister(), i.InputDoubleRegister(0), 1); |
1395 } | 1392 } |
1396 break; | 1393 break; |
1397 case kSSEFloat64InsertLowWord32: | 1394 case kSSEFloat64InsertLowWord32: |
1398 if (instr->InputAt(1)->IsRegister()) { | 1395 if (instr->InputAt(1)->IsRegister()) { |
1399 __ Pinsrd(i.OutputDoubleRegister(), i.InputRegister(1), 0); | 1396 __ Pinsrd(i.OutputDoubleRegister(), i.InputRegister(1), 0); |
1400 } else { | 1397 } else { |
1401 __ Pinsrd(i.OutputDoubleRegister(), i.InputOperand(1), 0); | 1398 __ Pinsrd(i.OutputDoubleRegister(), i.InputOperand(1), 0); |
1402 } | 1399 } |
1403 break; | 1400 break; |
1404 case kSSEFloat64InsertHighWord32: | 1401 case kSSEFloat64InsertHighWord32: |
1405 if (instr->InputAt(1)->IsRegister()) { | 1402 if (instr->InputAt(1)->IsRegister()) { |
1406 __ Pinsrd(i.OutputDoubleRegister(), i.InputRegister(1), 1); | 1403 __ Pinsrd(i.OutputDoubleRegister(), i.InputRegister(1), 1); |
1407 } else { | 1404 } else { |
1408 __ Pinsrd(i.OutputDoubleRegister(), i.InputOperand(1), 1); | 1405 __ Pinsrd(i.OutputDoubleRegister(), i.InputOperand(1), 1); |
1409 } | 1406 } |
1410 break; | 1407 break; |
1411 case kSSEFloat64LoadLowWord32: | 1408 case kSSEFloat64LoadLowWord32: |
1412 if (instr->InputAt(0)->IsRegister()) { | 1409 if (instr->InputAt(0)->IsRegister()) { |
1413 __ Movd(i.OutputDoubleRegister(), i.InputRegister(0)); | 1410 __ Movd(i.OutputDoubleRegister(), i.InputRegister(0)); |
1414 } else { | 1411 } else { |
1415 __ Movd(i.OutputDoubleRegister(), i.InputOperand(0)); | 1412 __ Movd(i.OutputDoubleRegister(), i.InputOperand(0)); |
1416 } | 1413 } |
1417 break; | 1414 break; |
1418 case kAVXFloat32Cmp: { | 1415 case kAVXFloat32Cmp: { |
1419 CpuFeatureScope avx_scope(masm(), AVX); | 1416 CpuFeatureScope avx_scope(masm(), AVX); |
1420 if (instr->InputAt(1)->IsDoubleRegister()) { | 1417 if (instr->InputAt(1)->IsFPRegister()) { |
1421 __ vucomiss(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); | 1418 __ vucomiss(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); |
1422 } else { | 1419 } else { |
1423 __ vucomiss(i.InputDoubleRegister(0), i.InputOperand(1)); | 1420 __ vucomiss(i.InputDoubleRegister(0), i.InputOperand(1)); |
1424 } | 1421 } |
1425 break; | 1422 break; |
1426 } | 1423 } |
1427 case kAVXFloat32Add: | 1424 case kAVXFloat32Add: |
1428 ASSEMBLE_AVX_BINOP(vaddss); | 1425 ASSEMBLE_AVX_BINOP(vaddss); |
1429 break; | 1426 break; |
1430 case kAVXFloat32Sub: | 1427 case kAVXFloat32Sub: |
1431 ASSEMBLE_AVX_BINOP(vsubss); | 1428 ASSEMBLE_AVX_BINOP(vsubss); |
1432 break; | 1429 break; |
1433 case kAVXFloat32Mul: | 1430 case kAVXFloat32Mul: |
1434 ASSEMBLE_AVX_BINOP(vmulss); | 1431 ASSEMBLE_AVX_BINOP(vmulss); |
1435 break; | 1432 break; |
1436 case kAVXFloat32Div: | 1433 case kAVXFloat32Div: |
1437 ASSEMBLE_AVX_BINOP(vdivss); | 1434 ASSEMBLE_AVX_BINOP(vdivss); |
1438 // Don't delete this mov. It may improve performance on some CPUs, | 1435 // Don't delete this mov. It may improve performance on some CPUs, |
1439 // when there is a (v)mulss depending on the result. | 1436 // when there is a (v)mulss depending on the result. |
1440 __ Movaps(i.OutputDoubleRegister(), i.OutputDoubleRegister()); | 1437 __ Movaps(i.OutputDoubleRegister(), i.OutputDoubleRegister()); |
1441 break; | 1438 break; |
1442 case kAVXFloat32Max: | 1439 case kAVXFloat32Max: |
1443 ASSEMBLE_AVX_BINOP(vmaxss); | 1440 ASSEMBLE_AVX_BINOP(vmaxss); |
1444 break; | 1441 break; |
1445 case kAVXFloat32Min: | 1442 case kAVXFloat32Min: |
1446 ASSEMBLE_AVX_BINOP(vminss); | 1443 ASSEMBLE_AVX_BINOP(vminss); |
1447 break; | 1444 break; |
1448 case kAVXFloat64Cmp: { | 1445 case kAVXFloat64Cmp: { |
1449 CpuFeatureScope avx_scope(masm(), AVX); | 1446 CpuFeatureScope avx_scope(masm(), AVX); |
1450 if (instr->InputAt(1)->IsDoubleRegister()) { | 1447 if (instr->InputAt(1)->IsFPRegister()) { |
1451 __ vucomisd(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); | 1448 __ vucomisd(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); |
1452 } else { | 1449 } else { |
1453 __ vucomisd(i.InputDoubleRegister(0), i.InputOperand(1)); | 1450 __ vucomisd(i.InputDoubleRegister(0), i.InputOperand(1)); |
1454 } | 1451 } |
1455 break; | 1452 break; |
1456 } | 1453 } |
1457 case kAVXFloat64Add: | 1454 case kAVXFloat64Add: |
1458 ASSEMBLE_AVX_BINOP(vaddsd); | 1455 ASSEMBLE_AVX_BINOP(vaddsd); |
1459 break; | 1456 break; |
1460 case kAVXFloat64Sub: | 1457 case kAVXFloat64Sub: |
(...skipping 12 matching lines...) Expand all Loading... |
1473 ASSEMBLE_AVX_BINOP(vmaxsd); | 1470 ASSEMBLE_AVX_BINOP(vmaxsd); |
1474 break; | 1471 break; |
1475 case kAVXFloat64Min: | 1472 case kAVXFloat64Min: |
1476 ASSEMBLE_AVX_BINOP(vminsd); | 1473 ASSEMBLE_AVX_BINOP(vminsd); |
1477 break; | 1474 break; |
1478 case kAVXFloat32Abs: { | 1475 case kAVXFloat32Abs: { |
1479 // TODO(bmeurer): Use RIP relative 128-bit constants. | 1476 // TODO(bmeurer): Use RIP relative 128-bit constants. |
1480 CpuFeatureScope avx_scope(masm(), AVX); | 1477 CpuFeatureScope avx_scope(masm(), AVX); |
1481 __ vpcmpeqd(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg); | 1478 __ vpcmpeqd(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg); |
1482 __ vpsrlq(kScratchDoubleReg, kScratchDoubleReg, 33); | 1479 __ vpsrlq(kScratchDoubleReg, kScratchDoubleReg, 33); |
1483 if (instr->InputAt(0)->IsDoubleRegister()) { | 1480 if (instr->InputAt(0)->IsFPRegister()) { |
1484 __ vandps(i.OutputDoubleRegister(), kScratchDoubleReg, | 1481 __ vandps(i.OutputDoubleRegister(), kScratchDoubleReg, |
1485 i.InputDoubleRegister(0)); | 1482 i.InputDoubleRegister(0)); |
1486 } else { | 1483 } else { |
1487 __ vandps(i.OutputDoubleRegister(), kScratchDoubleReg, | 1484 __ vandps(i.OutputDoubleRegister(), kScratchDoubleReg, |
1488 i.InputOperand(0)); | 1485 i.InputOperand(0)); |
1489 } | 1486 } |
1490 break; | 1487 break; |
1491 } | 1488 } |
1492 case kAVXFloat32Neg: { | 1489 case kAVXFloat32Neg: { |
1493 // TODO(bmeurer): Use RIP relative 128-bit constants. | 1490 // TODO(bmeurer): Use RIP relative 128-bit constants. |
1494 CpuFeatureScope avx_scope(masm(), AVX); | 1491 CpuFeatureScope avx_scope(masm(), AVX); |
1495 __ vpcmpeqd(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg); | 1492 __ vpcmpeqd(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg); |
1496 __ vpsllq(kScratchDoubleReg, kScratchDoubleReg, 31); | 1493 __ vpsllq(kScratchDoubleReg, kScratchDoubleReg, 31); |
1497 if (instr->InputAt(0)->IsDoubleRegister()) { | 1494 if (instr->InputAt(0)->IsFPRegister()) { |
1498 __ vxorps(i.OutputDoubleRegister(), kScratchDoubleReg, | 1495 __ vxorps(i.OutputDoubleRegister(), kScratchDoubleReg, |
1499 i.InputDoubleRegister(0)); | 1496 i.InputDoubleRegister(0)); |
1500 } else { | 1497 } else { |
1501 __ vxorps(i.OutputDoubleRegister(), kScratchDoubleReg, | 1498 __ vxorps(i.OutputDoubleRegister(), kScratchDoubleReg, |
1502 i.InputOperand(0)); | 1499 i.InputOperand(0)); |
1503 } | 1500 } |
1504 break; | 1501 break; |
1505 } | 1502 } |
1506 case kAVXFloat64Abs: { | 1503 case kAVXFloat64Abs: { |
1507 // TODO(bmeurer): Use RIP relative 128-bit constants. | 1504 // TODO(bmeurer): Use RIP relative 128-bit constants. |
1508 CpuFeatureScope avx_scope(masm(), AVX); | 1505 CpuFeatureScope avx_scope(masm(), AVX); |
1509 __ vpcmpeqd(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg); | 1506 __ vpcmpeqd(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg); |
1510 __ vpsrlq(kScratchDoubleReg, kScratchDoubleReg, 1); | 1507 __ vpsrlq(kScratchDoubleReg, kScratchDoubleReg, 1); |
1511 if (instr->InputAt(0)->IsDoubleRegister()) { | 1508 if (instr->InputAt(0)->IsFPRegister()) { |
1512 __ vandpd(i.OutputDoubleRegister(), kScratchDoubleReg, | 1509 __ vandpd(i.OutputDoubleRegister(), kScratchDoubleReg, |
1513 i.InputDoubleRegister(0)); | 1510 i.InputDoubleRegister(0)); |
1514 } else { | 1511 } else { |
1515 __ vandpd(i.OutputDoubleRegister(), kScratchDoubleReg, | 1512 __ vandpd(i.OutputDoubleRegister(), kScratchDoubleReg, |
1516 i.InputOperand(0)); | 1513 i.InputOperand(0)); |
1517 } | 1514 } |
1518 break; | 1515 break; |
1519 } | 1516 } |
1520 case kAVXFloat64Neg: { | 1517 case kAVXFloat64Neg: { |
1521 // TODO(bmeurer): Use RIP relative 128-bit constants. | 1518 // TODO(bmeurer): Use RIP relative 128-bit constants. |
1522 CpuFeatureScope avx_scope(masm(), AVX); | 1519 CpuFeatureScope avx_scope(masm(), AVX); |
1523 __ vpcmpeqd(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg); | 1520 __ vpcmpeqd(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg); |
1524 __ vpsllq(kScratchDoubleReg, kScratchDoubleReg, 63); | 1521 __ vpsllq(kScratchDoubleReg, kScratchDoubleReg, 63); |
1525 if (instr->InputAt(0)->IsDoubleRegister()) { | 1522 if (instr->InputAt(0)->IsFPRegister()) { |
1526 __ vxorpd(i.OutputDoubleRegister(), kScratchDoubleReg, | 1523 __ vxorpd(i.OutputDoubleRegister(), kScratchDoubleReg, |
1527 i.InputDoubleRegister(0)); | 1524 i.InputDoubleRegister(0)); |
1528 } else { | 1525 } else { |
1529 __ vxorpd(i.OutputDoubleRegister(), kScratchDoubleReg, | 1526 __ vxorpd(i.OutputDoubleRegister(), kScratchDoubleReg, |
1530 i.InputOperand(0)); | 1527 i.InputOperand(0)); |
1531 } | 1528 } |
1532 break; | 1529 break; |
1533 } | 1530 } |
1534 case kX64Movsxbl: | 1531 case kX64Movsxbl: |
1535 ASSEMBLE_MOVX(movsxbl); | 1532 ASSEMBLE_MOVX(movsxbl); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1617 case kX64Movsd: | 1614 case kX64Movsd: |
1618 if (instr->HasOutput()) { | 1615 if (instr->HasOutput()) { |
1619 __ Movsd(i.OutputDoubleRegister(), i.MemoryOperand()); | 1616 __ Movsd(i.OutputDoubleRegister(), i.MemoryOperand()); |
1620 } else { | 1617 } else { |
1621 size_t index = 0; | 1618 size_t index = 0; |
1622 Operand operand = i.MemoryOperand(&index); | 1619 Operand operand = i.MemoryOperand(&index); |
1623 __ Movsd(operand, i.InputDoubleRegister(index)); | 1620 __ Movsd(operand, i.InputDoubleRegister(index)); |
1624 } | 1621 } |
1625 break; | 1622 break; |
1626 case kX64BitcastFI: | 1623 case kX64BitcastFI: |
1627 if (instr->InputAt(0)->IsDoubleStackSlot()) { | 1624 if (instr->InputAt(0)->IsFPStackSlot()) { |
1628 __ movl(i.OutputRegister(), i.InputOperand(0)); | 1625 __ movl(i.OutputRegister(), i.InputOperand(0)); |
1629 } else { | 1626 } else { |
1630 __ Movd(i.OutputRegister(), i.InputDoubleRegister(0)); | 1627 __ Movd(i.OutputRegister(), i.InputDoubleRegister(0)); |
1631 } | 1628 } |
1632 break; | 1629 break; |
1633 case kX64BitcastDL: | 1630 case kX64BitcastDL: |
1634 if (instr->InputAt(0)->IsDoubleStackSlot()) { | 1631 if (instr->InputAt(0)->IsFPStackSlot()) { |
1635 __ movq(i.OutputRegister(), i.InputOperand(0)); | 1632 __ movq(i.OutputRegister(), i.InputOperand(0)); |
1636 } else { | 1633 } else { |
1637 __ Movq(i.OutputRegister(), i.InputDoubleRegister(0)); | 1634 __ Movq(i.OutputRegister(), i.InputDoubleRegister(0)); |
1638 } | 1635 } |
1639 break; | 1636 break; |
1640 case kX64BitcastIF: | 1637 case kX64BitcastIF: |
1641 if (instr->InputAt(0)->IsRegister()) { | 1638 if (instr->InputAt(0)->IsRegister()) { |
1642 __ Movd(i.OutputDoubleRegister(), i.InputRegister(0)); | 1639 __ Movd(i.OutputDoubleRegister(), i.InputRegister(0)); |
1643 } else { | 1640 } else { |
1644 __ movss(i.OutputDoubleRegister(), i.InputOperand(0)); | 1641 __ movss(i.OutputDoubleRegister(), i.InputOperand(0)); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1695 __ incl(i.OutputRegister()); | 1692 __ incl(i.OutputRegister()); |
1696 break; | 1693 break; |
1697 case kX64Push: | 1694 case kX64Push: |
1698 if (HasImmediateInput(instr, 0)) { | 1695 if (HasImmediateInput(instr, 0)) { |
1699 __ pushq(i.InputImmediate(0)); | 1696 __ pushq(i.InputImmediate(0)); |
1700 frame_access_state()->IncreaseSPDelta(1); | 1697 frame_access_state()->IncreaseSPDelta(1); |
1701 } else { | 1698 } else { |
1702 if (instr->InputAt(0)->IsRegister()) { | 1699 if (instr->InputAt(0)->IsRegister()) { |
1703 __ pushq(i.InputRegister(0)); | 1700 __ pushq(i.InputRegister(0)); |
1704 frame_access_state()->IncreaseSPDelta(1); | 1701 frame_access_state()->IncreaseSPDelta(1); |
1705 } else if (instr->InputAt(0)->IsDoubleRegister()) { | 1702 } else if (instr->InputAt(0)->IsFPRegister()) { |
1706 // TODO(titzer): use another machine instruction? | 1703 // TODO(titzer): use another machine instruction? |
1707 __ subq(rsp, Immediate(kDoubleSize)); | 1704 __ subq(rsp, Immediate(kDoubleSize)); |
1708 frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize); | 1705 frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize); |
1709 __ Movsd(Operand(rsp, 0), i.InputDoubleRegister(0)); | 1706 __ Movsd(Operand(rsp, 0), i.InputDoubleRegister(0)); |
1710 } else { | 1707 } else { |
1711 __ pushq(i.InputOperand(0)); | 1708 __ pushq(i.InputOperand(0)); |
1712 frame_access_state()->IncreaseSPDelta(1); | 1709 frame_access_state()->IncreaseSPDelta(1); |
1713 } | 1710 } |
1714 } | 1711 } |
1715 break; | 1712 break; |
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2185 case Constant::kRpoNumber: | 2182 case Constant::kRpoNumber: |
2186 UNREACHABLE(); // TODO(dcarney): load of labels on x64. | 2183 UNREACHABLE(); // TODO(dcarney): load of labels on x64. |
2187 break; | 2184 break; |
2188 } | 2185 } |
2189 if (destination->IsStackSlot()) { | 2186 if (destination->IsStackSlot()) { |
2190 __ movq(g.ToOperand(destination), kScratchRegister); | 2187 __ movq(g.ToOperand(destination), kScratchRegister); |
2191 } | 2188 } |
2192 } else if (src.type() == Constant::kFloat32) { | 2189 } else if (src.type() == Constant::kFloat32) { |
2193 // TODO(turbofan): Can we do better here? | 2190 // TODO(turbofan): Can we do better here? |
2194 uint32_t src_const = bit_cast<uint32_t>(src.ToFloat32()); | 2191 uint32_t src_const = bit_cast<uint32_t>(src.ToFloat32()); |
2195 if (destination->IsDoubleRegister()) { | 2192 if (destination->IsFPRegister()) { |
2196 __ Move(g.ToDoubleRegister(destination), src_const); | 2193 __ Move(g.ToDoubleRegister(destination), src_const); |
2197 } else { | 2194 } else { |
2198 DCHECK(destination->IsDoubleStackSlot()); | 2195 DCHECK(destination->IsFPStackSlot()); |
2199 Operand dst = g.ToOperand(destination); | 2196 Operand dst = g.ToOperand(destination); |
2200 __ movl(dst, Immediate(src_const)); | 2197 __ movl(dst, Immediate(src_const)); |
2201 } | 2198 } |
2202 } else { | 2199 } else { |
2203 DCHECK_EQ(Constant::kFloat64, src.type()); | 2200 DCHECK_EQ(Constant::kFloat64, src.type()); |
2204 uint64_t src_const = bit_cast<uint64_t>(src.ToFloat64()); | 2201 uint64_t src_const = bit_cast<uint64_t>(src.ToFloat64()); |
2205 if (destination->IsDoubleRegister()) { | 2202 if (destination->IsFPRegister()) { |
2206 __ Move(g.ToDoubleRegister(destination), src_const); | 2203 __ Move(g.ToDoubleRegister(destination), src_const); |
2207 } else { | 2204 } else { |
2208 DCHECK(destination->IsDoubleStackSlot()); | 2205 DCHECK(destination->IsFPStackSlot()); |
2209 __ movq(kScratchRegister, src_const); | 2206 __ movq(kScratchRegister, src_const); |
2210 __ movq(g.ToOperand(destination), kScratchRegister); | 2207 __ movq(g.ToOperand(destination), kScratchRegister); |
2211 } | 2208 } |
2212 } | 2209 } |
2213 } else if (source->IsDoubleRegister()) { | 2210 } else if (source->IsFPRegister()) { |
2214 XMMRegister src = g.ToDoubleRegister(source); | 2211 XMMRegister src = g.ToDoubleRegister(source); |
2215 if (destination->IsDoubleRegister()) { | 2212 if (destination->IsFPRegister()) { |
2216 XMMRegister dst = g.ToDoubleRegister(destination); | 2213 XMMRegister dst = g.ToDoubleRegister(destination); |
2217 __ Movapd(dst, src); | 2214 __ Movapd(dst, src); |
2218 } else { | 2215 } else { |
2219 DCHECK(destination->IsDoubleStackSlot()); | 2216 DCHECK(destination->IsFPStackSlot()); |
2220 Operand dst = g.ToOperand(destination); | 2217 Operand dst = g.ToOperand(destination); |
2221 __ Movsd(dst, src); | 2218 __ Movsd(dst, src); |
2222 } | 2219 } |
2223 } else if (source->IsDoubleStackSlot()) { | 2220 } else if (source->IsFPStackSlot()) { |
2224 DCHECK(destination->IsDoubleRegister() || destination->IsDoubleStackSlot()); | 2221 DCHECK(destination->IsFPRegister() || destination->IsFPStackSlot()); |
2225 Operand src = g.ToOperand(source); | 2222 Operand src = g.ToOperand(source); |
2226 if (destination->IsDoubleRegister()) { | 2223 if (destination->IsFPRegister()) { |
2227 XMMRegister dst = g.ToDoubleRegister(destination); | 2224 XMMRegister dst = g.ToDoubleRegister(destination); |
2228 __ Movsd(dst, src); | 2225 __ Movsd(dst, src); |
2229 } else { | 2226 } else { |
2230 // We rely on having xmm0 available as a fixed scratch register. | 2227 // We rely on having xmm0 available as a fixed scratch register. |
2231 Operand dst = g.ToOperand(destination); | 2228 Operand dst = g.ToOperand(destination); |
2232 __ Movsd(xmm0, src); | 2229 __ Movsd(xmm0, src); |
2233 __ Movsd(dst, xmm0); | 2230 __ Movsd(dst, xmm0); |
2234 } | 2231 } |
2235 } else { | 2232 } else { |
2236 UNREACHABLE(); | 2233 UNREACHABLE(); |
(...skipping 16 matching lines...) Expand all Loading... |
2253 } else if (source->IsRegister() && destination->IsStackSlot()) { | 2250 } else if (source->IsRegister() && destination->IsStackSlot()) { |
2254 Register src = g.ToRegister(source); | 2251 Register src = g.ToRegister(source); |
2255 __ pushq(src); | 2252 __ pushq(src); |
2256 frame_access_state()->IncreaseSPDelta(1); | 2253 frame_access_state()->IncreaseSPDelta(1); |
2257 Operand dst = g.ToOperand(destination); | 2254 Operand dst = g.ToOperand(destination); |
2258 __ movq(src, dst); | 2255 __ movq(src, dst); |
2259 frame_access_state()->IncreaseSPDelta(-1); | 2256 frame_access_state()->IncreaseSPDelta(-1); |
2260 dst = g.ToOperand(destination); | 2257 dst = g.ToOperand(destination); |
2261 __ popq(dst); | 2258 __ popq(dst); |
2262 } else if ((source->IsStackSlot() && destination->IsStackSlot()) || | 2259 } else if ((source->IsStackSlot() && destination->IsStackSlot()) || |
2263 (source->IsDoubleStackSlot() && | 2260 (source->IsFPStackSlot() && destination->IsFPStackSlot())) { |
2264 destination->IsDoubleStackSlot())) { | |
2265 // Memory-memory. | 2261 // Memory-memory. |
2266 Register tmp = kScratchRegister; | 2262 Register tmp = kScratchRegister; |
2267 Operand src = g.ToOperand(source); | 2263 Operand src = g.ToOperand(source); |
2268 Operand dst = g.ToOperand(destination); | 2264 Operand dst = g.ToOperand(destination); |
2269 __ movq(tmp, dst); | 2265 __ movq(tmp, dst); |
2270 __ pushq(src); | 2266 __ pushq(src); |
2271 frame_access_state()->IncreaseSPDelta(1); | 2267 frame_access_state()->IncreaseSPDelta(1); |
2272 src = g.ToOperand(source); | 2268 src = g.ToOperand(source); |
2273 __ movq(src, tmp); | 2269 __ movq(src, tmp); |
2274 frame_access_state()->IncreaseSPDelta(-1); | 2270 frame_access_state()->IncreaseSPDelta(-1); |
2275 dst = g.ToOperand(destination); | 2271 dst = g.ToOperand(destination); |
2276 __ popq(dst); | 2272 __ popq(dst); |
2277 } else if (source->IsDoubleRegister() && destination->IsDoubleRegister()) { | 2273 } else if (source->IsFPRegister() && destination->IsFPRegister()) { |
2278 // XMM register-register swap. We rely on having xmm0 | 2274 // XMM register-register swap. We rely on having xmm0 |
2279 // available as a fixed scratch register. | 2275 // available as a fixed scratch register. |
2280 XMMRegister src = g.ToDoubleRegister(source); | 2276 XMMRegister src = g.ToDoubleRegister(source); |
2281 XMMRegister dst = g.ToDoubleRegister(destination); | 2277 XMMRegister dst = g.ToDoubleRegister(destination); |
2282 __ Movapd(xmm0, src); | 2278 __ Movapd(xmm0, src); |
2283 __ Movapd(src, dst); | 2279 __ Movapd(src, dst); |
2284 __ Movapd(dst, xmm0); | 2280 __ Movapd(dst, xmm0); |
2285 } else if (source->IsDoubleRegister() && destination->IsDoubleStackSlot()) { | 2281 } else if (source->IsFPRegister() && destination->IsFPStackSlot()) { |
2286 // XMM register-memory swap. We rely on having xmm0 | 2282 // XMM register-memory swap. We rely on having xmm0 |
2287 // available as a fixed scratch register. | 2283 // available as a fixed scratch register. |
2288 XMMRegister src = g.ToDoubleRegister(source); | 2284 XMMRegister src = g.ToDoubleRegister(source); |
2289 Operand dst = g.ToOperand(destination); | 2285 Operand dst = g.ToOperand(destination); |
2290 __ Movsd(xmm0, src); | 2286 __ Movsd(xmm0, src); |
2291 __ Movsd(src, dst); | 2287 __ Movsd(src, dst); |
2292 __ Movsd(dst, xmm0); | 2288 __ Movsd(dst, xmm0); |
2293 } else { | 2289 } else { |
2294 // No other combinations are possible. | 2290 // No other combinations are possible. |
2295 UNREACHABLE(); | 2291 UNREACHABLE(); |
(...skipping 21 matching lines...) Expand all Loading... |
2317 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; | 2313 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; |
2318 __ Nop(padding_size); | 2314 __ Nop(padding_size); |
2319 } | 2315 } |
2320 } | 2316 } |
2321 | 2317 |
2322 #undef __ | 2318 #undef __ |
2323 | 2319 |
2324 } // namespace compiler | 2320 } // namespace compiler |
2325 } // namespace internal | 2321 } // namespace internal |
2326 } // namespace v8 | 2322 } // namespace v8 |
OLD | NEW |