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