diff options
author | Evan Cheng <evan.cheng@apple.com> | 2008-11-05 18:35:52 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2008-11-05 18:35:52 +0000 |
commit | edda31c412d524531ee6cd3f2d21c2ef85b6afb0 (patch) | |
tree | 3fde33185237109f0417a914c2b17101e984ccd7 | |
parent | 28c04dab38fa7205fedbc8954f08e2250e84c273 (diff) |
Restructure ARM code emitter to use instruction formats instead of addressing modes to determine how to encode instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58764 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/ARM/ARM.td | 4 | ||||
-rw-r--r-- | lib/Target/ARM/ARMCodeEmitter.cpp | 260 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrFormats.td | 77 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.h | 74 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 172 |
5 files changed, 302 insertions, 285 deletions
diff --git a/lib/Target/ARM/ARM.td b/lib/Target/ARM/ARM.td index 290f8ff399..3ce8baaab4 100644 --- a/lib/Target/ARM/ARM.td +++ b/lib/Target/ARM/ARM.td @@ -102,12 +102,14 @@ def ARMInstrInfo : InstrInfo { "SizeFlag", "IndexModeBits", "Opcode", + "isUnaryDataProc", "Form"]; let TSFlagsShifts = [0, 4, 7, 9, - 13]; + 13, + 14]; } //===----------------------------------------------------------------------===// diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index 47aa22b7d9..193df988dc 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -69,10 +69,6 @@ namespace { void emitPseudoInstruction(const MachineInstr &MI); - unsigned getAddrModeNoneInstrBinary(const MachineInstr &MI, - const TargetInstrDesc &TID, - unsigned Binary); - unsigned getMachineSoRegOpValue(const MachineInstr &MI, const TargetInstrDesc &TID, const MachineOperand &MO, @@ -85,25 +81,19 @@ namespace { unsigned getAddrModeSBit(const MachineInstr &MI, const TargetInstrDesc &TID) const; - unsigned getAddrMode1InstrBinary(const MachineInstr &MI, - const TargetInstrDesc &TID, - unsigned Binary); - unsigned getAddrMode2InstrBinary(const MachineInstr &MI, - const TargetInstrDesc &TID, - unsigned Binary); - unsigned getAddrMode3InstrBinary(const MachineInstr &MI, - const TargetInstrDesc &TID, - unsigned Binary); - unsigned getAddrMode4InstrBinary(const MachineInstr &MI, - const TargetInstrDesc &TID, - unsigned Binary); - unsigned getAddrMode6InstrBinary(const MachineInstr &MI, - const TargetInstrDesc &TID, - unsigned Binary); - - /// getInstrBinary - Return binary encoding for the specified - /// machine instruction. - unsigned getInstrBinary(const MachineInstr &MI); + void emitDataProcessingInstruction(const MachineInstr &MI); + + void emitLoadStoreInstruction(const MachineInstr &MI); + + void emitMiscLoadStoreInstruction(const MachineInstr &MI); + + void emitLoadStoreMultipleInstruction(const MachineInstr &MI); + + void emitMulFrm1Instruction(const MachineInstr &MI); + + void emitBranchInstruction(const MachineInstr &MI); + + void emitMiscBranchInstruction(const MachineInstr &MI); /// getBinaryCodeForInstr - This function, generated by the /// CodeEmitterGenerator using TableGen, produces the binary encoding for @@ -260,10 +250,39 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) { DOUT << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << MI; NumEmitted++; // Keep track of the # of mi's emitted - if ((MI.getDesc().TSFlags & ARMII::FormMask) == ARMII::Pseudo) + switch (MI.getDesc().TSFlags & ARMII::FormMask) { + default: + assert(0 && "Unhandled instruction encoding format!"); + break; + case ARMII::Pseudo: emitPseudoInstruction(MI); - else - MCE.emitWordLE(getInstrBinary(MI)); + break; + case ARMII::DPFrm: + case ARMII::DPSoRegFrm: + emitDataProcessingInstruction(MI); + break; + case ARMII::LdFrm: + case ARMII::StFrm: + emitLoadStoreInstruction(MI); + break; + case ARMII::LdMiscFrm: + case ARMII::StMiscFrm: + emitMiscLoadStoreInstruction(MI); + break; + case ARMII::LdMulFrm: + case ARMII::StMulFrm: + emitLoadStoreMultipleInstruction(MI); + break; + case ARMII::MulFrm1: + emitMulFrm1Instruction(MI); + break; + case ARMII::Branch: + emitBranchInstruction(MI); + break; + case ARMII::BranchMisc: + emitMiscBranchInstruction(MI); + break; + } } void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) { @@ -329,51 +348,13 @@ void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) { JTI->addPCLabelAddr(MO2.getImm(), MCE.getCurrentPCValue()); // PICADD is just an add instruction that implicitly read pc. - unsigned Binary = getBinaryCodeForInstr(MI); - const TargetInstrDesc &TID = MI.getDesc(); - MCE.emitWordLE(getAddrMode1InstrBinary(MI, TID, Binary)); + emitDataProcessingInstruction(MI); break; } } } -unsigned ARMCodeEmitter::getAddrModeNoneInstrBinary(const MachineInstr &MI, - const TargetInstrDesc &TID, - unsigned Binary) { - // Set the conditional execution predicate - Binary |= II->getPredicate(&MI) << 28; - - switch (TID.TSFlags & ARMII::FormMask) { - default: - assert(0 && "Unknown instruction subtype!"); - break; - case ARMII::Branch: { - // Set signed_immed_24 field - Binary |= getMachineOpValue(MI, 0); - - // if it is a conditional branch, set cond field - if (TID.Opcode == ARM::Bcc) { - Binary &= 0x0FFFFFFF; // clear conditional field - Binary |= getMachineOpValue(MI, 1) << 28; // set conditional field - } - break; - } - case ARMII::BranchMisc: { - if (TID.Opcode == ARM::BX) - abort(); // FIXME - if (TID.Opcode == ARM::BX_RET) - Binary |= 0xe; // the return register is LR - else - // otherwise, set the return register - Binary |= getMachineOpValue(MI, 0); - break; - } - } - - return Binary; -} - unsigned ARMCodeEmitter::getMachineSoRegOpValue(const MachineInstr &MI, const TargetInstrDesc &TID, const MachineOperand &MO, @@ -453,9 +434,14 @@ unsigned ARMCodeEmitter::getAddrModeSBit(const MachineInstr &MI, return 0; } -unsigned ARMCodeEmitter::getAddrMode1InstrBinary(const MachineInstr &MI, - const TargetInstrDesc &TID, - unsigned Binary) { +void ARMCodeEmitter::emitDataProcessingInstruction(const MachineInstr &MI) { + const TargetInstrDesc &TID = MI.getDesc(); + if (TID.getOpcode() == ARM::MOVi2pieces) + abort(); // FIXME + + // Part of binary is determined by TableGn. + unsigned Binary = getBinaryCodeForInstr(MI); + // Set the conditional execution predicate Binary |= II->getPredicate(&MI) << 28; @@ -471,16 +457,12 @@ unsigned ARMCodeEmitter::getAddrMode1InstrBinary(const MachineInstr &MI, } // Encode first non-shifter register operand if there is one. - unsigned Format = TID.TSFlags & ARMII::FormMask; - bool HasRnReg = !(Format == ARMII::DPRdMisc || - Format == ARMII::DPRdIm || - Format == ARMII::DPRdReg || - Format == ARMII::DPRdSoReg); - if (HasRnReg) { + bool isUnary = TID.TSFlags & ARMII::UnaryDP; + if (!isUnary) { if (TID.getOpcode() == ARM::PICADD) - // Special handling for PICADD. It implicitly use add. - Binary |= - ARMRegisterInfo::getRegisterNumbering(ARM::PC) << ARMII::RegRnShift; + // Special handling for PICADD. It implicitly uses PC register. + Binary |= (ARMRegisterInfo::getRegisterNumbering(ARM::PC) + << ARMII::RegRnShift); else { Binary |= getMachineOpValue(MI, OpIdx) << ARMII::RegRnShift; ++OpIdx; @@ -488,30 +470,33 @@ unsigned ARMCodeEmitter::getAddrMode1InstrBinary(const MachineInstr &MI, } // Encode shifter operand. - bool HasSoReg = (Format == ARMII::DPRdSoReg || - Format == ARMII::DPRnSoReg || - Format == ARMII::DPRSoReg || - Format == ARMII::DPRSoRegS); - const MachineOperand &MO = MI.getOperand(OpIdx); - if (HasSoReg) + if ((TID.TSFlags & ARMII::FormMask) == ARMII::DPSoRegFrm) { // Encode SoReg. - return Binary | getMachineSoRegOpValue(MI, TID, MO, OpIdx); + MCE.emitWordLE(Binary | getMachineSoRegOpValue(MI, TID, MO, OpIdx)); + return; + } - if (MO.isReg()) + if (MO.isReg()) { // Encode register Rm. - return Binary | ARMRegisterInfo::getRegisterNumbering(MO.getReg()); + MCE.emitWordLE(Binary | ARMRegisterInfo::getRegisterNumbering(MO.getReg())); + return; + } // Encode so_imm. // Set bit I(25) to identify this is the immediate form of <shifter_op> Binary |= 1 << ARMII::I_BitShift; Binary |= getMachineSoImmOpValue(MI, TID, MO); - return Binary; + + MCE.emitWordLE(Binary); } -unsigned ARMCodeEmitter::getAddrMode2InstrBinary(const MachineInstr &MI, - const TargetInstrDesc &TID, - unsigned Binary) { +void ARMCodeEmitter::emitLoadStoreInstruction(const MachineInstr &MI) { + const TargetInstrDesc &TID = MI.getDesc(); + + // Part of binary is determined by TableGn. + unsigned Binary = getBinaryCodeForInstr(MI); + // Set the conditional execution predicate Binary |= II->getPredicate(&MI) << 28; @@ -531,7 +516,8 @@ unsigned ARMCodeEmitter::getAddrMode2InstrBinary(const MachineInstr &MI, if (ARM_AM::getAM2Offset(MO3.getImm())) // Set the value of offset_12 field Binary |= ARM_AM::getAM2Offset(MO3.getImm()); - return Binary; + MCE.emitWordLE(Binary); + return; } // Set bit I(25), because this is not in immediate enconding. @@ -547,12 +533,15 @@ unsigned ARMCodeEmitter::getAddrMode2InstrBinary(const MachineInstr &MI, Binary |= ShImm << 7; // shift_immed } - return Binary; + MCE.emitWordLE(Binary); } -unsigned ARMCodeEmitter::getAddrMode3InstrBinary(const MachineInstr &MI, - const TargetInstrDesc &TID, - unsigned Binary) { +void ARMCodeEmitter::emitMiscLoadStoreInstruction(const MachineInstr &MI) { + const TargetInstrDesc &TID = MI.getDesc(); + + // Part of binary is determined by TableGn. + unsigned Binary = getBinaryCodeForInstr(MI); + // Set the conditional execution predicate Binary |= II->getPredicate(&MI) << 28; @@ -573,7 +562,8 @@ unsigned ARMCodeEmitter::getAddrMode3InstrBinary(const MachineInstr &MI, // to the corresponding Rm register. if (MO2.getReg()) { Binary |= ARMRegisterInfo::getRegisterNumbering(MO2.getReg()); - return Binary; + MCE.emitWordLE(Binary); + return; } // if this instr is in immediate offset/index encoding, set bit 22 to 1 @@ -584,12 +574,15 @@ unsigned ARMCodeEmitter::getAddrMode3InstrBinary(const MachineInstr &MI, Binary |= (ImmOffs & ~0xF); // immedL } - return Binary; + MCE.emitWordLE(Binary); } -unsigned ARMCodeEmitter::getAddrMode4InstrBinary(const MachineInstr &MI, - const TargetInstrDesc &TID, - unsigned Binary) { +void ARMCodeEmitter::emitLoadStoreMultipleInstruction(const MachineInstr &MI) { + const TargetInstrDesc &TID = MI.getDesc(); + + // Part of binary is determined by TableGn. + unsigned Binary = getBinaryCodeForInstr(MI); + // Set the conditional execution predicate Binary |= II->getPredicate(&MI) << 28; @@ -626,12 +619,15 @@ unsigned ARMCodeEmitter::getAddrMode4InstrBinary(const MachineInstr &MI, Binary |= 0x1 << RegNum; } - return Binary; + MCE.emitWordLE(Binary); } -unsigned ARMCodeEmitter::getAddrMode6InstrBinary(const MachineInstr &MI, - const TargetInstrDesc &TID, - unsigned Binary) { +void ARMCodeEmitter::emitMulFrm1Instruction(const MachineInstr &MI) { + const TargetInstrDesc &TID = MI.getDesc(); + + // Part of binary is determined by TableGn. + unsigned Binary = getBinaryCodeForInstr(MI); + // Set the conditional execution predicate Binary |= II->getPredicate(&MI) << 28; @@ -653,33 +649,49 @@ unsigned ARMCodeEmitter::getAddrMode6InstrBinary(const MachineInstr &MI, // Encode Rs Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRsShift; - return Binary; + MCE.emitWordLE(Binary); } -/// getInstrBinary - Return binary encoding for the specified -/// machine instruction. -unsigned ARMCodeEmitter::getInstrBinary(const MachineInstr &MI) { +void ARMCodeEmitter::emitBranchInstruction(const MachineInstr &MI) { + const TargetInstrDesc &TID = MI.getDesc(); + // Part of binary is determined by TableGn. unsigned Binary = getBinaryCodeForInstr(MI); - const TargetInstrDesc &TID = MI.getDesc(); - switch (TID.TSFlags & ARMII::AddrModeMask) { - case ARMII::AddrModeNone: - return getAddrModeNoneInstrBinary(MI, TID, Binary); - case ARMII::AddrMode1: - return getAddrMode1InstrBinary(MI, TID, Binary); - case ARMII::AddrMode2: - return getAddrMode2InstrBinary(MI, TID, Binary); - case ARMII::AddrMode3: - return getAddrMode3InstrBinary(MI, TID, Binary); - case ARMII::AddrMode4: - return getAddrMode4InstrBinary(MI, TID, Binary); - case ARMII::AddrMode6: - return getAddrMode6InstrBinary(MI, TID, Binary); + // Set the conditional execution predicate + Binary |= II->getPredicate(&MI) << 28; + + // Set signed_immed_24 field + Binary |= getMachineOpValue(MI, 0); + + // if it is a conditional branch, set cond field + if (TID.Opcode == ARM::Bcc) { + Binary &= 0x0FFFFFFF; // clear conditional field + Binary |= getMachineOpValue(MI, 1) << 28; // set conditional field } - abort(); - return 0; + MCE.emitWordLE(Binary); +} + +void ARMCodeEmitter::emitMiscBranchInstruction(const MachineInstr &MI) { + const TargetInstrDesc &TID = MI.getDesc(); + if (TID.Opcode == ARM::BX) + abort(); // FIXME + + // Part of binary is determined by TableGn. + unsigned Binary = getBinaryCodeForInstr(MI); + + // Set the conditional execution predicate + Binary |= II->getPredicate(&MI) << 28; + + if (TID.Opcode == ARM::BX_RET) + // The return register is LR. + Binary |= ARMRegisterInfo::getRegisterNumbering(ARM::LR); + else + // otherwise, set the return register + Binary |= getMachineOpValue(MI, 0); + + MCE.emitWordLE(Binary); } #include "ARMGenCodeEmitter.inc" diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index e64247763e..d284cd0dd5 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -20,35 +20,32 @@ class Format<bits<5> val> { } def Pseudo : Format<1>; -def MulFrm : Format<2>; -def MulSMLAW : Format<3>; -def MulSMULW : Format<4>; -def MulSMLA : Format<5>; -def MulSMUL : Format<6>; -def Branch : Format<7>; -def BranchMisc : Format<8>; - -def DPRdIm : Format<9>; -def DPRdReg : Format<10>; -def DPRdSoReg : Format<11>; -def DPRdMisc : Format<12>; -def DPRnIm : Format<13>; -def DPRnReg : Format<14>; -def DPRnSoReg : Format<15>; -def DPRIm : Format<16>; -def DPRReg : Format<17>; -def DPRSoReg : Format<18>; -def DPRImS : Format<19>; -def DPRRegS : Format<20>; -def DPRSoRegS : Format<21>; - -def LdFrm : Format<22>; -def StFrm : Format<23>; - -def ArithMisc : Format<24>; -def ThumbFrm : Format<25>; -def VFPFrm : Format<26>; - +def MulFrm1 : Format<2>; +def MulFrm2 : Format<3>; +def MulSMLAW : Format<4>; +def MulSMULW : Format<5>; +def MulSMLA : Format<6>; +def MulSMUL : Format<7>; +def Branch : Format<8>; +def BranchMisc : Format<9>; + +def DPFrm : Format<10>; +def DPSoRegFrm : Format<11>; + +def LdFrm : Format<12>; +def StFrm : Format<13>; +def LdMiscFrm : Format<14>; +def StMiscFrm : Format<15>; +def LdMulFrm : Format<16>; +def StMulFrm : Format<17>; + +def ArithMisc : Format<18>; +def ThumbFrm : Format<19>; +def VFPFrm : Format<20>; + +// Misc flag for data processing instructions that indicates whether +// the instruction has a Rn register operand. +class UnaryDP { bit isUnaryDataProc = 1; } //===----------------------------------------------------------------------===// @@ -63,6 +60,8 @@ class InstARM<bits<4> opcod, AddrMode am, SizeFlagVal sz, IndexMode im, let Namespace = "ARM"; bits<4> Opcode = opcod; + + // TSFlagsFields AddrMode AM = am; bits<4> AddrModeBits = AM.Value; @@ -74,6 +73,11 @@ class InstARM<bits<4> opcod, AddrMode am, SizeFlagVal sz, IndexMode im, Format F = f; bits<5> Form = F.Value; + + // + // Attributes specific to ARM instructions... + // + bit isUnaryDataProc = 0; let Constraints = cstr; } @@ -658,23 +662,20 @@ class AXI4st<bits<4> opcod, dag oops, dag iops, Format f, string asm, let Inst{27-25} = 0b100; } -// addrmode6 // Unsigned multiply, multiply-accumulate instructions. -class AI6<bits<4> opcod, dag oops, dag iops, Format f, string opc, +class AMul1I<bits<4> opcod, dag oops, dag iops, string opc, string asm, list<dag> pattern> - : I<opcod, oops, iops, AddrMode6, Size4Bytes, IndexModeNone, f, opc, - asm,"",pattern> -{ + : I<opcod, oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm1, opc, + asm,"",pattern> { // FIXME: bits 7-4 should be a sub-mode (for SMLAxx, SMLAWy, ...) let Inst{7-4} = 0b1001; let Inst{27-24} = 0b0000; let Inst{23-20} = opcod; } -class AsI6<bits<4> opcod, dag oops, dag iops, Format f, string opc, +class AsMul1I<bits<4> opcod, dag oops, dag iops, string opc, string asm, list<dag> pattern> - : sI<opcod, oops, iops, AddrMode6, Size4Bytes, IndexModeNone, f, opc, - asm,"",pattern> -{ + : sI<opcod, oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm1, opc, + asm,"",pattern> { // FIXME: bits 7-4 should be a sub-mode (for SMLAxx, SMLAWy, ...) let Inst{7-4} = 0b1001; let Inst{27-24} = 0b0000; diff --git a/lib/Target/ARM/ARMInstrInfo.h b/lib/Target/ARM/ARMInstrInfo.h index eb6109ebf3..6f1bf3831d 100644 --- a/lib/Target/ARM/ARMInstrInfo.h +++ b/lib/Target/ARM/ARMInstrInfo.h @@ -39,11 +39,10 @@ namespace ARMII { AddrMode3 = 3, AddrMode4 = 4, AddrMode5 = 5, - AddrMode6 = 6, - AddrModeT1 = 7, - AddrModeT2 = 8, - AddrModeT4 = 9, - AddrModeTs = 10, // i8 * 4 for pc and sp relative data + AddrModeT1 = 6, + AddrModeT2 = 7, + AddrModeT4 = 8, + AddrModeTs = 9, // i8 * 4 for pc and sp relative data // Size* - Flags to keep track of the size of an instruction. SizeShift = 4, @@ -63,56 +62,57 @@ namespace ARMII { // Opcode OpcodeShift = 9, OpcodeMask = 0xf << OpcodeShift, - - // Format - FormShift = 13, - FormMask = 31 << FormShift, + + //===------------------------------------------------------------------===// + // Misc flags. + + // UnaryDP - Indicates this is a unary data processing instruction, i.e. + // it doesn't have a Rn operand. + UnaryDP = 1 << 13, + + //===------------------------------------------------------------------===// + // Instruction encoding formats. + // + FormShift = 14, + FormMask = 0x1f << FormShift, // Pseudo instructions Pseudo = 1 << FormShift, // Multiply instructions - MulFrm = 2 << FormShift, - MulSMLAW = 3 << FormShift, - MulSMULW = 4 << FormShift, - MulSMLA = 5 << FormShift, - MulSMUL = 6 << FormShift, + MulFrm1 = 2 << FormShift, + MulFrm2 = 3 << FormShift, + MulSMLAW = 4 << FormShift, + MulSMULW = 5 << FormShift, + MulSMLA = 6 << FormShift, + MulSMUL = 7 << FormShift, // Branch instructions - Branch = 7 << FormShift, - BranchMisc = 8 << FormShift, + Branch = 8 << FormShift, + BranchMisc = 9 << FormShift, // Data Processing instructions - DPRdIm = 9 << FormShift, - DPRdReg = 10 << FormShift, - DPRdSoReg = 11 << FormShift, - DPRdMisc = 12 << FormShift, - - DPRnIm = 13 << FormShift, - DPRnReg = 14 << FormShift, - DPRnSoReg = 15 << FormShift, - - DPRIm = 16 << FormShift, - DPRReg = 17 << FormShift, - DPRSoReg = 18 << FormShift, - - DPRImS = 19 << FormShift, - DPRRegS = 20 << FormShift, - DPRSoRegS = 21 << FormShift, + DPFrm = 10 << FormShift, + DPSoRegFrm = 11 << FormShift, // Load and Store - LdFrm = 22 << FormShift, - StFrm = 23 << FormShift, + LdFrm = 12 << FormShift, + StFrm = 13 << FormShift, + LdMiscFrm = 14 << FormShift, + StMiscFrm = 15 << FormShift, + LdMulFrm = 16 << FormShift, + StMulFrm = 17 << FormShift, // Miscellaneous arithmetic instructions - ArithMisc = 24 << FormShift, + ArithMisc = 18 << FormShift, // Thumb format - ThumbFrm = 25 << FormShift, + ThumbFrm = 19 << FormShift, // VFP format - VPFFrm = 26 << FormShift, + VPFFrm = 20 << FormShift, + //===------------------------------------------------------------------===// // Field shifts - such shifts are used to set field while generating // machine instructions. RotImmShift = 8, diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index d2ea2b1088..07119a2edb 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -310,11 +310,10 @@ def AddrMode2 : AddrMode<2>; def AddrMode3 : AddrMode<3>; def AddrMode4 : AddrMode<4>; def AddrMode5 : AddrMode<5>; -def AddrMode6 : AddrMode<6>; -def AddrModeT1 : AddrMode<7>; -def AddrModeT2 : AddrMode<8>; -def AddrModeT4 : AddrMode<9>; -def AddrModeTs : AddrMode<10>; +def AddrModeT1 : AddrMode<6>; +def AddrModeT2 : AddrMode<7>; +def AddrModeT4 : AddrMode<8>; +def AddrModeTs : AddrMode<9>; // Instruction size. class SizeFlagVal<bits<3> val> { @@ -345,13 +344,13 @@ include "ARMInstrFormats.td" /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a /// binop that produces a value. multiclass AsI1_bin_irs<bits<4> opcod, string opc, PatFrag opnode> { - def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPRIm, + def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm, opc, " $dst, $a, $b", [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>; - def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPRReg, + def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, opc, " $dst, $a, $b", [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>; - def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPRSoReg, + def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm, opc, " $dst, $a, $b", [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>; } @@ -360,13 +359,13 @@ multiclass AsI1_bin_irs<bits<4> opcod, string opc, PatFrag opnode> { /// instruction modifies the CSPR register. let Defs = [CPSR] in { multiclass ASI1_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode> { - def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPRImS, + def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm, opc, "s $dst, $a, $b", [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>; - def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPRRegS, + def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, opc, "s $dst, $a, $b", [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>; - def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPRSoRegS, + def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm, opc, "s $dst, $a, $b", [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>; } @@ -377,13 +376,13 @@ multiclass ASI1_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode> { /// a explicit result, only implicitly set CPSR. let Defs = [CPSR] in { multiclass AI1_cmp_irs<bits<4> opcod, string opc, PatFrag opnode> { - def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPRnIm, + def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPFrm, opc, " $a, $b", [(opnode GPR:$a, so_imm:$b)]>; - def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPRnReg, + def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPFrm, opc, " $a, $b", [(opnode GPR:$a, GPR:$b)]>; - def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPRnSoReg, + def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPSoRegFrm, opc, " $a, $b", [(opnode GPR:$a, so_reg:$b)]>; } @@ -420,13 +419,13 @@ multiclass AI_bin_rrot<bits<4> opcod, string opc, PatFrag opnode> { let Uses = [CPSR] in { multiclass AsXI1_bin_c_irs<bits<4> opcod, string opc, PatFrag opnode> { def ri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b, cc_out:$s), - DPRIm, !strconcat(opc, "${s} $dst, $a, $b"), + DPFrm, !strconcat(opc, "${s} $dst, $a, $b"), [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>; def rr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b, cc_out:$s), - DPRReg, !strconcat(opc, "${s} $dst, $a, $b"), + DPFrm, !strconcat(opc, "${s} $dst, $a, $b"), [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>; def rs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b, cc_out:$s), - DPRSoReg, !strconcat(opc, "${s} $dst, $a, $b"), + DPSoRegFrm, !strconcat(opc, "${s} $dst, $a, $b"), [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>; } } @@ -533,7 +532,7 @@ let isReturn = 1, isTerminator = 1 in let isReturn = 1, isTerminator = 1 in def LDM_RET : AXI4ldpc<0x0, (outs), (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops), - LdFrm, "ldm${p}${addr:submode} $addr, $dst1", + LdMulFrm, "ldm${p}${addr:submode} $addr, $dst1", []>; let isCall = 1, @@ -610,7 +609,7 @@ def LDRcp : AI2ldw<0x0, (outs GPR:$dst), (ins addrmode2:$addr), LdFrm, "ldr", " $dst, $addr", []>; // Loads with zero extension -def LDRH : AI3ldh<0xB, (outs GPR:$dst), (ins addrmode3:$addr), LdFrm, +def LDRH : AI3ldh<0xB, (outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm, "ldr", "h $dst, $addr", [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>; @@ -619,17 +618,17 @@ def LDRB : AI2ldb<0x1, (outs GPR:$dst), (ins addrmode2:$addr), LdFrm, [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>; // Loads with sign extension -def LDRSH : AI3ldsh<0xE, (outs GPR:$dst), (ins addrmode3:$addr), LdFrm, +def LDRSH : AI3ldsh<0xE, (outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm, "ldr", "sh $dst, $addr", [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>; -def LDRSB : AI3ldsb<0xD, (outs GPR:$dst), (ins addrmode3:$addr), LdFrm, +def LDRSB : AI3ldsb<0xD, (outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm, "ldr", "sb $dst, $addr", [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>; let mayLoad = 1 in { // Load doubleword -def LDRD : AI3ldd<0xD, (outs GPR:$dst), (ins addrmode3:$addr), LdFrm, +def LDRD : AI3ldd<0xD, (outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm, "ldr", "d $dst, $addr", []>, Requires<[IsARM, HasV5T]>; @@ -643,11 +642,11 @@ def LDR_POST : AI2ldwpo<0x0, (outs GPR:$dst, GPR:$base_wb), "ldr", " $dst, [$base], $offset", "$base = $base_wb", []>; def LDRH_PRE : AI3ldhpr<0xB, (outs GPR:$dst, GPR:$base_wb), - (ins addrmode3:$addr), LdFrm, + (ins addrmode3:$addr), LdMiscFrm, "ldr", "h $dst, $addr!", "$addr.base = $base_wb", []>; def LDRH_POST : AI3ldhpo<0xB, (outs GPR:$dst, GPR:$base_wb), - (ins GPR:$base,am3offset:$offset), LdFrm, + (ins GPR:$base,am3offset:$offset), LdMiscFrm, "ldr", "h $dst, [$base], $offset", "$base = $base_wb", []>; def LDRB_PRE : AI2ldbpr<0x1, (outs GPR:$dst, GPR:$base_wb), @@ -659,19 +658,19 @@ def LDRB_POST : AI2ldbpo<0x1, (outs GPR:$dst, GPR:$base_wb), "ldr", "b $dst, [$base], $offset", "$base = $base_wb", []>; def LDRSH_PRE : AI3ldshpr<0xE, (outs GPR:$dst, GPR:$base_wb), - (ins addrmode3:$addr), LdFrm, + (ins addrmode3:$addr), LdMiscFrm, "ldr", "sh $dst, $addr!", "$addr.base = $base_wb", []>; def LDRSH_POST: AI3ldshpo<0xE, (outs GPR:$dst, GPR:$base_wb), - (ins GPR:$base,am3offset:$offset), LdFrm, + (ins GPR:$base,am3offset:$offset), LdMiscFrm, "ldr", "sh $dst, [$base], $offset", "$base = $base_wb", []>; def LDRSB_PRE : AI3ldsbpr<0xD, (outs GPR:$dst, GPR:$base_wb), - (ins addrmode3:$addr), LdFrm, + (ins addrmode3:$addr), LdMiscFrm, "ldr", "sb $dst, $addr!", "$addr.base = $base_wb", []>; def LDRSB_POST: AI3ldsbpo<0xD, (outs GPR:$dst, GPR:$base_wb), - (ins GPR:$base,am3offset:$offset), LdFrm, + (ins GPR:$base,am3offset:$offset), LdMiscFrm, "ldr", "sb $dst, [$base], $offset", "$base = $base_wb", []>; } @@ -681,7 +680,7 @@ def STR : AI2stw<0x0, (outs), (ins GPR:$src, addrmode2:$addr), StFrm, [(store GPR:$src, addrmode2:$addr)]>; // Stores with truncate -def STRH : AI3sth<0xB, (outs), (ins GPR:$src, addrmode3:$addr), StFrm, +def STRH : AI3sth<0xB, (outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm, "str", "h $src, $addr", [(truncstorei16 GPR:$src, addrmode3:$addr)]>; @@ -691,7 +690,7 @@ def STRB : AI2stb<0x1, (outs), (ins GPR:$src, addrmode2:$addr), StFrm, // Store doubleword let mayStore = 1 in -def STRD : AI3std<0xF, (outs), (ins GPR:$src, addrmode3:$addr), StFrm, +def STRD : AI3std<0xF, (outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm, "str", "d $src, $addr", []>, Requires<[IsARM, HasV5T]>; @@ -709,13 +708,13 @@ def STR_POST : AI2stwpo<0x0, (outs GPR:$base_wb), (post_store GPR:$src, GPR:$base, am2offset:$offset))]>; def STRH_PRE : AI3sthpr<0xB, (outs GPR:$base_wb), - (ins GPR:$src, GPR:$base,am3offset:$offset), StFrm, + (ins GPR:$src, GPR:$base,am3offset:$offset), StMiscFrm, "str", "h $src, [$base, $offset]!", "$base = $base_wb", [(set GPR:$base_wb, (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>; def STRH_POST: AI3sthpo<0xB, (outs GPR:$base_wb), - (ins GPR:$src, GPR:$base,am3offset:$offset), StFrm, + (ins GPR:$src, GPR:$base,am3offset:$offset), StMiscFrm, "str", "h $src, [$base], $offset", "$base = $base_wb", [(set GPR:$base_wb, (post_truncsti16 GPR:$src, GPR:$base, am3offset:$offset))]>; @@ -740,42 +739,42 @@ def STRB_POST: AI2stbpo<0x1, (outs GPR:$base_wb), let mayLoad = 1 in def LDM : AXI4ld<0x0, (outs), (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops), - LdFrm, "ldm${p}${addr:submode} $addr, $dst1", + LdMulFrm, "ldm${p}${addr:submode} $addr, $dst1", []>; let mayStore = 1 in def STM : AXI4st<0x0, (outs), (ins addrmode4:$addr, pred:$p, reglist:$src1, variable_ops), - StFrm, "stm${p}${addr:submode} $addr, $src1", + StMulFrm, "stm${p}${addr:submode} $addr, $src1", []>; //===----------------------------------------------------------------------===// // Move Instructions. // -def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPRdReg, - "mov", " $dst, $src", []>; -def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src), DPRdSoReg, - "mov", " $dst, $src", [(set GPR:$dst, so_reg:$src)]>; +def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, + "mov", " $dst, $src", []>, UnaryDP; +def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm, + "mov", " $dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP; let isReMaterializable = 1 in -def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPRdIm, - "mov", " $dst, $src", [(set GPR:$dst, so_imm:$src)]>; +def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm, + "mov", " $dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP; -def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPRdMisc, +def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, "mov", " $dst, $src, rrx", - [(set GPR:$dst, (ARMrrx GPR:$src))]>; + [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP; // These aren't really mov instructions, but we have to define them this way // due to flag operands. let Defs = [CPSR] in { -def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPRdMisc, +def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, "mov", "s $dst, $src, lsr #1", - [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>; -def MOVsra_flag : AI1 |