| 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/ast/scopes.h" | 5 #include "src/ast/scopes.h" |
| 6 #include "src/compiler/code-generator.h" | 6 #include "src/compiler/code-generator.h" |
| 7 #include "src/compiler/code-generator-impl.h" | 7 #include "src/compiler/code-generator-impl.h" |
| 8 #include "src/compiler/gap-resolver.h" | 8 #include "src/compiler/gap-resolver.h" |
| 9 #include "src/compiler/node-matchers.h" | 9 #include "src/compiler/node-matchers.h" |
| 10 #include "src/compiler/osr.h" | 10 #include "src/compiler/osr.h" |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 case kEqual: | 292 case kEqual: |
| 293 return eq; | 293 return eq; |
| 294 default: | 294 default: |
| 295 break; | 295 break; |
| 296 } | 296 } |
| 297 UNREACHABLE(); | 297 UNREACHABLE(); |
| 298 return kNoCondition; | 298 return kNoCondition; |
| 299 } | 299 } |
| 300 | 300 |
| 301 | 301 |
| 302 Condition FlagsConditionToConditionOvf(FlagsCondition condition) { | |
| 303 switch (condition) { | |
| 304 case kOverflow: | |
| 305 return lt; | |
| 306 case kNotOverflow: | |
| 307 return ge; | |
| 308 default: | |
| 309 break; | |
| 310 } | |
| 311 UNREACHABLE(); | |
| 312 return kNoCondition; | |
| 313 } | |
| 314 | |
| 315 FPUCondition FlagsConditionToConditionCmpFPU(bool& predicate, | 302 FPUCondition FlagsConditionToConditionCmpFPU(bool& predicate, |
| 316 FlagsCondition condition) { | 303 FlagsCondition condition) { |
| 317 switch (condition) { | 304 switch (condition) { |
| 318 case kEqual: | 305 case kEqual: |
| 319 predicate = true; | 306 predicate = true; |
| 320 return EQ; | 307 return EQ; |
| 321 case kNotEqual: | 308 case kNotEqual: |
| 322 predicate = false; | 309 predicate = false; |
| 323 return EQ; | 310 return EQ; |
| 324 case kUnsignedLessThan: | 311 case kUnsignedLessThan: |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 620 __ CheckPageFlag(object, scratch0, | 607 __ CheckPageFlag(object, scratch0, |
| 621 MemoryChunk::kPointersFromHereAreInterestingMask, ne, | 608 MemoryChunk::kPointersFromHereAreInterestingMask, ne, |
| 622 ool->entry()); | 609 ool->entry()); |
| 623 __ bind(ool->exit()); | 610 __ bind(ool->exit()); |
| 624 break; | 611 break; |
| 625 } | 612 } |
| 626 case kMipsAdd: | 613 case kMipsAdd: |
| 627 __ Addu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); | 614 __ Addu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); |
| 628 break; | 615 break; |
| 629 case kMipsAddOvf: | 616 case kMipsAddOvf: |
| 630 __ AdduAndCheckForOverflow(i.OutputRegister(), i.InputRegister(0), | 617 // Pseudo-instruction used for overflow/branch. No opcode emitted here. |
| 631 i.InputOperand(1), kCompareReg, kScratchReg); | |
| 632 break; | 618 break; |
| 633 case kMipsSub: | 619 case kMipsSub: |
| 634 __ Subu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); | 620 __ Subu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); |
| 635 break; | 621 break; |
| 636 case kMipsSubOvf: | 622 case kMipsSubOvf: |
| 637 __ SubuAndCheckForOverflow(i.OutputRegister(), i.InputRegister(0), | 623 // Pseudo-instruction used for overflow/branch. No opcode emitted here. |
| 638 i.InputOperand(1), kCompareReg, kScratchReg); | |
| 639 break; | 624 break; |
| 640 case kMipsMul: | 625 case kMipsMul: |
| 641 __ Mul(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); | 626 __ Mul(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); |
| 642 break; | 627 break; |
| 643 case kMipsMulHigh: | 628 case kMipsMulHigh: |
| 644 __ Mulh(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); | 629 __ Mulh(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); |
| 645 break; | 630 break; |
| 646 case kMipsMulHighU: | 631 case kMipsMulHighU: |
| 647 __ Mulhu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); | 632 __ Mulhu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); |
| 648 break; | 633 break; |
| (...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1102 // implemented differently than on the other arch's. The compare operations | 1087 // implemented differently than on the other arch's. The compare operations |
| 1103 // emit mips pseudo-instructions, which are handled here by branch | 1088 // emit mips pseudo-instructions, which are handled here by branch |
| 1104 // instructions that do the actual comparison. Essential that the input | 1089 // instructions that do the actual comparison. Essential that the input |
| 1105 // registers to compare pseudo-op are not modified before this branch op, as | 1090 // registers to compare pseudo-op are not modified before this branch op, as |
| 1106 // they are tested here. | 1091 // they are tested here. |
| 1107 | 1092 |
| 1108 if (instr->arch_opcode() == kMipsTst) { | 1093 if (instr->arch_opcode() == kMipsTst) { |
| 1109 cc = FlagsConditionToConditionTst(branch->condition); | 1094 cc = FlagsConditionToConditionTst(branch->condition); |
| 1110 __ And(at, i.InputRegister(0), i.InputOperand(1)); | 1095 __ And(at, i.InputRegister(0), i.InputOperand(1)); |
| 1111 __ Branch(tlabel, cc, at, Operand(zero_reg)); | 1096 __ Branch(tlabel, cc, at, Operand(zero_reg)); |
| 1112 } else if (instr->arch_opcode() == kMipsAddOvf || | 1097 } else if (instr->arch_opcode() == kMipsAddOvf) { |
| 1113 instr->arch_opcode() == kMipsSubOvf) { | 1098 switch (branch->condition) { |
| 1114 // kMipsAddOvf, SubOvf emit negative result to 'kCompareReg' on overflow. | 1099 case kOverflow: |
| 1115 cc = FlagsConditionToConditionOvf(branch->condition); | 1100 __ AddBranchOvf(i.OutputRegister(), i.InputRegister(0), |
| 1116 __ Branch(tlabel, cc, kCompareReg, Operand(zero_reg)); | 1101 i.InputOperand(1), tlabel, flabel); |
| 1102 break; |
| 1103 case kNotOverflow: |
| 1104 __ AddBranchOvf(i.OutputRegister(), i.InputRegister(0), |
| 1105 i.InputOperand(1), flabel, tlabel); |
| 1106 break; |
| 1107 default: |
| 1108 UNSUPPORTED_COND(kMipsAddOvf, branch->condition); |
| 1109 break; |
| 1110 } |
| 1111 } else if (instr->arch_opcode() == kMipsSubOvf) { |
| 1112 switch (branch->condition) { |
| 1113 case kOverflow: |
| 1114 __ SubBranchOvf(i.OutputRegister(), i.InputRegister(0), |
| 1115 i.InputOperand(1), tlabel, flabel); |
| 1116 break; |
| 1117 case kNotOverflow: |
| 1118 __ SubBranchOvf(i.OutputRegister(), i.InputRegister(0), |
| 1119 i.InputOperand(1), flabel, tlabel); |
| 1120 break; |
| 1121 default: |
| 1122 UNSUPPORTED_COND(kMipsAddOvf, branch->condition); |
| 1123 break; |
| 1124 } |
| 1117 } else if (instr->arch_opcode() == kMipsCmp) { | 1125 } else if (instr->arch_opcode() == kMipsCmp) { |
| 1118 cc = FlagsConditionToConditionCmp(branch->condition); | 1126 cc = FlagsConditionToConditionCmp(branch->condition); |
| 1119 __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1)); | 1127 __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1)); |
| 1120 } else if (instr->arch_opcode() == kMipsCmpS) { | 1128 } else if (instr->arch_opcode() == kMipsCmpS) { |
| 1121 if (!convertCondition(branch->condition, cc)) { | 1129 if (!convertCondition(branch->condition, cc)) { |
| 1122 UNSUPPORTED_COND(kMips64CmpS, branch->condition); | 1130 UNSUPPORTED_COND(kMips64CmpS, branch->condition); |
| 1123 } | 1131 } |
| 1124 FPURegister left = i.InputOrZeroSingleRegister(0); | 1132 FPURegister left = i.InputOrZeroSingleRegister(0); |
| 1125 FPURegister right = i.InputOrZeroSingleRegister(1); | 1133 FPURegister right = i.InputOrZeroSingleRegister(1); |
| 1126 if ((left.is(kDoubleRegZero) || right.is(kDoubleRegZero)) && | 1134 if ((left.is(kDoubleRegZero) || right.is(kDoubleRegZero)) && |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1173 cc = FlagsConditionToConditionTst(condition); | 1181 cc = FlagsConditionToConditionTst(condition); |
| 1174 __ And(kScratchReg, i.InputRegister(0), i.InputOperand(1)); | 1182 __ And(kScratchReg, i.InputRegister(0), i.InputOperand(1)); |
| 1175 __ Sltu(result, zero_reg, kScratchReg); | 1183 __ Sltu(result, zero_reg, kScratchReg); |
| 1176 if (cc == eq) { | 1184 if (cc == eq) { |
| 1177 // Sltu produces 0 for equality, invert the result. | 1185 // Sltu produces 0 for equality, invert the result. |
| 1178 __ xori(result, result, 1); | 1186 __ xori(result, result, 1); |
| 1179 } | 1187 } |
| 1180 return; | 1188 return; |
| 1181 } else if (instr->arch_opcode() == kMipsAddOvf || | 1189 } else if (instr->arch_opcode() == kMipsAddOvf || |
| 1182 instr->arch_opcode() == kMipsSubOvf) { | 1190 instr->arch_opcode() == kMipsSubOvf) { |
| 1183 // kMipsAddOvf, SubOvf emits negative result to 'kCompareReg' on overflow. | 1191 Label flabel, tlabel; |
| 1184 cc = FlagsConditionToConditionOvf(condition); | 1192 switch (instr->arch_opcode()) { |
| 1185 // Return 1 on overflow. | 1193 case kMipsAddOvf: |
| 1186 __ Slt(result, kCompareReg, Operand(zero_reg)); | 1194 __ AddBranchNoOvf(i.OutputRegister(), i.InputRegister(0), |
| 1187 if (cc == ge) // Invert result on not overflow. | 1195 i.InputOperand(1), &flabel); |
| 1188 __ xori(result, result, 1); | 1196 |
| 1189 return; | 1197 break; |
| 1198 case kMipsSubOvf: |
| 1199 __ SubBranchNoOvf(i.OutputRegister(), i.InputRegister(0), |
| 1200 i.InputOperand(1), &flabel); |
| 1201 break; |
| 1202 default: |
| 1203 UNREACHABLE(); |
| 1204 break; |
| 1205 } |
| 1206 __ li(result, 1); |
| 1207 __ Branch(&tlabel); |
| 1208 __ bind(&flabel); |
| 1209 __ li(result, 0); |
| 1210 __ bind(&tlabel); |
| 1190 } else if (instr->arch_opcode() == kMipsCmp) { | 1211 } else if (instr->arch_opcode() == kMipsCmp) { |
| 1191 cc = FlagsConditionToConditionCmp(condition); | 1212 cc = FlagsConditionToConditionCmp(condition); |
| 1192 switch (cc) { | 1213 switch (cc) { |
| 1193 case eq: | 1214 case eq: |
| 1194 case ne: { | 1215 case ne: { |
| 1195 Register left = i.InputRegister(0); | 1216 Register left = i.InputRegister(0); |
| 1196 Operand right = i.InputOperand(1); | 1217 Operand right = i.InputOperand(1); |
| 1197 Register select; | 1218 Register select; |
| 1198 if (instr->InputAt(1)->IsImmediate() && right.immediate() == 0) { | 1219 if (instr->InputAt(1)->IsImmediate() && right.immediate() == 0) { |
| 1199 // Pass left operand if right is zero. | 1220 // Pass left operand if right is zero. |
| (...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1638 padding_size -= v8::internal::Assembler::kInstrSize; | 1659 padding_size -= v8::internal::Assembler::kInstrSize; |
| 1639 } | 1660 } |
| 1640 } | 1661 } |
| 1641 } | 1662 } |
| 1642 | 1663 |
| 1643 #undef __ | 1664 #undef __ |
| 1644 | 1665 |
| 1645 } // namespace compiler | 1666 } // namespace compiler |
| 1646 } // namespace internal | 1667 } // namespace internal |
| 1647 } // namespace v8 | 1668 } // namespace v8 |
| OLD | NEW |