diff options
-rw-r--r-- | lib/Target/ARM/ARMAsmPrinter.cpp | 14 | ||||
-rw-r--r-- | lib/Target/ARM/ARMCodeEmitter.cpp | 4 | ||||
-rw-r--r-- | lib/Target/ARM/ARMISelDAGToDAG.cpp | 142 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrThumb.td | 188 | ||||
-rw-r--r-- | lib/Target/ARM/ARMMCCodeEmitter.cpp | 40 | ||||
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 30 | ||||
-rw-r--r-- | lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp | 54 | ||||
-rw-r--r-- | lib/Target/ARM/InstPrinter/ARMInstPrinter.h | 16 | ||||
-rw-r--r-- | lib/Target/ARM/Thumb1RegisterInfo.cpp | 11 | ||||
-rw-r--r-- | lib/Target/ARM/Thumb2SizeReduction.cpp | 65 | ||||
-rw-r--r-- | utils/TableGen/EDEmitter.cpp | 14 |
11 files changed, 348 insertions, 230 deletions
diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index b2111674dd..0ba7b40177 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -1129,13 +1129,12 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { } { MCInst TmpInst; - TmpInst.setOpcode(ARM::tSTR); + TmpInst.setOpcode(ARM::tSTRi); TmpInst.addOperand(MCOperand::CreateReg(ValReg)); TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); // The offset immediate is #4. The operand value is scaled by 4 for the // tSTR instruction. TmpInst.addOperand(MCOperand::CreateImm(1)); - TmpInst.addOperand(MCOperand::CreateReg(0)); // Predicate. TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); TmpInst.addOperand(MCOperand::CreateReg(0)); @@ -1312,13 +1311,12 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { unsigned ScratchReg = MI->getOperand(1).getReg(); { MCInst TmpInst; - TmpInst.setOpcode(ARM::tLDR); + TmpInst.setOpcode(ARM::tLDRi); TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); // The offset immediate is #8. The operand value is scaled by 4 for the - // tSTR instruction. + // tLDR instruction. TmpInst.addOperand(MCOperand::CreateImm(2)); - TmpInst.addOperand(MCOperand::CreateReg(0)); // Predicate. TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); TmpInst.addOperand(MCOperand::CreateReg(0)); @@ -1336,11 +1334,10 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { } { MCInst TmpInst; - TmpInst.setOpcode(ARM::tLDR); + TmpInst.setOpcode(ARM::tLDRi); TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); TmpInst.addOperand(MCOperand::CreateImm(1)); - TmpInst.addOperand(MCOperand::CreateReg(0)); // Predicate. TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); TmpInst.addOperand(MCOperand::CreateReg(0)); @@ -1348,10 +1345,9 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { } { MCInst TmpInst; - TmpInst.setOpcode(ARM::tLDR); + TmpInst.setOpcode(ARM::tLDRr); TmpInst.addOperand(MCOperand::CreateReg(ARM::R7)); TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); - TmpInst.addOperand(MCOperand::CreateImm(0)); TmpInst.addOperand(MCOperand::CreateReg(0)); // Predicate. TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index 5e302ae281..0c403a9a05 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -193,7 +193,7 @@ namespace { const { return 0; } unsigned getSORegOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } - unsigned getTAddrModeRegRegOpValue(const MachineInstr &MI, unsigned Op) + unsigned getThumbAddrModeRegRegOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } unsigned getT2AddrModeImm12OpValue(const MachineInstr &MI, unsigned Op) const { return 0; } @@ -265,6 +265,8 @@ namespace { const { return 0; } uint32_t getAddrModeSOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } + uint32_t getAddrModeISOpValue(const MachineInstr &MI, unsigned Op) + const { return 0; } uint32_t getAddrModePCOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } uint32_t getAddrMode5OpValue(const MachineInstr &MI, unsigned Op) const { diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index f96f68fa16..476fe6efac 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -130,18 +130,24 @@ public: bool SelectAddrModePC(SDValue N, SDValue &Offset, SDValue &Label); + // Thumb Addressing Modes: bool SelectThumbAddrModeRR(SDValue N, SDValue &Base, SDValue &Offset); - bool SelectThumbAddrModeRI5(SDValue N, unsigned Scale, - SDValue &Base, SDValue &OffImm, - SDValue &Offset); - bool SelectThumbAddrModeS1(SDValue N, SDValue &Base, - SDValue &OffImm, SDValue &Offset); - bool SelectThumbAddrModeS2(SDValue N, SDValue &Base, - SDValue &OffImm, SDValue &Offset); - bool SelectThumbAddrModeS4(SDValue N, SDValue &Base, - SDValue &OffImm, SDValue &Offset); + bool SelectThumbAddrModeRI(SDValue N, SDValue &Base, SDValue &Offset, + unsigned Scale); + bool SelectThumbAddrModeRI5S1(SDValue N, SDValue &Base, SDValue &Offset); + bool SelectThumbAddrModeRI5S2(SDValue N, SDValue &Base, SDValue &Offset); + bool SelectThumbAddrModeRI5S4(SDValue N, SDValue &Base, SDValue &Offset); + bool SelectThumbAddrModeImm5S(SDValue N, unsigned Scale, SDValue &Base, + SDValue &OffImm); + bool SelectThumbAddrModeImm5S1(SDValue N, SDValue &Base, + SDValue &OffImm); + bool SelectThumbAddrModeImm5S2(SDValue N, SDValue &Base, + SDValue &OffImm); + bool SelectThumbAddrModeImm5S4(SDValue N, SDValue &Base, + SDValue &OffImm); bool SelectThumbAddrModeSP(SDValue N, SDValue &Base, SDValue &OffImm); + // Thumb 2 Addressing Modes: bool SelectT2ShifterOperandReg(SDValue N, SDValue &BaseReg, SDValue &Opc); bool SelectT2AddrModeImm12(SDValue N, SDValue &Base, SDValue &OffImm); @@ -872,9 +878,16 @@ bool ARMDAGToDAGISel::SelectAddrModePC(SDValue N, MVT::i32); return true; } + return false; } + +//===----------------------------------------------------------------------===// +// Thumb Addressing Modes +//===----------------------------------------------------------------------===// + + bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDValue N, SDValue &Base, SDValue &Offset){ // FIXME dl should come from the parent load or store, not the address @@ -893,13 +906,13 @@ bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDValue N, } bool -ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDValue N, - unsigned Scale, SDValue &Base, - SDValue &OffImm, SDValue &Offset) { +ARMDAGToDAGISel::SelectThumbAddrModeRI(SDValue N, SDValue &Base, + SDValue &Offset, unsigned Scale) { if (Scale == 4) { SDValue TmpBase, TmpOffImm; if (SelectThumbAddrModeSP(N, TmpBase, TmpOffImm)) return false; // We want to select tLDRspi / tSTRspi instead. + if (N.getOpcode() == ARMISD::Wrapper && N.getOperand(0).getOpcode() == ISD::TargetConstantPool) return false; // We want to select tLDRpci instead. @@ -907,14 +920,13 @@ ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDValue N, if (N.getOpcode() != ISD::ADD) { if (N.getOpcode() == ARMISD::Wrapper && - !(Subtarget->useMovt() && - N.getOperand(0).getOpcode() == ISD::TargetGlobalAddress)) { + (!Subtarget->useMovt() || + N.getOperand(0).getOpcode() != ISD::TargetGlobalAddress)) Base = N.getOperand(0); - } else + else Base = N; Offset = CurDAG->getRegister(0, MVT::i32); - OffImm = CurDAG->getTargetConstant(0, MVT::i32); return true; } @@ -925,6 +937,68 @@ ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDValue N, (RHSR && RHSR->getReg() == ARM::SP)) { Base = N; Offset = CurDAG->getRegister(0, MVT::i32); + return true; + } + + if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { + int RHSC = (int)RHS->getZExtValue(); + + if ((RHSC & (Scale - 1)) == 0) { // The constant is implicitly multiplied. + RHSC /= Scale; + + if (RHSC >= 0 && RHSC < 32) + return false; + } + } + + Base = N.getOperand(0); + Offset = N.getOperand(1); + return true; +} + +bool +ARMDAGToDAGISel::SelectThumbAddrModeRI5S1(SDValue N, + SDValue &Base, + SDValue &Offset) { + return SelectThumbAddrModeRI(N, Base, Offset, 1); +} + +bool +ARMDAGToDAGISel::SelectThumbAddrModeRI5S2(SDValue N, + SDValue &Base, + SDValue &Offset) { + return SelectThumbAddrModeRI(N, Base, Offset, 2); +} + +bool +ARMDAGToDAGISel::SelectThumbAddrModeRI5S4(SDValue N, + SDValue &Base, + SDValue &Offset) { + return SelectThumbAddrModeRI(N, Base, Offset, 4); +} + +bool +ARMDAGToDAGISel::SelectThumbAddrModeImm5S(SDValue N, unsigned Scale, + SDValue &Base, SDValue &OffImm) { + if (Scale == 4) { + SDValue TmpBase, TmpOffImm; + if (SelectThumbAddrModeSP(N, TmpBase, TmpOffImm)) + return false; // We want to select tLDRspi / tSTRspi instead. + + if (N.getOpcode() == ARMISD::Wrapper && + N.getOperand(0).getOpcode() == ISD::TargetConstantPool) + return false; // We want to select tLDRpci instead. + } + + if (N.getOpcode() != ISD::ADD) { + if (N.getOpcode() == ARMISD::Wrapper && + !(Subtarget->useMovt() && + N.getOperand(0).getOpcode() == ISD::TargetGlobalAddress)) { + Base = N.getOperand(0); + } else { + Base = N; + } + OffImm = CurDAG->getTargetConstant(0, MVT::i32); return true; } @@ -932,11 +1006,12 @@ ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDValue N, // If the RHS is + imm5 * scale, fold into addr mode. if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { int RHSC = (int)RHS->getZExtValue(); - if ((RHSC & (Scale-1)) == 0) { // The constant is implicitly multiplied. + + if ((RHSC & (Scale - 1)) == 0) { // The constant is implicitly multiplied. RHSC /= Scale; + if (RHSC >= 0 && RHSC < 32) { Base = N.getOperand(0); - Offset = CurDAG->getRegister(0, MVT::i32); OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); return true; } @@ -944,27 +1019,26 @@ ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDValue N, } Base = N.getOperand(0); - Offset = N.getOperand(1); OffImm = CurDAG->getTargetConstant(0, MVT::i32); return true; } -bool ARMDAGToDAGISel::SelectThumbAddrModeS1(SDValue N, - SDValue &Base, SDValue &OffImm, - SDValue &Offset) { - return SelectThumbAddrModeRI5(N, 1, Base, OffImm, Offset); +bool +ARMDAGToDAGISel::SelectThumbAddrModeImm5S4(SDValue N, SDValue &Base, + SDValue &OffImm) { + return SelectThumbAddrModeImm5S(N, 4, Base, OffImm); } -bool ARMDAGToDAGISel::SelectThumbAddrModeS2(SDValue N, - SDValue &Base, SDValue &OffImm, - SDValue &Offset) { - return SelectThumbAddrModeRI5(N, 2, Base, OffImm, Offset); +bool +ARMDAGToDAGISel::SelectThumbAddrModeImm5S2(SDValue N, SDValue &Base, + SDValue &OffImm) { + return SelectThumbAddrModeImm5S(N, 2, Base, OffImm); } -bool ARMDAGToDAGISel::SelectThumbAddrModeS4(SDValue N, - SDValue &Base, SDValue &OffImm, - SDValue &Offset) { - return SelectThumbAddrModeRI5(N, 4, Base, OffImm, Offset); +bool +ARMDAGToDAGISel::SelectThumbAddrModeImm5S1(SDValue N, SDValue &Base, + SDValue &OffImm) { + return SelectThumbAddrModeImm5S(N, 1, Base, OffImm); } bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDValue N, @@ -1003,6 +1077,12 @@ bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDValue N, return false; } + +//===----------------------------------------------------------------------===// +// Thumb 2 Addressing Modes +//===----------------------------------------------------------------------===// + + bool ARMDAGToDAGISel::SelectT2ShifterOperandReg(SDValue N, SDValue &BaseReg, SDValue &Opc) { if (DisableShifterOp) diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index c119291011..2d416ebc5a 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -94,8 +94,13 @@ def t_blxtarget : Operand<i32> { let EncoderMethod = "getThumbBLXTargetOpValue"; } -def MemModeThumbAsmOperand : AsmOperandClass { - let Name = "MemModeThumb"; +def MemModeRegThumbAsmOperand : AsmOperandClass { + let Name = "MemModeRegThumb"; + let SuperClasses = []; +} + +def MemModeImmThumbAsmOperand : AsmOperandClass { + let Name = "MemModeImmThumb"; let SuperClasses = []; } @@ -103,42 +108,64 @@ def MemModeThumbAsmOperand : AsmOperandClass { // def t_addrmode_rr : Operand<i32>, ComplexPattern<i32, 2, "SelectThumbAddrModeRR", []> { - let EncoderMethod = "getTAddrModeRegRegOpValue"; + let EncoderMethod = "getThumbAddrModeRegRegOpValue"; + let PrintMethod = "printThumbAddrModeRROperand"; + let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg); +} + +// t_addrmode_rrs := reg + reg +// +def t_addrmode_rrs1 : Operand<i32>, + ComplexPattern<i32, 2, "SelectThumbAddrModeRI5S1", []> { + let EncoderMethod = "getThumbAddrModeRegRegOpValue"; let PrintMethod = "printThumbAddrModeRROperand"; let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg); + let ParserMatchClass = MemModeRegThumbAsmOperand; } -// t_addrmode_s4 := reg + reg -// reg + imm5 * 4 +def t_addrmode_rrs2 : Operand<i32>, + ComplexPattern<i32, 2, "SelectThumbAddrModeRI5S2", []> { + let EncoderMethod = "getThumbAddrModeRegRegOpValue"; + let PrintMethod = "printThumbAddrModeRROperand"; + let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg); + let ParserMatchClass = MemModeRegThumbAsmOperand; +} +def t_addrmode_rrs4 : Operand<i32>, + ComplexPattern<i32, 2, "SelectThumbAddrModeRI5S4", []> { + let EncoderMethod = "getThumbAddrModeRegRegOpValue"; + let PrintMethod = "printThumbAddrModeRROperand"; + let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg); + let ParserMatchClass = MemModeRegThumbAsmOperand; +} + +// t_addrmode_is4 := reg + imm5 * 4 // -def t_addrmode_s4 : Operand<i32>, - ComplexPattern<i32, 3, "SelectThumbAddrModeS4", []> { - let EncoderMethod = "getAddrModeSOpValue"; - let PrintMethod = "printThumbAddrModeS4Operand"; - let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg); - let ParserMatchClass = MemModeThumbAsmOperand; +def t_addrmode_is4 : Operand<i32>, + ComplexPattern<i32, 2, "SelectThumbAddrModeImm5S4", []> { + let EncoderMethod = "getAddrModeISOpValue"; + let PrintMethod = "printThumbAddrModeImm5S4Operand"; + let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm); + let ParserMatchClass = MemModeImmThumbAsmOperand; } -// t_addrmode_s2 := reg + reg -// reg + imm5 * 2 +// t_addrmode_is2 := reg + imm5 * 2 // -def t_addrmode_s2 : Operand<i32>, - ComplexPattern<i32, 3, "SelectThumbAddrModeS2", []> { - let EncoderMethod = "getAddrModeSOpValue"; - let PrintMethod = "printThumbAddrModeS2Operand"; - let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg); - let ParserMatchClass = MemModeThumbAsmOperand; +def t_addrmode_is2 : Operand<i32>, + ComplexPattern<i32, 2, "SelectThumbAddrModeImm5S2", []> { + let EncoderMethod = "getAddrModeISOpValue"; + let PrintMethod = "printThumbAddrModeImm5S2Operand"; + let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm); + let ParserMatchClass = MemModeImmThumbAsmOperand; } -// t_addrmode_s1 := reg + reg -// reg + imm5 +// t_addrmode_is1 := reg + imm5 // -def t_addrmode_s1 : Operand<i32>, - ComplexPattern<i32, 3, "SelectThumbAddrModeS1", []> { - let EncoderMethod = "getAddrModeSOpValue"; - let PrintMethod = "printThumbAddrModeS1Operand"; - let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg); - let ParserMatchClass = MemModeThumbAsmOperand; +def t_addrmode_is1 : Operand<i32>, + ComplexPattern<i32, 2, "SelectThumbAddrModeImm5S1", []> { + let EncoderMethod = "getAddrModeISOpValue"; + let PrintMethod = "printThumbAddrModeImm5S1Operand"; + let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm); + let ParserMatchClass = MemModeImmThumbAsmOperand; } // t_addrmode_sp := sp + imm8 * 4 @@ -148,14 +175,14 @@ def t_addrmode_sp : Operand<i32>, let EncoderMethod = "getAddrModeThumbSPOpValue"; let PrintMethod = "printThumbAddrModeSPOperand"; let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); - let ParserMatchClass = MemModeThumbAsmOperand; + let ParserMatchClass = MemModeImmThumbAsmOperand; } // t_addrmode_pc := <label> => pc + imm8 * 4 // def t_addrmode_pc : Operand<i32> { let EncoderMethod = "getAddrModePCOpValue"; - let ParserMatchClass = MemModeThumbAsmOperand; + let ParserMatchClass = MemModeImmThumbAsmOperand; } //===----------------------------------------------------------------------===// @@ -580,41 +607,41 @@ def tTRAP : TI<(outs), (ins), IIC_Br, // let canFoldAsLoad = 1, isReMaterializable = 1 in -def tLDR : // A8.6.60 - T1pILdStEncode<0b100, (outs tGPR:$Rt), (ins t_addrmode_s4:$addr), +def tLDRr : // A8.6.60 + T1pILdStEncode<0b100, (outs tGPR:$Rt), (ins t_addrmode_rrs4:$addr), AddrModeT1_4, IIC_iLoad_r, "ldr", "\t$Rt, $addr", - [(set tGPR:$Rt, (load t_addrmode_s4:$addr))]>; + [(set tGPR:$Rt, (load t_addrmode_rrs4:$addr))]>; def tLDRi : // A8.6.57 - T1pILdStEncodeImm<0b0110, 1, (outs tGPR:$Rt), (ins t_addrmode_s4:$addr), + T1pILdStEncodeImm<0b0110, 1, (outs tGPR:$Rt), (ins t_addrmode_is4:$addr), AddrModeT1_4, IIC_iLoad_r, "ldr", "\t$Rt, $addr", - []>; + [(set tGPR:$Rt, (load t_addrmode_is4:$addr))]>; -def tLDRB : // A8.6.64 - T1pILdStEncode<0b110, (outs tGPR:$Rt), (ins t_addrmode_s1:$addr), +def tLDRBr : // A8.6.64 + T1pILdStEncode<0b110, (outs tGPR:$Rt), (ins t_addrmode_rrs1:$addr), AddrModeT1_1, IIC_iLoad_bh_r, "ldrb", "\t$Rt, $addr", - [(set tGPR:$Rt, (zextloadi8 t_addrmode_s1:$addr))]>; + [(set tGPR:$Rt, (zextloadi8 t_addrmode_rrs1:$addr))]>; def tLDRBi : // A8.6.61 - T1pILdStEncodeImm<0b0111, 1, (outs tGPR:$Rt), (ins t_addrmode_s1:$addr), + T1pILdStEncodeImm<0b0111, 1, (outs tGPR:$Rt), (ins t_addrmode_is1:$addr), AddrModeT1_1, IIC_iLoad_bh_r, "ldrb", "\t$Rt, $addr", - []>; + [(set tGPR:$Rt, (zextloadi8 t_addrmode_is1:$addr))]>; -def tLDRH : // A8.6.76 - T1pILdStEncode<0b101, (outs tGPR:$dst), (ins t_addrmode_s2:$addr), +def tLDRHr : // A8.6.76 + T1pILdStEncode<0b101, (outs tGPR:$Rt), (ins t_addrmode_rrs2:$addr), AddrModeT1_2, IIC_iLoad_bh_r, - "ldrh", "\t$dst, $addr", - [(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>; + "ldrh", "\t$Rt, $addr", + [(set tGPR:$Rt, (zextloadi16 t_addrmode_rrs2:$addr))]>; def tLDRHi : // A8.6.73 - T1pILdStEncodeImm<0b1000, 1, (outs tGPR:$Rt), (ins t_addrmode_s2:$addr), + T1pILdStEncodeImm<0b1000, 1, (outs tGPR:$Rt), (ins t_addrmode_is2:$addr), AddrModeT1_2, IIC_iLoad_bh_r, "ldrh", "\t$Rt, $addr", - []>; + [(set tGPR:$Rt, (zextloadi16 t_addrmode_is2:$addr))]>; let AddedComplexity = 10 in def tLDRSB : // A8.6.80 @@ -676,45 +703,45 @@ def tLDRcp : T1pIs<(outs tGPR:$Rt), (ins i32imm:$addr), IIC_iLoad_i, let Inst{7-0} = addr; } -def tSTR : // A8.6.194 - T1pILdStEncode<0b000, (outs), (ins tGPR:$src, t_addrmode_s4:$addr), +def tSTRr : // A8.6.194 + T1pILdStEncode<0b000, (outs), (ins tGPR:$Rt, t_addrmode_rrs4:$addr), AddrModeT1_4, IIC_iStore_r, - "str", "\t$src, $addr", - [(store tGPR:$src, t_addrmode_s4:$addr)]>; + "str", "\t$Rt, $addr", + [(store tGPR:$Rt, t_addrmode_rrs4:$addr)]>; def tSTRi : // A8.6.192 - T1pILdStEncodeImm<0b0110, 0, (outs), (ins tGPR:$Rt, t_addrmode_s4:$addr), + T1pILdStEncodeImm<0b0110, 0, (outs), (ins tGPR:$Rt, t_addrmode_is4:$addr), AddrModeT1_4, IIC_iStore_r, "str", "\t$Rt, $addr", - []>; + [(store tGPR:$Rt, t_addrmode_is4:$addr)]>; -def tSTRB : // A8.6.197 - T1pILdStEncode<0b010, (outs), (ins tGPR:$src, t_addrmode_s1:$addr), +def tSTRBr : // A8.6.197 + T1pILdStEncode<0b010, (outs), (ins tGPR:$Rt, t_addrmode_rrs1:$addr), AddrModeT1_1, IIC_iStore_bh_r, - "strb", "\t$src, $addr", - [(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>; + "strb", "\t$Rt, $addr", + [(truncstorei8 tGPR:$Rt, t_addrmode_rrs1:$addr)]>; def tSTRBi : // A8.6.195 - T1pILdStEncodeImm<0b0111, 0, (outs), (ins tGPR:$Rt, t_addrmode_s1:$addr), + T1pILdStEncodeImm<0b0111, 0, (outs), (ins tGPR:$Rt, t_addrmode_is1:$addr), AddrModeT1_1, IIC_iStore_bh_r, "strb", "\t$Rt, $addr", - []>; + [(truncstorei8 tGPR:$Rt, t_addrmode_is1:$addr)]>; -def tSTRH : // A8.6.207 - T1pILdStEncode<0b001, (outs), (ins tGPR:$src, t_addrmode_s2:$addr), +def tSTRHr : // A8.6.207 + T1pILdStEncode<0b001, (outs), (ins tGPR:$Rt, t_addrmode_rrs2:$addr), AddrModeT1_2, IIC_iStore_bh_r, - "strh", "\t$src, $addr", - [(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>; + "strh", "\t$Rt, $addr", + [(truncstorei16 tGPR:$Rt, t_addrmode_rrs2:$addr)]>; def tSTRHi : // A8.6.205 - T1pILdStEncodeImm<0b1000, 0, (outs), (ins tGPR:$Rt, t_addrmode_s2:$addr), + T1pILdStEncodeImm<0b1000, 0, (outs), (ins tGPR:$Rt, t_addrmode_is2:$addr), AddrModeT1_2, IIC_iStore_bh_r, "strh", "\t$Rt, $addr", - []>; + [(truncstorei16 tGPR:$Rt, t_addrmode_is2:$addr)]>; def tSTRspi : T1pIs<(outs), (ins tGPR:$Rt, t_addrmode_sp:$addr), IIC_iStore_i, - "str", "\t$Rt, $addr", - [(store tGPR:$Rt, t_addrmode_sp:$addr)]>, + "str", "\t$Rt, $addr", + [(store tGPR:$Rt, t_addrmode_sp:$addr)]>, T1LdStSP<{0,?,?}> { bits<3> Rt; bits<8> addr; @@ -1390,27 +1417,32 @@ def : Tv5Pat<(ARMcall GPR:$dst), (tBLXr_r9 GPR:$dst)>, Requires<[IsThumb, HasV5T, IsDarwin]>; // zextload i1 -> zextload i8 -def : T1Pat<(zextloadi1 t_addrmode_s1:$addr), - (tLDRB t_addrmode_s1:$addr)>; +def : T1Pat<(zextloadi1 t_addrmode_rrs1:$addr), + (tLDRBr t_addrmode_rrs1:$addr)>; +def : T1Pat<(zextloadi1 t_addrmode_is1:$addr), + (tLDRBi t_addrmode_is1:$addr)>; // extload -> zextload -def : T1Pat<(extloadi1 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>; -def : T1Pat<(extloadi8 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>; -def : T1Pat<(extloadi16 t_addrmode_s2:$addr), (tLDRH t_addrmode_s2:$addr)>; +def : T1Pat<(extloadi1 t_addrmode_rrs1:$addr), (tLDRBr t_addrmode_rrs1:$addr)>; +def : T1Pat<(extloadi1 t_addrmode_is1:$addr), (tLDRBi t_addrmode_is1:$addr)>; +def : T1Pat<(extloadi8 t_addrmode_rrs1:$addr), (tLDRBr t_addrmode_rrs1:$addr)>; +def : T1Pat<(extloadi8 t_addrmode_is1:$addr), (tLDRBi t_addrmode_is1:$addr)>; +def : T1Pat<(extloadi16 t_addrmode_rrs2:$addr), (tLDRHr t_addrmode_rrs2:$addr)>; +def : T1Pat<(extloadi16 t_addrmode_is2:$addr), (tLDRHi t_addrmode_is2:$addr)>; // If it's impossible to use [r,r] address mode for sextload, select to // ldr{b|h} + sxt{b|h} instead. -def : T1Pat<(sextloadi8 t_addrmode_s1:$addr), - (tSXTB (tLDRB t_addrmode_s1:$addr))>, +def : T1Pat<(sextloadi8 t_addrmode_rrs1:$addr), + (tSXTB (tLDRBr t_addrmode_rrs1:$addr))>, Requires<[IsThumb, IsThumb1Only, HasV6]>; -def : T1Pat<(sextloadi16 t_addrmode_s2:$addr), - (tSXTH (tLDRH t_addrmode_s2:$addr))>, +def : T1Pat<(sextloadi16 t_addrmode_rrs2:$addr), + (tSXTH (tLDRHr t_addrmode_rrs2:$addr))>, Requires<[IsThumb, IsThumb1Only, HasV6]>; -def : T1Pat<(sextloadi8 t_addrmode_s1:$addr), - (tASRri (tLSLri (tLDRB t_addrmode_s1:$addr), 24), 24)>; -def : T1Pat<(sextloadi16 t_addrmode_s1:$addr), - (tASRri (tLSLri (tLDRH t_addrmode_s1:$addr), 16), 16)>; +def : T1Pat<(sextloadi8 t_addrmode_rrs1:$addr), + (tASRri (tLSLri (tLDRBr t_addrmode_rrs1:$addr), 24), 24)>; +def : T1Pat<(sextloadi16 t_addrmode_rrs1:$addr), + (tASRri (tLSLri (tLDRHr t_addrmode_rrs1:$addr), 16), 16)>; // Large immediate handling. diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp index 8dca2c35c6..b82d38ed72 100644 --- a/lib/Target/ARM/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp @@ -144,9 +144,9 @@ public: uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups) const; - /// getTAddrModeRegRegOpValue - Return encoding for 'reg + reg' operand. - uint32_t getTAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, - SmallVectorImpl<MCFixup> &Fixups) const; + /// getThumbAddrModeRegRegOpValue - Return encoding for 'reg + reg' operand. + uint32_t getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl<MCFixup> &Fixups)const; /// getT2AddrModeImm8s4OpValue - Return encoding info for 'reg +/- imm8<<2' /// operand. @@ -207,9 +207,9 @@ public: uint32_t getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups) const; - /// getAddrModeSOpValue - Encode the t_addrmode_s# operands. - uint32_t getAddrModeSOpValue(const MCInst &MI, unsigned OpIdx, - SmallVectorImpl<MCFixup> &) const; + /// getAddrModeISOpValue - Encode the t_addrmode_is# operands. + uint32_t getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl<MCFixup> &) const; /// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands. uint32_t getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx, @@ -559,12 +559,16 @@ getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, Fixups); } -/// getTAddrModeRegRegOpValue - Return encoding info for 'reg + reg' operand. +/// getThumbAddrModeRegRegOpValue - Return encoding info for 'reg + reg' +/// operand. uint32_t ARMMCCodeEmitter:: -getTAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, - SmallVectorImpl<MCFixup> &Fixups) const { +getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl<MCFixup> &) const { + // [Rn, Rm] + // {5-3} = Rm + // {2-0} = Rn const MCOperand &MO1 = MI.getOperand(OpIdx); - const MCOperand &MO2 = MI.getOperand(OpIdx+1); + const MCOperand &MO2 = MI.getOperand(OpIdx + 1); unsigned Rn = getARMRegisterNumbering(MO1.getReg()); unsigned Rm = getARMRegisterNumbering(MO2.getReg()); return (Rm << 3) | Rn; @@ -796,27 +800,17 @@ getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx, return MO1.getImm() & 0xff; } -/// getAddrModeSOpValue - Encode the t_addrmode_s# operands. +/// getAddrModeISOpValue - Encode the t_addrmode_is# operands. uint32_t ARMMCCodeEmitter:: -getAddrModeSOpValue(const MCInst &MI, unsigned OpIdx, - SmallVectorImpl<MCFixup> &) const { - // [Rn, Rm] - // {5-3} = Rm - // {2-0} = Rn - // +getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl<MCFixup> &) const { // [Rn, #imm] // {7-3} = imm5 // {2-0} = Rn const MCOperand &MO = MI.getOperand(OpIdx); const MCOperand &MO1 = MI.getOperand(OpIdx + 1); - const MCOperand &MO2 = MI.getOperand(OpIdx + 2); unsigned Rn = getARMRegisterNumbering(MO.getReg()); unsigned Imm5 = MO1.getImm(); - - if (MO2.getReg() != 0) - // Is an immediate. - Imm5 = getARMRegisterNumbering(MO2.getReg()); - return ((Imm5 & 0x1f) << 3) | Rn; } diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index c21a07c7d0..8322d70ced 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -236,11 +236,16 @@ public: int64_t Value = CE->getValue(); return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020); } - bool isMemModeThumb() const { + bool isMemModeRegThumb() const { + if (!isMemory() || (!Mem.OffsetIsReg && !Mem.Offset) || Mem.Writeback) + return false; + return !Mem.Offset || !isa<MCConstantExpr>(Mem.Offset); + } + bool isMemModeImmThumb() const { if (!isMemory() || (!Mem.OffsetIsReg && !Mem.Offset) || Mem.Writeback) return false; - if (!Mem.Offset) return true; + if (!Mem.Offset) return false; const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.Offset); if (!CE) return false; @@ -324,19 +329,18 @@ public: } } - void addMemModeThumbOperands(MCInst &Inst, unsigned N) const { - assert(N == 3 && isMemModeThumb() && "Invalid number of operands!"); + void addMemModeRegThumbOperands(MCInst &Inst, unsigned N) const { + assert(N == 2 && isMemModeRegThumb() && "Invalid number of operands!"); Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); + Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); + } - if (Mem.Offset) { - const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.Offset); - assert(CE && "Non-constant mode offset operand!"); - Inst.addOperand(MCOperand::CreateImm(CE->getValue())); - Inst.addOperand(MCOperand::CreateReg(0)); - } else { - Inst.addOperand(MCOperand::CreateImm(0)); - Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); - } + void addMemModeImmThumbOperands(MCInst &Inst, unsigned N) const { + assert(N == 2 && isMemModeImmThumb() && "Invalid number of operands!"); + Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); + const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.Offset); + assert(CE && "Non-constant mode offset operand!"); + Inst.addOperand(MCOperand::CreateImm(CE->getValue())); } virtual void dump(raw_ostream &OS) const; diff --git a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp index 4f401b9a8f..00160da446 100644 --- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp +++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp @@ -482,17 +482,25 @@ void ARMInstPrinter::printThumbITMask(const MCInst *MI, unsigned OpNum, void ARMInstPrinter::printThumbAddrModeRROperand(const MCInst *MI, unsigned Op, raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(Op); - const MCOperand &MO2 = MI->getOperand(Op+1); + const MCOperand &MO2 = MI->getOperand(Op + 1); + + if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. + printOperand(MI, Op, O); + return; + } + O << "[" << getRegisterName(MO1.getReg()); - O << ", " << getRegisterName(MO2.getReg()) << "]"; + if (unsigned RegNum = MO2.getReg()) + O << ", " << getRegisterName(RegNum); + O << "]"; } -void ARMInstPrinter::printThumbAddrModeRI5Operand(const MCInst *MI, unsigned Op, - raw_ostream &O, - unsigned Scale) { +void ARMInstPrinter::printThumbAddrModeImm5SOperand(const MCInst *MI, + unsigned Op, + raw_ostream &O, + unsigned Scale) { const MCOperand &MO1 = MI->getOperand(Op); - const MCOperand &MO2 = MI->getOperand(Op+1); - const MCOperand &MO3 = MI->getOperand(Op+2); + const MCOperand &MO2 = MI->getOperand(Op + 1); if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. printOperand(MI, Op, O); @@ -500,36 +508,32 @@ void ARMInstPrinter::printThumbAddrModeRI5Operand(const MCInst *MI, unsigned Op, } O << "[" << getRegisterName(MO1.getReg()); - if (MO3.getReg()) - O << ", " << getRegisterName(MO3.getReg()); - else if (unsigned ImmOffs = MO2.getImm()) + if (unsigned ImmOffs = MO2.getImm()) O << ", #" << ImmOffs * Scale; O << "]"; } -void ARMInstPrinter::printThumbAddrModeS1Operand(const MCInst *MI, unsigned Op, - raw_ostream &O) { - printThumbAddrModeRI5Operand(MI, Op, O, 1); +void ARMInstPrinter::printThumbAddrModeImm5S1Operand(const MCInst *MI, + unsigned Op, + raw_ostream &O) { + printThumbAddrModeImm5SOperand(MI, Op, O, 1); } -void ARMInstPrinter::printThumbAddrModeS2Operand(const MCInst *MI, unsigned Op, - raw_ostream &O) { - printThumbAddrModeRI5Operand(MI, Op, O, 2); +void ARMInstPrinter::printThumbAddrModeImm5S2Operand(const MCInst *MI, + unsigned Op, + raw_ostream &O) { + printThumbAddrModeImm5SOperand(MI, Op, O, 2); } -void ARMInstPrinter::printThumbAddrModeS4Operand(const MCInst *MI, unsigned O |