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 __ dsrl(at, kScratchReg, 31); | 185 __ dsrl(at, kScratchReg, 31); |
186 __ dsll(at, at, 31); | 186 __ dsll(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 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 } else { \ | 416 } else { \ |
427 int offset = static_cast<int>(i.InputOperand(0).immediate()); \ | 417 int offset = static_cast<int>(i.InputOperand(0).immediate()); \ |
428 auto value = i.InputRegister(2); \ | 418 auto value = i.InputRegister(2); \ |
429 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \ | 419 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \ |
430 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ | 420 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ |
431 } \ | 421 } \ |
432 __ bind(&done); \ | 422 __ bind(&done); \ |
433 } while (0) | 423 } while (0) |
434 | 424 |
435 | 425 |
436 #define ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(asm_instr, operation) \ | 426 #define ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(asm_instr) \ |
437 do { \ | 427 do { \ |
438 auto ool = \ | 428 auto ool = new (zone()) OutOfLineRound(this, i.OutputDoubleRegister()); \ |
439 new (zone()) OutOfLine##operation(this, i.OutputDoubleRegister()); \ | |
440 Label done; \ | 429 Label done; \ |
441 __ mfhc1(kScratchReg, i.InputDoubleRegister(0)); \ | 430 __ mfhc1(kScratchReg, i.InputDoubleRegister(0)); \ |
442 __ Ext(at, kScratchReg, HeapNumber::kExponentShift, \ | 431 __ Ext(at, kScratchReg, HeapNumber::kExponentShift, \ |
443 HeapNumber::kExponentBits); \ | 432 HeapNumber::kExponentBits); \ |
444 __ Branch(USE_DELAY_SLOT, &done, hs, at, \ | 433 __ Branch(USE_DELAY_SLOT, &done, hs, at, \ |
445 Operand(HeapNumber::kExponentBias + HeapNumber::kMantissaBits)); \ | 434 Operand(HeapNumber::kExponentBias + HeapNumber::kMantissaBits)); \ |
446 __ mov_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ | 435 __ mov_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ |
447 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ | 436 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ |
448 __ dmfc1(at, i.OutputDoubleRegister()); \ | 437 __ dmfc1(at, i.OutputDoubleRegister()); \ |
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 |
| 444 #define ASSEMBLE_ROUND_FLOAT_TO_FLOAT(asm_instr) \ |
| 445 do { \ |
| 446 int32_t kFloat32ExponentBias = 127; \ |
| 447 int32_t kFloat32MantissaBits = 23; \ |
| 448 int32_t kFloat32ExponentBits = 8; \ |
| 449 auto ool = new (zone()) OutOfLineRound32(this, i.OutputDoubleRegister()); \ |
| 450 Label done; \ |
| 451 __ mfc1(kScratchReg, i.InputDoubleRegister(0)); \ |
| 452 __ Ext(at, kScratchReg, kFloat32MantissaBits, kFloat32ExponentBits); \ |
| 453 __ Branch(USE_DELAY_SLOT, &done, hs, at, \ |
| 454 Operand(kFloat32ExponentBias + kFloat32MantissaBits)); \ |
| 455 __ mov_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ |
| 456 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ |
| 457 __ mfc1(at, i.OutputDoubleRegister()); \ |
| 458 __ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg)); \ |
| 459 __ cvt_s_w(i.OutputDoubleRegister(), i.OutputDoubleRegister()); \ |
| 460 __ bind(ool->exit()); \ |
| 461 __ bind(&done); \ |
| 462 } while (0) |
455 | 463 |
456 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { | 464 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { |
457 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); | 465 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); |
458 if (sp_slot_delta > 0) { | 466 if (sp_slot_delta > 0) { |
459 __ daddiu(sp, sp, sp_slot_delta * kPointerSize); | 467 __ daddiu(sp, sp, sp_slot_delta * kPointerSize); |
460 } | 468 } |
461 if (frame()->needs_frame()) { | 469 if (frame()->needs_frame()) { |
462 __ Pop(ra, fp); | 470 __ Pop(ra, fp); |
463 } | 471 } |
464 frame_access_state()->SetFrameAccessToDefault(); | 472 frame_access_state()->SetFrameAccessToDefault(); |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
870 } | 878 } |
871 case kMips64MaxD: | 879 case kMips64MaxD: |
872 __ max_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0), | 880 __ max_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0), |
873 i.InputDoubleRegister(1)); | 881 i.InputDoubleRegister(1)); |
874 break; | 882 break; |
875 case kMips64MinD: | 883 case kMips64MinD: |
876 __ min_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0), | 884 __ min_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0), |
877 i.InputDoubleRegister(1)); | 885 i.InputDoubleRegister(1)); |
878 break; | 886 break; |
879 case kMips64Float64RoundDown: { | 887 case kMips64Float64RoundDown: { |
880 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(floor_l_d, Floor); | 888 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(floor_l_d); |
| 889 break; |
| 890 } |
| 891 case kMips64Float32RoundDown: { |
| 892 ASSEMBLE_ROUND_FLOAT_TO_FLOAT(floor_w_s); |
881 break; | 893 break; |
882 } | 894 } |
883 case kMips64Float64RoundTruncate: { | 895 case kMips64Float64RoundTruncate: { |
884 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(trunc_l_d, Truncate); | 896 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(trunc_l_d); |
| 897 break; |
| 898 } |
| 899 case kMips64Float32RoundTruncate: { |
| 900 ASSEMBLE_ROUND_FLOAT_TO_FLOAT(trunc_w_s); |
885 break; | 901 break; |
886 } | 902 } |
887 case kMips64Float64RoundUp: { | 903 case kMips64Float64RoundUp: { |
888 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(ceil_l_d, Ceil); | 904 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(ceil_l_d); |
| 905 break; |
| 906 } |
| 907 case kMips64Float32RoundUp: { |
| 908 ASSEMBLE_ROUND_FLOAT_TO_FLOAT(ceil_w_s); |
889 break; | 909 break; |
890 } | 910 } |
891 case kMips64Float64RoundTiesEven: { | 911 case kMips64Float64RoundTiesEven: { |
892 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(round_l_d, TiesEven); | 912 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(round_l_d); |
| 913 break; |
| 914 } |
| 915 case kMips64Float32RoundTiesEven: { |
| 916 ASSEMBLE_ROUND_FLOAT_TO_FLOAT(round_w_s); |
893 break; | 917 break; |
894 } | 918 } |
895 case kMips64Float64Max: { | 919 case kMips64Float64Max: { |
896 // (b < a) ? a : b | 920 // (b < a) ? a : b |
897 if (kArchVariant == kMips64r6) { | 921 if (kArchVariant == kMips64r6) { |
898 __ cmp_d(OLT, i.OutputDoubleRegister(), i.InputDoubleRegister(1), | 922 __ cmp_d(OLT, i.OutputDoubleRegister(), i.InputDoubleRegister(1), |
899 i.InputDoubleRegister(0)); | 923 i.InputDoubleRegister(0)); |
900 __ sel_d(i.OutputDoubleRegister(), i.InputDoubleRegister(1), | 924 __ sel_d(i.OutputDoubleRegister(), i.InputDoubleRegister(1), |
901 i.InputDoubleRegister(0)); | 925 i.InputDoubleRegister(0)); |
902 } else { | 926 } else { |
(...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1728 padding_size -= v8::internal::Assembler::kInstrSize; | 1752 padding_size -= v8::internal::Assembler::kInstrSize; |
1729 } | 1753 } |
1730 } | 1754 } |
1731 } | 1755 } |
1732 | 1756 |
1733 #undef __ | 1757 #undef __ |
1734 | 1758 |
1735 } // namespace compiler | 1759 } // namespace compiler |
1736 } // namespace internal | 1760 } // namespace internal |
1737 } // namespace v8 | 1761 } // namespace v8 |
OLD | NEW |