From e7cbe4118b7ddf05032ff8772a98c51e1637bb5c Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Wed, 8 Jul 2009 21:03:57 +0000 Subject: [PATCH] Change how so_imm and t2_so_imm are handled. At instruction selection time, the immediates are no longer encoded in the imm8 + rot format, that are left as it is. The encoding is now done in ams printing and code emission time instead. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75048 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMAddressingModes.h | 23 --------------- lib/Target/ARM/ARMBaseInstrInfo.cpp | 5 ++-- lib/Target/ARM/ARMBaseRegisterInfo.cpp | 17 +++++------ lib/Target/ARM/ARMCodeEmitter.cpp | 17 ++++++----- lib/Target/ARM/ARMISelDAGToDAG.cpp | 6 ++-- lib/Target/ARM/ARMInstrInfo.td | 31 ++++++++------------- lib/Target/ARM/ARMInstrThumb2.td | 31 ++++++--------------- lib/Target/ARM/ARMLoadStoreOptimizer.cpp | 5 ++-- lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp | 24 ++++------------ 9 files changed, 48 insertions(+), 111 deletions(-) diff --git a/lib/Target/ARM/ARMAddressingModes.h b/lib/Target/ARM/ARMAddressingModes.h index 15c9ec1fc23..6b90b73d13d 100644 --- a/lib/Target/ARM/ARMAddressingModes.h +++ b/lib/Target/ARM/ARMAddressingModes.h @@ -273,29 +273,6 @@ namespace ARM_AM { return V >> getThumbImmValShift(V); } - /// getT2SOImmValDecode - Given a 12-bit encoded Thumb-2 modified immediate, - /// return the corresponding 32-bit immediate value. - /// See ARM Reference Manual A6.3.2. - static inline unsigned getT2SOImmValDecode(unsigned Imm) { - unsigned Base = Imm & 0xff; - switch ((Imm >> 8) & 0xf) { - case 0: - return Base; - case 1: - return Base | (Base << 16); - case 2: - return (Base << 8) | (Base << 24); - case 3: - return Base | (Base << 8) | (Base << 16) | (Base << 24); - default: - break; - } - - // shifted immediate - unsigned RotAmount = ((Imm >> 7) & 0x1f) - 8; - return (Base | 0x80) << (24 - RotAmount); - } - /// getT2SOImmValSplat - Return the 12-bit encoded representation /// if the specified value can be obtained by splatting the low 8 bits /// into every other byte or every byte of a 32-bit value. i.e., diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index a1ea692d3bf..f659cb50a05 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -91,15 +91,14 @@ ARMBaseInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI, bool isSub = ARM_AM::getAM2Op(OffImm) == ARM_AM::sub; unsigned Amt = ARM_AM::getAM2Offset(OffImm); if (OffReg == 0) { - int SOImmVal = ARM_AM::getSOImmVal(Amt); - if (SOImmVal == -1) + if (ARM_AM::getSOImmVal(Amt) == -1) // Can't encode it in a so_imm operand. This transformation will // add more than 1 instruction. Abandon! return NULL; UpdateMI = BuildMI(MF, MI->getDebugLoc(), get(isSub ? getOpcode(ARMII::SUBri) : getOpcode(ARMII::ADDri)), WBReg) - .addReg(BaseReg).addImm(SOImmVal) + .addReg(BaseReg).addImm(Amt) .addImm(Pred).addReg(0).addReg(0); } else if (Amt != 0) { ARM_AM::ShiftOpc ShOpc = ARM_AM::getAM2ShiftOpc(OffImm); diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp index 2bf7e51d833..0c05904d612 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -942,13 +942,11 @@ void emitARMRegPlusImmediate(MachineBasicBlock &MBB, // We will handle these bits from offset, clear them. NumBytes &= ~ThisVal; - // Get the properly encoded SOImmVal field. - int SOImmVal = ARM_AM::getSOImmVal(ThisVal); - assert(SOImmVal != -1 && "Bit extraction didn't work?"); + assert(ARM_AM::getSOImmVal(ThisVal) != -1 && "Bit extraction didn't work?"); // Build the new ADD / SUB. BuildMI(MBB, MBBI, dl, TII.get(TII.getOpcode(isSub ? ARMII::SUBri : ARMII::ADDri)), DestReg) - .addReg(BaseReg, RegState::Kill).addImm(SOImmVal) + .addReg(BaseReg, RegState::Kill).addImm(ThisVal) .addImm((unsigned)Pred).addReg(PredReg).addReg(0); BaseReg = DestReg; } @@ -1071,11 +1069,10 @@ eliminateFrameIndex(MachineBasicBlock::iterator II, } // Common case: small offset, fits into instruction. - int ImmedOffset = ARM_AM::getSOImmVal(Offset); - if (ImmedOffset != -1) { + if (ARM_AM::getSOImmVal(Offset) != -1) { // Replace the FrameIndex with sp / fp MI.getOperand(i).ChangeToRegister(FrameReg, false); - MI.getOperand(i+1).ChangeToImmediate(ImmedOffset); + MI.getOperand(i+1).ChangeToImmediate(Offset); return; } @@ -1089,9 +1086,9 @@ eliminateFrameIndex(MachineBasicBlock::iterator II, Offset &= ~ThisImmVal; // Get the properly encoded SOImmVal field. - int ThisSOImmVal = ARM_AM::getSOImmVal(ThisImmVal); - assert(ThisSOImmVal != -1 && "Bit extraction didn't work?"); - MI.getOperand(i+1).ChangeToImmediate(ThisSOImmVal); + assert(ARM_AM::getSOImmVal(ThisImmVal) != -1 && + "Bit extraction didn't work?"); + MI.getOperand(i+1).ChangeToImmediate(ThisImmVal); } else { unsigned ImmIdx = 0; int InstrOffs = 0; diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index d43a76edc5e..35502aa4cd9 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -470,7 +470,8 @@ template void Emitter::emitMOVi2piecesInstruction(const MachineInstr &MI) { const MachineOperand &MO0 = MI.getOperand(0); const MachineOperand &MO1 = MI.getOperand(1); - assert(MO1.isImm() && "Not a valid so_imm value!"); + assert(MO1.isImm() && ARM_AM::getSOImmVal(MO1.isImm()) != -1 && + "Not a valid so_imm value!"); unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO1.getImm()); unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO1.getImm()); @@ -486,7 +487,7 @@ void Emitter::emitMOVi2piecesInstruction(const MachineInstr &MI) { // Encode so_imm. // Set bit I(25) to identify this is the immediate form of Binary |= 1 << ARMII::I_BitShift; - Binary |= getMachineSoImmOpValue(ARM_AM::getSOImmVal(V1)); + Binary |= getMachineSoImmOpValue(V1); emitWordLE(Binary); // Now the 'orr' instruction. @@ -504,7 +505,7 @@ void Emitter::emitMOVi2piecesInstruction(const MachineInstr &MI) { // Encode so_imm. // Set bit I(25) to identify this is the immediate form of Binary |= 1 << ARMII::I_BitShift; - Binary |= getMachineSoImmOpValue(ARM_AM::getSOImmVal(V2)); + Binary |= getMachineSoImmOpValue(V2); emitWordLE(Binary); } @@ -714,12 +715,15 @@ unsigned Emitter::getMachineSoRegOpValue( template unsigned Emitter::getMachineSoImmOpValue(unsigned SoImm) { + int SoImmVal = ARM_AM::getSOImmVal(SoImm); + assert(SoImmVal != -1 && "Not a valid so_imm value!"); + // Encode rotate_imm. - unsigned Binary = (ARM_AM::getSOImmValRot(SoImm) >> 1) + unsigned Binary = (ARM_AM::getSOImmValRot((unsigned)SoImmVal) >> 1) << ARMII::SoRotImmShift; // Encode immed_8. - Binary |= ARM_AM::getSOImmValImm(SoImm); + Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal); return Binary; } @@ -796,8 +800,7 @@ void Emitter::emitDataProcessingInstruction( } // Encode so_imm. - Binary |= 1 << ARMII::I_BitShift; - Binary |= getMachineSoImmOpValue(MO.getImm()); + Binary |= getMachineSoImmOpValue((unsigned)MO.getImm()); emitWordLE(Binary); } diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index 71a63059002..50db5896dd5 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -1071,10 +1071,10 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) { } // Pattern: (ARMcmov:i32 GPR:i32:$false, - // (imm:i32)<><>:$true, + // (imm:i32)<>:$true, // (imm:i32):$cc) // Emits: (MOVCCi:i32 GPR:i32:$false, - // (so_imm_XFORM:i32 (imm:i32):$true), (imm:i32):$cc) + // (so_imm:i32 (imm:i32):$true), (imm:i32):$cc) // Pattern complexity = 10 cost = 1 size = 0 if (N3.getOpcode() == ISD::Constant) { if (Subtarget->isThumb()) { @@ -1082,7 +1082,6 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) { SDValue Tmp1 = CurDAG->getTargetConstant(((unsigned) cast(N1)->getZExtValue()), MVT::i32); - Tmp1 = Transform_t2_so_imm_XFORM(Tmp1.getNode()); SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) cast(N2)->getZExtValue()), MVT::i32); @@ -1095,7 +1094,6 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) { SDValue Tmp1 = CurDAG->getTargetConstant(((unsigned) cast(N1)->getZExtValue()), MVT::i32); - Tmp1 = Transform_so_imm_XFORM(Tmp1.getNode()); SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) cast(N2)->getZExtValue()), MVT::i32); diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 6d812d66900..cea0de2b9ee 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -118,25 +118,16 @@ class RegConstraint { // ARM specific transformation functions and pattern fragments. // -// so_imm_XFORM - Return a so_imm value packed into the format described for -// so_imm def below. -def so_imm_XFORM : SDNodeXFormgetTargetConstant(ARM_AM::getSOImmVal(N->getZExtValue()), - MVT::i32); -}]>; - // so_imm_neg_XFORM - Return a so_imm value packed into the format described for // so_imm_neg def below. def so_imm_neg_XFORM : SDNodeXFormgetTargetConstant(ARM_AM::getSOImmVal(-(int)N->getZExtValue()), - MVT::i32); + return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32); }]>; // so_imm_not_XFORM - Return a so_imm value packed into the format described for // so_imm_not def below. def so_imm_not_XFORM : SDNodeXFormgetTargetConstant(ARM_AM::getSOImmVal(~(int)N->getZExtValue()), - MVT::i32); + return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32); }]>; // rot_imm predicate - True if the 32-bit immediate is equal to 8, 16, or 24. @@ -234,9 +225,9 @@ def so_reg : Operand, // reg reg imm // into so_imm instructions: the 8-bit immediate is the least significant bits // [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11]. def so_imm : Operand, - PatLeaf<(imm), - [{ return ARM_AM::getSOImmVal(N->getZExtValue()) != -1; }], - so_imm_XFORM> { + PatLeaf<(imm), [{ + return ARM_AM::getSOImmVal(N->getZExtValue()) != -1; + }]> { let PrintMethod = "printSOImmOperand"; } @@ -252,12 +243,12 @@ def so_imm2part : Operand, def so_imm2part_1 : SDNodeXFormgetZExtValue()); - return CurDAG->getTargetConstant(ARM_AM::getSOImmVal(V), MVT::i32); + return CurDAG->getTargetConstant(V, MVT::i32); }]>; def so_imm2part_2 : SDNodeXFormgetZExtValue()); - return CurDAG->getTargetConstant(ARM_AM::getSOImmVal(V), MVT::i32); + return CurDAG->getTargetConstant(V, MVT::i32); }]>; @@ -1440,11 +1431,11 @@ def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src), Pseudo, [(set GPR:$dst, so_imm2part:$src)]>; def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS), - (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)), - (so_imm2part_2 imm:$RHS))>; + (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)), + (so_imm2part_2 imm:$RHS))>; def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS), - (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)), - (so_imm2part_2 imm:$RHS))>; + (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)), + (so_imm2part_2 imm:$RHS))>; // TODO: add,sub,and, 3-instr forms? diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 330c7a9ffa5..22d670ba249 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -20,23 +20,14 @@ def t2_so_reg : Operand, // reg imm let MIOperandInfo = (ops GPR, i32imm); } -// t2_so_imm_XFORM - Return a t2_so_imm value packed into the format -// described for t2_so_imm def below. -def t2_so_imm_XFORM : SDNodeXFormgetTargetConstant( - ARM_AM::getT2SOImmVal(N->getZExtValue()), MVT::i32); -}]>; - // t2_so_imm_not_XFORM - Return the complement of a t2_so_imm value def t2_so_imm_not_XFORM : SDNodeXFormgetTargetConstant( - ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())), MVT::i32); + return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), MVT::i32); }]>; // t2_so_imm_neg_XFORM - Return the negation of a t2_so_imm value def t2_so_imm_neg_XFORM : SDNodeXFormgetTargetConstant( - ARM_AM::getT2SOImmVal(-((int)N->getZExtValue())), MVT::i32); + return CurDAG->getTargetConstant(-((int)N->getZExtValue()), MVT::i32); }]>; // t2_so_imm - Match a 32-bit immediate operand, which is an @@ -47,27 +38,21 @@ def t2_so_imm_neg_XFORM : SDNodeXForm, PatLeaf<(imm), [{ - return ARM_AM::getT2SOImmVal((uint32_t)N->getZExtValue()) != -1; - }], t2_so_imm_XFORM> { - let PrintMethod = "printT2SOImmOperand"; -} + return ARM_AM::getT2SOImmVal((uint32_t)N->getZExtValue()) != -1; +}]>; // t2_so_imm_not - Match an immediate that is a complement // of a t2_so_imm. def t2_so_imm_not : Operand, PatLeaf<(imm), [{ - return ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())) != -1; - }], t2_so_imm_not_XFORM> { - let PrintMethod = "printT2SOImmOperand"; -} + return ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())) != -1; +}], t2_so_imm_not_XFORM>; // t2_so_imm_neg - Match an immediate that is a negation of a t2_so_imm. def t2_so_imm_neg : Operand, PatLeaf<(imm), [{ - return ARM_AM::getT2SOImmVal(-((int)N->getZExtValue())) != -1; - }], t2_so_imm_neg_XFORM> { - let PrintMethod = "printT2SOImmOperand"; -} + return ARM_AM::getT2SOImmVal(-((int)N->getZExtValue())) != -1; +}], t2_so_imm_neg_XFORM>; /// imm1_31 predicate - True if the 32-bit immediate is in the range [1,31]. def imm1_31 : PatLeaf<(i32 imm), [{ diff --git a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp index 67c42580465..c449c50f46d 100644 --- a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp +++ b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp @@ -171,12 +171,11 @@ ARMLoadStoreOpt::MergeOps(MachineBasicBlock &MBB, BaseOpc = ARM::SUBri; Offset = - Offset; } - int ImmedOffset = ARM_AM::getSOImmVal(Offset); - if (ImmedOffset == -1) + if (ARM_AM::getSOImmVal(Offset) == -1) return false; // Probably not worth it then. BuildMI(MBB, MBBI, dl, TII->get(BaseOpc), NewBase) - .addReg(Base, getKillRegState(BaseKill)).addImm(ImmedOffset) + .addReg(Base, getKillRegState(BaseKill)).addImm(Offset) .addImm(Pred).addReg(PredReg).addReg(0); Base = NewBase; BaseKill = true; // New base is always killed right its use. diff --git a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp index c4deb4bdb39..a228d2a0b4d 100644 --- a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp @@ -119,7 +119,6 @@ namespace { void printThumbAddrModeS4Operand(const MachineInstr *MI, int OpNum); void printThumbAddrModeSPOperand(const MachineInstr *MI, int OpNum); - void printT2SOImmOperand(const MachineInstr *MI, int OpNum); void printT2SOOperand(const MachineInstr *MI, int OpNum); void printT2AddrModeImm12Operand(const MachineInstr *MI, int OpNum); void printT2AddrModeImm8Operand(const MachineInstr *MI, int OpNum); @@ -370,7 +369,10 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, static void printSOImm(raw_ostream &O, int64_t V, bool VerboseAsm, const TargetAsmInfo *TAI) { - assert(V < (1 << 12) && "Not a valid so_imm value!"); + // Break it up into two parts that make up a shifter immediate. + V = ARM_AM::getSOImmVal(V); + assert(V != -1 && "Not a valid so_imm value!"); + unsigned Imm = ARM_AM::getSOImmValImm(V); unsigned Rot = ARM_AM::getSOImmValRot(V); @@ -402,7 +404,7 @@ void ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum) { assert(MO.isImm() && "Not a valid so_imm value!"); unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO.getImm()); unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO.getImm()); - printSOImm(O, ARM_AM::getSOImmVal(V1), VerboseAsm, TAI); + printSOImm(O, V1, VerboseAsm, TAI); O << "\n\torr"; printPredicateOperand(MI, 2); O << " "; @@ -410,7 +412,7 @@ void ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum) { O << ", "; printOperand(MI, 0); O << ", "; - printSOImm(O, ARM_AM::getSOImmVal(V2), VerboseAsm, TAI); + printSOImm(O, V2, VerboseAsm, TAI); } // so_reg is a 4-operand unit corresponding to register forms of the A5.1 @@ -687,20 +689,6 @@ void ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op) { //===--------------------------------------------------------------------===// -/// printT2SOImmOperand - T2SOImm is: -/// 1. a 4-bit splat control value and 8 bit immediate value -/// 2. a 5-bit rotate amount and a non-zero 8-bit immediate value -/// represented by a normalizedin 7-bit value (msb is always 1) -void ARMAsmPrinter::printT2SOImmOperand(const MachineInstr *MI, int OpNum) { - const MachineOperand &MO = MI->getOperand(OpNum); - assert(MO.isImm() && "Not a valid so_imm value!"); - - unsigned Imm = ARM_AM::getT2SOImmValDecode(MO.getImm()); - // Always print the immediate directly, as the "rotate" form - // is deprecated in some contexts. - O << "#" << Imm; -} - // Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2 // register with shift forms. // REG 0 0 - e.g. R5