OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/arm/macro-assembler-arm.h" | 7 #include "src/arm/macro-assembler-arm.h" |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/compiler/code-generator-impl.h" | 9 #include "src/compiler/code-generator-impl.h" |
10 #include "src/compiler/gap-resolver.h" | 10 #include "src/compiler/gap-resolver.h" |
11 #include "src/compiler/node-matchers.h" | 11 #include "src/compiler/node-matchers.h" |
12 #include "src/compiler/osr.h" | 12 #include "src/compiler/osr.h" |
13 | 13 |
14 namespace v8 { | 14 namespace v8 { |
15 namespace internal { | 15 namespace internal { |
16 namespace compiler { | 16 namespace compiler { |
17 | 17 |
18 #define __ masm()-> | 18 #define __ masm()-> |
19 | 19 |
20 | 20 |
21 #define kScratchReg r9 | 21 #define kScratchReg r9 |
22 | 22 |
23 | 23 |
24 // Adds Arm-specific methods to convert InstructionOperands. | 24 // Adds Arm-specific methods to convert InstructionOperands. |
25 class ArmOperandConverter final : public InstructionOperandConverter { | 25 class ArmOperandConverter final : public InstructionOperandConverter { |
26 public: | 26 public: |
27 ArmOperandConverter(CodeGenerator* gen, Instruction* instr) | 27 ArmOperandConverter(CodeGenerator* gen, Instruction* instr) |
28 : InstructionOperandConverter(gen, instr) {} | 28 : InstructionOperandConverter(gen, instr) {} |
29 | 29 |
30 SwVfpRegister OutputFloat32Register(size_t index = 0) { | |
31 return ToFloat32Register(instr_->OutputAt(index)); | |
32 } | |
33 | |
34 SwVfpRegister InputFloat32Register(size_t index) { | |
35 return ToFloat32Register(instr_->InputAt(index)); | |
36 } | |
37 | |
38 SwVfpRegister ToFloat32Register(InstructionOperand* op) { | |
39 DCHECK(LocationOperand::cast(op)->representation() == | |
40 MachineRepresentation::kFloat32); | |
41 return LocationOperand::cast(op)->GetFloatRegister(); | |
42 } | |
43 | |
44 LowDwVfpRegister OutputFloat64Register(size_t index = 0) { | |
45 return ToFloat64Register(instr_->OutputAt(index)); | |
46 } | |
47 | |
48 LowDwVfpRegister InputFloat64Register(size_t index) { | |
49 return ToFloat64Register(instr_->InputAt(index)); | |
50 } | |
51 | |
52 LowDwVfpRegister ToFloat64Register(InstructionOperand* op) { | |
53 return LowDwVfpRegister::from_code(ToDoubleRegister(op).code()); | |
54 } | |
55 | |
56 SBit OutputSBit() const { | 30 SBit OutputSBit() const { |
57 switch (instr_->flags_mode()) { | 31 switch (instr_->flags_mode()) { |
58 case kFlags_branch: | 32 case kFlags_branch: |
59 case kFlags_deoptimize: | 33 case kFlags_deoptimize: |
60 case kFlags_set: | 34 case kFlags_set: |
61 return SetCC; | 35 return SetCC; |
62 case kFlags_none: | 36 case kFlags_none: |
63 return LeaveCC; | 37 return LeaveCC; |
64 } | 38 } |
65 UNREACHABLE(); | 39 UNREACHABLE(); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 | 134 |
161 MemOperand SlotToMemOperand(int slot) const { | 135 MemOperand SlotToMemOperand(int slot) const { |
162 FrameOffset offset = frame_access_state()->GetFrameOffset(slot); | 136 FrameOffset offset = frame_access_state()->GetFrameOffset(slot); |
163 return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset()); | 137 return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset()); |
164 } | 138 } |
165 }; | 139 }; |
166 | 140 |
167 | 141 |
168 namespace { | 142 namespace { |
169 | 143 |
170 class OutOfLineLoadFloat32 final : public OutOfLineCode { | 144 class OutOfLineLoadFloat final : public OutOfLineCode { |
171 public: | 145 public: |
172 OutOfLineLoadFloat32(CodeGenerator* gen, SwVfpRegister result) | 146 OutOfLineLoadFloat(CodeGenerator* gen, SwVfpRegister result) |
173 : OutOfLineCode(gen), result_(result) {} | 147 : OutOfLineCode(gen), result_(result) {} |
174 | 148 |
175 void Generate() final { | 149 void Generate() final { |
176 // Compute sqrtf(-1.0f), which results in a quiet single-precision NaN. | 150 // Compute sqrtf(-1.0f), which results in a quiet single-precision NaN. |
177 __ vmov(result_, -1.0f); | 151 __ vmov(result_, -1.0f); |
178 __ vsqrt(result_, result_); | 152 __ vsqrt(result_, result_); |
179 } | 153 } |
180 | 154 |
181 private: | 155 private: |
182 SwVfpRegister const result_; | 156 SwVfpRegister const result_; |
183 }; | 157 }; |
184 | 158 |
185 | 159 class OutOfLineLoadDouble final : public OutOfLineCode { |
186 class OutOfLineLoadFloat64 final : public OutOfLineCode { | |
187 public: | 160 public: |
188 OutOfLineLoadFloat64(CodeGenerator* gen, DwVfpRegister result) | 161 OutOfLineLoadDouble(CodeGenerator* gen, DwVfpRegister result) |
189 : OutOfLineCode(gen), result_(result) {} | 162 : OutOfLineCode(gen), result_(result) {} |
190 | 163 |
191 void Generate() final { | 164 void Generate() final { |
192 // Compute sqrt(-1.0), which results in a quiet double-precision NaN. | 165 // Compute sqrt(-1.0), which results in a quiet double-precision NaN. |
193 __ vmov(result_, -1.0); | 166 __ vmov(result_, -1.0); |
194 __ vsqrt(result_, result_); | 167 __ vsqrt(result_, result_); |
195 } | 168 } |
196 | 169 |
197 private: | 170 private: |
198 DwVfpRegister const result_; | 171 DwVfpRegister const result_; |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 return vc; | 298 return vc; |
326 default: | 299 default: |
327 break; | 300 break; |
328 } | 301 } |
329 UNREACHABLE(); | 302 UNREACHABLE(); |
330 return kNoCondition; | 303 return kNoCondition; |
331 } | 304 } |
332 | 305 |
333 } // namespace | 306 } // namespace |
334 | 307 |
335 | 308 #define ASSEMBLE_CHECKED_LOAD_FP(Type) \ |
336 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width) \ | 309 do { \ |
337 do { \ | 310 auto result = i.Output##Type##Register(); \ |
338 auto result = i.OutputFloat##width##Register(); \ | 311 auto offset = i.InputRegister(0); \ |
339 auto offset = i.InputRegister(0); \ | 312 if (instr->InputAt(1)->IsRegister()) { \ |
340 if (instr->InputAt(1)->IsRegister()) { \ | 313 __ cmp(offset, i.InputRegister(1)); \ |
341 __ cmp(offset, i.InputRegister(1)); \ | 314 } else { \ |
342 } else { \ | 315 __ cmp(offset, i.InputImmediate(1)); \ |
343 __ cmp(offset, i.InputImmediate(1)); \ | 316 } \ |
344 } \ | 317 auto ool = new (zone()) OutOfLineLoad##Type(this, result); \ |
345 auto ool = new (zone()) OutOfLineLoadFloat##width(this, result); \ | 318 __ b(hs, ool->entry()); \ |
346 __ b(hs, ool->entry()); \ | 319 __ vldr(result, i.InputOffset(2)); \ |
347 __ vldr(result, i.InputOffset(2)); \ | 320 __ bind(ool->exit()); \ |
348 __ bind(ool->exit()); \ | 321 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ |
349 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ | |
350 } while (0) | 322 } while (0) |
351 | 323 |
352 | |
353 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ | 324 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ |
354 do { \ | 325 do { \ |
355 auto result = i.OutputRegister(); \ | 326 auto result = i.OutputRegister(); \ |
356 auto offset = i.InputRegister(0); \ | 327 auto offset = i.InputRegister(0); \ |
357 if (instr->InputAt(1)->IsRegister()) { \ | 328 if (instr->InputAt(1)->IsRegister()) { \ |
358 __ cmp(offset, i.InputRegister(1)); \ | 329 __ cmp(offset, i.InputRegister(1)); \ |
359 } else { \ | 330 } else { \ |
360 __ cmp(offset, i.InputImmediate(1)); \ | 331 __ cmp(offset, i.InputImmediate(1)); \ |
361 } \ | 332 } \ |
362 auto ool = new (zone()) OutOfLineLoadInteger(this, result); \ | 333 auto ool = new (zone()) OutOfLineLoadInteger(this, result); \ |
363 __ b(hs, ool->entry()); \ | 334 __ b(hs, ool->entry()); \ |
364 __ asm_instr(result, i.InputOffset(2)); \ | 335 __ asm_instr(result, i.InputOffset(2)); \ |
365 __ bind(ool->exit()); \ | 336 __ bind(ool->exit()); \ |
366 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ | 337 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ |
367 } while (0) | 338 } while (0) |
368 | 339 |
369 | 340 #define ASSEMBLE_CHECKED_STORE_FP(Type) \ |
370 #define ASSEMBLE_CHECKED_STORE_FLOAT(width) \ | 341 do { \ |
371 do { \ | 342 auto offset = i.InputRegister(0); \ |
372 auto offset = i.InputRegister(0); \ | 343 if (instr->InputAt(1)->IsRegister()) { \ |
373 if (instr->InputAt(1)->IsRegister()) { \ | 344 __ cmp(offset, i.InputRegister(1)); \ |
374 __ cmp(offset, i.InputRegister(1)); \ | 345 } else { \ |
375 } else { \ | 346 __ cmp(offset, i.InputImmediate(1)); \ |
376 __ cmp(offset, i.InputImmediate(1)); \ | 347 } \ |
377 } \ | 348 auto value = i.Input##Type##Register(2); \ |
378 auto value = i.InputFloat##width##Register(2); \ | 349 __ vstr(value, i.InputOffset(3), lo); \ |
379 __ vstr(value, i.InputOffset(3), lo); \ | 350 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ |
380 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ | |
381 } while (0) | 351 } while (0) |
382 | 352 |
383 | |
384 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ | 353 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ |
385 do { \ | 354 do { \ |
386 auto offset = i.InputRegister(0); \ | 355 auto offset = i.InputRegister(0); \ |
387 if (instr->InputAt(1)->IsRegister()) { \ | 356 if (instr->InputAt(1)->IsRegister()) { \ |
388 __ cmp(offset, i.InputRegister(1)); \ | 357 __ cmp(offset, i.InputRegister(1)); \ |
389 } else { \ | 358 } else { \ |
390 __ cmp(offset, i.InputImmediate(1)); \ | 359 __ cmp(offset, i.InputImmediate(1)); \ |
391 } \ | 360 } \ |
392 auto value = i.InputRegister(2); \ | 361 auto value = i.InputRegister(2); \ |
393 __ asm_instr(value, i.InputOffset(3), lo); \ | 362 __ asm_instr(value, i.InputOffset(3), lo); \ |
(...skipping 14 matching lines...) Expand all Loading... |
408 MemOperand(i.InputRegister(0), i.InputRegister(1))); \ | 377 MemOperand(i.InputRegister(0), i.InputRegister(1))); \ |
409 __ dmb(ISH); \ | 378 __ dmb(ISH); \ |
410 } while (0) | 379 } while (0) |
411 | 380 |
412 #define ASSEMBLE_IEEE754_BINOP(name) \ | 381 #define ASSEMBLE_IEEE754_BINOP(name) \ |
413 do { \ | 382 do { \ |
414 /* TODO(bmeurer): We should really get rid of this special instruction, */ \ | 383 /* TODO(bmeurer): We should really get rid of this special instruction, */ \ |
415 /* and generate a CallAddress instruction instead. */ \ | 384 /* and generate a CallAddress instruction instead. */ \ |
416 FrameScope scope(masm(), StackFrame::MANUAL); \ | 385 FrameScope scope(masm(), StackFrame::MANUAL); \ |
417 __ PrepareCallCFunction(0, 2, kScratchReg); \ | 386 __ PrepareCallCFunction(0, 2, kScratchReg); \ |
418 __ MovToFloatParameters(i.InputFloat64Register(0), \ | 387 __ MovToFloatParameters(i.InputDoubleRegister(0), \ |
419 i.InputFloat64Register(1)); \ | 388 i.InputDoubleRegister(1)); \ |
420 __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \ | 389 __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \ |
421 0, 2); \ | 390 0, 2); \ |
422 /* Move the result in the double result register. */ \ | 391 /* Move the result in the double result register. */ \ |
423 __ MovFromFloatResult(i.OutputFloat64Register()); \ | 392 __ MovFromFloatResult(i.OutputDoubleRegister()); \ |
424 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ | 393 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ |
425 } while (0) | 394 } while (0) |
426 | 395 |
427 #define ASSEMBLE_IEEE754_UNOP(name) \ | 396 #define ASSEMBLE_IEEE754_UNOP(name) \ |
428 do { \ | 397 do { \ |
429 /* TODO(bmeurer): We should really get rid of this special instruction, */ \ | 398 /* TODO(bmeurer): We should really get rid of this special instruction, */ \ |
430 /* and generate a CallAddress instruction instead. */ \ | 399 /* and generate a CallAddress instruction instead. */ \ |
431 FrameScope scope(masm(), StackFrame::MANUAL); \ | 400 FrameScope scope(masm(), StackFrame::MANUAL); \ |
432 __ PrepareCallCFunction(0, 1, kScratchReg); \ | 401 __ PrepareCallCFunction(0, 1, kScratchReg); \ |
433 __ MovToFloatParameter(i.InputFloat64Register(0)); \ | 402 __ MovToFloatParameter(i.InputDoubleRegister(0)); \ |
434 __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \ | 403 __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \ |
435 0, 1); \ | 404 0, 1); \ |
436 /* Move the result in the double result register. */ \ | 405 /* Move the result in the double result register. */ \ |
437 __ MovFromFloatResult(i.OutputFloat64Register()); \ | 406 __ MovFromFloatResult(i.OutputDoubleRegister()); \ |
438 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ | 407 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ |
439 } while (0) | 408 } while (0) |
440 | 409 |
441 void CodeGenerator::AssembleDeconstructFrame() { | 410 void CodeGenerator::AssembleDeconstructFrame() { |
442 __ LeaveFrame(StackFrame::MANUAL); | 411 __ LeaveFrame(StackFrame::MANUAL); |
443 } | 412 } |
444 | 413 |
445 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { | 414 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { |
446 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); | 415 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); |
447 if (sp_slot_delta > 0) { | 416 if (sp_slot_delta > 0) { |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 623 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
655 break; | 624 break; |
656 case kArchParentFramePointer: | 625 case kArchParentFramePointer: |
657 if (frame_access_state()->has_frame()) { | 626 if (frame_access_state()->has_frame()) { |
658 __ ldr(i.OutputRegister(), MemOperand(fp, 0)); | 627 __ ldr(i.OutputRegister(), MemOperand(fp, 0)); |
659 } else { | 628 } else { |
660 __ mov(i.OutputRegister(), fp); | 629 __ mov(i.OutputRegister(), fp); |
661 } | 630 } |
662 break; | 631 break; |
663 case kArchTruncateDoubleToI: | 632 case kArchTruncateDoubleToI: |
664 __ TruncateDoubleToI(i.OutputRegister(), i.InputFloat64Register(0)); | 633 __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0)); |
665 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 634 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
666 break; | 635 break; |
667 case kArchStoreWithWriteBarrier: { | 636 case kArchStoreWithWriteBarrier: { |
668 RecordWriteMode mode = | 637 RecordWriteMode mode = |
669 static_cast<RecordWriteMode>(MiscField::decode(instr->opcode())); | 638 static_cast<RecordWriteMode>(MiscField::decode(instr->opcode())); |
670 Register object = i.InputRegister(0); | 639 Register object = i.InputRegister(0); |
671 Register value = i.InputRegister(2); | 640 Register value = i.InputRegister(2); |
672 Register scratch0 = i.TempRegister(0); | 641 Register scratch0 = i.TempRegister(0); |
673 Register scratch1 = i.TempRegister(1); | 642 Register scratch1 = i.TempRegister(1); |
674 OutOfLineRecordWrite* ool; | 643 OutOfLineRecordWrite* ool; |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
956 if (instr->InputAt(2)->IsImmediate()) { | 925 if (instr->InputAt(2)->IsImmediate()) { |
957 __ AsrPair(i.OutputRegister(0), i.OutputRegister(1), i.InputRegister(0), | 926 __ AsrPair(i.OutputRegister(0), i.OutputRegister(1), i.InputRegister(0), |
958 i.InputRegister(1), i.InputInt32(2)); | 927 i.InputRegister(1), i.InputInt32(2)); |
959 } else { | 928 } else { |
960 __ AsrPair(i.OutputRegister(0), i.OutputRegister(1), i.InputRegister(0), | 929 __ AsrPair(i.OutputRegister(0), i.OutputRegister(1), i.InputRegister(0), |
961 i.InputRegister(1), kScratchReg, i.InputRegister(2)); | 930 i.InputRegister(1), kScratchReg, i.InputRegister(2)); |
962 } | 931 } |
963 break; | 932 break; |
964 case kArmVcmpF32: | 933 case kArmVcmpF32: |
965 if (instr->InputAt(1)->IsFPRegister()) { | 934 if (instr->InputAt(1)->IsFPRegister()) { |
966 __ VFPCompareAndSetFlags(i.InputFloat32Register(0), | 935 __ VFPCompareAndSetFlags(i.InputFloatRegister(0), |
967 i.InputFloat32Register(1)); | 936 i.InputFloatRegister(1)); |
968 } else { | 937 } else { |
969 DCHECK(instr->InputAt(1)->IsImmediate()); | 938 DCHECK(instr->InputAt(1)->IsImmediate()); |
970 // 0.0 is the only immediate supported by vcmp instructions. | 939 // 0.0 is the only immediate supported by vcmp instructions. |
971 DCHECK(i.InputFloat32(1) == 0.0f); | 940 DCHECK(i.InputFloat32(1) == 0.0f); |
972 __ VFPCompareAndSetFlags(i.InputFloat32Register(0), i.InputFloat32(1)); | 941 __ VFPCompareAndSetFlags(i.InputFloatRegister(0), i.InputFloat32(1)); |
973 } | 942 } |
974 DCHECK_EQ(SetCC, i.OutputSBit()); | 943 DCHECK_EQ(SetCC, i.OutputSBit()); |
975 break; | 944 break; |
976 case kArmVaddF32: | 945 case kArmVaddF32: |
977 __ vadd(i.OutputFloat32Register(), i.InputFloat32Register(0), | 946 __ vadd(i.OutputFloatRegister(), i.InputFloatRegister(0), |
978 i.InputFloat32Register(1)); | 947 i.InputFloatRegister(1)); |
979 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 948 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
980 break; | 949 break; |
981 case kArmVsubF32: | 950 case kArmVsubF32: |
982 __ vsub(i.OutputFloat32Register(), i.InputFloat32Register(0), | 951 __ vsub(i.OutputFloatRegister(), i.InputFloatRegister(0), |
983 i.InputFloat32Register(1)); | 952 i.InputFloatRegister(1)); |
984 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 953 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
985 break; | 954 break; |
986 case kArmVmulF32: | 955 case kArmVmulF32: |
987 __ vmul(i.OutputFloat32Register(), i.InputFloat32Register(0), | 956 __ vmul(i.OutputFloatRegister(), i.InputFloatRegister(0), |
988 i.InputFloat32Register(1)); | 957 i.InputFloatRegister(1)); |
989 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 958 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
990 break; | 959 break; |
991 case kArmVmlaF32: | 960 case kArmVmlaF32: |
992 __ vmla(i.OutputFloat32Register(), i.InputFloat32Register(1), | 961 __ vmla(i.OutputFloatRegister(), i.InputFloatRegister(1), |
993 i.InputFloat32Register(2)); | 962 i.InputFloatRegister(2)); |
994 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 963 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
995 break; | 964 break; |
996 case kArmVmlsF32: | 965 case kArmVmlsF32: |
997 __ vmls(i.OutputFloat32Register(), i.InputFloat32Register(1), | 966 __ vmls(i.OutputFloatRegister(), i.InputFloatRegister(1), |
998 i.InputFloat32Register(2)); | 967 i.InputFloatRegister(2)); |
999 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 968 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1000 break; | 969 break; |
1001 case kArmVdivF32: | 970 case kArmVdivF32: |
1002 __ vdiv(i.OutputFloat32Register(), i.InputFloat32Register(0), | 971 __ vdiv(i.OutputFloatRegister(), i.InputFloatRegister(0), |
1003 i.InputFloat32Register(1)); | 972 i.InputFloatRegister(1)); |
1004 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 973 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1005 break; | 974 break; |
1006 case kArmVsqrtF32: | 975 case kArmVsqrtF32: |
1007 __ vsqrt(i.OutputFloat32Register(), i.InputFloat32Register(0)); | 976 __ vsqrt(i.OutputFloatRegister(), i.InputFloatRegister(0)); |
1008 break; | 977 break; |
1009 case kArmVabsF32: | 978 case kArmVabsF32: |
1010 __ vabs(i.OutputFloat32Register(), i.InputFloat32Register(0)); | 979 __ vabs(i.OutputFloatRegister(), i.InputFloatRegister(0)); |
1011 break; | 980 break; |
1012 case kArmVnegF32: | 981 case kArmVnegF32: |
1013 __ vneg(i.OutputFloat32Register(), i.InputFloat32Register(0)); | 982 __ vneg(i.OutputFloatRegister(), i.InputFloatRegister(0)); |
1014 break; | 983 break; |
1015 case kArmVcmpF64: | 984 case kArmVcmpF64: |
1016 if (instr->InputAt(1)->IsFPRegister()) { | 985 if (instr->InputAt(1)->IsFPRegister()) { |
1017 __ VFPCompareAndSetFlags(i.InputFloat64Register(0), | 986 __ VFPCompareAndSetFlags(i.InputDoubleRegister(0), |
1018 i.InputFloat64Register(1)); | 987 i.InputDoubleRegister(1)); |
1019 } else { | 988 } else { |
1020 DCHECK(instr->InputAt(1)->IsImmediate()); | 989 DCHECK(instr->InputAt(1)->IsImmediate()); |
1021 // 0.0 is the only immediate supported by vcmp instructions. | 990 // 0.0 is the only immediate supported by vcmp instructions. |
1022 DCHECK(i.InputDouble(1) == 0.0); | 991 DCHECK(i.InputDouble(1) == 0.0); |
1023 __ VFPCompareAndSetFlags(i.InputFloat64Register(0), i.InputDouble(1)); | 992 __ VFPCompareAndSetFlags(i.InputDoubleRegister(0), i.InputDouble(1)); |
1024 } | 993 } |
1025 DCHECK_EQ(SetCC, i.OutputSBit()); | 994 DCHECK_EQ(SetCC, i.OutputSBit()); |
1026 break; | 995 break; |
1027 case kArmVaddF64: | 996 case kArmVaddF64: |
1028 __ vadd(i.OutputFloat64Register(), i.InputFloat64Register(0), | 997 __ vadd(i.OutputDoubleRegister(), i.InputDoubleRegister(0), |
1029 i.InputFloat64Register(1)); | 998 i.InputDoubleRegister(1)); |
1030 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 999 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1031 break; | 1000 break; |
1032 case kArmVsubF64: | 1001 case kArmVsubF64: |
1033 __ vsub(i.OutputFloat64Register(), i.InputFloat64Register(0), | 1002 __ vsub(i.OutputDoubleRegister(), i.InputDoubleRegister(0), |
1034 i.InputFloat64Register(1)); | 1003 i.InputDoubleRegister(1)); |
1035 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1004 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1036 break; | 1005 break; |
1037 case kArmVmulF64: | 1006 case kArmVmulF64: |
1038 __ vmul(i.OutputFloat64Register(), i.InputFloat64Register(0), | 1007 __ vmul(i.OutputDoubleRegister(), i.InputDoubleRegister(0), |
1039 i.InputFloat64Register(1)); | 1008 i.InputDoubleRegister(1)); |
1040 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1009 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1041 break; | 1010 break; |
1042 case kArmVmlaF64: | 1011 case kArmVmlaF64: |
1043 __ vmla(i.OutputFloat64Register(), i.InputFloat64Register(1), | 1012 __ vmla(i.OutputDoubleRegister(), i.InputDoubleRegister(1), |
1044 i.InputFloat64Register(2)); | 1013 i.InputDoubleRegister(2)); |
1045 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1014 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1046 break; | 1015 break; |
1047 case kArmVmlsF64: | 1016 case kArmVmlsF64: |
1048 __ vmls(i.OutputFloat64Register(), i.InputFloat64Register(1), | 1017 __ vmls(i.OutputDoubleRegister(), i.InputDoubleRegister(1), |
1049 i.InputFloat64Register(2)); | 1018 i.InputDoubleRegister(2)); |
1050 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1019 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1051 break; | 1020 break; |
1052 case kArmVdivF64: | 1021 case kArmVdivF64: |
1053 __ vdiv(i.OutputFloat64Register(), i.InputFloat64Register(0), | 1022 __ vdiv(i.OutputDoubleRegister(), i.InputDoubleRegister(0), |
1054 i.InputFloat64Register(1)); | 1023 i.InputDoubleRegister(1)); |
1055 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1024 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1056 break; | 1025 break; |
1057 case kArmVmodF64: { | 1026 case kArmVmodF64: { |
1058 // TODO(bmeurer): We should really get rid of this special instruction, | 1027 // TODO(bmeurer): We should really get rid of this special instruction, |
1059 // and generate a CallAddress instruction instead. | 1028 // and generate a CallAddress instruction instead. |
1060 FrameScope scope(masm(), StackFrame::MANUAL); | 1029 FrameScope scope(masm(), StackFrame::MANUAL); |
1061 __ PrepareCallCFunction(0, 2, kScratchReg); | 1030 __ PrepareCallCFunction(0, 2, kScratchReg); |
1062 __ MovToFloatParameters(i.InputFloat64Register(0), | 1031 __ MovToFloatParameters(i.InputDoubleRegister(0), |
1063 i.InputFloat64Register(1)); | 1032 i.InputDoubleRegister(1)); |
1064 __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()), | 1033 __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()), |
1065 0, 2); | 1034 0, 2); |
1066 // Move the result in the double result register. | 1035 // Move the result in the double result register. |
1067 __ MovFromFloatResult(i.OutputFloat64Register()); | 1036 __ MovFromFloatResult(i.OutputDoubleRegister()); |
1068 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1037 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1069 break; | 1038 break; |
1070 } | 1039 } |
1071 case kArmVsqrtF64: | 1040 case kArmVsqrtF64: |
1072 __ vsqrt(i.OutputFloat64Register(), i.InputFloat64Register(0)); | 1041 __ vsqrt(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
1073 break; | 1042 break; |
1074 case kArmVabsF64: | 1043 case kArmVabsF64: |
1075 __ vabs(i.OutputFloat64Register(), i.InputFloat64Register(0)); | 1044 __ vabs(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
1076 break; | 1045 break; |
1077 case kArmVnegF64: | 1046 case kArmVnegF64: |
1078 __ vneg(i.OutputFloat64Register(), i.InputFloat64Register(0)); | 1047 __ vneg(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
1079 break; | 1048 break; |
1080 case kArmVrintmF32: | 1049 case kArmVrintmF32: |
1081 __ vrintm(i.OutputFloat32Register(), i.InputFloat32Register(0)); | 1050 __ vrintm(i.OutputFloatRegister(), i.InputFloatRegister(0)); |
1082 break; | 1051 break; |
1083 case kArmVrintmF64: | 1052 case kArmVrintmF64: |
1084 __ vrintm(i.OutputFloat64Register(), i.InputFloat64Register(0)); | 1053 __ vrintm(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
1085 break; | 1054 break; |
1086 case kArmVrintpF32: | 1055 case kArmVrintpF32: |
1087 __ vrintp(i.OutputFloat32Register(), i.InputFloat32Register(0)); | 1056 __ vrintp(i.OutputFloatRegister(), i.InputFloatRegister(0)); |
1088 break; | 1057 break; |
1089 case kArmVrintpF64: | 1058 case kArmVrintpF64: |
1090 __ vrintp(i.OutputFloat64Register(), i.InputFloat64Register(0)); | 1059 __ vrintp(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
1091 break; | 1060 break; |
1092 case kArmVrintzF32: | 1061 case kArmVrintzF32: |
1093 __ vrintz(i.OutputFloat32Register(), i.InputFloat32Register(0)); | 1062 __ vrintz(i.OutputFloatRegister(), i.InputFloatRegister(0)); |
1094 break; | 1063 break; |
1095 case kArmVrintzF64: | 1064 case kArmVrintzF64: |
1096 __ vrintz(i.OutputFloat64Register(), i.InputFloat64Register(0)); | 1065 __ vrintz(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
1097 break; | 1066 break; |
1098 case kArmVrintaF64: | 1067 case kArmVrintaF64: |
1099 __ vrinta(i.OutputFloat64Register(), i.InputFloat64Register(0)); | 1068 __ vrinta(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
1100 break; | 1069 break; |
1101 case kArmVrintnF32: | 1070 case kArmVrintnF32: |
1102 __ vrintn(i.OutputFloat32Register(), i.InputFloat32Register(0)); | 1071 __ vrintn(i.OutputFloatRegister(), i.InputFloatRegister(0)); |
1103 break; | 1072 break; |
1104 case kArmVrintnF64: | 1073 case kArmVrintnF64: |
1105 __ vrintn(i.OutputFloat64Register(), i.InputFloat64Register(0)); | 1074 __ vrintn(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
1106 break; | 1075 break; |
1107 case kArmVcvtF32F64: { | 1076 case kArmVcvtF32F64: { |
1108 __ vcvt_f32_f64(i.OutputFloat32Register(), i.InputFloat64Register(0)); | 1077 __ vcvt_f32_f64(i.OutputFloatRegister(), i.InputDoubleRegister(0)); |
1109 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1078 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1110 break; | 1079 break; |
1111 } | 1080 } |
1112 case kArmVcvtF64F32: { | 1081 case kArmVcvtF64F32: { |
1113 __ vcvt_f64_f32(i.OutputFloat64Register(), i.InputFloat32Register(0)); | 1082 __ vcvt_f64_f32(i.OutputDoubleRegister(), i.InputFloatRegister(0)); |
1114 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1083 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1115 break; | 1084 break; |
1116 } | 1085 } |
1117 case kArmVcvtF32S32: { | 1086 case kArmVcvtF32S32: { |
1118 SwVfpRegister scratch = kScratchDoubleReg.low(); | 1087 SwVfpRegister scratch = kScratchDoubleReg.low(); |
1119 __ vmov(scratch, i.InputRegister(0)); | 1088 __ vmov(scratch, i.InputRegister(0)); |
1120 __ vcvt_f32_s32(i.OutputFloat32Register(), scratch); | 1089 __ vcvt_f32_s32(i.OutputFloatRegister(), scratch); |
1121 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1090 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1122 break; | 1091 break; |
1123 } | 1092 } |
1124 case kArmVcvtF32U32: { | 1093 case kArmVcvtF32U32: { |
1125 SwVfpRegister scratch = kScratchDoubleReg.low(); | 1094 SwVfpRegister scratch = kScratchDoubleReg.low(); |
1126 __ vmov(scratch, i.InputRegister(0)); | 1095 __ vmov(scratch, i.InputRegister(0)); |
1127 __ vcvt_f32_u32(i.OutputFloat32Register(), scratch); | 1096 __ vcvt_f32_u32(i.OutputFloatRegister(), scratch); |
1128 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1097 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1129 break; | 1098 break; |
1130 } | 1099 } |
1131 case kArmVcvtF64S32: { | 1100 case kArmVcvtF64S32: { |
1132 SwVfpRegister scratch = kScratchDoubleReg.low(); | 1101 SwVfpRegister scratch = kScratchDoubleReg.low(); |
1133 __ vmov(scratch, i.InputRegister(0)); | 1102 __ vmov(scratch, i.InputRegister(0)); |
1134 __ vcvt_f64_s32(i.OutputFloat64Register(), scratch); | 1103 __ vcvt_f64_s32(i.OutputDoubleRegister(), scratch); |
1135 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1104 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1136 break; | 1105 break; |
1137 } | 1106 } |
1138 case kArmVcvtF64U32: { | 1107 case kArmVcvtF64U32: { |
1139 SwVfpRegister scratch = kScratchDoubleReg.low(); | 1108 SwVfpRegister scratch = kScratchDoubleReg.low(); |
1140 __ vmov(scratch, i.InputRegister(0)); | 1109 __ vmov(scratch, i.InputRegister(0)); |
1141 __ vcvt_f64_u32(i.OutputFloat64Register(), scratch); | 1110 __ vcvt_f64_u32(i.OutputDoubleRegister(), scratch); |
1142 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1111 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1143 break; | 1112 break; |
1144 } | 1113 } |
1145 case kArmVcvtS32F32: { | 1114 case kArmVcvtS32F32: { |
1146 SwVfpRegister scratch = kScratchDoubleReg.low(); | 1115 SwVfpRegister scratch = kScratchDoubleReg.low(); |
1147 __ vcvt_s32_f32(scratch, i.InputFloat32Register(0)); | 1116 __ vcvt_s32_f32(scratch, i.InputFloatRegister(0)); |
1148 __ vmov(i.OutputRegister(), scratch); | 1117 __ vmov(i.OutputRegister(), scratch); |
1149 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1118 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1150 break; | 1119 break; |
1151 } | 1120 } |
1152 case kArmVcvtU32F32: { | 1121 case kArmVcvtU32F32: { |
1153 SwVfpRegister scratch = kScratchDoubleReg.low(); | 1122 SwVfpRegister scratch = kScratchDoubleReg.low(); |
1154 __ vcvt_u32_f32(scratch, i.InputFloat32Register(0)); | 1123 __ vcvt_u32_f32(scratch, i.InputFloatRegister(0)); |
1155 __ vmov(i.OutputRegister(), scratch); | 1124 __ vmov(i.OutputRegister(), scratch); |
1156 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1125 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1157 break; | 1126 break; |
1158 } | 1127 } |
1159 case kArmVcvtS32F64: { | 1128 case kArmVcvtS32F64: { |
1160 SwVfpRegister scratch = kScratchDoubleReg.low(); | 1129 SwVfpRegister scratch = kScratchDoubleReg.low(); |
1161 __ vcvt_s32_f64(scratch, i.InputFloat64Register(0)); | 1130 __ vcvt_s32_f64(scratch, i.InputDoubleRegister(0)); |
1162 __ vmov(i.OutputRegister(), scratch); | 1131 __ vmov(i.OutputRegister(), scratch); |
1163 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1132 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1164 break; | 1133 break; |
1165 } | 1134 } |
1166 case kArmVcvtU32F64: { | 1135 case kArmVcvtU32F64: { |
1167 SwVfpRegister scratch = kScratchDoubleReg.low(); | 1136 SwVfpRegister scratch = kScratchDoubleReg.low(); |
1168 __ vcvt_u32_f64(scratch, i.InputFloat64Register(0)); | 1137 __ vcvt_u32_f64(scratch, i.InputDoubleRegister(0)); |
1169 __ vmov(i.OutputRegister(), scratch); | 1138 __ vmov(i.OutputRegister(), scratch); |
1170 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1139 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1171 break; | 1140 break; |
1172 } | 1141 } |
1173 case kArmVmovU32F32: | 1142 case kArmVmovU32F32: |
1174 __ vmov(i.OutputRegister(), i.InputFloat32Register(0)); | 1143 __ vmov(i.OutputRegister(), i.InputFloatRegister(0)); |
1175 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1144 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1176 break; | 1145 break; |
1177 case kArmVmovF32U32: | 1146 case kArmVmovF32U32: |
1178 __ vmov(i.OutputFloat32Register(), i.InputRegister(0)); | 1147 __ vmov(i.OutputFloatRegister(), i.InputRegister(0)); |
1179 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1148 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1180 break; | 1149 break; |
1181 case kArmVmovLowU32F64: | 1150 case kArmVmovLowU32F64: |
1182 __ VmovLow(i.OutputRegister(), i.InputFloat64Register(0)); | 1151 __ VmovLow(i.OutputRegister(), i.InputDoubleRegister(0)); |
1183 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1152 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1184 break; | 1153 break; |
1185 case kArmVmovLowF64U32: | 1154 case kArmVmovLowF64U32: |
1186 __ VmovLow(i.OutputFloat64Register(), i.InputRegister(1)); | 1155 __ VmovLow(i.OutputDoubleRegister(), i.InputRegister(1)); |
1187 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1156 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1188 break; | 1157 break; |
1189 case kArmVmovHighU32F64: | 1158 case kArmVmovHighU32F64: |
1190 __ VmovHigh(i.OutputRegister(), i.InputFloat64Register(0)); | 1159 __ VmovHigh(i.OutputRegister(), i.InputDoubleRegister(0)); |
1191 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1160 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1192 break; | 1161 break; |
1193 case kArmVmovHighF64U32: | 1162 case kArmVmovHighF64U32: |
1194 __ VmovHigh(i.OutputFloat64Register(), i.InputRegister(1)); | 1163 __ VmovHigh(i.OutputDoubleRegister(), i.InputRegister(1)); |
1195 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1164 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1196 break; | 1165 break; |
1197 case kArmVmovF64U32U32: | 1166 case kArmVmovF64U32U32: |
1198 __ vmov(i.OutputFloat64Register(), i.InputRegister(0), | 1167 __ vmov(i.OutputDoubleRegister(), i.InputRegister(0), i.InputRegister(1)); |
1199 i.InputRegister(1)); | |
1200 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1168 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1201 break; | 1169 break; |
1202 case kArmLdrb: | 1170 case kArmLdrb: |
1203 __ ldrb(i.OutputRegister(), i.InputOffset()); | 1171 __ ldrb(i.OutputRegister(), i.InputOffset()); |
1204 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1172 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1205 break; | 1173 break; |
1206 case kArmLdrsb: | 1174 case kArmLdrsb: |
1207 __ ldrsb(i.OutputRegister(), i.InputOffset()); | 1175 __ ldrsb(i.OutputRegister(), i.InputOffset()); |
1208 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1176 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1209 break; | 1177 break; |
(...skipping 12 matching lines...) Expand all Loading... |
1222 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1190 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1223 break; | 1191 break; |
1224 case kArmLdr: | 1192 case kArmLdr: |
1225 __ ldr(i.OutputRegister(), i.InputOffset()); | 1193 __ ldr(i.OutputRegister(), i.InputOffset()); |
1226 break; | 1194 break; |
1227 case kArmStr: | 1195 case kArmStr: |
1228 __ str(i.InputRegister(0), i.InputOffset(1)); | 1196 __ str(i.InputRegister(0), i.InputOffset(1)); |
1229 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1197 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1230 break; | 1198 break; |
1231 case kArmVldrF32: { | 1199 case kArmVldrF32: { |
1232 __ vldr(i.OutputFloat32Register(), i.InputOffset()); | 1200 __ vldr(i.OutputFloatRegister(), i.InputOffset()); |
1233 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1201 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1234 break; | 1202 break; |
1235 } | 1203 } |
1236 case kArmVstrF32: | 1204 case kArmVstrF32: |
1237 __ vstr(i.InputFloat32Register(0), i.InputOffset(1)); | 1205 __ vstr(i.InputFloatRegister(0), i.InputOffset(1)); |
1238 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1206 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1239 break; | 1207 break; |
1240 case kArmVldrF64: | 1208 case kArmVldrF64: |
1241 __ vldr(i.OutputFloat64Register(), i.InputOffset()); | 1209 __ vldr(i.OutputDoubleRegister(), i.InputOffset()); |
1242 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1210 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1243 break; | 1211 break; |
1244 case kArmVstrF64: | 1212 case kArmVstrF64: |
1245 __ vstr(i.InputFloat64Register(0), i.InputOffset(1)); | 1213 __ vstr(i.InputDoubleRegister(0), i.InputOffset(1)); |
1246 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1214 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1247 break; | 1215 break; |
1248 case kArmFloat32Max: { | 1216 case kArmFloat32Max: { |
1249 CpuFeatureScope scope(masm(), ARMv8); | 1217 CpuFeatureScope scope(masm(), ARMv8); |
1250 // (b < a) ? a : b | 1218 // (b < a) ? a : b |
1251 SwVfpRegister a = i.InputFloat32Register(0); | 1219 SwVfpRegister a = i.InputFloatRegister(0); |
1252 SwVfpRegister b = i.InputFloat32Register(1); | 1220 SwVfpRegister b = i.InputFloatRegister(1); |
1253 SwVfpRegister result = i.OutputFloat32Register(0); | 1221 SwVfpRegister result = i.OutputFloatRegister(); |
1254 __ VFPCompareAndSetFlags(a, b); | 1222 __ VFPCompareAndSetFlags(a, b); |
1255 __ vsel(gt, result, a, b); | 1223 __ vsel(gt, result, a, b); |
1256 break; | 1224 break; |
1257 } | 1225 } |
1258 case kArmFloat32Min: { | 1226 case kArmFloat32Min: { |
1259 CpuFeatureScope scope(masm(), ARMv8); | 1227 CpuFeatureScope scope(masm(), ARMv8); |
1260 // (a < b) ? a : b | 1228 // (a < b) ? a : b |
1261 SwVfpRegister a = i.InputFloat32Register(0); | 1229 SwVfpRegister a = i.InputFloatRegister(0); |
1262 SwVfpRegister b = i.InputFloat32Register(1); | 1230 SwVfpRegister b = i.InputFloatRegister(1); |
1263 SwVfpRegister result = i.OutputFloat32Register(0); | 1231 SwVfpRegister result = i.OutputFloatRegister(); |
1264 __ VFPCompareAndSetFlags(b, a); | 1232 __ VFPCompareAndSetFlags(b, a); |
1265 __ vsel(gt, result, a, b); | 1233 __ vsel(gt, result, a, b); |
1266 break; | 1234 break; |
1267 } | 1235 } |
1268 case kArmFloat64Max: { | 1236 case kArmFloat64Max: { |
1269 CpuFeatureScope scope(masm(), ARMv8); | 1237 CpuFeatureScope scope(masm(), ARMv8); |
1270 // (b < a) ? a : b | 1238 // (b < a) ? a : b |
1271 DwVfpRegister a = i.InputFloat64Register(0); | 1239 DwVfpRegister a = i.InputDoubleRegister(0); |
1272 DwVfpRegister b = i.InputFloat64Register(1); | 1240 DwVfpRegister b = i.InputDoubleRegister(1); |
1273 DwVfpRegister result = i.OutputFloat64Register(0); | 1241 DwVfpRegister result = i.OutputDoubleRegister(); |
1274 __ VFPCompareAndSetFlags(a, b); | 1242 __ VFPCompareAndSetFlags(a, b); |
1275 __ vsel(gt, result, a, b); | 1243 __ vsel(gt, result, a, b); |
1276 break; | 1244 break; |
1277 } | 1245 } |
1278 case kArmFloat64Min: { | 1246 case kArmFloat64Min: { |
1279 CpuFeatureScope scope(masm(), ARMv8); | 1247 CpuFeatureScope scope(masm(), ARMv8); |
1280 // (a < b) ? a : b | 1248 // (a < b) ? a : b |
1281 DwVfpRegister a = i.InputFloat64Register(0); | 1249 DwVfpRegister a = i.InputDoubleRegister(0); |
1282 DwVfpRegister b = i.InputFloat64Register(1); | 1250 DwVfpRegister b = i.InputDoubleRegister(1); |
1283 DwVfpRegister result = i.OutputFloat64Register(0); | 1251 DwVfpRegister result = i.OutputDoubleRegister(); |
1284 __ VFPCompareAndSetFlags(b, a); | 1252 __ VFPCompareAndSetFlags(b, a); |
1285 __ vsel(gt, result, a, b); | 1253 __ vsel(gt, result, a, b); |
1286 break; | 1254 break; |
1287 } | 1255 } |
1288 case kArmFloat64SilenceNaN: { | 1256 case kArmFloat64SilenceNaN: { |
1289 DwVfpRegister value = i.InputFloat64Register(0); | 1257 DwVfpRegister value = i.InputDoubleRegister(0); |
1290 DwVfpRegister result = i.OutputFloat64Register(0); | 1258 DwVfpRegister result = i.OutputDoubleRegister(); |
1291 __ VFPCanonicalizeNaN(result, value); | 1259 __ VFPCanonicalizeNaN(result, value); |
1292 break; | 1260 break; |
1293 } | 1261 } |
1294 case kArmPush: | 1262 case kArmPush: |
1295 if (instr->InputAt(0)->IsFPRegister()) { | 1263 if (instr->InputAt(0)->IsFPRegister()) { |
1296 LocationOperand* op = LocationOperand::cast(instr->InputAt(0)); | 1264 LocationOperand* op = LocationOperand::cast(instr->InputAt(0)); |
1297 if (op->representation() == MachineRepresentation::kFloat64) { | 1265 if (op->representation() == MachineRepresentation::kFloat64) { |
1298 __ vpush(i.InputFloat64Register(0)); | 1266 __ vpush(i.InputDoubleRegister(0)); |
1299 frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize); | 1267 frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize); |
1300 } else { | 1268 } else { |
1301 DCHECK_EQ(MachineRepresentation::kFloat32, op->representation()); | 1269 DCHECK_EQ(MachineRepresentation::kFloat32, op->representation()); |
1302 __ vpush(i.InputFloat32Register(0)); | 1270 __ vpush(i.InputFloatRegister(0)); |
1303 frame_access_state()->IncreaseSPDelta(1); | 1271 frame_access_state()->IncreaseSPDelta(1); |
1304 } | 1272 } |
1305 } else { | 1273 } else { |
1306 __ push(i.InputRegister(0)); | 1274 __ push(i.InputRegister(0)); |
1307 frame_access_state()->IncreaseSPDelta(1); | 1275 frame_access_state()->IncreaseSPDelta(1); |
1308 } | 1276 } |
1309 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1277 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1310 break; | 1278 break; |
1311 case kArmPoke: { | 1279 case kArmPoke: { |
1312 int const slot = MiscField::decode(instr->opcode()); | 1280 int const slot = MiscField::decode(instr->opcode()); |
(...skipping 10 matching lines...) Expand all Loading... |
1323 case kCheckedLoadInt16: | 1291 case kCheckedLoadInt16: |
1324 ASSEMBLE_CHECKED_LOAD_INTEGER(ldrsh); | 1292 ASSEMBLE_CHECKED_LOAD_INTEGER(ldrsh); |
1325 break; | 1293 break; |
1326 case kCheckedLoadUint16: | 1294 case kCheckedLoadUint16: |
1327 ASSEMBLE_CHECKED_LOAD_INTEGER(ldrh); | 1295 ASSEMBLE_CHECKED_LOAD_INTEGER(ldrh); |
1328 break; | 1296 break; |
1329 case kCheckedLoadWord32: | 1297 case kCheckedLoadWord32: |
1330 ASSEMBLE_CHECKED_LOAD_INTEGER(ldr); | 1298 ASSEMBLE_CHECKED_LOAD_INTEGER(ldr); |
1331 break; | 1299 break; |
1332 case kCheckedLoadFloat32: | 1300 case kCheckedLoadFloat32: |
1333 ASSEMBLE_CHECKED_LOAD_FLOAT(32); | 1301 ASSEMBLE_CHECKED_LOAD_FP(Float); |
1334 break; | 1302 break; |
1335 case kCheckedLoadFloat64: | 1303 case kCheckedLoadFloat64: |
1336 ASSEMBLE_CHECKED_LOAD_FLOAT(64); | 1304 ASSEMBLE_CHECKED_LOAD_FP(Double); |
1337 break; | 1305 break; |
1338 case kCheckedStoreWord8: | 1306 case kCheckedStoreWord8: |
1339 ASSEMBLE_CHECKED_STORE_INTEGER(strb); | 1307 ASSEMBLE_CHECKED_STORE_INTEGER(strb); |
1340 break; | 1308 break; |
1341 case kCheckedStoreWord16: | 1309 case kCheckedStoreWord16: |
1342 ASSEMBLE_CHECKED_STORE_INTEGER(strh); | 1310 ASSEMBLE_CHECKED_STORE_INTEGER(strh); |
1343 break; | 1311 break; |
1344 case kCheckedStoreWord32: | 1312 case kCheckedStoreWord32: |
1345 ASSEMBLE_CHECKED_STORE_INTEGER(str); | 1313 ASSEMBLE_CHECKED_STORE_INTEGER(str); |
1346 break; | 1314 break; |
1347 case kCheckedStoreFloat32: | 1315 case kCheckedStoreFloat32: |
1348 ASSEMBLE_CHECKED_STORE_FLOAT(32); | 1316 ASSEMBLE_CHECKED_STORE_FP(Float); |
1349 break; | 1317 break; |
1350 case kCheckedStoreFloat64: | 1318 case kCheckedStoreFloat64: |
1351 ASSEMBLE_CHECKED_STORE_FLOAT(64); | 1319 ASSEMBLE_CHECKED_STORE_FP(Double); |
1352 break; | 1320 break; |
1353 case kCheckedLoadWord64: | 1321 case kCheckedLoadWord64: |
1354 case kCheckedStoreWord64: | 1322 case kCheckedStoreWord64: |
1355 UNREACHABLE(); // currently unsupported checked int64 load/store. | 1323 UNREACHABLE(); // currently unsupported checked int64 load/store. |
1356 break; | 1324 break; |
1357 | 1325 |
1358 case kAtomicLoadInt8: | 1326 case kAtomicLoadInt8: |
1359 ASSEMBLE_ATOMIC_LOAD_INTEGER(ldrsb); | 1327 ASSEMBLE_ATOMIC_LOAD_INTEGER(ldrsb); |
1360 break; | 1328 break; |
1361 case kAtomicLoadUint8: | 1329 case kAtomicLoadUint8: |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1647 UNREACHABLE(); // TODO(dcarney): loading RPO constants on arm. | 1615 UNREACHABLE(); // TODO(dcarney): loading RPO constants on arm. |
1648 break; | 1616 break; |
1649 } | 1617 } |
1650 if (destination->IsStackSlot()) __ str(dst, g.ToMemOperand(destination)); | 1618 if (destination->IsStackSlot()) __ str(dst, g.ToMemOperand(destination)); |
1651 } else if (src.type() == Constant::kFloat32) { | 1619 } else if (src.type() == Constant::kFloat32) { |
1652 if (destination->IsFPStackSlot()) { | 1620 if (destination->IsFPStackSlot()) { |
1653 MemOperand dst = g.ToMemOperand(destination); | 1621 MemOperand dst = g.ToMemOperand(destination); |
1654 __ mov(ip, Operand(bit_cast<int32_t>(src.ToFloat32()))); | 1622 __ mov(ip, Operand(bit_cast<int32_t>(src.ToFloat32()))); |
1655 __ str(ip, dst); | 1623 __ str(ip, dst); |
1656 } else { | 1624 } else { |
1657 SwVfpRegister dst = g.ToFloat32Register(destination); | 1625 SwVfpRegister dst = g.ToFloatRegister(destination); |
1658 __ vmov(dst, src.ToFloat32()); | 1626 __ vmov(dst, src.ToFloat32()); |
1659 } | 1627 } |
1660 } else { | 1628 } else { |
1661 DCHECK_EQ(Constant::kFloat64, src.type()); | 1629 DCHECK_EQ(Constant::kFloat64, src.type()); |
1662 DwVfpRegister dst = destination->IsFPRegister() | 1630 DwVfpRegister dst = destination->IsFPRegister() |
1663 ? g.ToFloat64Register(destination) | 1631 ? g.ToDoubleRegister(destination) |
1664 : kScratchDoubleReg; | 1632 : kScratchDoubleReg; |
1665 __ vmov(dst, src.ToFloat64(), kScratchReg); | 1633 __ vmov(dst, src.ToFloat64(), kScratchReg); |
1666 if (destination->IsFPStackSlot()) { | 1634 if (destination->IsFPStackSlot()) { |
1667 __ vstr(dst, g.ToMemOperand(destination)); | 1635 __ vstr(dst, g.ToMemOperand(destination)); |
1668 } | 1636 } |
1669 } | 1637 } |
1670 } else if (source->IsFPRegister()) { | 1638 } else if (source->IsFPRegister()) { |
1671 MachineRepresentation rep = LocationOperand::cast(source)->representation(); | 1639 MachineRepresentation rep = LocationOperand::cast(source)->representation(); |
1672 if (rep == MachineRepresentation::kFloat64) { | 1640 if (rep == MachineRepresentation::kFloat64) { |
1673 DwVfpRegister src = g.ToDoubleRegister(source); | 1641 DwVfpRegister src = g.ToDoubleRegister(source); |
1674 if (destination->IsFPRegister()) { | 1642 if (destination->IsFPRegister()) { |
1675 DwVfpRegister dst = g.ToDoubleRegister(destination); | 1643 DwVfpRegister dst = g.ToDoubleRegister(destination); |
1676 __ Move(dst, src); | 1644 __ Move(dst, src); |
1677 } else { | 1645 } else { |
1678 DCHECK(destination->IsFPStackSlot()); | 1646 DCHECK(destination->IsFPStackSlot()); |
1679 __ vstr(src, g.ToMemOperand(destination)); | 1647 __ vstr(src, g.ToMemOperand(destination)); |
1680 } | 1648 } |
1681 } else { | 1649 } else { |
1682 DCHECK_EQ(MachineRepresentation::kFloat32, rep); | 1650 DCHECK_EQ(MachineRepresentation::kFloat32, rep); |
1683 SwVfpRegister src = g.ToFloat32Register(source); | 1651 SwVfpRegister src = g.ToFloatRegister(source); |
1684 if (destination->IsFPRegister()) { | 1652 if (destination->IsFPRegister()) { |
1685 SwVfpRegister dst = g.ToFloat32Register(destination); | 1653 SwVfpRegister dst = g.ToFloatRegister(destination); |
1686 __ Move(dst, src); | 1654 __ Move(dst, src); |
1687 } else { | 1655 } else { |
1688 DCHECK(destination->IsFPStackSlot()); | 1656 DCHECK(destination->IsFPStackSlot()); |
1689 __ vstr(src, g.ToMemOperand(destination)); | 1657 __ vstr(src, g.ToMemOperand(destination)); |
1690 } | 1658 } |
1691 } | 1659 } |
1692 } else if (source->IsFPStackSlot()) { | 1660 } else if (source->IsFPStackSlot()) { |
1693 MemOperand src = g.ToMemOperand(source); | 1661 MemOperand src = g.ToMemOperand(source); |
1694 MachineRepresentation rep = | 1662 MachineRepresentation rep = |
1695 LocationOperand::cast(destination)->representation(); | 1663 LocationOperand::cast(destination)->representation(); |
1696 if (destination->IsFPRegister()) { | 1664 if (destination->IsFPRegister()) { |
1697 if (rep == MachineRepresentation::kFloat64) { | 1665 if (rep == MachineRepresentation::kFloat64) { |
1698 __ vldr(g.ToDoubleRegister(destination), src); | 1666 __ vldr(g.ToDoubleRegister(destination), src); |
1699 } else { | 1667 } else { |
1700 DCHECK_EQ(MachineRepresentation::kFloat32, rep); | 1668 DCHECK_EQ(MachineRepresentation::kFloat32, rep); |
1701 __ vldr(g.ToFloat32Register(destination), src); | 1669 __ vldr(g.ToFloatRegister(destination), src); |
1702 } | 1670 } |
1703 } else { | 1671 } else { |
1704 DCHECK(destination->IsFPStackSlot()); | 1672 DCHECK(destination->IsFPStackSlot()); |
1705 if (rep == MachineRepresentation::kFloat64) { | 1673 if (rep == MachineRepresentation::kFloat64) { |
1706 DwVfpRegister temp = kScratchDoubleReg; | 1674 DwVfpRegister temp = kScratchDoubleReg; |
1707 __ vldr(temp, src); | 1675 __ vldr(temp, src); |
1708 __ vstr(temp, g.ToMemOperand(destination)); | 1676 __ vstr(temp, g.ToMemOperand(destination)); |
1709 } else { | 1677 } else { |
1710 DCHECK_EQ(MachineRepresentation::kFloat32, rep); | 1678 DCHECK_EQ(MachineRepresentation::kFloat32, rep); |
1711 SwVfpRegister temp = kScratchDoubleReg.low(); | 1679 SwVfpRegister temp = kScratchDoubleReg.low(); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1762 __ Move(dst, temp); | 1730 __ Move(dst, temp); |
1763 } else { | 1731 } else { |
1764 DCHECK(destination->IsFPStackSlot()); | 1732 DCHECK(destination->IsFPStackSlot()); |
1765 MemOperand dst = g.ToMemOperand(destination); | 1733 MemOperand dst = g.ToMemOperand(destination); |
1766 __ Move(temp, src); | 1734 __ Move(temp, src); |
1767 __ vldr(src, dst); | 1735 __ vldr(src, dst); |
1768 __ vstr(temp, dst); | 1736 __ vstr(temp, dst); |
1769 } | 1737 } |
1770 } else { | 1738 } else { |
1771 DCHECK_EQ(MachineRepresentation::kFloat32, rep); | 1739 DCHECK_EQ(MachineRepresentation::kFloat32, rep); |
1772 SwVfpRegister src = g.ToFloat32Register(source); | 1740 SwVfpRegister src = g.ToFloatRegister(source); |
1773 if (destination->IsFPRegister()) { | 1741 if (destination->IsFPRegister()) { |
1774 SwVfpRegister dst = g.ToFloat32Register(destination); | 1742 SwVfpRegister dst = g.ToFloatRegister(destination); |
1775 __ Move(temp.low(), src); | 1743 __ Move(temp.low(), src); |
1776 __ Move(src, dst); | 1744 __ Move(src, dst); |
1777 __ Move(dst, temp.low()); | 1745 __ Move(dst, temp.low()); |
1778 } else { | 1746 } else { |
1779 DCHECK(destination->IsFPStackSlot()); | 1747 DCHECK(destination->IsFPStackSlot()); |
1780 MemOperand dst = g.ToMemOperand(destination); | 1748 MemOperand dst = g.ToMemOperand(destination); |
1781 __ Move(temp.low(), src); | 1749 __ Move(temp.low(), src); |
1782 __ vldr(src, dst); | 1750 __ vldr(src, dst); |
1783 __ vstr(temp.low(), dst); | 1751 __ vstr(temp.low(), dst); |
1784 } | 1752 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1838 padding_size -= v8::internal::Assembler::kInstrSize; | 1806 padding_size -= v8::internal::Assembler::kInstrSize; |
1839 } | 1807 } |
1840 } | 1808 } |
1841 } | 1809 } |
1842 | 1810 |
1843 #undef __ | 1811 #undef __ |
1844 | 1812 |
1845 } // namespace compiler | 1813 } // namespace compiler |
1846 } // namespace internal | 1814 } // namespace internal |
1847 } // namespace v8 | 1815 } // namespace v8 |
OLD | NEW |