diff options
Diffstat (limited to 'lib/Target/ARM')
29 files changed, 872 insertions, 604 deletions
diff --git a/lib/Target/ARM/ARM.td b/lib/Target/ARM/ARM.td index ce0aed9..bd1c7af 100644 --- a/lib/Target/ARM/ARM.td +++ b/lib/Target/ARM/ARM.td @@ -180,7 +180,7 @@ def HasV8Ops : SubtargetFeature<"v8", "HasV8Ops", "true", "Support ARM v8 instructions", [HasV7Ops, FeatureVirtualization, FeatureMP]>; -def FeatureV8_1a : SubtargetFeature<"v8.1a", "HasV8_1a", "true", +def HasV8_1aOps : SubtargetFeature<"v8.1a", "HasV8_1aOps", "true", "Support ARM v8.1a instructions", [HasV8Ops, FeatureAClass, FeatureCRC]>; @@ -260,6 +260,14 @@ def ProcA57 : SubtargetFeature<"a57", "ARMProcFamily", "CortexA57", FeatureTrustZone, FeatureT2XtPk, FeatureCrypto, FeatureCRC]>; +def ProcR4 : SubtargetFeature<"r4", "ARMProcFamily", "CortexR4", + "Cortex-R4 ARM processors", + [FeatureHWDiv, + FeatureAvoidPartialCPSR, + FeatureDSPThumb2, FeatureT2XtPk, + HasV7Ops, FeatureDB, FeatureHasRAS, + FeatureRClass]>; + def ProcR5 : SubtargetFeature<"r5", "ARMProcFamily", "CortexR5", "Cortex-R5 ARM processors", [FeatureSlowFPBrcc, @@ -396,6 +404,16 @@ def : ProcessorModel<"krait", CortexA9Model, FeatureDSPThumb2, FeatureHasRAS, FeatureAClass]>; +// FIXME: R4 has currently the same ProcessorModel as A8. +def : ProcessorModel<"cortex-r4", CortexA8Model, + [ProcR4]>; + +// FIXME: R4F has currently the same ProcessorModel as A8. +def : ProcessorModel<"cortex-r4f", CortexA8Model, + [ProcR4, + FeatureSlowFPBrcc, FeatureHasSlowFPVMLx, + FeatureVFP3, FeatureVFPOnlySP, FeatureD16]>; + // FIXME: R5 has currently the same ProcessorModel as A8. def : ProcessorModel<"cortex-r5", CortexA8Model, [ProcR5, HasV7Ops, FeatureDB, @@ -457,14 +475,6 @@ def : ProcessorModel<"cyclone", SwiftModel, FeatureDB,FeatureDSPThumb2, FeatureHasRAS, FeatureZCZeroing]>; -// V8.1 Processors -def : ProcNoItin<"generic-armv8.1-a", [HasV8Ops, FeatureV8_1a, - FeatureDB, FeatureFPARMv8, - FeatureNEON, FeatureDSPThumb2, - FeatureHWDiv, FeatureHWDivARM, - FeatureTrustZone, FeatureT2XtPk, - FeatureCrypto]>; - //===----------------------------------------------------------------------===// // Register File Description //===----------------------------------------------------------------------===// @@ -485,7 +495,15 @@ def ARMInstrInfo : InstrInfo; // Declare the target which we are implementing //===----------------------------------------------------------------------===// +def ARMAsmWriter : AsmWriter { + string AsmWriterClassName = "InstPrinter"; + int PassSubtarget = 1; + int Variant = 0; + bit isMCAsmWriter = 1; +} + def ARM : Target { // Pull in Instruction Info: let InstructionSet = ARMInstrInfo; + let AssemblyWriters = [ARMAsmWriter]; } diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index 102def1..1a2acf5 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -207,7 +207,7 @@ GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const { SmallString<60> Name; raw_svector_ostream(Name) << DL->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_' << uid << '_' << uid2; - return OutContext.GetOrCreateSymbol(Name.str()); + return OutContext.GetOrCreateSymbol(Name); } @@ -216,7 +216,7 @@ MCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel() const { SmallString<60> Name; raw_svector_ostream(Name) << DL->getPrivateGlobalPrefix() << "SJLJEH" << getFunctionNumber(); - return OutContext.GetOrCreateSymbol(Name.str()); + return OutContext.GetOrCreateSymbol(Name); } bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, @@ -520,28 +520,6 @@ void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) { // generates code that does this, it is always safe to set. OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); } - - // Emit a .data.rel section containing any stubs that were created. - if (TT.isOSBinFormatELF()) { - const TargetLoweringObjectFileELF &TLOFELF = - static_cast<const TargetLoweringObjectFileELF &>(getObjFileLowering()); - - MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>(); - - // Output stubs for external and common global variables. - MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList(); - if (!Stubs.empty()) { - OutStreamer.SwitchSection(TLOFELF.getDataRelSection()); - const DataLayout *TD = TM.getDataLayout(); - - for (auto &stub: Stubs) { - OutStreamer.EmitLabel(stub.first); - OutStreamer.EmitSymbolValue(stub.second.getPointer(), - TD->getPointerSize(0)); - } - Stubs.clear(); - } - } } //===----------------------------------------------------------------------===// @@ -597,7 +575,7 @@ void ARMAsmPrinter::emitAttributes() { std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU); if (!FS.empty()) { if (!ArchFS.empty()) - ArchFS = ArchFS + "," + FS.str(); + ArchFS = (Twine(ArchFS) + "," + FS).str(); else ArchFS = FS; } @@ -661,8 +639,8 @@ void ARMAsmPrinter::emitAttributes() { // Emit Tag_Advanced_SIMD_arch for ARMv8 architecture if (STI.hasV8Ops()) ATS.emitAttribute(ARMBuildAttrs::Advanced_SIMD_arch, - STI.hasV8_1a() ? ARMBuildAttrs::AllowNeonARMv8_1a: - ARMBuildAttrs::AllowNeonARMv8); + STI.hasV8_1aOps() ? ARMBuildAttrs::AllowNeonARMv8_1a: + ARMBuildAttrs::AllowNeonARMv8); } else { if (STI.hasFPARMv8()) // FPv5 and FP-ARMv8 have the same instructions, so are modeled as one diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp index a8c7657..3f79a9b 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -245,11 +245,15 @@ ARMBaseRegisterInfo::getRegAllocationHints(unsigned VirtReg, // This register should preferably be even (Odd == 0) or odd (Odd == 1). // Check if the other part of the pair has already been assigned, and provide // the paired register as the first hint. + unsigned Paired = Hint.second; + if (Paired == 0) + return; + unsigned PairedPhys = 0; - if (VRM && VRM->hasPhys(Hint.second)) { - PairedPhys = getPairedGPR(VRM->getPhys(Hint.second), Odd, this); - if (PairedPhys && MRI.isReserved(PairedPhys)) - PairedPhys = 0; + if (TargetRegisterInfo::isPhysicalRegister(Paired)) { + PairedPhys = Paired; + } else if (VRM && VRM->hasPhys(Paired)) { + PairedPhys = getPairedGPR(VRM->getPhys(Paired), Odd, this); } // First prefer the paired physreg. @@ -284,9 +288,14 @@ ARMBaseRegisterInfo::updateRegAllocHint(unsigned Reg, unsigned NewReg, // change. unsigned OtherReg = Hint.second; Hint = MRI->getRegAllocationHint(OtherReg); - if (Hint.second == Reg) - // Make sure the pair has not already divorced. + // Make sure the pair has not already divorced. + if (Hint.second == Reg) { MRI->setRegAllocationHint(OtherReg, Hint.first, NewReg); + if (TargetRegisterInfo::isVirtualRegister(NewReg)) + MRI->setRegAllocationHint(NewReg, + Hint.first == (unsigned)ARMRI::RegPairOdd ? ARMRI::RegPairEven + : ARMRI::RegPairOdd, OtherReg); + } } } diff --git a/lib/Target/ARM/ARMConstantPoolValue.h b/lib/Target/ARM/ARMConstantPoolValue.h index 13bef54..36f63e2 100644 --- a/lib/Target/ARM/ARMConstantPoolValue.h +++ b/lib/Target/ARM/ARMConstantPoolValue.h @@ -86,7 +86,7 @@ protected: } public: - virtual ~ARMConstantPoolValue(); + ~ARMConstantPoolValue() override; ARMCP::ARMCPModifier getModifier() const { return Modifier; } const char *getModifierText() const; diff --git a/lib/Target/ARM/ARMFrameLowering.cpp b/lib/Target/ARM/ARMFrameLowering.cpp index 830953b..9d2b09b 100644 --- a/lib/Target/ARM/ARMFrameLowering.cpp +++ b/lib/Target/ARM/ARMFrameLowering.cpp @@ -311,6 +311,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const { return; StackAdjustingInsts DefCFAOffsetCandidates; + bool HasFP = hasFP(MF); // Allocate the vararg register save area. if (ArgRegsSaveSize) { @@ -327,6 +328,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const { DefCFAOffsetCandidates.addInst(std::prev(MBBI), NumBytes - ArgRegsSaveSize, true); } + DefCFAOffsetCandidates.emitDefCFAOffsets(MMI, MBB, dl, TII, HasFP); return; } @@ -375,7 +377,6 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const { } // Determine starting offsets of spill areas. - bool HasFP = hasFP(MF); unsigned GPRCS1Offset = NumBytes - ArgRegsSaveSize - GPRCS1Size; unsigned GPRCS2Offset = GPRCS1Offset - GPRCS2Size; unsigned DPRAlign = DPRCSSize ? std::min(8U, Align) : 4U; diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 3b1b8dd..72afd2c 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -3504,25 +3504,34 @@ SDValue ARMTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const { ARMCC::CondCodes CondCode, CondCode2; FPCCToARMCC(CC, CondCode, CondCode2); - // Try to generate VSEL on ARMv8. + // Try to generate VMAXNM/VMINNM on ARMv8. if (Subtarget->hasFPARMv8() && (TrueVal.getValueType() == MVT::f32 || TrueVal.getValueType() == MVT::f64)) { - // We can select VMAXNM/VMINNM from a compare followed by a select with the + // We can use VMAXNM/VMINNM for a compare followed by a select with the // same operands, as follows: - // c = fcmp [ogt, olt, ugt, ult] a, b + // c = fcmp [?gt, ?ge, ?lt, ?le] a, b // select c, a, b - // We only do this in unsafe-fp-math, because signed zeros and NaNs are - // handled differently than the original code sequence. + // In NoNaNsFPMath the CC will have been changed from, e.g., 'ogt' to 'gt'. + // We only do this transformation in UnsafeFPMath and for no-NaNs + // comparisons, because signed zeros and NaNs are handled differently than + // the original code sequence. + // FIXME: There are more cases that can be transformed even with NaNs, + // signed zeroes and safe math. E.g. in the following, the result will be + // FalseVal if a is a NaN or -0./0. and that's what vmaxnm will give, too. + // c = fcmp ogt, a, 0. ; select c, a, 0. => vmaxnm a, 0. + // FIXME: There is similar code that allows some extensions in + // AArch64TargetLowering::LowerSELECT_CC that should be shared with this + // code. if (getTargetMachine().Options.UnsafeFPMath) { if (LHS == TrueVal && RHS == FalseVal) { - if (CC == ISD::SETOGT || CC == ISD::SETUGT) + if (CC == ISD::SETGT || CC == ISD::SETGE) return DAG.getNode(ARMISD::VMAXNM, dl, VT, TrueVal, FalseVal); - if (CC == ISD::SETOLT || CC == ISD::SETULT) + if (CC == ISD::SETLT || CC == ISD::SETLE) return DAG.getNode(ARMISD::VMINNM, dl, VT, TrueVal, FalseVal); } else if (LHS == FalseVal && RHS == TrueVal) { - if (CC == ISD::SETOLT || CC == ISD::SETULT) + if (CC == ISD::SETLT || CC == ISD::SETLE) return DAG.getNode(ARMISD::VMAXNM, dl, VT, TrueVal, FalseVal); - if (CC == ISD::SETOGT || CC == ISD::SETUGT) + if (CC == ISD::SETGT || CC == ISD::SETGE) return DAG.getNode(ARMISD::VMINNM, dl, VT, TrueVal, FalseVal); } } diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index c3984ca..52f3555 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -208,6 +208,8 @@ def HasV8 : Predicate<"Subtarget->hasV8Ops()">, AssemblerPredicate<"HasV8Ops", "armv8">; def PreV8 : Predicate<"!Subtarget->hasV8Ops()">, AssemblerPredicate<"!HasV8Ops", "armv7 or earlier">; +def HasV8_1a : Predicate<"Subtarget->hasV8_1aOps()">, + AssemblerPredicate<"HasV8_1aOps", "armv8.1a">; def NoVFP : Predicate<"!Subtarget->hasVFP2()">; def HasVFP2 : Predicate<"Subtarget->hasVFP2()">, AssemblerPredicate<"FeatureVFP2", "VFP2">; @@ -226,8 +228,6 @@ def HasCrypto : Predicate<"Subtarget->hasCrypto()">, AssemblerPredicate<"FeatureCrypto", "crypto">; def HasCRC : Predicate<"Subtarget->hasCRC()">, AssemblerPredicate<"FeatureCRC", "crc">; -def HasV8_1a : Predicate<"Subtarget->hasV8_1a()">, - AssemblerPredicate<"FeatureV8_1a", "v8.1a">; def HasFP16 : Predicate<"Subtarget->hasFP16()">, AssemblerPredicate<"FeatureFP16","half-float">; def HasDivide : Predicate<"Subtarget->hasDivide()">, @@ -388,6 +388,9 @@ def fsub_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fsub node:$lhs, node:$rhs),[{ // Immediate operands with a shared generic asm render method. class ImmAsmOperand : AsmOperandClass { let RenderMethod = "addImmOperands"; } +// Operands that are part of a memory addressing mode. +class MemOperand : Operand<i32> { let OperandType = "OPERAND_MEMORY"; } + // Branch target. // FIXME: rename brtarget to t2_brtarget def brtarget : Operand<OtherVT> { @@ -790,7 +793,7 @@ def imm1_16 : Operand<i32>, PatLeaf<(imm), [{ return Imm > 0 && Imm <= 16; }], // addrmode_imm12 := reg +/- imm12 // def MemImm12OffsetAsmOperand : AsmOperandClass { let Name = "MemImm12Offset"; } -class AddrMode_Imm12 : Operand<i32>, +class AddrMode_Imm12 : MemOperand, ComplexPattern<i32, 2, "SelectAddrModeImm12", []> { // 12-bit immediate operand. Note that instructions using this encode // #0 and #-0 differently. We flag #-0 as the magic value INT32_MIN. All other @@ -813,7 +816,7 @@ def addrmode_imm12_pre : AddrMode_Imm12 { // ldst_so_reg := reg +/- reg shop imm // def MemRegOffsetAsmOperand : AsmOperandClass { let Name = "MemRegOffset"; } -def ldst_so_reg : Operand<i32>, +def ldst_so_reg : MemOperand, ComplexPattern<i32, 3, "SelectLdStSOReg", []> { let EncoderMethod = "getLdStSORegOpValue"; // FIXME: Simplify the printer @@ -829,7 +832,7 @@ def ldst_so_reg : Operand<i32>, // {8} 1 is imm8 is non-negative. 0 otherwise. // {7-0} [0,255] imm8 value. def PostIdxImm8AsmOperand : AsmOperandClass { let Name = "PostIdxImm8"; } -def postidx_imm8 : Operand<i32> { +def postidx_imm8 : MemOperand { let PrintMethod = "printPostIdxImm8Operand"; let ParserMatchClass = PostIdxImm8AsmOperand; let MIOperandInfo = (ops i32imm); @@ -841,7 +844,7 @@ def postidx_imm8 : Operand<i32> { // {8} 1 is imm8 is non-negative. 0 otherwise. // {7-0} [0,255] imm8 value, scaled by 4. def PostIdxImm8s4AsmOperand : AsmOperandClass { let Name = "PostIdxImm8s4"; } -def postidx_imm8s4 : Operand<i32> { +def postidx_imm8s4 : MemOperand { let PrintMethod = "printPostIdxImm8s4Operand"; let ParserMatchClass = PostIdxImm8s4AsmOperand; let MIOperandInfo = (ops i32imm); @@ -854,7 +857,7 @@ def PostIdxRegAsmOperand : AsmOperandClass { let Name = "PostIdxReg"; let ParserMethod = "parsePostIdxReg"; } -def postidx_reg : Operand<i32> { +def postidx_reg : MemOperand { let EncoderMethod = "getPostIdxRegOpValue"; let DecoderMethod = "DecodePostIdxReg"; let PrintMethod = "printPostIdxRegOperand"; @@ -869,7 +872,7 @@ def postidx_reg : Operand<i32> { // FIXME: addrmode2 should be refactored the rest of the way to always // use explicit imm vs. reg versions above (addrmode_imm12 and ldst_so_reg). def AddrMode2AsmOperand : AsmOperandClass { let Name = "AddrMode2"; } -def addrmode2 : Operand<i32>, +def addrmode2 : MemOperand, ComplexPattern<i32, 3, "SelectAddrMode2", []> { let EncoderMethod = "getAddrMode2OpValue"; let PrintMethod = "printAddrMode2Operand"; @@ -881,7 +884,7 @@ def PostIdxRegShiftedAsmOperand : AsmOperandClass { let Name = "PostIdxRegShifted"; let ParserMethod = "parsePostIdxReg"; } -def am2offset_reg : Operand<i32>, +def am2offset_reg : MemOperand, ComplexPattern<i32, 2, "SelectAddrMode2OffsetReg", [], [SDNPWantRoot]> { let EncoderMethod = "getAddrMode2OffsetOpValue"; @@ -894,7 +897,7 @@ def am2offset_reg : Operand<i32>, // FIXME: am2offset_imm should only need the immediate, not the GPR. Having // the GPR is purely vestigal at this point. def AM2OffsetImmAsmOperand : AsmOperandClass { let Name = "AM2OffsetImm"; } -def am2offset_imm : Operand<i32>, +def am2offset_imm : MemOperand, ComplexPattern<i32, 2, "SelectAddrMode2OffsetImm", [], [SDNPWantRoot]> { let EncoderMethod = "getAddrMode2OffsetOpValue"; @@ -909,7 +912,7 @@ def am2offset_imm : Operand<i32>, // // FIXME: split into imm vs. reg versions. def AddrMode3AsmOperand : AsmOperandClass { let Name = "AddrMode3"; } -class AddrMode3 : Operand<i32>, +class AddrMode3 : MemOperand, ComplexPattern<i32, 3, "SelectAddrMode3", []> { let EncoderMethod = "getAddrMode3OpValue"; let ParserMatchClass = AddrMode3AsmOperand; @@ -932,7 +935,7 @@ def AM3OffsetAsmOperand : AsmOperandClass { let Name = "AM3Offset"; let ParserMethod = "parseAM3Offset"; } -def am3offset : Operand<i32>, +def am3offset : MemOperand, ComplexPattern<i32, 2, "SelectAddrMode3Offset", [], [SDNPWantRoot]> { let EncoderMethod = "getAddrMode3OffsetOpValue"; @@ -951,7 +954,7 @@ def ldstm_mode : OptionalDefOperand<OtherVT, (ops i32), (ops (i32 1))> { // addrmode5 := reg +/- imm8*4 // def AddrMode5AsmOperand : AsmOperandClass { let Name = "AddrMode5"; } -class AddrMode5 : Operand<i32>, +class AddrMode5 : MemOperand, ComplexPattern<i32, 2, "SelectAddrMode5", []> { let EncoderMethod = "getAddrMode5OpValue"; let DecoderMethod = "DecodeAddrMode5Operand"; @@ -970,7 +973,7 @@ def addrmode5_pre : AddrMode5 { // addrmode6 := reg with optional alignment // def AddrMode6AsmOperand : AsmOperandClass { let Name = "AlignedMemory"; } -def addrmode6 : Operand<i32>, +def addrmode6 : MemOperand, ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{ let PrintMethod = "printAddrMode6Operand"; let MIOperandInfo = (ops GPR:$addr, i32imm:$align); @@ -979,7 +982,7 @@ def addrmode6 : Operand<i32>, let ParserMatchClass = AddrMode6AsmOperand; } -def am6offset : Operand<i32>, +def am6offset : MemOperand, ComplexPattern<i32, 1, "SelectAddrMode6Offset", [], [SDNPWantRoot]> { let PrintMethod = "printAddrMode6OffsetOperand"; @@ -990,7 +993,7 @@ def am6offset : Operand<i32>, // Special version of addrmode6 to handle alignment encoding for VST1/VLD1 // (single element from one lane) for size 32. -def addrmode6oneL32 : Operand<i32>, +def addrmode6oneL32 : MemOperand, ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{ let PrintMethod = "printAddrMode6Operand"; let MIOperandInfo = (ops GPR:$addr, i32imm); @@ -998,7 +1001,7 @@ def addrmode6oneL32 : Operand<i32>, } // Base class for addrmode6 with specific alignment restrictions. -class AddrMode6Align : Operand<i32>, +class AddrMode6Align : MemOperand, ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{ let PrintMethod = "printAddrMode6Operand"; let MIOperandInfo = (ops GPR:$addr, i32imm:$align); @@ -1074,7 +1077,7 @@ def addrmode6align64or128or256 : AddrMode6Align { // Special version of addrmode6 to handle alignment encoding for VLD-dup // instructions, specifically VLD4-dup. -def addrmode6dup : Operand<i32>, +def addrmode6dup : MemOperand, ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{ let PrintMethod = "printAddrMode6Operand"; let MIOperandInfo = (ops GPR:$addr, i32imm); @@ -1085,7 +1088,7 @@ def addrmode6dup : Operand<i32>, } // Base class for addrmode6dup with specific alignment restrictions. -class AddrMode6DupAlign : Operand<i32>, +class AddrMode6DupAlign : MemOperand, ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{ let PrintMethod = "printAddrMode6Operand"; let MIOperandInfo = (ops GPR:$addr, i32imm); @@ -1149,7 +1152,7 @@ def addrmode6dupalign64or128 : AddrMode6DupAlign { // addrmodepc := pc + reg // -def addrmodepc : Operand<i32>, +def addrmodepc : MemOperand, ComplexPattern<i32, 2, "SelectAddrModePC", []> { let PrintMethod = "printAddrModePCOperand"; let MIOperandInfo = (ops GPR, i32imm); @@ -1158,7 +1161,7 @@ def addrmodepc : Operand<i32>, // addr_offset_none := reg // def MemNoOffsetAsmOperand : AsmOperandClass { let Name = "MemNoOffset"; } -def addr_offset_none : Operand<i32>, +def addr_offset_none : MemOperand, ComplexPattern<i32, 1, "SelectAddrOffsetNone", []> { let PrintMethod = "printAddrMode7Operand"; let DecoderMethod = "DecodeAddrMode7Operand"; @@ -1417,7 +1420,8 @@ multiclass AsI1_rbin_s_is<InstrItinClass iii, InstrItinClass iir, let isCompare = 1, Defs = [CPSR] in { multiclass AI1_cmp_irs<bits<4> opcod, string opc, InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, - PatFrag opnode, bit Commutable = 0> { + PatFrag opnode, bit Commutable = 0, + string rrDecoderMethod = ""> { def ri : AI1<opcod, (outs), (ins GPR:$Rn, mod_imm:$imm), DPFrm, iii, opc, "\t$Rn, $imm", [(opnode GPR:$Rn, mod_imm:$imm)]>, @@ -1445,6 +1449,7 @@ multiclass AI1_cmp_irs<bits<4> opcod, string opc, let Inst{15-12} = 0b0000; let Inst{11-4} = 0b00000000; let Inst{3-0} = Rm; + let DecoderMethod = rrDecoderMethod; let Unpredictable{15-12} = 0b1111; } @@ -4263,6 +4268,30 @@ def CRC32W : AI_crc32<0, 0b10, "w", int_arm_crc32w>; def CRC32CW : AI_crc32<1, 0b10, "cw", int_arm_crc32cw>; //===----------------------------------------------------------------------===// +// ARMv8.1a Privilege Access Never extension +// +// SETPAN #imm1 + +def SETPAN : AInoP<(outs), (ins imm0_1:$imm), MiscFrm, NoItinerary, "setpan", + "\t$imm", []>, Requires<[IsARM, HasV8, HasV8_1a]> { + bits<1> imm; + + let Inst{31-28} = 0b1111; + let Inst{27-20} = 0b00010001; + let Inst{19-16} = 0b0000; + let Inst{15-10} = 0b000000; + let Inst{9} = imm; + let Inst{8} = 0b0; + let Inst{7-4} = 0b0000; + let Inst{3-0} = 0b0000; + + let Unpredictable{19-16} = 0b1111; + let Unpredictable{15-10} = 0b111111; + let Unpredictable{8} = 0b1; + let Unpredictable{3-0} = 0b1111; +} + +//===----------------------------------------------------------------------===// // Comparison Instructions... // @@ -4366,7 +4395,8 @@ def : ARMPat<(ARMcmpZ GPR:$src, mod_imm_neg:$imm), // Note that TST/TEQ don't set all the same flags that CMP does! defm TST : AI1_cmp_irs<0b1000, "tst", IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr, - BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>, 1>; + BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>, 1, + "DecodeTSTInstruction">; defm TEQ : AI1_cmp_irs<0b1001, "teq", IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr, BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>, 1>; diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index 3c62e0e..d0ade77 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -142,7 +142,7 @@ def t_blxtarget : Operand<i32> { // t_addrmode_pc := <label> => pc + imm8 * 4 // -def t_addrmode_pc : Operand<i32> { +def t_addrmode_pc : MemOperand { let EncoderMethod = "getAddrModePCOpValue"; let DecoderMethod = "DecodeThumbAddrModePC"; let PrintMethod = "printThumbLdrLabelOperand"; @@ -153,7 +153,7 @@ def t_addrmode_pc : Operand<i32> { // t_addrmode_rr := reg + reg // def t_addrmode_rr_asm_operand : AsmOperandClass { let Name = "MemThumbRR"; } -def t_addrmode_rr : Operand<i32>, +def t_addrmode_rr : MemOperand, ComplexPattern<i32, 2, "SelectThumbAddrModeRR", []> { let EncoderMethod = "getThumbAddrModeRegRegOpValue"; let PrintMethod = "printThumbAddrModeRROperand"; @@ -169,7 +169,7 @@ def t_addrmode_rr : Operand<i32>, // the reg+imm forms will match instead. This is a horrible way to do that, // as it forces tight coupling between the methods, but it's how selectiondag // currently works. -def t_addrmode_rrs1 : Operand<i32>, +def t_addrmode_rrs1 : MemOperand, ComplexPattern<i32, 2, "SelectThumbAddrModeRI5S1", []> { let EncoderMethod = "getThumbAddrModeRegRegOpValue"; let PrintMethod = "printThumbAddrModeRROperand"; @@ -177,7 +177,7 @@ def t_addrmode_rrs1 : Operand<i32>, let ParserMatchClass = t_addrmode_rr_asm_operand; let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg); } -def t_addrmode_rrs2 : Operand<i32>, +def t_addrmode_rrs2 : MemOperand, ComplexPattern<i32, 2, "SelectThumbAddrModeRI5S2", []> { let EncoderMethod = "getThumbAddrModeRegRegOpValue"; let DecoderMethod = "DecodeThumbAddrModeRR"; @@ -185,7 +185,7 @@ def t_addrmode_rrs2 : Operand<i32>, let ParserMatchClass = t_addrmode_rr_asm_operand; let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg); } -def t_addrmode_rrs4 : Operand<i32>, +def t_addrmode_rrs4 : MemOperand, ComplexPattern<i32, 2, "SelectThumbAddrModeRI5S4", []> { let EncoderMethod = "getThumbAddrModeRegRegOpValue"; let DecoderMethod = "DecodeThumbAddrModeRR"; @@ -197,7 +197,7 @@ def t_addrmode_rrs4 : Operand<i32>, // t_addrmode_is4 := reg + imm5 * 4 // def t_addrmode_is4_asm_operand : AsmOperandClass { let Name = "MemThumbRIs4"; } -def t_addrmode_is4 : Operand<i32>, +def t_addrmode_is4 : MemOperand, ComplexPattern<i32, 2, "SelectThumbAddrModeImm5S4", []> { let EncoderMethod = "getAddrModeISOpValue"; let DecoderMethod = "DecodeThumbAddrModeIS"; @@ -209,7 +209,7 @@ def t_addrmode_is4 : Operand<i32>, // t_addrmode_is2 := reg + imm5 * 2 // def t_addrmode_is2_asm_operand : AsmOperandClass { let Name = "MemThumbRIs2"; } -def t_addrmode_is2 : Operand<i32>, +def t_addrmode_is2 : MemOperand, ComplexPattern<i32, 2, "SelectThumbAddrModeImm5S2", []> { let EncoderMethod = "getAddrModeISOpValue"; let DecoderMethod = "DecodeThumbAddrModeIS"; @@ -221,7 +221,7 @@ def t_addrmode_is2 : Operand<i32>, // t_addrmode_is1 := reg + imm5 // def t_addrmode_is1_asm_operand : AsmOperandClass { let Name = "MemThumbRIs1"; } -def t_addrmode_is1 : Operand<i32>, +def t_addrmode_is1 : MemOperand, ComplexPattern<i32, 2, "SelectThumbAddrModeImm5S1", []> { let EncoderMethod = "getAddrModeISOpValue"; let DecoderMethod = "DecodeThumbAddrModeIS"; @@ -235,7 +235,7 @@ def t_addrmode_is1 : Operand<i32>, // FIXME: This really shouldn't have an explicit SP operand at all. It should // be implicit, just like in the instruction encoding itself. def t_addrmode_sp_asm_operand : AsmOperandClass { let Name = "MemThumbSPI"; } -def t_addrmode_sp : Operand<i32>, +def t_addrmode_sp : MemOperand, ComplexPattern<i32, 2, "SelectThumbAddrModeSP", []> { let EncoderMethod = "getAddrModeThumbSPOpValue"; let DecoderMethod = "DecodeThumbAddrModeSP"; diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 10b0a0e..103ee00 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -148,7 +148,7 @@ def lo5AllOne : PatLeaf<(i32 imm), [{ // t2addrmode_imm12 := reg + imm12 def t2addrmode_imm12_asmoperand : AsmOperandClass {let Name="MemUImm12Offset";} -def t2addrmode_imm12 : Operand<i32>, +def t2addrmode_imm12 : MemOperand, ComplexPattern<i32, 2, "SelectT2AddrModeImm12", []> { let PrintMethod = "printAddrModeImm12Operand<false>"; let EncoderMethod = "getAddrModeImm12OpValue"; @@ -178,7 +178,7 @@ def t2adrlabel : Operand<i32> { // t2addrmode_posimm8 := reg + imm8 def MemPosImm8OffsetAsmOperand : AsmOperandClass {let Name="MemPosImm8Offset";} -def t2addrmode_posimm8 : Operand<i32> { +def t2addrmode_posimm8 : MemOperand { let PrintMethod = "printT2AddrModeImm8Operand<false>"; let EncoderMethod = "getT2AddrModeImm8OpValue"; let DecoderMethod = "DecodeT2AddrModeImm8"; @@ -188,7 +188,7 @@ def t2addrmode_posimm8 : Operand<i32> { // t2addrmode_negimm8 := reg - imm8 def MemNegImm8OffsetAsmOperand : AsmOperandClass {let Name="MemNegImm8Offset";} -def t2addrmode_negimm8 : Operand<i32>, +def t2addrmode_negimm8 : MemOperand, ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> { let PrintMethod = "printT2AddrModeImm8Operand<false>"; let EncoderMethod = "getT2AddrModeImm8OpValue"; @@ -199,7 +199,7 @@ def t2addrmode_negimm8 : Operand<i32>, // t2addrmode_imm8 := reg +/- imm8 def MemImm8OffsetAsmOperand : AsmOperandClass { let Name = "MemImm8Offset"; } -class T2AddrMode_Imm8 : Operand<i32>, +class T2AddrMode_Imm8 : MemOperand, ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> { let EncoderMethod = "getT2AddrModeImm8OpValue"; let DecoderMethod = "DecodeT2AddrModeImm8"; @@ -215,7 +215,7 @@ def t2addrmode_imm8_pre : T2AddrMode_Imm8 { let PrintMethod = "printT2AddrModeImm8Operand<true>"; } -def t2am_imm8_offset : Operand<i32>, +def t2am_imm8_offset : MemOperand, ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset", [], [SDNPWantRoot]> { let PrintMethod = "printT2AddrModeImm8OffsetOperand"; @@ -225,7 +225,7 @@ def t2am_imm8_offset : Operand<i32>, // t2addrmode_imm8s4 := reg +/- (imm8 << 2) def MemImm8s4OffsetAsmOperand : AsmOperandClass {let Name = "MemImm8s4Offset";} -class T2AddrMode_Imm8s4 : Operand<i32> { +class T2AddrMode_Imm8s4 : MemOperand { let EncoderMethod = "getT2AddrModeImm8s4OpValue"; let DecoderMethod = "DecodeT2AddrModeImm8s4"; let ParserMatchClass = MemImm8s4OffsetAsmOperand; @@ -241,7 +241,7 @@ def t2addrmode_imm8s4_pre : T2AddrMode_Imm8s4 { } def t2am_imm8s4_offset_asmoperand : AsmOperandClass { let Name = "Imm8s4"; } -def t2am_imm8s4_offset : Operand<i32> { +def t2am_imm8s4_offset : MemOperand { let PrintMethod = "printT2AddrModeImm8s4OffsetOperand"; let EncoderMethod = "getT2Imm8s4OpValue"; let DecoderMethod = "DecodeT2Imm8S4"; @@ -251,7 +251,7 @@ def t2am_imm8s4_offset : Operand<i32> { def MemImm0_1020s4OffsetAsmOperand : AsmOperandClass { let Name = "MemImm0_1020s4Offset"; } -def t2addrmode_imm0_1020s4 : Operand<i32>, +def t2addrmode_imm0_1020s4 : MemOperand, ComplexPattern<i32, 2, "SelectT2AddrModeExclusive"> { let PrintMethod = "printT2AddrModeImm0_1020s4Operand"; let EncoderMethod = "getT2AddrModeImm0_1020s4OpValue"; @@ -262,7 +262,7 @@ def t2addrmode_imm0_1020s4 : Operand<i32>, // t2addrmode_so_reg := reg + (reg << imm2) def t2addrmode_so_reg_asmoperand : AsmOperandClass {let Name="T2MemRegOffset";} -def t2addrmode_so_reg : Operand<i32>, +def t2addrmode_so_reg : MemOperand, ComplexPattern<i32, 3, "SelectT2AddrModeSoReg", []> { let PrintMethod = "printT2AddrModeSoRegOperand"; let EncoderMethod = "getT2AddrModeSORegOpValue"; @@ -273,13 +273,13 @@ def t2addrmode_so_reg : Operand<i32>, // Addresses for the TBB/TBH instructions. def addrmode_tbb_asmoperand : AsmOperandClass { let Name = "MemTBB"; } -def addrmode_tbb : Operand<i32> { +def addrmode_tbb : MemOperand { let PrintMethod = "printAddrModeTBB"; let ParserMatchClass = addrmode_tbb_asmoperand; let MIOperandInfo = (ops GPR:$Rn, rGPR:$Rm); } def addrmode_tbh_asmoperand : AsmOperandClass { let Name = "MemTBH"; } -def addrmode_tbh : Operand<i32> { +def addrmode_tbh : MemOperand { let PrintMethod = "printAddrModeTBH"; let ParserMatchClass = addrmode_tbh_asmoperand; let MIOperandInfo = (ops GPR:$Rn, rGPR:$Rm); @@ -3630,8 +3630,8 @@ def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask), // Branch and Exchange Jazelle -- for disassembly only // Rm = Inst{19-16} -def t2BXJ : T2I<(outs), (ins rGPR:$func), NoItinerary, "bxj", "\t$func", []>, - Sched<[WriteBr]>, Requires<[IsThumb2, IsNotMClass, PreV8]> { +def t2BXJ : T2I<(outs), (ins GPRnopc:$func), NoItinerary, "bxj", "\t$func", []>, + Sched<[WriteBr]>, Requires<[IsThumb2, IsNotMClass]> { bits<4> func; let Inst{31-27} = 0b11110; let Inst{26} = 0; @@ -4281,6 +4281,23 @@ def t2CDP2 : T2Cop<0b1111, (outs), (ins p_imm:$cop, imm0_15:$opc1, //===----------------------------------------------------------------------===// +// ARMv8.1 Privilege Access Never extension +// +// SETPAN #imm1 + +def t2SETPAN : T1I<(outs), (ins imm0_1:$imm), NoItinerary, "setpan\t$imm", []>, + T1Misc<0b0110000>, Requires<[IsThumb2, HasV8, HasV8_1a]> { + bits<1> imm; + + let Inst{4} = 0b1; + let Inst{3} = imm; + let Inst{2-0} = 0b000; + + let Unpredictable{4} = 0b1; + let Unpredictable{2-0} = 0b111; +} + +//===----------------------------------------------------------------------===// // Non-Instruction Patterns // diff --git a/lib/Target/ARM/ARMSubtarget.cpp b/lib/Target/ARM/ARMSubtarget.cpp index fbec9e6..2a3e1da 100644 --- a/lib/Target/ARM/ARMSubtarget.cpp +++ b/lib/Target/ARM/ARMSubtarget.cpp @@ -133,6 +133,7 @@ void ARMSubtarget::initializeEnvironment() { HasV6T2Ops = false; HasV7Ops = false; HasV8Ops = false; + HasV8_1aOps = false; HasVFPv2 = false; HasVFPv3 = false; HasVFPv4 = false; @@ -166,7 +167,6 @@ void ARMSubtarget::initializeEnvironment() { HasTrustZone = false; HasCrypto = false; HasCRC = false; - HasV8_1a = false; HasZeroCycleZeroing = false; AllowsUnalignedMem = false; Thumb2DSP = false; @@ -191,7 +191,7 @@ void ARMSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) { ARM_MC::ParseARMTriple(TargetTriple.getTriple(), CPUString); if (!FS.empty()) { if (!ArchFS.empty()) - ArchFS = ArchFS + "," + FS.str(); + ArchFS = (Twine(ArchFS) + "," + FS).str(); else ArchFS = FS; } @@ -254,7 +254,7 @@ void ARMSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) { switch (IT) { case DefaultIT: - RestrictIT = hasV8Ops() ? true : false; + RestrictIT = hasV8Ops(); break; case RestrictedIT: RestrictIT = true; diff --git a/lib/Target/ARM/ARMSubtarget.h b/lib/Target/ARM/ARMSubtarget.h index f36cd5c..d82314d 100644 --- a/lib/Target/ARM/ARMSubtarget.h +++ b/lib/Target/ARM/ARMSubtarget.h @@ -43,7 +43,7 @@ class ARMSubtarget : public ARMGenSubtargetInfo { protected: enum ARMProcFamilyEnum { Others, CortexA5, CortexA7, CortexA8, CortexA9, CortexA12, CortexA15, - CortexA17, CortexR5, Swift, CortexA53, CortexA57, Krait, + CortexA17, CortexR4, CortexR4F, CortexR5, Swift, CortexA53, CortexA57, Krait, }; enum ARMProcClassEnum { None, AClass, RClass, MClass @@ -67,6 +67,7 @@ protected: bool HasV6T2Ops; bool HasV7Ops; bool HasV8Ops; + bool HasV8_1aOps; /// HasVFPv2, HasVFPv3, HasVFPv4, HasFPARMv8, HasNEON - Specify what /// floating point ISAs are supported. @@ -182,9 +183,6 @@ protected: /// HasCRC - if true, processor supports CRC instructions bool HasCRC; - /// HasV8_1a - if true, the processor has V8.1a: PAN and RDMA extensions - bool HasV8_1a; - /// If true, the instructions "vmov.i32 d0, #0" and "vmov.i32 q0, #0" are /// particularly effective at zeroing a VFP register. bool HasZeroCycleZeroing; @@ -295,6 +293,7 @@ public: bool hasV6T2Ops() const { return HasV6T2Ops; } bool hasV7Ops() const { return HasV7Ops; } bool hasV8Ops() const { return HasV8Ops; } + bool hasV8_1aOps() const { return HasV8_1aOps; } bool isCortexA5() const { return ARMProcFamily == CortexA5; } bool isCortexA7() const { return ARMProcFamily == CortexA7; } @@ -316,7 +315,6 @@ public: bool hasNEON() const { return HasNEON; } bool hasCrypto() const { return HasCrypto; } bool hasCRC() const { return HasCRC; } - bool hasV8_1a() const { return HasV8_1a; } bool hasVirtualization() const { return HasVirtualization; } bool useNEONForSinglePrecisionFP() const { return hasNEON() && UseNEONForSinglePrecisionFP; diff --git a/lib/Target/ARM/ARMTargetMachine.cpp b/lib/Target/ARM/ARMTargetMachine.cpp index 1bee1b0..ae33340 100644 --- a/lib/Target/ARM/ARMTargetMachine.cpp +++ b/lib/Target/ARM/ARMTargetMachine.cpp @@ -42,6 +42,11 @@ EnableARMLoadStoreOpt("arm-load-store-opt", cl::Hidden, cl::desc("Enable ARM load/store optimization pass"), cl::init(true)); +// FIXME: Unify control over GlobalMerge. +static cl::opt<cl::boolOrDefault> +EnableGlobalMerge("arm-global-merge", cl::Hidden, + cl::desc("Enable the global merge pass")); + extern "C" void LLVMInitializeARMTarget() { // Register the target. RegisterTargetMachine<ARMLETargetMachine> X(TheARMLETarget); @@ -332,7 +337,9 @@ void ARMPassConfig::addIRPasses() { } bool ARMPassConfig::addPreISel() { - if (TM->getOptLevel() == CodeGenOpt::Aggressive) + if ((TM->getOptLevel() == CodeGenOpt::Aggressive && + EnableGlobalMerge == cl::BOU_UNSET) || + EnableGlobalMerge == cl::BOU_TRUE) // FIXME: This is using the thumb1 only constant value for // maximal global offset for merging globals. We may want // to look into using the old value for non-thumb1 code of diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 2215efb..b9ad2c8 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -276,8 +276,8 @@ class ARMAsmParser : public MCTargetAsmParser { bool hasD16() const { return STI.getFeatureBits() & ARM::FeatureD16; } - bool hasV8_1a() const { - return STI.getFeatureBits() & ARM::FeatureV8_1a; + bool hasV8_1aOps() const { + return STI.getFeatureBits() & ARM::HasV8_1aOps; } void SwitchMode() { @@ -5418,47 +5418,44 @@ StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, /// inclusion of carry set or predication code operands. // // FIXME: It would be nice to autogen this. -void ARMAsmParser:: -getMnemonicAcceptInfo(StringRef Mnemonic, StringRef FullInst, - bool &CanAcceptCarrySet, bool &CanAcceptPredicationCode) { - if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || +void ARMAsmParser::getMnemonicAcceptInfo(StringRef Mnemonic, StringRef FullInst, + bool &CanAcceptCarrySet, + bool &CanAcceptPredicationCode) { + CanAcceptCarrySet = + Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || - Mnemonic == "add" || Mnemonic == "adc" || - Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || - Mnemonic == "orr" || Mnemonic == "mvn" || - Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || - Mnemonic == "sbc" || Mnemonic == "eor" || Mnemonic == "neg" || - Mnemonic == "vfm" || Mnemonic == "vfnm" || - (!isThumb() && (Mnemonic == "smull" || Mnemonic == "mov" || - Mnemonic == "mla" || Mnemonic == "smlal" || - Mnemonic == "umlal" || Mnemonic == "umull"))) { - CanAcceptCarrySet = true; - } else - CanAcceptCarrySet = false; + Mnemonic == "add" || Mnemonic == "adc" || Mnemonic == "mul" || + Mnemonic == "bic" || Mnemonic == "asr" || Mnemonic == "orr" || + Mnemonic == "mvn" || Mnemonic == "rsb" || Mnemonic == "rsc" || + Mnemonic == "orn" || Mnemonic == "sbc" || Mnemonic == "eor" || + Mnemonic == "neg" || Mnemonic == "vfm" || Mnemonic == "vfnm" || + (!isThumb() && + (Mnemonic == "smull" || Mnemonic == "mov" || Mnemonic == "mla" || + Mnemonic == "smlal" || Mnemonic == "umlal" || Mnemonic == "umull")); if (Mnemonic == "bkpt" || Mnemonic == "cbnz" || Mnemonic == "setend" || - Mnemonic == "cps" || Mnemonic == "it" || Mnemonic == "cbz" || + Mnemonic == "cps" || Mnemonic == "it" || Mnemonic == "cbz" || Mnemonic == "trap" || Mnemonic == "hlt" || Mnemonic == "udf" || Mnemonic.startswith("crc32") || Mnemonic.startswith("cps") || - Mnemonic.startswith("vsel") || - Mnemonic == "vmaxnm" || Mnemonic == "vminnm" || Mnemonic == "vcvta" || - Mnemonic == "vcvtn" || Mnemonic == "vcvtp" || Mnemonic == "vcvtm" || - Mnemonic == "vrinta" || Mnemonic == "vrintn" || Mnemonic == "vrintp" || - Mnemonic == "vrintm" || Mnemonic.startswith("aes") || Mnemonic == "hvc" || + Mnemonic.startswith("vsel") || Mnemonic == "vmaxnm" || + Mnemonic == "vminnm" || Mnemonic == "vcvta" || Mnemonic == "vcvtn" || + Mnemonic == "vcvtp" || Mnemonic == "vcvtm" || Mnemonic == "vrinta" || + Mnemonic == "vrintn" || Mnemonic == "vrintp" || Mnemonic == "vrintm" || + Mnemonic.startswith("aes") || Mnemonic == "hvc" || Mnemonic == "setpan" || Mnemonic.startswith("sha1") || Mnemonic.startswith("sha256") || (FullInst.startswith("vmull") && FullInst.endswith(".p64"))) { // These mnemonics are never predicable CanAcceptPredicationCode = false; } else if (!isThumb()) { // Some instructions are only predicable in Thumb mode - CanAcceptPredicationCode - = Mnemonic != "cdp2" && Mnemonic != "clrex" && Mnemonic != "mcr2" && + CanAcceptPredicationCode = + Mnemonic != "cdp2" && Mnemonic != "clrex" && Mnemonic != "mcr2" && Mnemonic != "mcrr2" && Mnemonic != "mrc2" && Mnemonic != "mrrc2" && Mnemonic != "dmb" && Mnemonic != "dsb" && Mnemonic != "isb" && Mnemonic != "pld" && Mnemonic != "pli" && Mnemonic != "pldw" && - Mnemonic != "ldc2" && Mnemonic != "ldc2l" && - Mnemonic != "stc2" && Mnemonic != "stc2l" && - !Mnemonic.startswith("rfe") && !Mnemonic.startswith("srs"); + Mnemonic != "ldc2" && Mnemonic != "ldc2l" && Mnemonic != "stc2" && + Mnemonic != "stc2l" && !Mnemonic.startswith("rfe") && + !Mnemonic.startswith("srs"); } else if (isThumbOne()) { if (hasV6MOps()) CanAcceptPredicationCode = Mnemonic != "movs"; @@ -6153,6 +6150,14 @@ bool ARMAsmParser::validateInstruction(MCInst &Inst, "destination operands can't be identical"); return false; } + case ARM::t2BXJ: { + const unsigned RmReg = Inst.getOperand(0).getReg(); + // Rm = SP is no longer unpredictable in v8-A + if (RmReg == ARM::SP && !hasV8Ops()) + return Error(Operands[2]->getStartLoc(), + "r13 (SP) is an unpredictable operand to BXJ"); + return false; + } case ARM::STRD: { // Rt2 must be Rt + 1. unsigned Rt = MRI->getEncodingValue(Inst.getOperand(0).getReg()); diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 4d5122a..4c169a8 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -91,7 +91,7 @@ public: MCDisassembler(STI, Ctx) { } - ~ARMDisassembler() {} + ~ARMDisassembler() override {} DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, ArrayRef<uint8_t> Bytes, uint64_t Address, @@ -106,7 +106,7 @@ public: MCDisassembler(STI, Ctx) { } - ~ThumbDisassembler() {} + ~ThumbDisassembler() override {} DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, ArrayRef<uint8_t> Bytes, uint64_t Address, @@ -212,6 +212,10 @@ static DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); static DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeTSTInstruction(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); +static DecodeStatus DecodeSETPANInstruction(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); static DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); static DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val, @@ -2119,6 +2123,54 @@ static DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn, return S; } +static DecodeStatus DecodeTSTInstruction(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + DecodeStatus S = MCDisassembler::Success; + + unsigned Pred = fieldFromInstruction(Insn, 28, 4); + unsigned Rn = fieldFromInstruction(Insn, 16, 4); + unsigned Rm = fieldFromInstruction(Insn, 0, 4); + + if (Pred == 0xF) + return DecodeSETPANInstruction(Inst, Insn, Address, Decoder); + + if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) + return MCDisassembler::Fail; + if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) + return MCDisassembler::Fail; + if (!Check(S, DecodePredicateOperand(Inst, Pred, Address, Decoder))) + return MCDisassembler::Fail; + + return S; +} + +static DecodeStatus DecodeSETPANInstruction(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + DecodeStatus S = MCDisassembler::Success; + + unsigned Imm = fieldFromInstruction(Insn, 9, 1); + + const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); + uint64_t FeatureBits = Dis->getSubtargetInfo().getFeatureBits(); + if ((FeatureBits & ARM::HasV8_1aOps) == 0 || + (FeatureBits & ARM::HasV8Ops) == 0 ) + return MCDisassembler::Fail; + + // Decoder can be called from DecodeTST, which does not check the full + // encoding is valid. + if (fieldFromInstruction(Insn, 20,12) != 0xf11 || + fieldFromInstruction(Insn, 4,4) != 0) + return MCDisassembler::Fail; + if (fieldFromInstruction(Insn, 10,10) != 0 || + fieldFromInstruction(Insn, 0,4) != 0) + S = MCDisassembler::SoftFail; + + Inst.setOpcode(ARM::SETPAN); + Inst.addOperand(MCOperand::CreateImm(Imm)); + + return S; +} + static DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder) { DecodeStatus S = MCDisassembler::Success; diff --git a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp index e15323d..c2e1b2a 100644 --- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp +++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp @@ -40,12 +40,12 @@ static unsigned translateShiftImm(unsigned imm) { /// Prints the shift value with an immediate value. static void printRegImmShift(raw_ostream &O, ARM_AM::ShiftOpc ShOpc, - unsigned ShImm, bool UseMarkup) { + unsigned ShImm, bool UseMarkup) { if (ShOpc == ARM_AM::no_shift || (ShOpc == ARM_AM::lsl && !ShImm)) return; O << ", "; - assert (!(ShOpc == ARM_AM::ror && !ShImm) && "Cannot have ror #0"); + assert(!(ShOpc == ARM_AM::ror && !ShImm) && "Cannot have ror #0"); O << getShiftOpcStr(ShOpc); if (ShOpc != ARM_AM::rrx) { @@ -58,49 +58,52 @@ static void printRegImmShift(raw_ostream &O, ARM_AM::ShiftOpc ShOpc, } } -ARMInstPrinter::ARMInstPrinter(const MCAsmInfo &MAI, - const MCInstrInfo &MII, - const MCRegisterInfo &MRI, - const MCSubtargetInfo &STI) : - MCInstPrinter(MAI, MII, MRI) { - // Initialize the set of available features. - setAvailableFeatures(STI.getFeatureBits()); -} +ARMInstPrinter::ARMInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, + const MCRegisterInfo &MRI) + : MCInstPrinter(MAI, MII, MRI) {} void ARMInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { - OS << markup("<reg:") - << getRegisterName(RegNo) - << markup(">"); + OS << markup("<reg:") << getRegisterName(RegNo) << markup(">"); } void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O, - StringRef Annot) { + StringRef Annot, const MCSubtargetInfo &STI) { unsigned Opcode = MI->getOpcode(); - switch(Opcode) { + switch (Opcode) { // Check for HINT instructions w/ canonical names. case ARM::HINT: case ARM::tHINT: case ARM::t2HINT: switch (MI->getOperand(0).getImm()) { - case 0: O << "\tnop"; break; - case 1: O << "\tyield"; break; - case 2: O << "\twfe"; break; - case 3: O << "\twfi"; break; - case 4: O << "\tsev"; break; + case 0: + O << "\tnop"; + break; + case 1: + O << "\tyield"; + break; + case 2: + O << "\twfe"; + break; + case 3: + O << "\twfi"; + break; + case 4: + O << "\tsev"; + break; case 5: - if ((getAvailableFeatures() & ARM::HasV8Ops)) { + if ((STI.getFeatureBits() & ARM::HasV8Ops)) { O << "\tsevl"; break; } // Fallthrough for non-v8 default: // Anything else should just print normally. - printInstruction(MI, O); + printInstruction(MI, STI, O); printAnnotation(O, Annot); return; } - printPredicateOperand(MI, 1, O); + printPredicateOperand(MI, 1, STI, O); if (Opcode == ARM::t2HINT) O << ".w"; printAnnotation(O, Annot); @@ -115,8 +118,8 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O, const MCOperand &MO3 = MI->getOperand(3); O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm())); - printSBitModifierOperand(MI, 6, O); - printPredicateOperand(MI, 4, O); + printSBitModifierOperand(MI, 6, STI, O); + printPredicateOperand(MI, 4, STI, O); O << '\t'; printRegName(O, Dst.getReg()); @@ -137,8 +140,8 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O, const MCOperand &MO2 = MI->getOperand(2); O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO2.getImm())); - printSBitModifierOperand(MI, 5, O); - printPredicateOperand(MI, 3, O); + printSBitModifierOperand(MI, 5, STI, O); + printPredicateOperand(MI, 3, STI, O); O << '\t'; printRegName(O, Dst.getReg()); @@ -150,10 +153,8 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O, return; } - O << ", " - << markup("<imm:") - << "#" << translateShiftImm(ARM_AM::getSORegOffset(MO2.getImm())) - << markup(">"); + O << ", " << markup("<imm:") << "#" + << translateShiftImm(ARM_AM::getSORegOffset(MO2.getImm())) << markup(">"); printAnnotation(O, Annot); return; } @@ -164,11 +165,11 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O, if (MI->getOperand(0).getReg() == ARM::SP && MI->getNumOperands() > 5) { // Should only print PUSH if there are at least two registers in the list. O << '\t' << "push"; - printPredicateOperand(MI, 2, O); + printPredicateOperand(MI, 2, STI, O); if (Opcode == ARM::t2STMDB_UPD) O << ".w"; O << '\t'; - printRegisterList(MI, 4, O); + printRegisterList(MI, 4, STI, O); printAnnotation(O, Annot); return; } else @@ -178,7 +179,7 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O, if (MI->getOperand(2).getReg() == ARM::SP && MI->getOperand(3).getImm() == -4) { O << '\t' << "push"; - printPredicateOperand(MI, 4, O); + printPredicateOperand(MI, 4, STI, O); O << "\t{"; printRegName(O, MI->getOperand(1).getReg()); O << "}"; @@ -193,11 +194,11 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O, if (MI->getOperand(0).getReg() == ARM::SP && MI->getNumOperands() > 5) { // Should only print POP if there are at least two registers in the list. O << '\t' << "pop"; - printPredicateOperand(MI, 2, O); + printPredicateOperand(MI, 2, STI, O); if (Opcode == ARM::t2LDMIA_UPD) O << ".w"; O << '\t'; - printRegisterList(MI, 4, O); + printRegisterList(MI, 4, STI, O); printAnnotation(O, Annot); return; } else @@ -207,7 +208,7 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O, if (MI->getOperand(2).getReg() == ARM::SP && MI->getOperand(4).getImm() == 4) { O << '\t' << "pop"; - printPredicateOperand(MI, 5, O); + printPredicateOperand(MI, 5, STI, O); O << "\t{"; printRegName(O, MI->getOperand(0).getReg()); O << "}"; @@ -221,9 +222,9 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O, case ARM::VSTMDDB_UPD: if (MI->getOperand(0).getReg() == ARM::SP) { O << '\t' << "vpush"; - printPredicateOperand(MI, 2, O); + printPredicateOperand(MI, 2, STI, O); O << '\t'; - printRegisterList(MI, 4, O); + printRegisterList(MI, 4, STI, O); printAnnotation(O, Annot); return; } else @@ -234,9 +235,9 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O, case ARM::VLDMDIA_UPD: if (MI->getOperand(0).getReg() == ARM::SP) { O << '\t' << "vpop"; - printPredicateOperand(MI, 2, O); + printPredicateOperand(MI, 2, STI, O); O << '\t'; - printRegisterList(MI, 4, O); + printRegisterList(MI, 4, STI, O); printAnnotation(O, Annot); return; } else @@ -252,12 +253,13 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O, O << "\tldm"; - printPredicateOperand(MI, 1, O); + printPredicateOperand(MI, 1, STI, O); O << '\t'; printRegName(O, BaseReg); - if (Writeback) O << "!"; + if (Writeback) + O << "!"; O << ", "; - printRegisterList(MI, 3, O); + printRegisterList(MI, 3, STI, O); printAnnotation(O, Annot); return; } @@ -268,9 +270,11 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O, // GPRs. However, when decoding them, the two GRPs cannot be automatically // expressed as a GPRPair, so we have to manually merge them. // FIXME: We would really like to be able to tablegen'erate this. - case ARM::LDREXD: case ARM::STREXD: - case ARM::LDAEXD: case ARM::STLEXD: { - const MCRegisterClass& MRC = MRI.getRegClass(ARM::GPRRegClassID); + case ARM::LDREXD: + case ARM::STREXD: + case ARM::LDAEXD: + case ARM::STLEXD: { + const MCRegisterClass &MRC = MRI.getRegClass(ARM::GPRRegClassID); bool isStore = Opcode == ARM::STREXD || Opcode == ARM::STLEXD; unsigned Reg = MI->getOperand(isStore ? 1 : 0).getReg(); if (MRC.contains(Reg)) { @@ -280,28 +284,27 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O, if (isStore) NewMI.addOperand(MI->getOperand(0)); - NewReg = MCOperand::CreateReg(MRI.getMatchingSuperReg(Reg, ARM::gsub_0, - &MRI.getRegClass(ARM::GPRPairRegClassID))); + NewReg = MCOperand::CreateReg(MRI.getMatchingSuperReg( + Reg, ARM::gsub_0, &MRI.getRegClass(ARM::GPRPairRegClassID))); NewMI.addOperand(NewReg); // Copy the rest operands into NewMI. - for(unsigned i= isStore ? 3 : 2; i < MI->getNumOperands(); ++i) + for (unsigned i = isStore ? 3 : 2; i < MI->getNumOperands(); ++i) NewMI.addOperand(MI->getOperand(i)); - printInstruction(&NewMI, O); + printInstruction(&NewMI, STI, O); return; } break; } - // B9.3.3 ERET (Thumb) - // For a target that has Virtualization Extensions, ERET is the preferred - // disassembly of SUBS PC, LR, #0 + // B9.3.3 ERET (Thumb) + // For a target that has Virtualization Extensions, ERET is the preferred + // disassembly of SUBS PC, LR, #0 case ARM::t2SUBS_PC_LR: { - if (MI->getNumOperands() == 3 && - MI->getOperand(0).isImm() && + if (MI->getNumOperands() == 3 && MI->getOperand(0).isImm() && MI->getOperand(0).getImm() == 0 && - (getAvailableFeatures() & ARM::FeatureVirtualization)) { + (STI.getFeatureBits() & ARM::FeatureVirtualization)) { O << "\teret"; - printPredicateOperand(MI, 1, O); + printPredicateOperand(MI, 1, STI, O); printAnnotation(O, Annot); return; } @@ -309,20 +312,18 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O, } } - printInstruction(MI, O); + printInstruction(MI, STI, O); printAnnotation(O, Annot); } void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &O) { + const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &Op = MI->getOperand(OpNo); if (Op.isReg()) { unsigned Reg = Op.getReg(); printRegName(O, Reg); } else if (Op.isImm()) { - O << markup("<imm:") - << '#' << formatImm(Op.getImm()) - << markup(">"); + O << markup("<imm:") << '#' << formatImm(Op.getImm()) << markup(">"); } else { assert(Op.isExpr() && "unknown operand kind in printOperand"); const MCExpr *Expr = Op.getExpr(); @@ -354,6 +355,7 @@ void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, } void ARMInstPrinter::printThumbLdrLabelOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(OpNum); if (MO1.isExpr()) { @@ -370,13 +372,9 @@ void ARMInstPrinter::printThumbLdrLabelOperand(const MCInst *MI, unsigned OpNum, if (OffImm == INT32_MIN) OffImm = 0; if (isSub) { - O << markup("<imm:") - << "#-" << formatImm(-OffImm) - << markup(">"); + O << markup("<imm:") << "#-" << formatImm(-OffImm) << markup(">"); } else { - O << markup("<imm:") - << "#" << formatImm(OffImm) - << markup(">"); + O << markup("<imm:") << "#" << formatImm(OffImm) << markup(">"); } O << "]" << markup(">"); } @@ -387,10 +385,11 @@ void ARMInstPrinter::printThumbLdrLabelOperand(const MCInst *MI, unsigned OpNum, // REG REG 0,SH_OPC - e.g. R5, ROR R3 // REG 0 IMM,SH_OPC - e.g. R5, LSL #3 void ARMInstPrinter::printSORegRegOperand(const MCInst *MI, unsigned OpNum, - raw_ostream &O) { + const MCSubtargetInfo &STI, + raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(OpNum); - const MCOperand &MO2 = MI->getOperand(OpNum+1); - const MCOperand &MO3 = MI->getOperand(OpNum+2); + const MCOperand &MO2 = MI->getOperand(OpNum + 1); + const MCOperand &MO3 = MI->getOperand(OpNum + 2); printRegName(O, MO1.getReg()); @@ -406,9 +405,10 @@ void ARMInstPrinter::printSORegRegOperand(const MCInst *MI, unsigned OpNum, } void ARMInstPrinter::printSORegImmOperand(const MCInst *MI, unsigned OpNum, - raw_ostream &O) { + const MCSubtargetInfo &STI, + raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(OpNum); - const MCOperand &MO2 = MI->getOperand(OpNum+1); + const MCOperand &MO2 = MI->getOperand(OpNum + 1); printRegName(O, MO1.getReg()); @@ -417,28 +417,25 @@ void ARMInstPrinter::printSORegImmOperand(const MCInst *MI, unsigned OpNum, ARM_AM::getSORegOffset(MO2.getImm()), UseMarkup); } - //===--------------------------------------------------------------------===// // Addressing Mode #2 //===--------------------------------------------------------------------===// void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op, + const MCSubtargetInfo &STI, raw_ostream &O) { 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); + const MCOperand &MO3 = MI->getOperand(Op + 2); O << markup("<mem:") << "["; printRegName(O, MO1.getReg()); if (!MO2.getReg()) { if (ARM_AM::getAM2Offset(MO3.getImm())) { // Don't print +0. - O << ", " - << markup("<imm:") - << "#" + O << ", " << markup("<imm:") << "#" << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) - << ARM_AM::getAM2Offset(MO3.getImm()) - << markup(">"); + << ARM_AM::getAM2Offset(MO3.getImm()) << markup(">"); } O << "]" << markup(">"); return; @@ -454,9 +451,10 @@ void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op, } void ARMInstPrinter::printAddrModeTBB(const MCInst *MI, unsigned Op, - raw_ostream &O) { + const MCSubtargetInfo &STI, + raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(Op); - const MCOperand &MO2 = MI->getOperand(Op+1); + const MCOperand &MO2 = MI->getOperand(Op + 1); O << markup("<mem:") << "["; printRegName(O, MO1.getReg()); O << ", "; @@ -465,9 +463,10 @@ void ARMInstPrinter::printAddrModeTBB(const MCInst *MI, unsigned Op, } void ARMInstPrinter::printAddrModeTBH(const MCInst *MI, unsigned Op, - raw_ostream &O) { + const MCSubtargetInfo &STI, + raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(Op); - const MCOperand &MO2 = MI->getOperand(Op+1); + const MCOperand &MO2 = MI->getOperand(Op + 1); O << markup("<mem:") << "["; printRegName(O, MO1.getReg()); O << ", "; @@ -476,35 +475,35 @@ void ARMInstPrinter::printAddrModeTBH(const MCInst *MI, unsigned Op, } void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op, + const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(Op); - if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. - printOperand(MI, Op, O); + if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. + printOperand(MI, Op, STI, O); return; } #ifndef NDEBUG - const MCOperand &MO3 = MI->getOperand(Op+2); + const MCOperand &MO3 = MI->getOperand(Op + 2); unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm()); - assert(IdxMode != ARMII::IndexModePost && - "Should be pre or offset index op"); + assert(IdxMode != ARMII::IndexModePost && "Should be pre or offset index op"); #endif - printAM2PreOrOffsetIndexOp(MI, Op, O); + printAM2PreOrOffsetIndexOp(MI, Op, STI, O); } void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(OpNum); - const MCOperand &MO2 = MI->getOperand(OpNum+1); + const MCOperand &MO2 = MI->getOperand(OpNum + 1); if (!MO1.getReg()) { unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm()); - O << markup("<imm:") - << '#' << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm())) - << ImmOffs + O << markup("<imm:") << '#' + << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm())) << ImmOffs << markup(">"); return; } @@ -524,8 +523,8 @@ void ARMInstPrinter::printAM3PreOrOffsetIndexOp(const MCInst *MI, unsigned Op, raw_ostream &O, bool AlwaysPrintImm0) { 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); + const MCOperand &MO3 = MI->getOperand(Op + 2); O << markup("<mem:") << '['; printRegName(O, MO1.getReg()); @@ -537,16 +536,12 @@ void ARMInstPrinter::printAM3PreOrOffsetIndexOp(const MCInst *MI, unsigned Op, return; } - //If the op is sub we have to print the immediate even if it is 0 + // If the op is sub we have to print the immediate even if it is 0 unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()); ARM_AM::AddrOpc op = ARM_AM::getAM3Op(MO3.getImm()); if (AlwaysPrintImm0 || ImmOffs || (op == ARM_AM::sub)) { - O << ", " - << markup("<imm:") - << "#" - << ARM_AM::getAddrOpcStr(op) - << ImmOffs + O << ", " << markup("<imm:") << "#" << ARM_AM::getAddrOpcStr(op) << ImmOffs << markup(">"); } O << ']' << markup(">"); @@ -554,10 +549,11 @@ void ARMInstPrinter::printAM3PreOrOffsetIndexOp(const MCInst *MI, unsigned Op, template <bool AlwaysPrintImm0> void ARMInstPrinter::printAddrMode3Operand(const MCInst *MI, unsigned Op, + const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(Op); - if (!MO1.isReg()) { // For label symbolic references. - printOperand(MI, Op, O); + if (!MO1.isReg()) { // For label symbolic references. + printOperand(MI, Op, STI, O); return; } @@ -569,9 +565,10 @@ void ARMInstPrinter::printAddrMode3Operand(const MCInst *MI, unsigned Op, void ARMInstPrinter::printAddrMode3OffsetOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(OpNum); - const MCOperand &MO2 = MI->getOperand(OpNum+1); + const MCOperand &MO2 = MI->getOperand(OpNum + 1); if (MO1.getReg()) { O << getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm())); @@ -580,56 +577,56 @@ void ARMInstPrinter::printAddrMode3OffsetOperand(const MCInst *MI, } unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm()); - O << markup("<imm:") - << '#' << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm())) << ImmOffs + O << markup("<imm:") << '#' + << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm())) << ImmOffs << markup(">"); } -void ARMInstPrinter::printPostIdxImm8Operand(const MCInst *MI, - unsigned OpNum, +void ARMInstPrinter::printPostIdxImm8Operand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &MO = MI->getOperand(OpNum); unsigned Imm = MO.getImm(); - O << markup("<imm:") - << '#' << ((Imm & 256) ? "" : "-") << (Imm & 0xff) + O << markup("<imm:") << '#' << ((Imm & 256) ? "" : "-") << (Imm & 0xff) << markup(">"); } void ARMInstPrinter::printPostIdxRegOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(OpNum); - const MCOperand &MO2 = MI->getOperand(OpNum+1); + const MCOperand &MO2 = MI->getOperand(OpNum + 1); O << (MO2.getImm() ? "" : "-"); printRegName(O, MO1.getReg()); } -void ARMInstPrinter::printPostIdxImm8s4Operand(const MCInst *MI, - unsigned OpNum, - raw_ostream &O) { +void ARMInstPrinter::printPostIdxImm8s4Operand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, + raw_ostream &O) { const MCOperand &MO = MI->getOperand(OpNum); unsigned Imm = MO.getImm(); - O << markup("<imm:") - << '#' << ((Imm & 256) ? "" : "-") << ((Imm & 0xff) << 2) + O << markup("<imm:") << '#' << ((Imm & 256) ? "" : "-") << ((Imm & 0xff) << 2) << markup(">"); } - void ARMInstPrinter::printLdStmModeOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { - ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MI->getOperand(OpNum) - .getImm()); + ARM_AM::AMSubMode Mode = + ARM_AM::getAM4SubMode(MI->getOperand(OpNum).getImm()); O << ARM_AM::getAMSubModeStr(Mode); } template <bool AlwaysPrintImm0> void ARMInstPrinter::printAddrMode5Operand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(OpNum); - const MCOperand &MO2 = MI->getOperand(OpNum+1); + const MCOperand &MO2 = MI->getOperand(OpNum + 1); - if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. - printOperand(MI, OpNum, O); + if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. + printOperand(MI, OpNum, STI, O); return; } @@ -639,20 +636,17 @@ void ARMInstPrinter::printAddrMode5Operand(const MCInst *MI, unsigned OpNum, unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm()); ARM_AM::AddrOpc Op = ARM_AM::getAM5Op(MO2.getImm()); if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM::sub) { - O << ", " - << markup("<imm:") - << "#" - << ARM_AM::getAddrOpcStr(Op) - << ImmOffs * 4 - << markup(">"); + O << ", " << markup("<imm:") << "#" << ARM_AM::getAddrOpcStr(Op) + << ImmOffs * 4 << markup(">"); } O << "]" << markup(">"); } void ARMInstPrinter::printAddrMode6Operand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(OpNum); - const MCOperand &MO2 = MI->getOperand(OpNum+1); + const MCOperand &MO2 = MI->getOperand(OpNum + 1); O << markup("<mem:") << "["; printRegName(O, MO1.getReg()); @@ -663,6 +657,7 @@ void ARMInstPrinter::printAddrMode6Operand(const MCInst *MI, unsigned OpNum, } void ARMInstPrinter::printAddrMode7Operand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(OpNum); O << markup("<mem:") << "["; @@ -672,6 +667,7 @@ void ARMInstPrinter::printAddrMode7Operand(const MCInst *MI, unsigned OpNum, void ARMInstPrinter::printAddrMode6OffsetOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &MO = MI->getOperand(OpNum); if (MO.getReg() == 0) @@ -684,49 +680,47 @@ void ARMInstPrinter::printAddrMode6OffsetOperand(const MCInst *MI, void ARMInstPrinter::printBitfieldInvMaskImmOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &MO = MI->getOperand(OpNum); uint32_t v = ~MO.getImm(); int32_t lsb = countTrailingZeros(v); - int32_t width = (32 - countLeadingZeros (v)) - lsb; + int32_t width = (32 - countLeadingZeros(v)) - lsb; assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!"); - O << markup("<imm:") << '#' << lsb << markup(">") - << ", " - << markup("<imm:") << '#' << width << markup(">"); + O << markup("<imm:") << '#' << lsb << markup(">") << ", " << markup("<imm:") + << '#' << width << markup(">"); } void ARMInstPrinter::printMemBOption(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { unsigned val = MI->getOperand(OpNum).getImm(); - O << ARM_MB::MemBOptToString(val, (getAvailableFeatures() & ARM::HasV8Ops)); + O << ARM_MB::MemBOptToString(val, (STI.getFeatureBits() & ARM::HasV8Ops)); } void ARMInstPrinter::printInstSyncBOption(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { unsigned val = MI->getOperand(OpNum).getImm(); O << ARM_ISB::InstSyncBOptToString(val); } void ARMInstPrinter::printShiftImmOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { unsigned ShiftOp = MI->getOperand(OpNum).getImm(); bool isASR = (ShiftOp & (1 << 5)) != 0; unsigned Amt = ShiftOp & 0x1f; if (isASR) { - O << ", asr " - << markup("<imm:") - << "#" << (Amt == 0 ? 32 : Amt) - << markup(">"); - } - else if (Amt) { - O << ", lsl " - << markup("<imm:") - << "#" << Amt + O << ", asr " << markup("<imm:") << "#" << (Amt == 0 ? 32 : Amt) << markup(">"); + } else if (Amt) { + O << ", lsl " << markup("<imm:") << "#" << Amt << markup(">"); } } void ARMInstPrinter::printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { unsigned Imm = MI->getOperand(OpNum).getImm(); if (Imm == 0) @@ -736,6 +730,7 @@ void ARMInstPrinter::printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum, } void ARMInstPrinter::printPKHASRShiftImm(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { unsigned Imm = MI->getOperand(OpNum).getImm(); // A shift amount of 32 is encoded as 0. @@ -746,16 +741,19 @@ void ARMInstPrinter::printPKHASRShiftImm(const MCInst *MI, unsigned OpNum, } void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { O << "{"; for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) { - if (i != OpNum) O << ", "; + if (i != OpNum) + O << ", "; printRegName(O, MI->getOperand(i).getReg()); } O << "}"; } void ARMInstPrinter::printGPRPairOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { unsigned Reg = MI->getOperand(OpNum).getReg(); printRegName(O, MRI.getSubReg(Reg, ARM::gsub_0)); @@ -763,8 +761,8 @@ void ARMInstPrinter::printGPRPairOperand(const MCInst *MI, unsigned OpNum, printRegName(O, MRI.getSubReg(Reg, ARM::gsub_1)); } - void ARMInstPrinter::printSetendOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &Op = MI->getOperand(OpNum); if (Op.getImm()) @@ -774,16 +772,16 @@ void ARMInstPrinter::printSetendOperand(const MCInst *MI, unsigned OpNum, } void ARMInstPrinter::printCPSIMod(const MCInst *MI, unsigned OpNum, - raw_ostream &O) { + const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &Op = MI->getOperand(OpNum); O << ARM_PROC::IModToString(Op.getImm()); } void ARMInstPrinter::printCPSIFlag(const MCInst *MI, unsigned OpNum, - raw_ostream &O) { + const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &Op = MI->getOperand(OpNum); unsigned IFlags = Op.getImm(); - for (int i=2; i >= 0; --i) + for (int i = 2; i >= 0; --i) if (IFlags & (1 << i)) O << ARM_PROC::IFlagsToString(1 << i); @@ -792,11 +790,12 @@ void ARMInstPrinter::printCPSIFlag(const MCInst *MI, unsigned OpNum, } void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &Op = MI->getOperand(OpNum); unsigned SpecRegRBit = Op.getImm() >> 4; unsigned Mask = Op.getImm() & 0xf; - uint64_t FeatureBits = getAvailableFeatures(); + uint64_t FeatureBits = STI.getFeatureBits(); if (FeatureBits & ARM::FeatureMClass) { unsigned SYSm = Op.getImm(); @@ -805,14 +804,30 @@ void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum, // For writes, handle extended mask bits if the DSP extension is present. if (Opcode == ARM::t2MSR_M && (FeatureBits & ARM::FeatureDSPThumb2)) { switch (SYSm) { - case 0x400: O << "apsr_g"; return; - case 0xc00: O << "apsr_nzcvqg"; return; - case 0x401: O << "iapsr_g"; return; - case 0xc01: O << "iapsr_nzcvqg"; return; - case 0x402: O << "eapsr_g"; return; - case 0xc02: O << "eapsr_nzcvqg"; return; - case 0x403: O << "xpsr_g"; return; - case 0xc03: O << "xpsr_nzcvqg"; return; + case 0x400: + O << "apsr_g"; + return; + case 0xc00: + O << "apsr_nzcvqg"; + return; + case 0x401: + O << "iapsr_g"; + return; + case 0xc01: + O << "iapsr_nzcvqg"; + return; + case 0x402: + O << "eapsr_g"; + return; + case 0xc02: + O << "eapsr_nzcvqg"; + return; + case 0x403: + O << "xpsr_g"; + return; + case 0xc03: + O << "xpsr_nzcvqg"; + return; } } @@ -823,29 +838,66 @@ void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum, // ARMv7-M deprecates using MSR APSR without a _<bits> qualifier as an // alias for MSR APSR_nzcvq. switch (SYSm) { - case 0: O << "apsr_nzcvq"; return; - case 1: O << "iapsr_nzcvq"; return; - case 2: O << "eapsr_nzcvq"; return; - case 3: O << "xpsr_nzcvq"; return; + case 0: + O << "apsr_nzcvq"; + return; + case 1: + O << "iapsr_nzcvq"; + return; + case 2: + O << "eapsr_nzcvq"; + return; + case 3: + O << "xpsr_nzcvq"; + return; } } switch (SYSm) { - default: llvm_unreachable("Unexpected mask value!"); - case 0: O << "apsr"; return; - case 1: O << "iapsr"; return; - case 2: O << "eapsr"; return; - case 3: O << "xpsr"; return; - case 5: O << "ipsr"; return; - case 6: O << "epsr"; return; - case 7: O << "iepsr"; return; - case 8: O << "msp"; return; - case 9: O << "psp"; return; - case 16: O << "primask"; return; - case 17: O << "basepri"; return; - case 18: O << "basepri_max"; return; - case 19: O << "faultmask"; return; - case 20: O << "control"; return; + default: + llvm_unreachable("Unexpected mask value!"); + case 0: + O << "apsr"; + return; + case 1: + O << "iapsr"; + return; + case 2: + O << "eapsr"; + return; + case 3: + O << "xpsr"; + return; + case 5: + O << "ipsr"; + return; + case 6: + O << "epsr"; + return; + case 7: + O << "iepsr"; + return; + case 8: + O << "msp"; + return; + case 9: + O << "psp"; + return; + case 16: + O << "primask"; + return; + case 17: + O << "basepri"; + return; + case 18: + O << "basepri_max"; + return; + case 19: + O << "faultmask"; + return; + case 20: + O << "control"; + return; } } @@ -854,10 +906,17 @@ void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum, if (!SpecRegRBit && (Mask == 8 || Mask == 4 || Mask == 12)) { O << "APSR_"; switch (Mask) { - default: llvm_unreachable("Unexpected mask value!"); - case 4: O << "g"; return; - case 8: O << "nzcvq"; return; - case 12: O << "nzcvqg"; return; + default: + llvm_unreachable("Unexpected mask value!"); + case 4: + O << "g"; + return; + case 8: + O << "nzcvq"; + return; + case 12: + O << "nzcvqg"; + return; } } @@ -868,14 +927,19 @@ void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum, if (Mask) { O << '_'; - if (Mask & 8) O << 'f'; - if (Mask & 4) O << 's'; - if (Mask & 2) O << 'x'; - if (Mask & 1) O << 'c'; + if (Mask & 8) + O << 'f'; + if (Mask & 4) + O << 's'; + if (Mask & 2) + O << 'x'; + if (Mask & 1) + O << 'c'; } } void ARMInstPrinter::printBankedRegOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { uint32_t Banked = MI->getOperand(OpNum).getImm(); uint32_t R = (Banked & 0x20) >> 5; @@ -886,25 +950,40 @@ void ARMInstPrinter::printBankedRegOperand(const MCInst *MI, unsigned OpNum, if (R) { O << "SPSR_"; - switch(SysM) { - case 0x0e: O << "fiq"; return; - case 0x10: O << "irq"; return; - case 0x12: O << "svc"; return; - case 0x14: O << "abt"; return; - case 0x16: O << "und"; return; - case 0x1c: O << "mon"; return; - case 0x1e: O << "hyp"; return; - default: llvm_unreachable("Invalid banked SPSR register"); + switch (SysM) { + case 0x0e: + O << "fiq"; + return; + case 0x10: + O << "irq"; + return; + case 0x12: + O << "svc"; + return; + case 0x14: + O << "abt"; + return; + case 0x16: + O << "und"; + return; + case 0x1c: + O << "mon"; + return; + case 0x1e: + O << "hyp"; + return; + default: + llvm_unreachable("Invalid banked SPSR register"); } } assert(!R && "should have dealt with SPSR regs"); const char *RegNames[] = { - "r8_usr", "r9_usr", "r10_usr", "r11_usr", "r12_usr", "sp_usr", "lr_usr", "", - "r8_fiq", "r9_fiq", "r10_fiq", "r11_fiq", "r12_fiq", "sp_fiq", "lr_fiq", "", - "lr_irq", "sp_irq", "lr_svc", "sp_svc", "lr_abt", "sp_abt", "lr_und", "sp_und", - "", "", "", "", "lr_mon", "sp_mon", "elr_hyp", "sp_hyp" - }; + "r8_usr", "r9_usr", "r10_usr", "r11_usr", "r12_usr", "sp_usr", "lr_usr", + "", "r8_fiq", "r9_fiq", "r10_fiq", "r11_fiq", "r12_fiq", "sp_fiq", + "lr_fiq", "", "lr_irq", "sp_irq", "lr_svc", "sp_svc", "lr_abt", + "sp_abt", "lr_und", "sp_und", "", "", "", "", + "lr_mon", "sp_mon", "elr_hyp", "sp_hyp"}; const char *Name = RegNames[SysM]; assert(Name[0] && "invalid banked register operand"); @@ -912,6 +991,7 @@ void ARMInstPrinter::printBankedRegOperand(const MCInst *MI, unsigned OpNum, } void ARMInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm(); // Handle the undefined 15 CC value here for printing so we don't abort(). @@ -923,12 +1003,14 @@ void ARMInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum, void ARMInstPrinter::printMandatoryPredicateOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm(); O << ARMCondCodeToString(CC); } void ARMInstPrinter::printSBitModifierOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { if (MI->getOperand(OpNum).getReg()) { assert(MI->getOperand(OpNum).getReg() == ARM::CPSR && @@ -938,33 +1020,38 @@ void ARMInstPrinter::printSBitModifierOperand(const MCInst *MI, unsigned OpNum, } void ARMInstPrinter::printNoHashImmediate(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { O << MI->getOperand(OpNum).getImm(); } void ARMInstPrinter::printPImmediate(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { O << "p" << MI->getOperand(OpNum).getImm(); } void ARMInstPrinter::printCImmediate(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { O << "c" << MI->getOperand(OpNum).getImm(); } void ARMInstPrinter::printCoprocOptionImm(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { O << "{" << MI->getOperand(OpNum).getImm() << "}"; } void ARMInstPrinter::printPCLabel(const MCInst *MI, unsigned OpNum, - raw_ostream &O) { + const MCSubtargetInfo &STI, raw_ostream &O) { llvm_unreachable("Unhandled PC-relative pseudo-instruction!"); } -template<unsigned scale> +template <unsigned scale> void ARMInstPrinter::printAdrLabelOperand(const MCInst *MI, unsigned OpNum, - raw_ostream &O) { + const MCSubtargetInfo &STI, + raw_ostream &O) { const MCOperand &MO = MI->getOperand(OpNum); if (MO.isExpr()) { @@ -985,25 +1072,26 @@ void ARMInstPrinter::printAdrLabelOperand(const MCInst *MI, unsigned OpNum, } void ARMInstPrinter::printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { - O << markup("<imm:") - << "#" << formatImm(MI->getOperand(OpNum).getImm() * 4) + O << markup("<imm:") << "#" << formatImm(MI->getOperand(OpNum).getImm() * 4) << markup(">"); } void ARMInstPrinter::printThumbSRImm(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { unsigned Imm = MI->getOperand(OpNum).getImm(); - O << markup("<imm:") - << "#" << formatImm((Imm == 0 ? 32 : Imm)) + O << markup("<imm:") << "#" << formatImm((Imm == 0 ? 32 : Imm)) << markup(">"); } void ARMInstPrinter::printThumbITMask(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { // (3 - the number of trailing zeros) is the number of then / else. unsigned Mask = MI->getOperand(OpNum).getImm(); - unsigned Firstcond = MI->getOperand(OpNum-1).getImm(); + unsigned Firstcond = MI->getOperand(OpNum - 1).getImm(); unsigned CondBit0 = Firstcond & 1; unsigned NumTZ = countTrailingZeros(Mask); assert(NumTZ <= 3 && "Invalid IT mask!"); @@ -1017,12 +1105,13 @@ void ARMInstPrinter::printThumbITMask(const MCInst *MI, unsigned OpNum, } void ARMInstPrinter::printThumbAddrModeRROperand(const MCInst *MI, unsigned Op, + const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(Op); const MCOperand &MO2 = MI->getOperand(Op + 1); - if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. - printOperand(MI, Op, O); + if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. + printOperand(MI, Op, STI, O); return; } @@ -1037,22 +1126,21 @@ void ARMInstPrinter::printThumbAddrModeRROperand(const MCInst *MI, unsigned Op, void ARMInstPrinter::printThumbAddrModeImm5SOperand(const MCInst *MI, unsigned Op, + const MCSubtargetInfo &STI, raw_ostream &O, unsigned Scale) { const MCOperand &MO1 = MI->getOperand(Op); const MCOperand &MO2 = MI->getOperand(Op + 1); - if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. - printOperand(MI, Op, O); + if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. + printOperand(MI, Op, STI, O); return; } O << markup("<mem:") << "["; printRegName(O, MO1.getReg()); if (unsigned ImmOffs = MO2.getImm()) { - O << ", " - << markup("<imm:") - << "#" << formatImm(ImmOffs * Scale) + O << ", " << markup("<imm:") << "#" << formatImm(ImmOffs * Scale) << markup(">"); } O << "]" << markup(">"); @@ -1060,25 +1148,29 @@ void ARMInstPrinter::printThumbAddrModeImm5SOperand(const MCInst *MI, void ARMInstPrinter::printThumbAddrModeImm5S1Operand(const MCInst *MI, unsigned Op, + const MCSubtargetInfo &STI, raw_ostream &O) { - printThumbAddrModeImm5SOperand(MI, Op, O, 1); + printThumbAddrModeImm5SOperand(MI, Op, STI, O, 1); } void ARMInstPrinter::printThumbAddrModeImm5S2Operand(const MCInst *MI, unsigned Op, + const MCSubtargetInfo &STI, raw_ostream &O) { - printThumbAddrModeImm5SOperand(MI, Op, O, 2); + printThumbAddrModeImm5SOperand(MI, Op, STI, O, 2); } void ARMInstPrinter::printThumbAddrModeImm5S4Operand(const MCInst *MI, unsigned Op, + const MCSubtargetInfo &STI, raw_ostream &O) { - printThumbAddrModeImm5SOperand(MI, Op, O, 4); + printThumbAddrModeImm5SOperand(MI, Op, STI, O, 4); } void ARMInstPrinter::printThumbAddrModeSPOperand(const MCInst *MI, unsigned Op, + const MCSubtargetInfo &STI, raw_ostream &O) { - printThumbAddrModeImm5SOperand(MI, Op, O, 4); + printThumbAddrModeImm5SOperand(MI, Op, STI, O, 4); } // Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2 @@ -1086,9 +1178,10 @@ void ARMInstPrinter::printThumbAddrModeSPOperand(const MCInst *MI, unsigned Op, // REG 0 0 - e.g. R5 // REG IMM, SH_OPC - e.g. R5, LSL #3 void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(OpNum); - const MCOperand &MO2 = MI->getOperand(OpNum+1); + const MCOperand &MO2 = MI->getOperand(OpNum + 1); unsigned Reg = MO1.getReg(); printRegName(O, Reg); @@ -1101,12 +1194,13 @@ void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum, template <bool AlwaysPrintImm0> void ARMInstPrinter::printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(OpNum); - const MCOperand &MO2 = MI->getOperand(OpNum+1); + const MCOperand &MO2 = MI->getOperand(OpNum + 1); - if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. - printOperand(MI, OpNum, O); + if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. + printOperand(MI, OpNum, STI, O); return; } @@ -1119,26 +1213,20 @@ void ARMInstPrinter::printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum, if (OffImm == INT32_MIN) OffImm = 0; if (isSub) { - O << ", " - << markup("<imm:") - << "#-" << formatImm(-OffImm) - << markup(">"); - } - else if (AlwaysPrintImm0 || OffImm > 0) { - O << ", " - << markup("<imm:") - << "#" << formatImm(OffImm) - << markup(">"); + O << ", " << markup("<imm:") << "#-" << formatImm(-OffImm) << markup(">"); + } else if (AlwaysPrintImm0 || OffImm > 0) { + O << ", " << markup("<imm:") << "#" << formatImm(OffImm) << markup(">"); } O << "]" << markup(">"); } -template<bool AlwaysPrintImm0> +template <bool AlwaysPrintImm0> void ARMInstPrinter::printT2AddrModeImm8Operand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(OpNum); - const MCOperand &MO2 = MI->getOperand(OpNum+1); + const MCOperand &MO2 = MI->getOperand(OpNum + 1); O << markup("<mem:") << "["; printRegName(O, MO1.getReg()); @@ -1149,28 +1237,23 @@ void ARMInstPrinter::printT2AddrModeImm8Operand(const MCInst *MI, if (OffImm == INT32_MIN) OffImm = 0; if (isSub) { - O << ", " - << markup("<imm:") - << "#-" << -OffImm - << markup(">"); + O << ", " << markup("<imm:") << "#-" << -OffImm << markup(">"); } else if (AlwaysPrintImm0 || OffImm > 0) { - O << ", " - << markup("<imm:") - << "#" << OffImm - << markup(">"); + O << ", " << markup("<imm:") << "#" << OffImm << markup(">"); } O << "]" << markup(">"); } -template<bool AlwaysPrintImm0> +template <bool AlwaysPrintImm0> void ARMInstPrinter::printT2AddrModeImm8s4Operand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(OpNum); - const MCOperand &MO2 = MI->getOperand(OpNum+1); + const MCOperand &MO2 = MI->getOperand(OpNum + 1); - if (!MO1.isReg()) { // For label symbolic references. - printOperand(MI, OpNum, O); + if (!MO1.isReg()) { // For label symbolic references. + printOperand(MI, OpNum, STI, O); return; } @@ -1186,39 +1269,31 @@ void ARMInstPrinter::printT2AddrModeImm8s4Operand(const MCInst *MI, if (OffImm == INT32_MIN) OffImm = 0; if (isSub) { - O << ", " - << markup("<imm:") - << "#-" << -OffImm - << markup(">"); + O << ", " << markup("<imm:") << "#-" << -OffImm << markup(">"); } else if (AlwaysPrintImm0 || OffImm > 0) { - O << ", " - << markup("<imm:") - << "#" << OffImm - << markup(">"); + O << ", " << markup("<imm:") << "#" << OffImm << markup(">"); } O << "]" << markup(">"); } -void ARMInstPrinter::printT2AddrModeImm0_1020s4Operand(const MCInst *MI, - unsigned OpNum, - raw_ostream &O) { +void ARMInstPrinter::printT2AddrModeImm0_1020s4Operand( + const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, + raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(OpNum); - const MCOperand &MO2 = MI->getOperand(OpNum+1); + const MCOperand &MO2 = MI->getOperand(OpNum + 1); O << markup("<mem:") << "["; printRegName(O, MO1.getReg()); if (MO2.getImm()) { - O << ", " - << markup("<imm:") - << "#" << formatImm(MO2.getImm() * 4) + O << ", " << markup("<imm:") << "#" << formatImm(MO2.getImm() * 4) << markup(">"); } O << "]" << markup(">"); } -void ARMInstPrinter::printT2AddrModeImm8OffsetOperand(const MCInst *MI, - unsigned OpNum, - raw_ostream &O) { +void ARMInstPrinter::printT2AddrModeImm8OffsetOperand( + const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, + raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(OpNum); int32_t OffImm = (int32_t)MO1.getImm(); O << ", " << markup("<imm:"); @@ -1231,9 +1306,9 @@ void ARMInstPrinter::printT2AddrModeImm8OffsetOperand(const MCInst *MI, O << markup(">"); } -void ARMInstPrinter::printT2AddrModeImm8s4OffsetOperand(const MCInst *MI, - unsigned OpNum, - raw_ostream &O) { +void ARMInstPrinter::printT2AddrModeImm8s4OffsetOperand( + const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, + raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(OpNum); int32_t OffImm = (int32_t)MO1.getImm(); @@ -1251,10 +1326,11 @@ void ARMInstPrinter::printT2AddrModeImm8s4OffsetOperand(const MCInst *MI, void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &MO1 = MI->getOperand(OpNum); - const MCOperand &MO2 = MI->getOperand(OpNum+1); - const MCOperand &MO3 = MI->getOperand(OpNum+2); + const MCOperand &MO2 = MI->getOperand(OpNum + 1); + const MCOperand &MO3 = MI->getOperand(OpNum + 2); O << markup("<mem:") << "["; printRegName(O, MO1.getReg()); @@ -1266,71 +1342,74 @@ void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst *MI, unsigned ShAmt = MO3.getImm(); if (ShAmt) { assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!"); - O << ", lsl " - << markup("<imm:") - << "#" << ShAmt - << markup(">"); + O << ", lsl " << markup("<imm:") << "#" << ShAmt << markup(">"); } O << "]" << markup(">"); } void ARMInstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &MO = MI->getOperand(OpNum); - O << markup("<imm:") - << '#' << ARM_AM::getFPImmFloat(MO.getImm()) + O << markup("<imm:") << '#' << ARM_AM::getFPImmFloat(MO.getImm()) << markup(">"); } void ARMInstPrinter::printNEONModImmOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { unsigned EncodedImm = MI->getOperand(OpNum).getImm(); unsigned EltBits; uint64_t Val = ARM_AM::decodeNEONModImm(EncodedImm, EltBits); - O << markup("<imm:") - << "#0x"; + O << markup("<imm:") << "#0x"; O.write_hex(Val); O << markup(">"); } void ARMInstPrinter::printImmPlusOneOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { unsigned Imm = MI->getOperand(OpNum).getImm(); - O << markup("<imm:") - << "#" << formatImm(Imm + 1) - << markup(">"); + O << markup("<imm:") << "#" << formatImm(Imm + 1) << markup(">"); } void ARMInstPrinter::printRotImmOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { unsigned Imm = MI->getOperand(OpNum).getImm(); if (Imm == 0) return; - O << ", ror " - << markup("<imm:") - << "#"; + O << ", ror " << markup("<imm:") << "#"; switch (Imm) { - default: assert (0 && "illegal ror immediate!"); - case 1: O << "8"; break; - case 2: O << "16"; break; - case 3: O << "24"; break; + default: + assert(0 && "illegal ror immediate!"); + case 1: + O << "8"; + break; + case 2: + O << "16"; + break; + case 3: + O << "24"; + break; } O << markup(">"); } void ARMInstPrinter::printModImmOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { MCOperand Op = MI->getOperand(OpNum); // Support for fixups (MCFixup) if (Op.isExpr()) - return printOperand(MI, OpNum, O); + return printOperand(MI, OpNum, STI, O); unsigned Bits = Op.getImm() & 0xFF; unsigned Rot = (Op.getImm() & 0xF00) >> 7; - bool PrintUnsigned = false; - switch (MI->getOpcode()){ + bool PrintUnsigned = false; + switch (MI->getOpcode()) { case ARM::MOVi: // Movs to PC should be treated unsigned PrintUnsigned = (MI->getOperand(OpNum - 1).getReg() == ARM::PC); @@ -1354,36 +1433,30 @@ void ARMInstPrinter::printModImmOperand(const MCInst *MI, unsigned OpNum, } // Explicit #bits, #rot implied - O << "#" - << markup("<imm:") - << Bits - << markup(">") - << ", #" - << markup("<imm:") - << Rot - << markup(">"); + O << "#" << markup("<imm:") << Bits << markup(">") << ", #" << markup("<imm:") + << Rot << markup(">"); } void ARMInstPrinter::printFBits16(const MCInst *MI, unsigned OpNum, - raw_ostream &O) { - O << markup("<imm:") - << "#" << 16 - MI->getOperand(OpNum).getImm() + const MCSubtargetInfo &STI, raw_ostream &O) { + O << markup("<imm:") << "#" << 16 - MI->getOperand(OpNum).getImm() << markup(">"); } void ARMInstPrinter::printFBits32(const MCInst *MI, unsigned OpNum, - raw_ostream &O) { - O << markup("<imm:") - << "#" << 32 - MI->getOperand(OpNum).getImm() + const MCSubtargetInfo &STI, raw_ostream &O) { + O << markup("<imm:") << "#" << 32 - MI->getOperand(OpNum).getImm() << markup(">"); } void ARMInstPrinter::printVectorIndex(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { O << "[" << MI->getOperand(OpNum).getImm() << "]"; } void ARMInstPrinter::printVectorListOne(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { O << "{"; printRegName(O, MI->getOperand(OpNum).getReg()); @@ -1391,7 +1464,8 @@ void ARMInstPrinter::printVectorListOne(const MCInst *MI, unsigned OpNum, } void ARMInstPrinter::printVectorListTwo(const MCInst *MI, unsigned OpNum, - raw_ostream &O) { + const MCSubtargetInfo &STI, + raw_ostream &O) { unsigned Reg = MI->getOperand(OpNum).getReg(); unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0); unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1); @@ -1402,8 +1476,8 @@ void ARMInstPrinter::printVectorListTwo(const MCInst *MI, unsigned OpNum, O << "}"; } -void ARMInstPrinter::printVectorListTwoSpaced(const MCInst *MI, - unsigned OpNum, +void ARMInstPrinter::printVectorListTwoSpaced(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { unsigned Reg = MI->getOperand(OpNum).getReg(); unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0); @@ -1416,6 +1490,7 @@ void ARMInstPrinter::printVectorListTwoSpaced(const MCInst *MI, } void ARMInstPrinter::printVectorListThree(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { // Normally, it's not safe to use register enum values directly with // addition to get the next register, but for VFP registers, the @@ -1430,6 +1505,7 @@ void ARMInstPrinter::printVectorListThree(const MCInst *MI, unsigned OpNum, } void ARMInstPrinter::printVectorListFour(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { // Normally, it's not safe to use register enum values directly with // addition to get the next register, but for VFP registers, the @@ -1447,6 +1523,7 @@ void ARMInstPrinter::printVectorListFour(const MCInst *MI, unsigned OpNum, void ARMInstPrinter::printVectorListOneAllLanes(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { O << "{"; printRegName(O, MI->getOperand(OpNum).getReg()); @@ -1455,6 +1532,7 @@ void ARMInstPrinter::printVectorListOneAllLanes(const MCInst *MI, void ARMInstPrinter::printVectorListTwoAllLanes(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { unsigned Reg = MI->getOperand(OpNum).getReg(); unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0); @@ -1468,6 +1546,7 @@ void ARMInstPrinter::printVectorListTwoAllLanes(const MCInst *MI, void ARMInstPrinter::printVectorListThreeAllLanes(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { // Normally, it's not safe to use register enum values directly with // addition to get the next register, but for VFP registers, the @@ -1482,8 +1561,9 @@ void ARMInstPrinter::printVectorListThreeAllLanes(const MCInst *MI, } void ARMInstPrinter::printVectorListFourAllLanes(const MCInst *MI, - unsigned OpNum, - raw_ostream &O) { + unsigned OpNum, + const MCSubtargetInfo &STI, + raw_ostream &O) { // Normally, it's not safe to use register enum values directly with // addition to get the next register, but for VFP registers, the // sort order is guaranteed because they're all of the form D<n>. @@ -1498,9 +1578,9 @@ void ARMInstPrinter::printVectorListFourAllLanes(const MCInst *MI, O << "[]}"; } -void ARMInstPrinter::printVectorListTwoSpacedAllLanes(const MCInst *MI, - unsigned OpNum, - raw_ostream &O) { +void ARMInstPrinter::printVectorListTwoSpacedAllLanes( + const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, + raw_ostream &O) { unsigned Reg = MI->getOperand(OpNum).getReg(); unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0); unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2); @@ -1511,24 +1591,24 @@ void ARMInstPrinter::printVectorListTwoSpacedAllLanes(const MCInst *MI, O << "[]}"; } -void ARMInstPrinter::printVectorListThreeSpacedAllLanes(const MCInst *MI, - unsigned OpNum, - raw_ostream &O) { +void ARMInstPrinter::printVectorListThreeSpacedAllLanes( + const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, + raw_ostream &O) { // Normally, it's not safe to use register enum values directly with // addition to get the next register, but for VFP registers, the // sort order is guaranteed because they're all of the form D<n>. O << "{"; printRegName(O, MI->getOperand(OpNum).getReg()); - O << "[], "; + O << "[], "; printRegName(O, MI->getOperand(OpNum).getReg() + 2); O << "[], "; printRegName(O, MI->getOperand(OpNum).getReg() + 4); O << "[]}"; } -void ARMInstPrinter::printVectorListFourSpacedAllLanes(const MCInst *MI, - unsigned OpNum, - raw_ostream &O) { +void ARMInstPrinter::printVectorListFourSpacedAllLanes( + const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, + raw_ostream &O) { // Normally, it's not safe to use register enum values directly with // addition to get the next register, but for VFP registers, the // sort order is guaranteed because they're all of the form D<n>. @@ -1545,6 +1625,7 @@ void ARMInstPrinter::printVectorListFourSpacedAllLanes(const MCInst *MI, void ARMInstPrinter::printVectorListThreeSpaced(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { // Normally, it's not safe to use register enum values directly with // addition to get the next register, but for VFP registers, the @@ -1558,9 +1639,9 @@ void ARMInstPrinter::printVectorListThreeSpaced(const MCInst *MI, O << "}"; } -void ARMInstPrinter::printVectorListFourSpaced(const MCInst *MI, - unsigned OpNum, - raw_ostream &O) { +void ARMInstPrinter::printVectorListFourSpaced(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, + raw_ostream &O) { // Normally, it's not safe to use register enum values directly with // addition to get the next register, but for VFP registers, the // sort order is guaranteed because they're all of the form D<n>. diff --git a/lib/Target/ARM/InstPrinter/ARMInstPrinter.h b/lib/Target/ARM/InstPrinter/ARMInstPrinter.h index f179e01..3927c9f 100644 --- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.h +++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.h @@ -24,146 +24,207 @@ class MCOperand; class ARMInstPrinter : public MCInstPrinter { public: ARMInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, - const MCRegisterInfo &MRI, const MCSubtargetInfo &STI); + const MCRegisterInfo &MRI); - void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot) override; + void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot, + const MCSubtargetInfo &STI) override; void printRegName(raw_ostream &OS, unsigned RegNo) const override; // Autogenerated by tblgen. - void printInstruction(const MCInst *MI, raw_ostream &O); + void printInstruction(const MCInst *MI, const MCSubtargetInfo &STI, + raw_ostream &O); static const char *getRegisterName(unsigned RegNo); - - void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); - - void printSORegRegOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printSORegImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - - void printAddrModeTBB(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printAddrModeTBH(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printAddrMode2Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printAM2PostIndexOp(const MCInst *MI, unsigned OpNum, raw_ostream &O); + void printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, + raw_ostream &O); + + void printSORegRegOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printSORegImmOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + + void printAddrModeTBB(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printAddrModeTBH(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printAddrMode2Operand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printAM2PostIndexOp(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); void printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned OpNum, - raw_ostream &O); + const MCSubtargetInfo &STI, raw_ostream &O); void printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum, - raw_ostream &O); + const MCSubtargetInfo &STI, raw_ostream &O); template <bool AlwaysPrintImm0> - void printAddrMode3Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O); + void printAddrMode3Operand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); void printAddrMode3OffsetOperand(const MCInst *MI, unsigned OpNum, - raw_ostream &O); + const MCSubtargetInfo &STI, raw_ostream &O); void printAM3PreOrOffsetIndexOp(const MCInst *MI, unsigned Op, raw_ostream &O, bool AlwaysPrintImm0); void printPostIdxImm8Operand(const MCInst *MI, unsigned OpNum, - raw_ostream &O); - void printPostIdxRegOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); + const MCSubtargetInfo &STI, raw_ostream &O); + void printPostIdxRegOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); void printPostIdxImm8s4Operand(const MCInst *MI, unsigned OpNum, - raw_ostream &O); + const MCSubtargetInfo &STI, raw_ostream &O); - void printLdStmModeOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); + void printLdStmModeOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); template <bool AlwaysPrintImm0> - void printAddrMode5Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printAddrMode6Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printAddrMode7Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O); + void printAddrMode5Operand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printAddrMode6Operand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printAddrMode7Operand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); void printAddrMode6OffsetOperand(const MCInst *MI, unsigned OpNum, - raw_ostream &O); + const MCSubtargetInfo &STI, raw_ostream &O); void printBitfieldInvMaskImmOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); - void printMemBOption(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printInstSyncBOption(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printShiftImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printPKHASRShiftImm(const MCInst *MI, unsigned OpNum, raw_ostream &O); + void printMemBOption(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printInstSyncBOption(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printShiftImmOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printPKHASRShiftImm(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); template <unsigned scale> - void printAdrLabelOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printThumbSRImm(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printThumbITMask(const MCInst *MI, unsigned OpNum, raw_ostream &O); + void printAdrLabelOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printThumbSRImm(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printThumbITMask(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); void printThumbAddrModeRROperand(const MCInst *MI, unsigned OpNum, - raw_ostream &O); + const MCSubtargetInfo &STI, raw_ostream &O); void printThumbAddrModeImm5SOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O, unsigned Scale); void printThumbAddrModeImm5S1Operand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); void printThumbAddrModeImm5S2Operand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); void printThumbAddrModeImm5S4Operand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); void printThumbAddrModeSPOperand(const MCInst *MI, unsigned OpNum, - raw_ostream &O); + const MCSubtargetInfo &STI, raw_ostream &O); - void printT2SOOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - template<bool AlwaysPrintImm0> + void printT2SOOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + template <bool AlwaysPrintImm0> void printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum, - raw_ostream &O); - template<bool AlwaysPrintImm0> + const MCSubtargetInfo &STI, raw_ostream &O); + template <bool AlwaysPrintImm0> void printT2AddrModeImm8Operand(const MCInst *MI, unsigned OpNum, - raw_ostream &O); - template<bool AlwaysPrintImm0> + const MCSubtargetInfo &STI, raw_ostream &O); + template <bool AlwaysPrintImm0> void printT2AddrModeImm8s4Operand(const MCInst *MI, unsigned OpNum, - raw_ostream &O); + const MCSubtargetInfo &STI, raw_ostream &O); void printT2AddrModeImm0_1020s4Operand(const MCInst *MI, unsigned OpNum, - raw_ostream &O); + const MCSubtargetInfo &STI, + raw_ostream &O); void printT2AddrModeImm8OffsetOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); void printT2AddrModeImm8s4OffsetOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); void printT2AddrModeSoRegOperand(const MCInst *MI, unsigned OpNum, - raw_ostream &O); - - void printSetendOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printCPSIMod(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printCPSIFlag(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printMSRMaskOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printBankedRegOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printPredicateOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); + const MCSubtargetInfo &STI, raw_ostream &O); + + void printSetendOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printCPSIMod(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printCPSIFlag(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printMSRMaskOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printBankedRegOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printPredicateOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); void printMandatoryPredicateOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); void printSBitModifierOperand(const MCInst *MI, unsigned OpNum, - raw_ostream &O); - void printRegisterList(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printNoHashImmediate(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printPImmediate(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printCImmediate(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printCoprocOptionImm(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printFPImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printNEONModImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printImmPlusOneOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printRotImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printModImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printGPRPairOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - - void printPCLabel(const MCInst *MI, unsigned OpNum, raw_ostream &O); + const MCSubtargetInfo &STI, raw_ostream &O); + void printRegisterList(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printNoHashImmediate(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printPImmediate(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printCImmediate(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printCoprocOptionImm(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printFPImmOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printNEONModImmOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printImmPlusOneOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printRotImmOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printModImmOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printGPRPairOperand(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + + void printPCLabel(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); void printThumbLdrLabelOperand(const MCInst *MI, unsigned OpNum, - raw_ostream &O); - void printFBits16(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printFBits32(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printVectorIndex(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printVectorListOne(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printVectorListTwo(const MCInst *MI, unsigned OpNum, raw_ostream &O); + const MCSubtargetInfo &STI, raw_ostream &O); + void printFBits16(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printFBits32(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printVectorIndex(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printVectorListOne(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printVectorListTwo(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); void printVectorListTwoSpaced(const MCInst *MI, unsigned OpNum, - raw_ostream &O); - void printVectorListThree(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printVectorListFour(const MCInst *MI, unsigned OpNum, raw_ostream &O); + const MCSubtargetInfo &STI, raw_ostream &O); + void printVectorListThree(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printVectorListFour(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); void printVectorListOneAllLanes(const MCInst *MI, unsigned OpNum, - raw_ostream &O); + const MCSubtargetInfo &STI, raw_ostream &O); void printVectorListTwoAllLanes(const MCInst *MI, unsigned OpNum, - raw_ostream &O); + const MCSubtargetInfo &STI, raw_ostream &O); void printVectorListThreeAllLanes(const MCInst *MI, unsigned OpNum, - raw_ostream &O); + const MCSubtargetInfo &STI, raw_ostream &O); void printVectorListFourAllLanes(const MCInst *MI, unsigned OpNum, - raw_ostream &O); + const MCSubtargetInfo &STI, raw_ostream &O); void printVectorListTwoSpacedAllLanes(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); void printVectorListThreeSpacedAllLanes(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); void printVectorListFourSpacedAllLanes(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); void printVectorListThreeSpaced(const MCInst *MI, unsigned OpNum, - raw_ostream &O); + const MCSubtargetInfo &STI, raw_ostream &O); void printVectorListFourSpaced(const MCInst *MI, unsigned OpNum, - raw_ostream &O); + const MCSubtargetInfo &STI, raw_ostream &O); }; } // end namespace llvm diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp index 0b2e3b0..590d72f 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp @@ -153,18 +153,20 @@ void ARMAsmBackend::handleAssemblerFlag(MCAssemblerFlag Flag) { } } // end anonymous namespace -static unsigned getRelaxedOpcode(unsigned Op) { +unsigned ARMAsmBackend::getRelaxedOpcode(unsigned Op) const { + bool HasThumb2 = STI->getFeatureBits() & ARM::FeatureThumb2; + switch (Op) { default: return Op; case ARM::tBcc: - return ARM::t2Bcc; + return HasThumb2 ? (unsigned)ARM::t2Bcc : Op; case ARM::tLDRpci: - return ARM::t2LDRpci; + return HasThumb2 ? (unsigned)ARM::t2LDRpci : Op; case ARM::tADR: - return ARM::t2ADR; + return HasThumb2 ? (unsigned)ARM::t2ADR : Op; case ARM::tB: - return ARM::t2B; + return HasThumb2 ? (unsigned)ARM::t2B : Op; case ARM::tCBZ: return ARM::tHINT; case ARM::tCBNZ: @@ -589,7 +591,7 @@ void ARMAsmBackend::processFixupValue(const MCAssembler &Asm, (unsigned)Fixup.getKind() != ARM::fixup_t2_adr_pcrel_12 && (unsigned)Fixup.getKind() != ARM::fixup_arm_thumb_cp) { if (A) { - const MCSymbol &Sym = A->getSymbol().AliasedSymbol(); + const MCSymbol &Sym = A->getSymbol(); if (Asm.isThumbFunc(&Sym)) Value |= 1; } @@ -598,7 +600,7 @@ void ARMAsmBackend::processFixupValue(const MCAssembler &Asm, // the basic blocks of the same function. Thus, we would like to resolve // the offset when the destination has the same MCFragment. if (A && (unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_bl) { - const MCSymbol &Sym = A->getSymbol().AliasedSymbol(); + const MCSymbol &Sym = A->getSymbol(); const MCSymbolData &SymData = Asm.getSymbolData(Sym); IsResolved = (SymData.getFragment() == DF); } diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h index f4f1082..4fa8c79 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h +++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h @@ -47,6 +47,8 @@ public: void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, uint64_t Value, bool IsPCRel) const override; + unsigned getRelaxedOpcode(unsigned Op) const; + bool mayNeedRelaxation(const MCInst &Inst) const override; bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h b/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h index 3bd7ab7..ebef789 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h +++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h @@ -23,7 +23,7 @@ public: HasDataInCodeSupport = true; } - MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { + MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override { return createARMMachObjectWriter(OS, /*Is64Bit=*/false, MachO::CPU_TYPE_ARM, Subtype); } diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackendELF.h b/lib/Target/ARM/MCTargetDesc/ARMAsmBackendELF.h index 4efd325..263c4c4 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackendELF.h +++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackendELF.h @@ -18,7 +18,7 @@ public: ARMAsmBackendELF(const Target &T, StringRef TT, uint8_t OSABI, bool IsLittle) : ARMAsmBackend(T, TT, IsLittle), OSABI(OSABI) {} - MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { + MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override { return createARMELFObjectWriter(OS, OSABI, isLittle()); } }; diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackendWinCOFF.h b/lib/Target/ARM/MCTargetDesc/ARMAsmBackendWinCOFF.h index 33be347..f2c4358 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackendWinCOFF.h +++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackendWinCOFF.h @@ -17,7 +17,7 @@ class ARMAsmBackendWinCOFF : public ARMAsmBackend { public: ARMAsmBackendWinCOFF(const Target &T, StringRef Triple) : ARMAsmBackend(T, Triple, true) {} - MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { + MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override { return createARMWinCOFFObjectWriter(OS, /*Is64Bit=*/false); } }; diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp index a821a6b..f4fedee 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp @@ -32,7 +32,7 @@ namespace { public: ARMELFObjectWriter(uint8_t OSABI); - virtual ~ARMELFObjectWriter(); + ~ARMELFObjectWriter() override; unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const override; @@ -81,7 +81,9 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, unsigned Type = 0; if (IsPCRel) { switch ((unsigned)Fixup.getKind()) { - default: llvm_unreachable("Unimplemented"); + default: + report_fatal_error("unsupported relocation on symbol"); + return ELF::R_ARM_NONE; case FK_Data_4: switch (Modifier) { default: llvm_unreachable("Unsupported Modifier"); @@ -147,7 +149,9 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, } } else { switch ((unsigned)Fixup.getKind()) { - default: llvm_unreachable("invalid fixup kind!"); + default: + report_fatal_error("unsupported relocation on symbol"); + return ELF::R_ARM_NONE; case FK_Data_1: switch (Modifier) { default: llvm_unreachable("unsupported Modifier"); @@ -247,7 +251,7 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, return Type; } -MCObjectWriter *llvm::createARMELFObjectWriter(raw_ostream &OS, +MCObjectWriter *llvm::createARMELFObjectWriter(raw_pwrite_stream &OS, uint8_t OSABI, bool IsLittleEndian) { MCELFObjectTargetWriter *MOTW = new ARMELFObjectWriter(OSABI); diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp index 9648ffa..e7c777e 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -472,7 +472,7 @@ class ARMELFStreamer : public MCELFStreamer { public: friend class ARMTargetELFStreamer; - ARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, + ARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_pwrite_stream &OS, MCCodeEmitter *Emitter, bool IsThumb) : MCELFStreamer(Context, TAB, OS, Emitter), IsThumb(IsThumb), MappingSymbolCounter(0), LastEMS(EMS_None) { @@ -1083,14 +1083,13 @@ inline void ARMELFStreamer::SwitchToEHSection(const char *Prefix, } // Get .ARM.extab or .ARM.exidx section - const MCSectionELF *EHSection = nullptr; - if (const MCSymbol *Group = FnSection.getGroup()) { - EHSection = - getContext().getELFSection(EHSecName, Type, Flags | ELF::SHF_GROUP, - FnSection.getEntrySize(), Group->getName()); - } else { - EHSection = getContext().getELFSection(EHSecName, Type, Flags); - } + const MCSymbol *Group = FnSection.getGroup(); + if (Group) + Flags |= ELF::SHF_GROUP; + const MCSectionELF *EHSection = + getContext().getELFSection(EHSecName, Type, Flags, 0, Group, + FnSection.getUniqueID(), nullptr, &FnSection); + assert(EHSection && "Failed to get the required EH section"); // Switch to .ARM.extab or .ARM.exidx section @@ -1383,8 +1382,9 @@ MCTargetStreamer *createARMObjectTargetStreamer(MCStreamer &S, } MCELFStreamer *createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, - raw_ostream &OS, MCCodeEmitter *Emitter, - bool RelaxAll, bool IsThumb) { + raw_pwrite_stream &OS, + MCCodeEmitter *Emitter, bool RelaxAll, + bool IsThumb) { ARMELFStreamer *S = new ARMELFStreamer(Context, TAB, OS, Emitter, IsThumb); // FIXME: This should eventually end up somewhere else where more // intelligent flag decisions can be made. For now we are just maintaining diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp index e48cabb..6b650f0 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp @@ -48,7 +48,7 @@ public: : MCII(mcii), CTX(ctx), IsLittleEndian(IsLittle) { } - ~ARMMCCodeEmitter() {} + ~ARMMCCodeEmitter() override {} bool isThumb(const MCSubtargetInfo &STI) const { return (STI.getFeatureBits() & ARM::ModeThumb) != 0; diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp index 7ff7f9a..daa8af2 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp @@ -255,7 +255,7 @@ MCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(StringRef TT, StringRef CPU, std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU); if (!FS.empty()) { if (!ArchFS.empty()) - ArchFS = ArchFS + "," + FS.str(); + ArchFS = (Twine(ArchFS) + "," + FS).str(); else ArchFS = FS; } @@ -310,27 +310,26 @@ static MCCodeGenInfo *createARMMCCodeGenInfo(StringRef TT, Reloc::Model RM, } static MCStreamer *createELFStreamer(const Triple &T, MCContext &Ctx, - MCAsmBackend &MAB, raw_ostream &OS, + MCAsmBackend &MAB, raw_pwrite_stream &OS, MCCodeEmitter *Emitter, bool RelaxAll) { return createARMELFStreamer(Ctx, MAB, OS, Emitter, false, T.getArch() == Triple::thumb); } static MCStreamer *createARMMachOStreamer(MCContext &Ctx, MCAsmBackend &MAB, - raw_ostream &OS, + raw_pwrite_stream &OS, MCCodeEmitter *Emitter, bool RelaxAll, bool DWARFMustBeAtTheEnd) { return createMachOStreamer(Ctx, MAB, OS, Emitter, false, DWARFMustBeAtTheEnd); } -static MCInstPrinter *createARMMCInstPrinter(const Target &T, +static MCInstPrinter *createARMMCInstPrinter(const Triple &T, unsigned SyntaxVariant, const MCAsmInfo &MAI, const MCInstrInfo &MII, - const MCRegisterInfo &MRI, - const MCSubtargetInfo &STI) { + const MCRegisterInfo &MRI) { if (SyntaxVariant == 0) - return new ARMInstPrinter(MAI, MII, MRI, STI); + return new ARMInstPrinter(MAI, MII, MRI); return nullptr; } diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h index 7e9ba66..24ca567 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h +++ b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h @@ -34,6 +34,7 @@ class StringRef; class Target; class Triple; class raw_ostream; +class raw_pwrite_stream; extern Target TheARMLETarget, TheThumbLETarget; extern Target TheARMBETarget, TheThumbBETarget; @@ -41,9 +42,8 @@ extern Target TheARMBETarget, TheThumbBETarget; namespace ARM_MC { std::string ParseARMTriple(StringRef TT, StringRef CPU); - /// createARMMCSubtargetInfo - Create a ARM MCSubtargetInfo instance. - /// This is exposed so Asm parser, etc. do not need to go through - /// TargetRegistry. + /// Create a ARM MCSubtargetInfo instance. This is exposed so Asm parser, etc. + /// do not need to go through TargetRegistry. MCSubtargetInfo *createARMMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS); } @@ -83,24 +83,23 @@ MCAsmBackend *createThumbBEAsmBackend(const Target &T, const MCRegisterInfo &MRI // Construct a PE/COFF machine code streamer which will generate a PE/COFF // object file. MCStreamer *createARMWinCOFFStreamer(MCContext &Context, MCAsmBackend &MAB, - raw_ostream &OS, MCCodeEmitter *Emitter, - bool RelaxAll); + raw_pwrite_stream &OS, + MCCodeEmitter *Emitter, bool RelaxAll); -/// createARMELFObjectWriter - Construct an ELF Mach-O object writer. -MCObjectWriter *createARMELFObjectWriter(raw_ostream &OS, - uint8_t OSABI, +/// Construct an ELF Mach-O object writer. +MCObjectWriter *createARMELFObjectWriter(raw_pwrite_stream &OS, uint8_t OSABI, bool IsLittleEndian); -/// createARMMachObjectWriter - Construct an ARM Mach-O object writer. -MCObjectWriter *createARMMachObjectWriter(raw_ostream &OS, - bool Is64Bit, +/// Construct an ARM Mach-O object writer. +MCObjectWriter *createARMMachObjectWriter(raw_pwrite_stream &OS, bool Is64Bit, uint32_t CPUType, uint32_t CPUSubtype); -/// createARMWinCOFFObjectWriter - Construct an ARM PE/COFF object writer. -MCObjectWriter *createARMWinCOFFObjectWriter(raw_ostream &OS, bool Is64Bit); +/// Construct an ARM PE/COFF object writer. +MCObjectWriter *createARMWinCOFFObjectWriter(raw_pwrite_stream &OS, + bool Is64Bit); -/// createARMMachORelocationInfo - Construct ARM Mach-O relocation info. +/// Construct ARM Mach-O relocation info. MCRelocationInfo *createARMMachORelocationInfo(MCContext &Ctx); } // End llvm namespace diff --git a/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp b/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp index 3187d36..b1f9b58 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp @@ -88,6 +88,7 @@ static bool getARMFixupKindMachOInfo(unsigned Kind, unsigned &RelocType, case ARM::fixup_arm_ldst_pcrel_12: case ARM::fixup_arm_pcrel_10: case ARM::fixup_arm_adr_pcrel_12: + case ARM::fixup_arm_thumb_br: return false; // Handle 24-bit branch kinds. @@ -101,12 +102,6 @@ static bool getARMFixupKindMachOInfo(unsigned Kind, unsigned &RelocType, Log2Size = llvm::Log2_32(4); return true; - // Handle Thumb branches. - case ARM::fixup_arm_thumb_br: - RelocType = unsigned(MachO::ARM_THUMB_RELOC_BR22); - Log2Size = llvm::Log2_32(2); - return true; - case ARM::fixup_t2_uncondbranch: case ARM::fixup_arm_thumb_bl: case ARM::fixup_arm_thumb_blx: @@ -477,9 +472,8 @@ void ARMMachObjectWriter::RecordRelocation(MachObjectWriter *Writer, Writer->addRelocation(RelSymbol, Fragment->getParent(), MRE); } -MCObjectWriter *llvm::createARMMachObjectWriter(raw_ostream &OS, - bool Is64Bit, - uint32_t CPUType, +MCObjectWriter *llvm::createARMMachObjectWriter(raw_pwrite_stream &OS, + bool Is64Bit, uint32_t CPUType, uint32_t CPUSubtype) { return createMachObjectWriter(new ARMMachObjectWriter(Is64Bit, CPUType, diff --git a/lib/Target/ARM/MCTargetDesc/ARMWinCOFFObjectWriter.cpp b/lib/Target/ARM/MCTargetDesc/ARMWinCOFFObjectWriter.cpp index 2fd6445..166c04b 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMWinCOFFObjectWriter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMWinCOFFObjectWriter.cpp @@ -26,7 +26,7 @@ public: : MCWinCOFFObjectTargetWriter(COFF::IMAGE_FILE_MACHINE_ARMNT) { assert(!Is64Bit && "AArch64 support not yet implemented"); } - virtual ~ARMWinCOFFObjectWriter() { } + ~ARMWinCOFFObjectWriter() override {} unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup, bool IsCrossSection, @@ -82,7 +82,8 @@ bool ARMWinCOFFObjectWriter::recordRelocation(const MCFixup &Fixup) const { } namespace llvm { -MCObjectWriter *createARMWinCOFFObjectWriter(raw_ostream &OS, bool Is64Bit) { +MCObjectWriter *createARMWinCOFFObjectWriter(raw_pwrite_stream &OS, + bool Is64Bit) { MCWinCOFFObjectTargetWriter *MOTW = new ARMWinCOFFObjectWriter(Is64Bit); return createWinCOFFObjectWriter(MOTW, OS); } diff --git a/lib/Target/ARM/MCTargetDesc/ARMWinCOFFStreamer.cpp b/lib/Target/ARM/MCTargetDesc/ARMWinCOFFStreamer.cpp index dc707dc..b993b1b 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMWinCOFFStreamer.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMWinCOFFStreamer.cpp @@ -16,8 +16,8 @@ namespace { class ARMWinCOFFStreamer : public MCWinCOFFStreamer { public: ARMWinCOFFStreamer(MCContext &C, MCAsmBackend &AB, MCCodeEmitter &CE, - raw_ostream &OS) - : MCWinCOFFStreamer(C, AB, CE, OS) { } + raw_pwrite_stream &OS) + : MCWinCOFFStreamer(C, AB, CE, OS) {} void EmitAssemblerFlag(MCAssemblerFlag Flag) override; void EmitThumbFunc(MCSymbol *Symbol) override; @@ -38,7 +38,8 @@ void ARMWinCOFFStreamer::EmitThumbFunc(MCSymbol *Symbol) { } MCStreamer *llvm::createARMWinCOFFStreamer(MCContext &Context, - MCAsmBackend &MAB, raw_ostream &OS, + MCAsmBackend &MAB, + raw_pwrite_stream &OS, MCCodeEmitter *Emitter, bool RelaxAll) { return new ARMWinCOFFStreamer(Context, MAB, *Emitter, OS); |