| 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 #include "src/compiler/code-generator-impl.h" | 6 #include "src/compiler/code-generator-impl.h" |
| 7 #include "src/compiler/gap-resolver.h" | 7 #include "src/compiler/gap-resolver.h" |
| 8 #include "src/compiler/node-matchers.h" | 8 #include "src/compiler/node-matchers.h" |
| 9 #include "src/compiler/osr.h" | 9 #include "src/compiler/osr.h" |
| 10 #include "src/mips/macro-assembler-mips.h" | 10 #include "src/mips/macro-assembler-mips.h" |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 __ srl(at, kScratchReg, 31); | 185 __ srl(at, kScratchReg, 31); |
| 186 __ sll(at, at, 31); | 186 __ sll(at, at, 31); |
| 187 __ Mthc1(at, result_); | 187 __ Mthc1(at, result_); |
| 188 } | 188 } |
| 189 | 189 |
| 190 private: | 190 private: |
| 191 DoubleRegister const result_; | 191 DoubleRegister const result_; |
| 192 }; | 192 }; |
| 193 | 193 |
| 194 | 194 |
| 195 class OutOfLineTruncate final : public OutOfLineRound { | 195 class OutOfLineRound32 : public OutOfLineCode { |
| 196 public: | 196 public: |
| 197 OutOfLineTruncate(CodeGenerator* gen, DoubleRegister result) | 197 OutOfLineRound32(CodeGenerator* gen, DoubleRegister result) |
| 198 : OutOfLineRound(gen, result) {} | 198 : OutOfLineCode(gen), result_(result) {} |
| 199 |
| 200 void Generate() final { |
| 201 // Handle rounding to zero case where sign has to be preserved. |
| 202 // High bits of float input already in kScratchReg. |
| 203 __ srl(at, kScratchReg, 31); |
| 204 __ sll(at, at, 31); |
| 205 __ mtc1(at, result_); |
| 206 } |
| 207 |
| 208 private: |
| 209 DoubleRegister const result_; |
| 199 }; | 210 }; |
| 200 | 211 |
| 201 | 212 |
| 202 class OutOfLineFloor final : public OutOfLineRound { | |
| 203 public: | |
| 204 OutOfLineFloor(CodeGenerator* gen, DoubleRegister result) | |
| 205 : OutOfLineRound(gen, result) {} | |
| 206 }; | |
| 207 | |
| 208 | |
| 209 class OutOfLineCeil final : public OutOfLineRound { | |
| 210 public: | |
| 211 OutOfLineCeil(CodeGenerator* gen, DoubleRegister result) | |
| 212 : OutOfLineRound(gen, result) {} | |
| 213 }; | |
| 214 | |
| 215 | |
| 216 class OutOfLineTiesEven final : public OutOfLineRound { | |
| 217 public: | |
| 218 OutOfLineTiesEven(CodeGenerator* gen, DoubleRegister result) | |
| 219 : OutOfLineRound(gen, result) {} | |
| 220 }; | |
| 221 | |
| 222 | |
| 223 class OutOfLineRecordWrite final : public OutOfLineCode { | 213 class OutOfLineRecordWrite final : public OutOfLineCode { |
| 224 public: | 214 public: |
| 225 OutOfLineRecordWrite(CodeGenerator* gen, Register object, Register index, | 215 OutOfLineRecordWrite(CodeGenerator* gen, Register object, Register index, |
| 226 Register value, Register scratch0, Register scratch1, | 216 Register value, Register scratch0, Register scratch1, |
| 227 RecordWriteMode mode) | 217 RecordWriteMode mode) |
| 228 : OutOfLineCode(gen), | 218 : OutOfLineCode(gen), |
| 229 object_(object), | 219 object_(object), |
| 230 index_(index), | 220 index_(index), |
| 231 value_(value), | 221 value_(value), |
| 232 scratch0_(scratch0), | 222 scratch0_(scratch0), |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 425 } else { \ | 415 } else { \ |
| 426 auto offset = i.InputOperand(0).immediate(); \ | 416 auto offset = i.InputOperand(0).immediate(); \ |
| 427 auto value = i.InputRegister(2); \ | 417 auto value = i.InputRegister(2); \ |
| 428 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \ | 418 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \ |
| 429 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ | 419 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ |
| 430 } \ | 420 } \ |
| 431 __ bind(&done); \ | 421 __ bind(&done); \ |
| 432 } while (0) | 422 } while (0) |
| 433 | 423 |
| 434 | 424 |
| 435 #define ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(asm_instr, operation) \ | 425 #define ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(asm_instr) \ |
| 436 do { \ | 426 do { \ |
| 437 auto ool = \ | 427 auto ool = new (zone()) OutOfLineRound(this, i.OutputDoubleRegister()); \ |
| 438 new (zone()) OutOfLine##operation(this, i.OutputDoubleRegister()); \ | |
| 439 Label done; \ | 428 Label done; \ |
| 440 __ Mfhc1(kScratchReg, i.InputDoubleRegister(0)); \ | 429 __ Mfhc1(kScratchReg, i.InputDoubleRegister(0)); \ |
| 441 __ Ext(at, kScratchReg, HeapNumber::kExponentShift, \ | 430 __ Ext(at, kScratchReg, HeapNumber::kExponentShift, \ |
| 442 HeapNumber::kExponentBits); \ | 431 HeapNumber::kExponentBits); \ |
| 443 __ Branch(USE_DELAY_SLOT, &done, hs, at, \ | 432 __ Branch(USE_DELAY_SLOT, &done, hs, at, \ |
| 444 Operand(HeapNumber::kExponentBias + HeapNumber::kMantissaBits)); \ | 433 Operand(HeapNumber::kExponentBias + HeapNumber::kMantissaBits)); \ |
| 445 __ mov_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ | 434 __ mov_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ |
| 446 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ | 435 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ |
| 447 __ Move(at, kScratchReg2, i.OutputDoubleRegister()); \ | 436 __ Move(at, kScratchReg2, i.OutputDoubleRegister()); \ |
| 448 __ or_(at, at, kScratchReg2); \ | 437 __ or_(at, at, kScratchReg2); \ |
| 449 __ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg)); \ | 438 __ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg)); \ |
| 450 __ cvt_d_l(i.OutputDoubleRegister(), i.OutputDoubleRegister()); \ | 439 __ cvt_d_l(i.OutputDoubleRegister(), i.OutputDoubleRegister()); \ |
| 451 __ bind(ool->exit()); \ | 440 __ bind(ool->exit()); \ |
| 452 __ bind(&done); \ | 441 __ bind(&done); \ |
| 453 } while (0) | 442 } while (0) |
| 454 | 443 |
| 455 | 444 |
| 445 #define ASSEMBLE_ROUND_FLOAT_TO_FLOAT(asm_instr) \ |
| 446 do { \ |
| 447 int32_t kFloat32ExponentBias = 127; \ |
| 448 int32_t kFloat32MantissaBits = 23; \ |
| 449 int32_t kFloat32ExponentBits = 8; \ |
| 450 auto ool = new (zone()) OutOfLineRound32(this, i.OutputDoubleRegister()); \ |
| 451 Label done; \ |
| 452 __ mfc1(kScratchReg, i.InputDoubleRegister(0)); \ |
| 453 __ Ext(at, kScratchReg, kFloat32MantissaBits, kFloat32ExponentBits); \ |
| 454 __ Branch(USE_DELAY_SLOT, &done, hs, at, \ |
| 455 Operand(kFloat32ExponentBias + kFloat32MantissaBits)); \ |
| 456 __ mov_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ |
| 457 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ |
| 458 __ mfc1(at, i.OutputDoubleRegister()); \ |
| 459 __ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg)); \ |
| 460 __ cvt_s_w(i.OutputDoubleRegister(), i.OutputDoubleRegister()); \ |
| 461 __ bind(ool->exit()); \ |
| 462 __ bind(&done); \ |
| 463 } while (0) |
| 464 |
| 456 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { | 465 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { |
| 457 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); | 466 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); |
| 458 if (sp_slot_delta > 0) { | 467 if (sp_slot_delta > 0) { |
| 459 __ addiu(sp, sp, sp_slot_delta * kPointerSize); | 468 __ addiu(sp, sp, sp_slot_delta * kPointerSize); |
| 460 } | 469 } |
| 461 if (frame()->needs_frame()) { | 470 if (frame()->needs_frame()) { |
| 462 __ Pop(ra, fp); | 471 __ Pop(ra, fp); |
| 463 } | 472 } |
| 464 frame_access_state()->SetFrameAccessToDefault(); | 473 frame_access_state()->SetFrameAccessToDefault(); |
| 465 } | 474 } |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 803 } | 812 } |
| 804 case kMipsMaxD: | 813 case kMipsMaxD: |
| 805 __ max_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0), | 814 __ max_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0), |
| 806 i.InputDoubleRegister(1)); | 815 i.InputDoubleRegister(1)); |
| 807 break; | 816 break; |
| 808 case kMipsMinD: | 817 case kMipsMinD: |
| 809 __ min_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0), | 818 __ min_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0), |
| 810 i.InputDoubleRegister(1)); | 819 i.InputDoubleRegister(1)); |
| 811 break; | 820 break; |
| 812 case kMipsFloat64RoundDown: { | 821 case kMipsFloat64RoundDown: { |
| 813 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(floor_l_d, Floor); | 822 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(floor_l_d); |
| 823 break; |
| 824 } |
| 825 case kMipsFloat32RoundDown: { |
| 826 ASSEMBLE_ROUND_FLOAT_TO_FLOAT(floor_w_s); |
| 814 break; | 827 break; |
| 815 } | 828 } |
| 816 case kMipsFloat64RoundTruncate: { | 829 case kMipsFloat64RoundTruncate: { |
| 817 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(trunc_l_d, Truncate); | 830 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(trunc_l_d); |
| 831 break; |
| 832 } |
| 833 case kMipsFloat32RoundTruncate: { |
| 834 ASSEMBLE_ROUND_FLOAT_TO_FLOAT(trunc_w_s); |
| 818 break; | 835 break; |
| 819 } | 836 } |
| 820 case kMipsFloat64RoundUp: { | 837 case kMipsFloat64RoundUp: { |
| 821 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(ceil_l_d, Ceil); | 838 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(ceil_l_d); |
| 839 break; |
| 840 } |
| 841 case kMipsFloat32RoundUp: { |
| 842 ASSEMBLE_ROUND_FLOAT_TO_FLOAT(ceil_w_s); |
| 822 break; | 843 break; |
| 823 } | 844 } |
| 824 case kMipsFloat64RoundTiesEven: { | 845 case kMipsFloat64RoundTiesEven: { |
| 825 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(round_l_d, TiesEven); | 846 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(round_l_d); |
| 847 break; |
| 848 } |
| 849 case kMipsFloat32RoundTiesEven: { |
| 850 ASSEMBLE_ROUND_FLOAT_TO_FLOAT(round_w_s); |
| 826 break; | 851 break; |
| 827 } | 852 } |
| 828 case kMipsFloat64Max: { | 853 case kMipsFloat64Max: { |
| 829 // (b < a) ? a : b | 854 // (b < a) ? a : b |
| 830 if (IsMipsArchVariant(kMips32r6)) { | 855 if (IsMipsArchVariant(kMips32r6)) { |
| 831 __ cmp_d(OLT, i.OutputDoubleRegister(), i.InputDoubleRegister(1), | 856 __ cmp_d(OLT, i.OutputDoubleRegister(), i.InputDoubleRegister(1), |
| 832 i.InputDoubleRegister(0)); | 857 i.InputDoubleRegister(0)); |
| 833 __ sel_d(i.OutputDoubleRegister(), i.InputDoubleRegister(1), | 858 __ sel_d(i.OutputDoubleRegister(), i.InputDoubleRegister(1), |
| 834 i.InputDoubleRegister(0)); | 859 i.InputDoubleRegister(0)); |
| 835 } else { | 860 } else { |
| (...skipping 776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1612 padding_size -= v8::internal::Assembler::kInstrSize; | 1637 padding_size -= v8::internal::Assembler::kInstrSize; |
| 1613 } | 1638 } |
| 1614 } | 1639 } |
| 1615 } | 1640 } |
| 1616 | 1641 |
| 1617 #undef __ | 1642 #undef __ |
| 1618 | 1643 |
| 1619 } // namespace compiler | 1644 } // namespace compiler |
| 1620 } // namespace internal | 1645 } // namespace internal |
| 1621 } // namespace v8 | 1646 } // namespace v8 |
| OLD | NEW |