diff --git a/lib/Target/ARM/ARM.h b/lib/Target/ARM/ARM.h index 7e49ae21180..ca84634bed4 100644 --- a/lib/Target/ARM/ARM.h +++ b/lib/Target/ARM/ARM.h @@ -41,6 +41,16 @@ namespace llvm { }; } + namespace ARMShift { + enum ShiftTypes { + LSL, + LSR, + ASR, + ROR, + RRX + }; + } + static const char *ARMCondCodeToString(ARMCC::CondCodes CC) { switch (CC) { default: assert(0 && "Unknown condition code"); diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index 55591b9f91c..695dcf0735b 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -158,13 +158,38 @@ bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { } void ARMAsmPrinter::printAddrMode1(const MachineInstr *MI, int opNum) { - const MachineOperand &MO1 = MI->getOperand(opNum); + const MachineOperand &Arg = MI->getOperand(opNum); + const MachineOperand &Shift = MI->getOperand(opNum + 1); + const MachineOperand &ShiftType = MI->getOperand(opNum + 2); - if(MO1.isImmediate()) { + if(Arg.isImmediate()) { + assert(Shift.getImmedValue() == 0); printOperand(MI, opNum); } else { - assert(MO1.isRegister()); + assert(Arg.isRegister()); printOperand(MI, opNum); + if(Shift.isRegister() || Shift.getImmedValue() != 0) { + const char *s = NULL; + switch(ShiftType.getImmedValue()) { + case ARMShift::LSL: + s = ", lsl "; + break; + case ARMShift::LSR: + s = ", lsr "; + break; + case ARMShift::ASR: + s = ", asr "; + break; + case ARMShift::ROR: + s = ", ror "; + break; + case ARMShift::RRX: + s = ", rrx "; + break; + } + O << s; + printOperand(MI, opNum + 1); + } } } diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index 8181e9c17f3..7597a316adc 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -445,7 +445,8 @@ public: SDNode *Select(SDOperand Op); virtual void InstructionSelectBasicBlock(SelectionDAG &DAG); bool SelectAddrRegImm(SDOperand N, SDOperand &Offset, SDOperand &Base); - bool SelectAddrMode1(SDOperand N, SDOperand &Arg); + bool SelectAddrMode1(SDOperand N, SDOperand &Arg, SDOperand &Shift, + SDOperand &ShiftType); // Include the pieces autogenerated from the target description. #include "ARMGenDAGISel.inc" @@ -480,17 +481,38 @@ static bool isInt12Immediate(SDOperand Op, short &Imm) { } bool ARMDAGToDAGISel::SelectAddrMode1(SDOperand N, - SDOperand &Arg) { + SDOperand &Arg, + SDOperand &Shift, + SDOperand &ShiftType) { switch(N.getOpcode()) { case ISD::Constant: { //TODO:check that we have a valid constant int32_t t = cast(N)->getValue(); - Arg = CurDAG->getTargetConstant(t, MVT::i32); + Arg = CurDAG->getTargetConstant(t, MVT::i32); + Shift = CurDAG->getTargetConstant(0, MVT::i32); + ShiftType = CurDAG->getTargetConstant(ARMShift::LSL, MVT::i32); return true; } + case ISD::SRA: + Arg = N.getOperand(0); + Shift = N.getOperand(1); + ShiftType = CurDAG->getTargetConstant(ARMShift::ASR, MVT::i32); + return true; + case ISD::SRL: + Arg = N.getOperand(0); + Shift = N.getOperand(1); + ShiftType = CurDAG->getTargetConstant(ARMShift::LSR, MVT::i32); + return true; + case ISD::SHL: + Arg = N.getOperand(0); + Shift = N.getOperand(1); + ShiftType = CurDAG->getTargetConstant(ARMShift::LSL, MVT::i32); + return true; } - Arg = N; + Arg = N; + Shift = CurDAG->getTargetConstant(0, MVT::i32); + ShiftType = CurDAG->getTargetConstant(ARMShift::LSL, MVT::i32); return true; } diff --git a/lib/Target/ARM/ARMInstrInfo.cpp b/lib/Target/ARM/ARMInstrInfo.cpp index da1479c8e53..810c254f9c0 100644 --- a/lib/Target/ARM/ARMInstrInfo.cpp +++ b/lib/Target/ARM/ARMInstrInfo.cpp @@ -33,15 +33,18 @@ bool ARMInstrInfo::isMoveInstr(const MachineInstr &MI, unsigned &SrcReg, unsigned &DstReg) const { MachineOpCode oc = MI.getOpcode(); switch (oc) { - case ARM::MOV: - assert(MI.getNumOperands() == 2 && + case ARM::MOV: { + assert(MI.getNumOperands() == 4 && MI.getOperand(0).isRegister() && "Invalid ARM MOV instruction"); - if (MI.getOperand(1).isRegister()) { + const MachineOperand &Arg = MI.getOperand(1); + const MachineOperand &Shift = MI.getOperand(2); + if (Arg.isRegister() && Shift.isImmediate() && Shift.getImmedValue() == 0) { SrcReg = MI.getOperand(1).getReg(); DstReg = MI.getOperand(0).getReg(); return true; } } + } return false; } diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index ecbe48b4d06..50f4650fdfe 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -15,8 +15,8 @@ // Address operands def op_addr_mode1 : Operand { let PrintMethod = "printAddrMode1"; - let NumMIOperands = 1; - let MIOperandInfo = (ops ptr_rc); + let NumMIOperands = 3; + let MIOperandInfo = (ops ptr_rc, ptr_rc, i32imm); } def memri : Operand { @@ -27,7 +27,7 @@ def memri : Operand { // Define ARM specific addressing mode. //Addressing Mode 1: data processing operands -def addr_mode1 : ComplexPattern; +def addr_mode1 : ComplexPattern; //register plus/minus 12 bit offset def iaddr : ComplexPattern; @@ -119,21 +119,6 @@ def AND : InstARM<(ops IntRegs:$dst, IntRegs:$a, op_addr_mode1:$b), "and $dst, $a, $b", [(set IntRegs:$dst, (and IntRegs:$a, addr_mode1:$b))]>; -// All arm data processing instructions have a shift. Maybe we don't have -// to implement this -def SHL : InstARM<(ops IntRegs:$dst, IntRegs:$a, IntRegs:$b), - "mov $dst, $a, lsl $b", - [(set IntRegs:$dst, (shl IntRegs:$a, IntRegs:$b))]>; - -def SRA : InstARM<(ops IntRegs:$dst, IntRegs:$a, IntRegs:$b), - "mov $dst, $a, asr $b", - [(set IntRegs:$dst, (sra IntRegs:$a, IntRegs:$b))]>; - -def SRL : InstARM<(ops IntRegs:$dst, IntRegs:$a, IntRegs:$b), - "mov $dst, $a, lsr $b", - [(set IntRegs:$dst, (srl IntRegs:$a, IntRegs:$b))]>; - - def EOR : InstARM<(ops IntRegs:$dst, IntRegs:$a, op_addr_mode1:$b), "eor $dst, $a, $b", [(set IntRegs:$dst, (xor IntRegs:$a, addr_mode1:$b))]>; diff --git a/lib/Target/ARM/ARMRegisterInfo.cpp b/lib/Target/ARM/ARMRegisterInfo.cpp index d5f6caaa4ce..1b0f3fd8e54 100644 --- a/lib/Target/ARM/ARMRegisterInfo.cpp +++ b/lib/Target/ARM/ARMRegisterInfo.cpp @@ -48,7 +48,8 @@ void ARMRegisterInfo::copyRegToReg(MachineBasicBlock &MBB, unsigned DestReg, unsigned SrcReg, const TargetRegisterClass *RC) const { assert (RC == ARM::IntRegsRegisterClass); - BuildMI(MBB, I, ARM::MOV, 1, DestReg).addReg(SrcReg); + BuildMI(MBB, I, ARM::MOV, 3, DestReg).addReg(SrcReg).addImm(0) + .addImm(ARMShift::LSL); } MachineInstr *ARMRegisterInfo::foldMemoryOperand(MachineInstr* MI, @@ -114,7 +115,8 @@ ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const { // Insert a set of r12 with the full address // r12 = r13 + offset MachineBasicBlock *MBB2 = MI.getParent(); - BuildMI(*MBB2, II, ARM::ADD, 2, ARM::R12).addReg(ARM::R13).addImm(Offset); + BuildMI(*MBB2, II, ARM::ADD, 4, ARM::R12).addReg(ARM::R13).addImm(Offset) + .addImm(0).addImm(ARMShift::LSL); // Replace the FrameIndex with r12 MI.getOperand(FrameIdx).ChangeToRegister(ARM::R12, false); @@ -140,7 +142,8 @@ void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const { MFI->setStackSize(NumBytes); //sub sp, sp, #NumBytes - BuildMI(MBB, MBBI, ARM::SUB, 2, ARM::R13).addReg(ARM::R13).addImm(NumBytes); + BuildMI(MBB, MBBI, ARM::SUB, 4, ARM::R13).addReg(ARM::R13).addImm(NumBytes) + .addImm(0).addImm(ARMShift::LSL); } void ARMRegisterInfo::emitEpilogue(MachineFunction &MF, @@ -153,7 +156,8 @@ void ARMRegisterInfo::emitEpilogue(MachineFunction &MF, int NumBytes = (int) MFI->getStackSize(); //add sp, sp, #NumBytes - BuildMI(MBB, MBBI, ARM::ADD, 2, ARM::R13).addReg(ARM::R13).addImm(NumBytes); + BuildMI(MBB, MBBI, ARM::ADD, 4, ARM::R13).addReg(ARM::R13).addImm(NumBytes) + .addImm(0).addImm(ARMShift::LSL); } unsigned ARMRegisterInfo::getRARegister() const {