diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Target/ARM/ARMInstrInfo.td | 5 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp | 39 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp | 31 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h | 5 | 
4 files changed, 75 insertions, 5 deletions
| diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td index 6ec78bc72ee..3e0691cbe9d 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -1582,8 +1582,9 @@ def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),                      (so_imm2part_2 imm:$RHS))>;  // 32-bit immediate using movw + movt. -// This is a single pseudo instruction to make it re-materializable. Remove -// when we can do generalized remat. +// This is a single pseudo instruction, the benefit is that it can be remat'd +// as a single unit instead of having to handle reg inputs. +// FIXME: Remove this when we can do generalized remat.  let isReMaterializable = 1 in  def MOVi32imm : AI1x2<(outs GPR:$dst), (ins i32imm:$src), Pseudo, IIC_iMOVi,                       "movw", " $dst, ${src:lo16}\n\tmovt${p} $dst, ${src:hi16}", diff --git a/llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp index f0be545d847..446287d1f38 100644 --- a/llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp +++ b/llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp @@ -1375,6 +1375,45 @@ void ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {      return;    } +  case ARM::MOVi2pieces: { // FIXME: Remove asmstring from td file. +    // This is a hack that lowers as a two instruction sequence. +    unsigned DstReg = MI->getOperand(0).getReg(); +    unsigned ImmVal = (unsigned)MI->getOperand(1).getImm(); + +    unsigned SOImmValV1 = ARM_AM::getSOImmTwoPartFirst(ImmVal); +    unsigned SOImmValV2 = ARM_AM::getSOImmTwoPartSecond(ImmVal); +     +    { +      MCInst TmpInst; +      TmpInst.setOpcode(ARM::MOVi); +      TmpInst.addOperand(MCOperand::CreateReg(DstReg)); +      TmpInst.addOperand(MCOperand::CreateImm(SOImmValV1)); +       +      // Predicate. +      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm())); +      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg())); +      printMCInst(&TmpInst); +      O << '\n'; +    } + +    { +      MCInst TmpInst; +      TmpInst.setOpcode(ARM::ORRri); +      TmpInst.addOperand(MCOperand::CreateReg(DstReg));     // dstreg +      TmpInst.addOperand(MCOperand::CreateReg(DstReg));     // inreg +      TmpInst.addOperand(MCOperand::CreateImm(SOImmValV2)); // so_imm +      // Predicate. +      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm())); +      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg())); +       +      TmpInst.addOperand(MCOperand::CreateReg(0));          // cc_out +      printMCInst(&TmpInst); +    } +    return;  +  } +      // FIXME: Also MOVi32imm. + +          }    MCInst TmpInst; diff --git a/llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp b/llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp index b227baec62a..abb0399fa45 100644 --- a/llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp +++ b/llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp @@ -79,6 +79,37 @@ void ARMInstPrinter::printSOImmOperand(const MCInst *MI, unsigned OpNum) {    printSOImm(O, MO.getImm(), VerboseAsm, &MAI);  } +/// printSOImm2PartOperand - SOImm is broken into two pieces using a 'mov' +/// followed by an 'orr' to materialize. +void ARMInstPrinter::printSOImm2PartOperand(const MCInst *MI, unsigned OpNum) { +  // FIXME: REMOVE this method. +  abort(); +} + +// so_reg is a 4-operand unit corresponding to register forms of the A5.1 +// "Addressing Mode 1 - Data-processing operands" forms.  This includes: +//    REG 0   0           - e.g. R5 +//    REG REG 0,SH_OPC    - e.g. R5, ROR R3 +//    REG 0   IMM,SH_OPC  - e.g. R5, LSL #3 +void ARMInstPrinter::printSORegOperand(const MCInst *MI, unsigned OpNum) { +  const MCOperand &MO1 = MI->getOperand(OpNum); +  const MCOperand &MO2 = MI->getOperand(OpNum+1); +  const MCOperand &MO3 = MI->getOperand(OpNum+2); +   +  O << getRegisterName(MO1.getReg()); +   +  // Print the shift opc. +  O << ", " +    << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm())) +    << ' '; +   +  if (MO2.getReg()) { +    O << getRegisterName(MO2.getReg()); +    assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0); +  } else { +    O << "#" << ARM_AM::getSORegOffset(MO3.getImm()); +  } +}  void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op) { diff --git a/llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h b/llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h index 41e59e9937c..99388e0d6c5 100644 --- a/llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h +++ b/llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h @@ -36,10 +36,9 @@ public:                      const char *Modifier = 0);    void printSOImmOperand(const MCInst *MI, unsigned OpNum); +  void printSOImm2PartOperand(const MCInst *MI, unsigned OpNum); -   -  void printSOImm2PartOperand(const MCInst *MI, unsigned OpNum) {} -  void printSORegOperand(const MCInst *MI, unsigned OpNum) {} +  void printSORegOperand(const MCInst *MI, unsigned OpNum);    void printAddrMode2Operand(const MCInst *MI, unsigned OpNum);    void printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum) {}    void printAddrMode3Operand(const MCInst *MI, unsigned OpNum) {} | 

