diff options
| author | Daniel Dunbar <daniel@zuster.org> | 2010-05-19 06:20:44 +0000 | 
|---|---|---|
| committer | Daniel Dunbar <daniel@zuster.org> | 2010-05-19 06:20:44 +0000 | 
| commit | 597f17d5f1ec86dee1796ad92a66abd98f7bacec (patch) | |
| tree | 242ff40a16fb51a48e711899d87b1ab6e2e9da0e | |
| parent | 5fd1c9be2d6ade68a8cf7b38041ebf79624d315c (diff) | |
MC/X86: Lower MOV{8,16,32,64}{rm,mr} to fixed-register forms, as appropriate.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@104112 91177308-0d34-0410-b5e6-96231b3b80d8
| -rw-r--r-- | lib/Target/X86/AsmPrinter/X86MCInstLower.cpp | 59 | 
1 files changed, 50 insertions, 9 deletions
| diff --git a/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp b/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp index dc92f076d5..c2a42932f5 100644 --- a/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp +++ b/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp @@ -239,10 +239,44 @@ static void SimplifyShortImmForm(MCInst &Inst, unsigned Opcode) {      return;    // If so, rewrite the instruction. -  MCInst New; -  New.setOpcode(Opcode); -  New.addOperand(Inst.getOperand(ImmOp)); -  Inst = New; +  MCOperand Saved = Inst.getOperand(ImmOp); +  Inst = MCInst(); +  Inst.setOpcode(Opcode); +  Inst.addOperand(Saved); +} + +/// \brief Simplify things like MOV32rm to MOV32o32a. +static void SimplifyShortMoveForm(MCInst &Inst, unsigned Opcode) { +  bool IsStore = Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg(); +  unsigned AddrBase = IsStore; +  unsigned RegOp = IsStore ? 0 : 5; +  unsigned AddrOp = AddrBase + 3; +  assert(Inst.getNumOperands() == 6 && Inst.getOperand(RegOp).isReg() && +         Inst.getOperand(AddrBase + 0).isReg() && // base +         Inst.getOperand(AddrBase + 1).isImm() && // scale +         Inst.getOperand(AddrBase + 2).isReg() && // index register +         (Inst.getOperand(AddrOp).isExpr() ||     // address +          Inst.getOperand(AddrOp).isImm())&& +         Inst.getOperand(AddrBase + 4).isReg() && // segment +         "Unexpected instruction!"); + +  // Check whether the destination register can be fixed. +  unsigned Reg = Inst.getOperand(RegOp).getReg(); +  if (Reg != X86::AL && Reg != X86::AX && Reg != X86::EAX && Reg != X86::RAX) +    return; + +  // Check whether this is an absolute address. +  if (Inst.getOperand(AddrBase + 0).getReg() != 0 || +      Inst.getOperand(AddrBase + 2).getReg() != 0 || +      Inst.getOperand(AddrBase + 4).getReg() != 0 || +      Inst.getOperand(AddrBase + 1).getImm() != 1) +    return; + +  // If so, rewrite the instruction. +  MCOperand Saved = Inst.getOperand(AddrOp); +  Inst = MCInst(); +  Inst.setOpcode(Opcode); +  Inst.addOperand(Saved);  }  void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { @@ -370,12 +404,19 @@ void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {    // now.    //    // Note, we are currently not handling the following instructions: -  // MOV8ao8, MOV8o8a -  // MOV16ao16, MOV16o16a -  // MOV32ao32, MOV32o32a -  // MOV64ao64, MOV64ao8 -  // MOV64o64a, MOV64o8a +  // MOV64ao8, MOV64o8a    // XCHG16ar, XCHG32ar, XCHG64ar +  case X86::MOV8mr_NOREX: +  case X86::MOV8mr:     SimplifyShortMoveForm(OutMI, X86::MOV8ao8); break; +  case X86::MOV8rm_NOREX: +  case X86::MOV8rm:     SimplifyShortMoveForm(OutMI, X86::MOV8o8a); break; +  case X86::MOV16mr:    SimplifyShortMoveForm(OutMI, X86::MOV16ao16); break; +  case X86::MOV16rm:    SimplifyShortMoveForm(OutMI, X86::MOV16o16a); break; +  case X86::MOV32mr:    SimplifyShortMoveForm(OutMI, X86::MOV32ao32); break; +  case X86::MOV32rm:    SimplifyShortMoveForm(OutMI, X86::MOV32o32a); break; +  case X86::MOV64mr:    SimplifyShortMoveForm(OutMI, X86::MOV64ao64); break; +  case X86::MOV64rm:    SimplifyShortMoveForm(OutMI, X86::MOV64o64a); break; +    case X86::ADC8ri:     SimplifyShortImmForm(OutMI, X86::ADC8i8);    break;    case X86::ADC16ri:    SimplifyShortImmForm(OutMI, X86::ADC16i16);  break;    case X86::ADC32ri:    SimplifyShortImmForm(OutMI, X86::ADC32i32);  break; | 
