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/node-properties-inl.h" | 9 #include "src/compiler/node-properties-inl.h" |
10 #include "src/mips/macro-assembler-mips.h" | 10 #include "src/mips/macro-assembler-mips.h" |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 __ srav(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); | 233 __ srav(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); |
234 } else { | 234 } else { |
235 int32_t imm = i.InputOperand(1).immediate(); | 235 int32_t imm = i.InputOperand(1).immediate(); |
236 __ sra(i.OutputRegister(), i.InputRegister(0), imm); | 236 __ sra(i.OutputRegister(), i.InputRegister(0), imm); |
237 } | 237 } |
238 break; | 238 break; |
239 case kMipsRor: | 239 case kMipsRor: |
240 __ Ror(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); | 240 __ Ror(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); |
241 break; | 241 break; |
242 case kMipsTst: | 242 case kMipsTst: |
243 // Psuedo-instruction used for tst/branch. | 243 // Pseudo-instruction used for tst/branch. No opcode emitted here. |
244 __ And(kCompareReg, i.InputRegister(0), i.InputOperand(1)); | |
245 break; | 244 break; |
246 case kMipsCmp: | 245 case kMipsCmp: |
247 // Psuedo-instruction used for cmp/branch. No opcode emitted here. | 246 // Pseudo-instruction used for cmp/branch. No opcode emitted here. |
248 break; | 247 break; |
249 case kMipsMov: | 248 case kMipsMov: |
250 // TODO(plind): Should we combine mov/li like this, or use separate instr? | 249 // TODO(plind): Should we combine mov/li like this, or use separate instr? |
251 // - Also see x64 ASSEMBLE_BINOP & RegisterOrOperandType | 250 // - Also see x64 ASSEMBLE_BINOP & RegisterOrOperandType |
252 if (HasRegisterInput(instr, 0)) { | 251 if (HasRegisterInput(instr, 0)) { |
253 __ mov(i.OutputRegister(), i.InputRegister(0)); | 252 __ mov(i.OutputRegister(), i.InputRegister(0)); |
254 } else { | 253 } else { |
255 __ li(i.OutputRegister(), i.InputOperand(0)); | 254 __ li(i.OutputRegister(), i.InputOperand(0)); |
256 } | 255 } |
257 break; | 256 break; |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 // MIPS does not have condition code flags, so compare and branch are | 410 // MIPS does not have condition code flags, so compare and branch are |
412 // implemented differently than on the other arch's. The compare operations | 411 // implemented differently than on the other arch's. The compare operations |
413 // emit mips psuedo-instructions, which are handled here by branch | 412 // emit mips psuedo-instructions, which are handled here by branch |
414 // instructions that do the actual comparison. Essential that the input | 413 // instructions that do the actual comparison. Essential that the input |
415 // registers to compare psuedo-op are not modified before this branch op, as | 414 // registers to compare psuedo-op are not modified before this branch op, as |
416 // they are tested here. | 415 // they are tested here. |
417 // TODO(plind): Add CHECK() to ensure that test/cmp and this branch were | 416 // TODO(plind): Add CHECK() to ensure that test/cmp and this branch were |
418 // not separated by other instructions. | 417 // not separated by other instructions. |
419 | 418 |
420 if (instr->arch_opcode() == kMipsTst) { | 419 if (instr->arch_opcode() == kMipsTst) { |
421 // The kMipsTst psuedo-instruction emits And to 'kCompareReg' register. | |
422 switch (condition) { | 420 switch (condition) { |
423 case kNotEqual: | 421 case kNotEqual: |
424 cc = ne; | 422 cc = ne; |
425 break; | 423 break; |
426 case kEqual: | 424 case kEqual: |
427 cc = eq; | 425 cc = eq; |
428 break; | 426 break; |
429 default: | 427 default: |
430 UNSUPPORTED_COND(kMipsTst, condition); | 428 UNSUPPORTED_COND(kMipsTst, condition); |
431 break; | 429 break; |
432 } | 430 } |
433 __ Branch(tlabel, cc, kCompareReg, Operand(zero_reg)); | 431 __ And(at, i.InputRegister(0), i.InputOperand(1)); |
| 432 __ Branch(tlabel, cc, at, Operand(zero_reg)); |
434 | 433 |
435 } else if (instr->arch_opcode() == kMipsAddOvf || | 434 } else if (instr->arch_opcode() == kMipsAddOvf || |
436 instr->arch_opcode() == kMipsSubOvf) { | 435 instr->arch_opcode() == kMipsSubOvf) { |
437 // kMipsAddOvf, SubOvf emit negative result to 'kCompareReg' on overflow. | 436 // kMipsAddOvf, SubOvf emit negative result to 'kCompareReg' on overflow. |
438 switch (condition) { | 437 switch (condition) { |
439 case kOverflow: | 438 case kOverflow: |
440 cc = lt; | 439 cc = lt; |
441 break; | 440 break; |
442 case kNotOverflow: | 441 case kNotOverflow: |
443 cc = ge; | 442 cc = ge; |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
550 // implemented differently than on the other arch's. The compare operations | 549 // implemented differently than on the other arch's. The compare operations |
551 // emit mips psuedo-instructions, which are checked and handled here. | 550 // emit mips psuedo-instructions, which are checked and handled here. |
552 | 551 |
553 // For materializations, we use delay slot to set the result true, and | 552 // For materializations, we use delay slot to set the result true, and |
554 // in the false case, where we fall thru the branch, we reset the result | 553 // in the false case, where we fall thru the branch, we reset the result |
555 // false. | 554 // false. |
556 | 555 |
557 // TODO(plind): Add CHECK() to ensure that test/cmp and this branch were | 556 // TODO(plind): Add CHECK() to ensure that test/cmp and this branch were |
558 // not separated by other instructions. | 557 // not separated by other instructions. |
559 if (instr->arch_opcode() == kMipsTst) { | 558 if (instr->arch_opcode() == kMipsTst) { |
560 // The kMipsTst psuedo-instruction emits And to 'kCompareReg' register. | |
561 switch (condition) { | 559 switch (condition) { |
562 case kNotEqual: | 560 case kNotEqual: |
563 cc = ne; | 561 cc = ne; |
564 break; | 562 break; |
565 case kEqual: | 563 case kEqual: |
566 cc = eq; | 564 cc = eq; |
567 break; | 565 break; |
568 default: | 566 default: |
569 UNSUPPORTED_COND(kMipsTst, condition); | 567 UNSUPPORTED_COND(kMipsTst, condition); |
570 break; | 568 break; |
571 } | 569 } |
572 __ Branch(USE_DELAY_SLOT, &done, cc, kCompareReg, Operand(zero_reg)); | 570 __ And(at, i.InputRegister(0), i.InputOperand(1)); |
| 571 __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(zero_reg)); |
573 __ li(result, Operand(1)); // In delay slot. | 572 __ li(result, Operand(1)); // In delay slot. |
574 | 573 |
575 } else if (instr->arch_opcode() == kMipsAddOvf || | 574 } else if (instr->arch_opcode() == kMipsAddOvf || |
576 instr->arch_opcode() == kMipsSubOvf) { | 575 instr->arch_opcode() == kMipsSubOvf) { |
577 // kMipsAddOvf, SubOvf emits negative result to 'kCompareReg' on overflow. | 576 // kMipsAddOvf, SubOvf emits negative result to 'kCompareReg' on overflow. |
578 switch (condition) { | 577 switch (condition) { |
579 case kOverflow: | 578 case kOverflow: |
580 cc = lt; | 579 cc = lt; |
581 break; | 580 break; |
582 case kNotOverflow: | 581 case kNotOverflow: |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
962 } | 961 } |
963 } | 962 } |
964 MarkLazyDeoptSite(); | 963 MarkLazyDeoptSite(); |
965 } | 964 } |
966 | 965 |
967 #undef __ | 966 #undef __ |
968 | 967 |
969 } // namespace compiler | 968 } // namespace compiler |
970 } // namespace internal | 969 } // namespace internal |
971 } // namespace v8 | 970 } // namespace v8 |
OLD | NEW |