| 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 |