From c38f2bc3c29337f777c48b33daa8b1d6c76c27bf Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Tue, 23 Jan 2007 22:59:13 +0000 Subject: [PATCH] - Reorg Thumb load / store instructions. Combine each rr and ri pair of instructions into one (e.g. tLDRrr, tLDRri -> tLDR). - Thumb ldrsb and ldrsh only have the [reg, reg] address format. If the address is not an add, materialize a 0 immediate into a register and use it as the offset field. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33470 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMAsmPrinter.cpp | 29 ++++--- lib/Target/ARM/ARMISelDAGToDAG.cpp | 59 ++++++++----- lib/Target/ARM/ARMInstrThumb.td | 128 +++++++++++++---------------- 3 files changed, 112 insertions(+), 104 deletions(-) diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index bd87539aa0b..1ca8bfd75cf 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -98,9 +98,9 @@ namespace { void printThumbAddrModeRROperand(const MachineInstr *MI, int OpNo); void printThumbAddrModeRI5Operand(const MachineInstr *MI, int OpNo, unsigned Scale); - void printThumbAddrModeRI5_1Operand(const MachineInstr *MI, int OpNo); - void printThumbAddrModeRI5_2Operand(const MachineInstr *MI, int OpNo); - void printThumbAddrModeRI5_4Operand(const MachineInstr *MI, int OpNo); + void printThumbAddrModeS1Operand(const MachineInstr *MI, int OpNo); + void printThumbAddrModeS2Operand(const MachineInstr *MI, int OpNo); + void printThumbAddrModeS4Operand(const MachineInstr *MI, int OpNo); void printThumbAddrModeSPOperand(const MachineInstr *MI, int OpNo); void printCCOperand(const MachineInstr *MI, int opNum); void printPCLabel(const MachineInstr *MI, int opNum); @@ -518,7 +518,7 @@ void ARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr *MI, int Op, unsigned Scale) { const MachineOperand &MO1 = MI->getOperand(Op); - const MachineOperand &MO2 = MI->getOperand(Op+1); + const MachineOperand &MO2 = MI->getOperand(Op+2); if (!MO1.isRegister()) { // FIXME: This is for CP entries, but isn't right. printOperand(MI, Op); @@ -535,16 +535,25 @@ ARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr *MI, int Op, } void -ARMAsmPrinter::printThumbAddrModeRI5_1Operand(const MachineInstr *MI, int Op) { - printThumbAddrModeRI5Operand(MI, Op, 1); +ARMAsmPrinter::printThumbAddrModeS1Operand(const MachineInstr *MI, int Op) { + if (MI->getOperand(Op+1).getReg()) + printThumbAddrModeRROperand(MI, Op); + else + printThumbAddrModeRI5Operand(MI, Op, 1); } void -ARMAsmPrinter::printThumbAddrModeRI5_2Operand(const MachineInstr *MI, int Op) { - printThumbAddrModeRI5Operand(MI, Op, 2); +ARMAsmPrinter::printThumbAddrModeS2Operand(const MachineInstr *MI, int Op) { + if (MI->getOperand(Op+1).getReg()) + printThumbAddrModeRROperand(MI, Op); + else + printThumbAddrModeRI5Operand(MI, Op, 2); } void -ARMAsmPrinter::printThumbAddrModeRI5_4Operand(const MachineInstr *MI, int Op) { - printThumbAddrModeRI5Operand(MI, Op, 4); +ARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr *MI, int Op) { + if (MI->getOperand(Op+1).getReg()) + printThumbAddrModeRROperand(MI, Op); + else + printThumbAddrModeRI5Operand(MI, Op, 4); } void ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op) { diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index f5f4599b5ce..42fbcfd670f 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -71,12 +71,12 @@ public: bool SelectThumbAddrModeRR(SDOperand Op, SDOperand N, SDOperand &Base, SDOperand &Offset); - bool SelectThumbAddrModeRI5_1(SDOperand Op, SDOperand N, SDOperand &Base, - SDOperand &Offset); - bool SelectThumbAddrModeRI5_2(SDOperand Op, SDOperand N, SDOperand &Base, - SDOperand &Offset); - bool SelectThumbAddrModeRI5_4(SDOperand Op, SDOperand N, SDOperand &Base, - SDOperand &Offset); + bool SelectThumbAddrModeS1(SDOperand Op, SDOperand N, SDOperand &Base, + SDOperand &Offset, SDOperand &OffImm); + bool SelectThumbAddrModeS2(SDOperand Op, SDOperand N, SDOperand &Base, + SDOperand &Offset, SDOperand &OffImm); + bool SelectThumbAddrModeS4(SDOperand Op, SDOperand N, SDOperand &Base, + SDOperand &Offset, SDOperand &OffImm); bool SelectThumbAddrModeSP(SDOperand Op, SDOperand N, SDOperand &Base, SDOperand &Offset); @@ -340,8 +340,16 @@ bool ARMDAGToDAGISel::SelectAddrModePC(SDOperand Op, SDOperand N, bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDOperand Op, SDOperand N, SDOperand &Base, SDOperand &Offset){ - if (N.getOpcode() != ISD::ADD) - return false; + if (N.getOpcode() != ISD::ADD) { + Base = N; + // We must materialize a zero in a reg! Returning an constant here won't + // work since its node is -1 so it won't get added to the selection queue. + // Explicitly issue a tMOVri8 node! + Offset = SDOperand(CurDAG->getTargetNode(ARM::tMOVri8, MVT::i32, + CurDAG->getTargetConstant(0, MVT::i32)), 0); + return true; + } + Base = N.getOperand(0); Offset = N.getOperand(1); return true; @@ -349,13 +357,15 @@ bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDOperand Op, SDOperand N, static bool SelectThumbAddrModeRI5(SDOperand N, unsigned Scale, TargetLowering &TLI, SelectionDAG *CurDAG, - SDOperand &Base, SDOperand &Offset) { + SDOperand &Base, SDOperand &Offset, + SDOperand &OffImm) { if (N.getOpcode() == ISD::FrameIndex) return false; if (N.getOpcode() != ISD::ADD) { Base = (N.getOpcode() == ARMISD::Wrapper) ? N.getOperand(0) : N; - Offset = CurDAG->getTargetConstant(0, MVT::i32); + Offset = CurDAG->getRegister(0, MVT::i32); + OffImm = CurDAG->getTargetConstant(0, MVT::i32); return true; } @@ -366,28 +376,35 @@ static bool SelectThumbAddrModeRI5(SDOperand N, unsigned Scale, RHSC /= Scale; if (RHSC >= 0 && RHSC < 32) { Base = N.getOperand(0); - Offset = CurDAG->getTargetConstant(RHSC, MVT::i32); + Offset = CurDAG->getRegister(0, MVT::i32); + OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); return true; } } } - return false; + Base = N.getOperand(0); + Offset = N.getOperand(1); + OffImm = CurDAG->getTargetConstant(0, MVT::i32); + return true; } -bool ARMDAGToDAGISel::SelectThumbAddrModeRI5_1(SDOperand Op, SDOperand N, - SDOperand &Base, SDOperand &Offset){ - return SelectThumbAddrModeRI5(N, 1, TLI, CurDAG, Base, Offset); +bool ARMDAGToDAGISel::SelectThumbAddrModeS1(SDOperand Op, SDOperand N, + SDOperand &Base, SDOperand &Offset, + SDOperand &OffImm) { + return SelectThumbAddrModeRI5(N, 1, TLI, CurDAG, Base, Offset, OffImm); } -bool ARMDAGToDAGISel::SelectThumbAddrModeRI5_2(SDOperand Op, SDOperand N, - SDOperand &Base, SDOperand &Offset){ - return SelectThumbAddrModeRI5(N, 2, TLI, CurDAG, Base, Offset); +bool ARMDAGToDAGISel::SelectThumbAddrModeS2(SDOperand Op, SDOperand N, + SDOperand &Base, SDOperand &Offset, + SDOperand &OffImm) { + return SelectThumbAddrModeRI5(N, 2, TLI, CurDAG, Base, Offset, OffImm); } -bool ARMDAGToDAGISel::SelectThumbAddrModeRI5_4(SDOperand Op, SDOperand N, - SDOperand &Base, SDOperand &Offset){ - return SelectThumbAddrModeRI5(N, 4, TLI, CurDAG, Base, Offset); +bool ARMDAGToDAGISel::SelectThumbAddrModeS4(SDOperand Op, SDOperand N, + SDOperand &Base, SDOperand &Offset, + SDOperand &OffImm) { + return SelectThumbAddrModeRI5(N, 4, TLI, CurDAG, Base, Offset, OffImm); } bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDOperand Op, SDOperand N, diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index 58cef041886..fa7afea976d 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -114,22 +114,31 @@ def t_addrmode_rr : Operand, let MIOperandInfo = (ops GPR:$base, GPR:$offsreg); } -// t_addrmode_ri5_{1|2|4} := reg + imm5 * {1|2|4} +// t_addrmode_s4 := reg + reg +// reg + imm5 * 4 // -def t_addrmode_ri5_1 : Operand, - ComplexPattern { - let PrintMethod = "printThumbAddrModeRI5_1Operand"; - let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); +def t_addrmode_s4 : Operand, + ComplexPattern { + let PrintMethod = "printThumbAddrModeS4Operand"; + let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); } -def t_addrmode_ri5_2 : Operand, - ComplexPattern { - let PrintMethod = "printThumbAddrModeRI5_2Operand"; - let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); + +// t_addrmode_s2 := reg + reg +// reg + imm5 * 2 +// +def t_addrmode_s2 : Operand, + ComplexPattern { + let PrintMethod = "printThumbAddrModeS2Operand"; + let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); } -def t_addrmode_ri5_4 : Operand, - ComplexPattern { - let PrintMethod = "printThumbAddrModeRI5_4Operand"; - let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); + +// t_addrmode_s1 := reg + reg +// reg + imm5 +// +def t_addrmode_s1 : Operand, + ComplexPattern { + let PrintMethod = "printThumbAddrModeS1Operand"; + let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); } // t_addrmode_sp := sp + imm8 * 4 @@ -191,71 +200,48 @@ let isBranch = 1, isTerminator = 1, noResults = 1, isBarrier = 1 in // let isLoad = 1 in { -def tLDRri : TI4<(ops GPR:$dst, t_addrmode_ri5_4:$addr), - "ldr $dst, $addr", - [(set GPR:$dst, (load t_addrmode_ri5_4:$addr))]>; +def tLDR : TI4<(ops GPR:$dst, t_addrmode_s4:$addr), + "ldr $dst, $addr", + [(set GPR:$dst, (load t_addrmode_s4:$addr))]>; + +def tLDRB : TI1<(ops GPR:$dst, t_addrmode_s1:$addr), + "ldrb $dst, $addr", + [(set GPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>; + +def tLDRH : TI2<(ops GPR:$dst, t_addrmode_s2:$addr), + "ldrh $dst, $addr", + [(set GPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>; + +def tLDRSB : TI1<(ops GPR:$dst, t_addrmode_rr:$addr), + "ldrsb $dst, $addr", + [(set GPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>; + +def tLDRSH : TI2<(ops GPR:$dst, t_addrmode_rr:$addr), + "ldrsh $dst, $addr", + [(set GPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>; -def tLDRrr : TI<(ops GPR:$dst, t_addrmode_rr:$addr), - "ldr $dst, $addr", - [(set GPR:$dst, (load t_addrmode_rr:$addr))]>; // def tLDRpci def tLDRspi : TIs<(ops GPR:$dst, t_addrmode_sp:$addr), "ldr $dst, $addr", [(set GPR:$dst, (load t_addrmode_sp:$addr))]>; - -def tLDRBri : TI1<(ops GPR:$dst, t_addrmode_ri5_1:$addr), - "ldrb $dst, $addr", - [(set GPR:$dst, (zextloadi8 t_addrmode_ri5_1:$addr))]>; - -def tLDRBrr : TI1<(ops GPR:$dst, t_addrmode_rr:$addr), - "ldrb $dst, $addr", - [(set GPR:$dst, (zextloadi8 t_addrmode_rr:$addr))]>; - -def tLDRHri : TI2<(ops GPR:$dst, t_addrmode_ri5_2:$addr), - "ldrh $dst, $addr", - [(set GPR:$dst, (zextloadi16 t_addrmode_ri5_2:$addr))]>; - -def tLDRHrr : TI2<(ops GPR:$dst, t_addrmode_rr:$addr), - "ldrh $dst, $addr", - [(set GPR:$dst, (zextloadi16 t_addrmode_rr:$addr))]>; - -def tLDRSBrr : TI1<(ops GPR:$dst, t_addrmode_rr:$addr), - "ldrsb $dst, $addr", - [(set GPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>; - -def tLDRSHrr : TI2<(ops GPR:$dst, t_addrmode_rr:$addr), - "ldrsh $dst, $addr", - [(set GPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>; } // isLoad let isStore = 1 in { -def tSTRri : TI4<(ops GPR:$src, t_addrmode_ri5_4:$addr), - "str $src, $addr", - [(store GPR:$src, t_addrmode_ri5_4:$addr)]>; +def tSTR : TI4<(ops GPR:$src, t_addrmode_s4:$addr), + "str $src, $addr", + [(store GPR:$src, t_addrmode_s4:$addr)]>; -def tSTRrr : TI<(ops GPR:$src, t_addrmode_rr:$addr), - "str $src, $addr", - [(store GPR:$src, t_addrmode_rr:$addr)]>; +def tSTRB : TI1<(ops GPR:$src, t_addrmode_s1:$addr), + "strb $src, $addr", + [(truncstorei8 GPR:$src, t_addrmode_s1:$addr)]>; + +def tSTRH : TI2<(ops GPR:$src, t_addrmode_s2:$addr), + "strh $src, $addr", + [(truncstorei16 GPR:$src, t_addrmode_s2:$addr)]>; def tSTRspi : TIs<(ops GPR:$src, t_addrmode_sp:$addr), "str $src, $addr", [(store GPR:$src, t_addrmode_sp:$addr)]>; - -def tSTRBri : TI1<(ops GPR:$src, t_addrmode_ri5_1:$addr), - "strb $src, $addr", - [(truncstorei8 GPR:$src, t_addrmode_ri5_1:$addr)]>; - -def tSTRBrr : TI1<(ops GPR:$src, t_addrmode_rr:$addr), - "strb $src, $addr", - [(truncstorei8 GPR:$src, t_addrmode_rr:$addr)]>; - -def tSTRHri : TI2<(ops GPR:$src, t_addrmode_ri5_2:$addr), - "strh $src, $addr", - [(truncstorei16 GPR:$src, t_addrmode_ri5_1:$addr)]>; - -def tSTRHrr : TI2<(ops GPR:$src, t_addrmode_rr:$addr), - "strh $src, $addr", - [(truncstorei16 GPR:$src, t_addrmode_rr:$addr)]>; } //===----------------------------------------------------------------------===// @@ -491,16 +477,12 @@ def : ThumbV5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym:$func)>; def : ThumbV5Pat<(ARMcall GPR:$dst), (tBLXr GPR:$dst)>; // zextload i1 -> zextload i8 -def : ThumbPat<(zextloadi1 t_addrmode_ri5_1:$addr), - (tLDRBri t_addrmode_ri5_1:$addr)>; -def : ThumbPat<(zextloadi1 t_addrmode_rr:$addr), - (tLDRBri t_addrmode_rr:$addr)>; +def : ThumbPat<(zextloadi1 t_addrmode_s1:$addr), + (tLDRB t_addrmode_s1:$addr)>; // truncstore i1 -> truncstore i8 -def : ThumbPat<(truncstorei1 GPR:$src, t_addrmode_ri5_1:$dst), - (tSTRBri GPR:$src, t_addrmode_ri5_1:$dst)>; -def : ThumbPat<(truncstorei1 GPR:$src, t_addrmode_rr:$dst), - (tSTRBrr GPR:$src, t_addrmode_rr:$dst)>; +def : ThumbPat<(truncstorei1 GPR:$src, t_addrmode_s1:$dst), + (tSTRB GPR:$src, t_addrmode_s1:$dst)>; // Large immediate handling.