| 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/mips/macro-assembler-mips.h" | 9 #include "src/mips/macro-assembler-mips.h" |
| 10 #include "src/scopes.h" | 10 #include "src/scopes.h" |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 return lt; | 255 return lt; |
| 256 case kNotOverflow: | 256 case kNotOverflow: |
| 257 return ge; | 257 return ge; |
| 258 default: | 258 default: |
| 259 break; | 259 break; |
| 260 } | 260 } |
| 261 UNREACHABLE(); | 261 UNREACHABLE(); |
| 262 return kNoCondition; | 262 return kNoCondition; |
| 263 } | 263 } |
| 264 | 264 |
| 265 FPUCondition FlagsConditionToConditionCmpD(bool& predicate, | |
| 266 FlagsCondition condition) { | |
| 267 switch (condition) { | |
| 268 case kEqual: | |
| 269 predicate = true; | |
| 270 return EQ; | |
| 271 case kNotEqual: | |
| 272 predicate = false; | |
| 273 return EQ; | |
| 274 case kUnsignedLessThan: | |
| 275 predicate = true; | |
| 276 return OLT; | |
| 277 case kUnsignedLessThanOrEqual: | |
| 278 predicate = true; | |
| 279 return OLE; | |
| 280 case kUnorderedEqual: | |
| 281 case kUnorderedNotEqual: | |
| 282 predicate = true; | |
| 283 break; | |
| 284 default: | |
| 285 predicate = true; | |
| 286 break; | |
| 287 } | |
| 288 UNREACHABLE(); | |
| 289 return kNoFPUCondition; | |
| 290 } | |
| 291 | |
| 292 } // namespace | 265 } // namespace |
| 293 | 266 |
| 294 | 267 |
| 295 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr) \ | 268 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr) \ |
| 296 do { \ | 269 do { \ |
| 297 auto result = i.Output##width##Register(); \ | 270 auto result = i.Output##width##Register(); \ |
| 298 auto ool = new (zone()) OutOfLineLoad##width(this, result); \ | 271 auto ool = new (zone()) OutOfLineLoad##width(this, result); \ |
| 299 if (instr->InputAt(0)->IsRegister()) { \ | 272 if (instr->InputAt(0)->IsRegister()) { \ |
| 300 auto offset = i.InputRegister(0); \ | 273 auto offset = i.InputRegister(0); \ |
| 301 __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \ | 274 __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \ |
| (...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 810 Condition cc = kNoCondition; | 783 Condition cc = kNoCondition; |
| 811 | 784 |
| 812 // MIPS does not have condition code flags, so compare and branch are | 785 // MIPS does not have condition code flags, so compare and branch are |
| 813 // implemented differently than on the other arch's. The compare operations | 786 // implemented differently than on the other arch's. The compare operations |
| 814 // emit mips psuedo-instructions, which are checked and handled here. | 787 // emit mips psuedo-instructions, which are checked and handled here. |
| 815 | 788 |
| 816 // For materializations, we use delay slot to set the result true, and | 789 // For materializations, we use delay slot to set the result true, and |
| 817 // in the false case, where we fall thru the branch, we reset the result | 790 // in the false case, where we fall thru the branch, we reset the result |
| 818 // false. | 791 // false. |
| 819 | 792 |
| 793 // TODO(plind): Add CHECK() to ensure that test/cmp and this branch were |
| 794 // not separated by other instructions. |
| 820 if (instr->arch_opcode() == kMipsTst) { | 795 if (instr->arch_opcode() == kMipsTst) { |
| 821 cc = FlagsConditionToConditionTst(condition); | 796 cc = FlagsConditionToConditionTst(condition); |
| 822 __ And(at, i.InputRegister(0), i.InputOperand(1)); | 797 __ And(at, i.InputRegister(0), i.InputOperand(1)); |
| 823 __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(zero_reg)); | 798 __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(zero_reg)); |
| 824 __ li(result, Operand(1)); // In delay slot. | 799 __ li(result, Operand(1)); // In delay slot. |
| 825 | 800 |
| 826 } else if (instr->arch_opcode() == kMipsAddOvf || | 801 } else if (instr->arch_opcode() == kMipsAddOvf || |
| 827 instr->arch_opcode() == kMipsSubOvf) { | 802 instr->arch_opcode() == kMipsSubOvf) { |
| 828 // kMipsAddOvf, SubOvf emits negative result to 'kCompareReg' on overflow. | 803 // kMipsAddOvf, SubOvf emits negative result to 'kCompareReg' on overflow. |
| 829 cc = FlagsConditionToConditionOvf(condition); | 804 cc = FlagsConditionToConditionOvf(condition); |
| 830 __ Branch(USE_DELAY_SLOT, &done, cc, kCompareReg, Operand(zero_reg)); | 805 __ Branch(USE_DELAY_SLOT, &done, cc, kCompareReg, Operand(zero_reg)); |
| 831 __ li(result, Operand(1)); // In delay slot. | 806 __ li(result, Operand(1)); // In delay slot. |
| 832 | 807 |
| 808 |
| 833 } else if (instr->arch_opcode() == kMipsCmp) { | 809 } else if (instr->arch_opcode() == kMipsCmp) { |
| 834 Register left = i.InputRegister(0); | 810 Register left = i.InputRegister(0); |
| 835 Operand right = i.InputOperand(1); | 811 Operand right = i.InputOperand(1); |
| 836 cc = FlagsConditionToConditionCmp(condition); | 812 cc = FlagsConditionToConditionCmp(condition); |
| 837 __ Branch(USE_DELAY_SLOT, &done, cc, left, right); | 813 __ Branch(USE_DELAY_SLOT, &done, cc, left, right); |
| 838 __ li(result, Operand(1)); // In delay slot. | 814 __ li(result, Operand(1)); // In delay slot. |
| 839 | 815 |
| 840 } else if (instr->arch_opcode() == kMipsCmpD) { | 816 } else if (instr->arch_opcode() == kMipsCmpD) { |
| 841 FPURegister left = i.InputDoubleRegister(0); | 817 FPURegister left = i.InputDoubleRegister(0); |
| 842 FPURegister right = i.InputDoubleRegister(1); | 818 FPURegister right = i.InputDoubleRegister(1); |
| 819 // TODO(plind): Provide NaN-testing macro-asm function without need for |
| 820 // BranchF. |
| 821 FPURegister dummy1 = f0; |
| 822 FPURegister dummy2 = f2; |
| 823 switch (condition) { |
| 824 case kEqual: |
| 825 // TODO(plind): improve the NaN testing throughout this function. |
| 826 __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2); |
| 827 cc = eq; |
| 828 break; |
| 829 case kNotEqual: |
| 830 __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2); |
| 831 __ li(result, Operand(1)); // In delay slot - returns 1 on NaN. |
| 832 cc = ne; |
| 833 break; |
| 834 case kUnsignedLessThan: |
| 835 __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2); |
| 836 cc = lt; |
| 837 break; |
| 838 case kUnsignedGreaterThanOrEqual: |
| 839 __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2); |
| 840 __ li(result, Operand(1)); // In delay slot - returns 1 on NaN. |
| 841 cc = ge; |
| 842 break; |
| 843 case kUnsignedLessThanOrEqual: |
| 844 __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2); |
| 845 cc = le; |
| 846 break; |
| 847 case kUnsignedGreaterThan: |
| 848 __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2); |
| 849 __ li(result, Operand(1)); // In delay slot - returns 1 on NaN. |
| 850 cc = gt; |
| 851 break; |
| 852 default: |
| 853 UNSUPPORTED_COND(kMipsCmp, condition); |
| 854 break; |
| 855 } |
| 856 __ BranchF(USE_DELAY_SLOT, &done, NULL, cc, left, right); |
| 857 __ li(result, Operand(1)); // In delay slot - branch taken returns 1. |
| 858 // Fall-thru (branch not taken) returns 0. |
| 843 | 859 |
| 844 bool predicate; | |
| 845 FPUCondition cc = FlagsConditionToConditionCmpD(predicate, condition); | |
| 846 if (!IsMipsArchVariant(kMips32r6)) { | |
| 847 __ li(result, Operand(1)); | |
| 848 __ c(cc, D, left, right); | |
| 849 if (predicate) { | |
| 850 __ Movf(result, zero_reg); | |
| 851 } else { | |
| 852 __ Movt(result, zero_reg); | |
| 853 } | |
| 854 } else { | |
| 855 __ cmp(cc, L, kDoubleCompareReg, left, right); | |
| 856 __ mfc1(at, kDoubleCompareReg); | |
| 857 __ srl(result, at, 31); // Cmp returns all 1s for true. | |
| 858 if (!predicate) // Toggle result for not equal. | |
| 859 __ xori(result, result, 1); | |
| 860 } | |
| 861 return; | |
| 862 } else { | 860 } else { |
| 863 PrintF("AssembleArchBranch Unimplemented arch_opcode is : %d\n", | 861 PrintF("AssembleArchBranch Unimplemented arch_opcode is : %d\n", |
| 864 instr->arch_opcode()); | 862 instr->arch_opcode()); |
| 865 TRACE_UNIMPL(); | 863 TRACE_UNIMPL(); |
| 866 UNIMPLEMENTED(); | 864 UNIMPLEMENTED(); |
| 867 } | 865 } |
| 868 | 866 // Fallthru case is the false materialization. |
| 869 // Fallthrough case is the false materialization. | |
| 870 __ bind(&false_value); | 867 __ bind(&false_value); |
| 871 __ li(result, Operand(0)); | 868 __ li(result, Operand(0)); |
| 872 __ bind(&done); | 869 __ bind(&done); |
| 873 } | 870 } |
| 874 | 871 |
| 875 | 872 |
| 876 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) { | 873 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) { |
| 877 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( | 874 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( |
| 878 isolate(), deoptimization_id, Deoptimizer::LAZY); | 875 isolate(), deoptimization_id, Deoptimizer::LAZY); |
| 879 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); | 876 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1146 } | 1143 } |
| 1147 } | 1144 } |
| 1148 MarkLazyDeoptSite(); | 1145 MarkLazyDeoptSite(); |
| 1149 } | 1146 } |
| 1150 | 1147 |
| 1151 #undef __ | 1148 #undef __ |
| 1152 | 1149 |
| 1153 } // namespace compiler | 1150 } // namespace compiler |
| 1154 } // namespace internal | 1151 } // namespace internal |
| 1155 } // namespace v8 | 1152 } // namespace v8 |
| OLD | NEW |