diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /llvm/lib/Target/AVR | |
parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) | |
download | src-vendor/llvm-project/master.tar.gz src-vendor/llvm-project/master.zip |
Vendor import of llvm-project master 2e10b7a39b9, the last commit beforevendor/llvm-project/llvmorg-11-init-20887-g2e10b7a39b9vendor/llvm-project/master
the llvmorg-12-init tag, from which release/11.x was branched.
Notes
Notes:
svn path=/vendor/llvm-project/master/; revision=363578
svn path=/vendor/llvm-project/llvmorg-11-init-20887-g2e10b7a39b9/; revision=363579; tag=vendor/llvm-project/llvmorg-11-init-20887-g2e10b7a39b9
Diffstat (limited to 'llvm/lib/Target/AVR')
33 files changed, 828 insertions, 624 deletions
diff --git a/llvm/lib/Target/AVR/AVRAsmPrinter.cpp b/llvm/lib/Target/AVR/AVRAsmPrinter.cpp index 9b09c7456543..722eecdc16a1 100644 --- a/llvm/lib/Target/AVR/AVRAsmPrinter.cpp +++ b/llvm/lib/Target/AVR/AVRAsmPrinter.cpp @@ -51,7 +51,7 @@ public: bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, const char *ExtraCode, raw_ostream &O) override; - void EmitInstruction(const MachineInstr *MI) override; + void emitInstruction(const MachineInstr *MI) override; private: const MCRegisterInfo &MRI; @@ -168,7 +168,7 @@ bool AVRAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, return false; } -void AVRAsmPrinter::EmitInstruction(const MachineInstr *MI) { +void AVRAsmPrinter::emitInstruction(const MachineInstr *MI) { AVRMCInstLower MCInstLowering(OutContext, *this); MCInst I; diff --git a/llvm/lib/Target/AVR/AVRCallingConv.td b/llvm/lib/Target/AVR/AVRCallingConv.td index 213e35fca66d..65545e531a88 100644 --- a/llvm/lib/Target/AVR/AVRCallingConv.td +++ b/llvm/lib/Target/AVR/AVRCallingConv.td @@ -6,21 +6,13 @@ // //===----------------------------------------------------------------------===// // This describes the calling conventions for AVR architecture. +// Normal functions use a special calling convention, solved in code. //===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// // AVR Return Value Calling Convention //===----------------------------------------------------------------------===// -def RetCC_AVR : CallingConv -<[ - // i8 is returned in R24. - CCIfType<[i8], CCAssignToReg<[R24]>>, - - // i16 are returned in R25:R24, R23:R22, R21:R20 and R19:R18. - CCIfType<[i16], CCAssignToReg<[R25R24, R23R22, R21R20, R19R18]>> -]>; - // Special return value calling convention for runtime functions. def RetCC_AVR_BUILTIN : CallingConv <[ @@ -41,14 +33,6 @@ def ArgCC_AVR_Vararg : CallingConv CCAssignToStack<2, 1> ]>; -// Special argument calling convention for -// division runtime functions. -def ArgCC_AVR_BUILTIN_DIV : CallingConv -<[ - CCIfType<[i8], CCAssignToReg<[R24,R22]>>, - CCIfType<[i16], CCAssignToReg<[R25R24, R23R22]>> -]>; - //===----------------------------------------------------------------------===// // Callee-saved register lists. //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/AVR/AVRDevices.td b/llvm/lib/Target/AVR/AVRDevices.td index 62def4574437..6730f2e1673e 100644 --- a/llvm/lib/Target/AVR/AVRDevices.td +++ b/llvm/lib/Target/AVR/AVRDevices.td @@ -121,6 +121,11 @@ def FeatureTinyEncoding : SubtargetFeature<"tinyencoding", "The device has Tiny core specific " "instruction encodings">; +// The device has CPU registers mapped in data address space +def FeatureMMR : SubtargetFeature<"memmappedregs", "m_hasMemMappedGPR", + "true", "The device has CPU registers " + "mapped in data address space">; + class ELFArch<string name> : SubtargetFeature<"", "ELFArch", !strconcat("ELF::",name), "">; @@ -152,7 +157,7 @@ def ELFArchXMEGA7 : ELFArch<"EF_AVR_ARCH_XMEGA7">; // device should have. def FamilyAVR0 : Family<"avr0", []>; -def FamilyAVR1 : Family<"avr1", [FamilyAVR0, FeatureLPM]>; +def FamilyAVR1 : Family<"avr1", [FamilyAVR0, FeatureLPM, FeatureMMR]>; def FamilyAVR2 : Family<"avr2", [FamilyAVR1, FeatureIJMPCALL, FeatureADDSUBIW, @@ -190,11 +195,14 @@ def FamilyAVR6 : Family<"avr6", def FamilyTiny : Family<"avrtiny", [FamilyAVR0, FeatureBREAK, FeatureSRAM, - FeatureTinyEncoding]>; + FeatureTinyEncoding, FeatureMMR]>; def FamilyXMEGA : Family<"xmega", - [FamilyAVR51, FeatureEIJMPCALL, FeatureSPMX, - FeatureDES]>; + [FamilyAVR0, FeatureLPM, FeatureIJMPCALL, FeatureADDSUBIW, + FeatureSRAM, FeatureJMPCALL, FeatureMultiplication, + FeatureMOVW, FeatureLPMX, FeatureSPM, + FeatureBREAK, FeatureEIJMPCALL, FeatureSPMX, + FeatureDES, FeatureELPM, FeatureELPMX]>; def FamilyXMEGAU : Family<"xmegau", [FamilyXMEGA, FeatureRMW]>; @@ -208,7 +216,7 @@ def FeatureSetSpecial : FeatureSet<"special", FeatureLPM, FeatureLPMX, FeatureELPM, FeatureELPMX, FeatureSPM, FeatureSPMX, FeatureDES, FeatureRMW, - FeatureMultiplication, FeatureBREAK]>; + FeatureMultiplication, FeatureBREAK, FeatureMMR]>; //===---------------------------------------------------------------------===// // AVR microcontrollers supported. diff --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp index f466c5c053ad..8ee69201e932 100644 --- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp +++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp @@ -51,9 +51,9 @@ private: const TargetInstrInfo *TII; /// The register to be used for temporary storage. - const unsigned SCRATCH_REGISTER = AVR::R0; + const Register SCRATCH_REGISTER = AVR::R0; /// The register that will always contain zero. - const unsigned ZERO_REGISTER = AVR::R1; + const Register ZERO_REGISTER = AVR::R1; /// The IO address of the status register. const unsigned SREG_ADDR = 0x3f; @@ -66,7 +66,7 @@ private: } MachineInstrBuilder buildMI(Block &MBB, BlockIt MBBI, unsigned Opcode, - unsigned DstReg) { + Register DstReg) { return BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(Opcode), DstReg); } @@ -91,7 +91,7 @@ private: BlockIt MBBI); /// Scavenges a free GPR8 register for use. - unsigned scavengeGPR8(MachineInstr &MI); + Register scavengeGPR8(MachineInstr &MI); }; char AVRExpandPseudo::ID = 0; @@ -141,7 +141,7 @@ bool AVRExpandPseudo::runOnMachineFunction(MachineFunction &MF) { bool AVRExpandPseudo:: expandArith(unsigned OpLo, unsigned OpHi, Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned SrcLoReg, SrcHiReg, DstLoReg, DstHiReg; + Register SrcLoReg, SrcHiReg, DstLoReg, DstHiReg; Register DstReg = MI.getOperand(0).getReg(); Register SrcReg = MI.getOperand(2).getReg(); bool DstIsDead = MI.getOperand(0).isDead(); @@ -174,7 +174,7 @@ expandArith(unsigned OpLo, unsigned OpHi, Block &MBB, BlockIt MBBI) { bool AVRExpandPseudo:: expandLogic(unsigned Op, Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned SrcLoReg, SrcHiReg, DstLoReg, DstHiReg; + Register SrcLoReg, SrcHiReg, DstLoReg, DstHiReg; Register DstReg = MI.getOperand(0).getReg(); Register SrcReg = MI.getOperand(2).getReg(); bool DstIsDead = MI.getOperand(0).isDead(); @@ -221,7 +221,7 @@ bool AVRExpandPseudo:: bool AVRExpandPseudo:: expandLogicImm(unsigned Op, Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned DstLoReg, DstHiReg; + Register DstLoReg, DstHiReg; Register DstReg = MI.getOperand(0).getReg(); bool DstIsDead = MI.getOperand(0).isDead(); bool SrcIsKill = MI.getOperand(1).isKill(); @@ -273,8 +273,8 @@ bool AVRExpandPseudo::expand<AVR::SUBWRdRr>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::SUBIWRdK>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned DstLoReg, DstHiReg; - unsigned DstReg = MI.getOperand(0).getReg(); + Register DstLoReg, DstHiReg; + Register DstReg = MI.getOperand(0).getReg(); bool DstIsDead = MI.getOperand(0).isDead(); bool SrcIsKill = MI.getOperand(1).isKill(); bool ImpIsDead = MI.getOperand(3).isDead(); @@ -325,16 +325,16 @@ bool AVRExpandPseudo::expand<AVR::SBCWRdRr>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::SBCIWRdK>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned OpLo, OpHi, DstLoReg, DstHiReg; - unsigned DstReg = MI.getOperand(0).getReg(); + Register DstLoReg, DstHiReg; + Register DstReg = MI.getOperand(0).getReg(); bool DstIsDead = MI.getOperand(0).isDead(); bool SrcIsKill = MI.getOperand(1).isKill(); bool ImpIsDead = MI.getOperand(3).isDead(); unsigned Imm = MI.getOperand(2).getImm(); unsigned Lo8 = Imm & 0xff; unsigned Hi8 = (Imm >> 8) & 0xff; - OpLo = AVR::SBCIRdK; - OpHi = AVR::SBCIRdK; + unsigned OpLo = AVR::SBCIRdK; + unsigned OpHi = AVR::SBCIRdK; TRI->splitReg(DstReg, DstLoReg, DstHiReg); auto MIBLO = buildMI(MBB, MBBI, OpLo) @@ -388,13 +388,13 @@ bool AVRExpandPseudo::expand<AVR::EORWRdRr>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::COMWRd>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned OpLo, OpHi, DstLoReg, DstHiReg; - unsigned DstReg = MI.getOperand(0).getReg(); + Register DstLoReg, DstHiReg; + Register DstReg = MI.getOperand(0).getReg(); bool DstIsDead = MI.getOperand(0).isDead(); bool DstIsKill = MI.getOperand(1).isKill(); bool ImpIsDead = MI.getOperand(2).isDead(); - OpLo = AVR::COMRd; - OpHi = AVR::COMRd; + unsigned OpLo = AVR::COMRd; + unsigned OpHi = AVR::COMRd; TRI->splitReg(DstReg, DstLoReg, DstHiReg); auto MIBLO = buildMI(MBB, MBBI, OpLo) @@ -418,14 +418,14 @@ bool AVRExpandPseudo::expand<AVR::COMWRd>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::CPWRdRr>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned OpLo, OpHi, SrcLoReg, SrcHiReg, DstLoReg, DstHiReg; - unsigned DstReg = MI.getOperand(0).getReg(); - unsigned SrcReg = MI.getOperand(1).getReg(); + Register SrcLoReg, SrcHiReg, DstLoReg, DstHiReg; + Register DstReg = MI.getOperand(0).getReg(); + Register SrcReg = MI.getOperand(1).getReg(); bool DstIsKill = MI.getOperand(0).isKill(); bool SrcIsKill = MI.getOperand(1).isKill(); bool ImpIsDead = MI.getOperand(2).isDead(); - OpLo = AVR::CPRdRr; - OpHi = AVR::CPCRdRr; + unsigned OpLo = AVR::CPRdRr; + unsigned OpHi = AVR::CPCRdRr; TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg); TRI->splitReg(DstReg, DstLoReg, DstHiReg); @@ -451,14 +451,14 @@ bool AVRExpandPseudo::expand<AVR::CPWRdRr>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::CPCWRdRr>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned OpLo, OpHi, SrcLoReg, SrcHiReg, DstLoReg, DstHiReg; - unsigned DstReg = MI.getOperand(0).getReg(); - unsigned SrcReg = MI.getOperand(1).getReg(); + Register SrcLoReg, SrcHiReg, DstLoReg, DstHiReg; + Register DstReg = MI.getOperand(0).getReg(); + Register SrcReg = MI.getOperand(1).getReg(); bool DstIsKill = MI.getOperand(0).isKill(); bool SrcIsKill = MI.getOperand(1).isKill(); bool ImpIsDead = MI.getOperand(2).isDead(); - OpLo = AVR::CPCRdRr; - OpHi = AVR::CPCRdRr; + unsigned OpLo = AVR::CPCRdRr; + unsigned OpHi = AVR::CPCRdRr; TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg); TRI->splitReg(DstReg, DstLoReg, DstHiReg); @@ -486,11 +486,11 @@ bool AVRExpandPseudo::expand<AVR::CPCWRdRr>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::LDIWRdK>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned OpLo, OpHi, DstLoReg, DstHiReg; - unsigned DstReg = MI.getOperand(0).getReg(); + Register DstLoReg, DstHiReg; + Register DstReg = MI.getOperand(0).getReg(); bool DstIsDead = MI.getOperand(0).isDead(); - OpLo = AVR::LDIRdK; - OpHi = AVR::LDIRdK; + unsigned OpLo = AVR::LDIRdK; + unsigned OpHi = AVR::LDIRdK; TRI->splitReg(DstReg, DstLoReg, DstHiReg); auto MIBLO = buildMI(MBB, MBBI, OpLo) @@ -535,11 +535,11 @@ bool AVRExpandPseudo::expand<AVR::LDIWRdK>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::LDSWRdK>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned OpLo, OpHi, DstLoReg, DstHiReg; - unsigned DstReg = MI.getOperand(0).getReg(); + Register DstLoReg, DstHiReg; + Register DstReg = MI.getOperand(0).getReg(); bool DstIsDead = MI.getOperand(0).isDead(); - OpLo = AVR::LDSRdK; - OpHi = AVR::LDSRdK; + unsigned OpLo = AVR::LDSRdK; + unsigned OpHi = AVR::LDSRdK; TRI->splitReg(DstReg, DstLoReg, DstHiReg); auto MIBLO = buildMI(MBB, MBBI, OpLo) @@ -579,26 +579,26 @@ bool AVRExpandPseudo::expand<AVR::LDSWRdK>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::LDWRdPtr>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned OpLo, OpHi, DstLoReg, DstHiReg; - unsigned DstReg = MI.getOperand(0).getReg(); - unsigned TmpReg = 0; // 0 for no temporary register - unsigned SrcReg = MI.getOperand(1).getReg(); + Register DstLoReg, DstHiReg; + Register DstReg = MI.getOperand(0).getReg(); + Register TmpReg = 0; // 0 for no temporary register + Register SrcReg = MI.getOperand(1).getReg(); bool SrcIsKill = MI.getOperand(1).isKill(); - OpLo = AVR::LDRdPtr; - OpHi = AVR::LDDRdPtrQ; + unsigned OpLo = AVR::LDRdPtr; + unsigned OpHi = AVR::LDDRdPtrQ; TRI->splitReg(DstReg, DstLoReg, DstHiReg); // Use a temporary register if src and dst registers are the same. if (DstReg == SrcReg) TmpReg = scavengeGPR8(MI); - unsigned CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg; - unsigned CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg; + Register CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg; + Register CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg; // Load low byte. auto MIBLO = buildMI(MBB, MBBI, OpLo) - .addReg(CurDstLoReg, RegState::Define) - .addReg(SrcReg, RegState::Define); + .addReg(CurDstLoReg, RegState::Define) + .addReg(SrcReg); // Push low byte onto stack if necessary. if (TmpReg) @@ -628,13 +628,13 @@ bool AVRExpandPseudo::expand<AVR::LDWRdPtr>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::LDWRdPtrPi>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned OpLo, OpHi, DstLoReg, DstHiReg; - unsigned DstReg = MI.getOperand(0).getReg(); - unsigned SrcReg = MI.getOperand(1).getReg(); + Register DstLoReg, DstHiReg; + Register DstReg = MI.getOperand(0).getReg(); + Register SrcReg = MI.getOperand(1).getReg(); bool DstIsDead = MI.getOperand(0).isDead(); bool SrcIsDead = MI.getOperand(1).isKill(); - OpLo = AVR::LDRdPtrPi; - OpHi = AVR::LDRdPtrPi; + unsigned OpLo = AVR::LDRdPtrPi; + unsigned OpHi = AVR::LDRdPtrPi; TRI->splitReg(DstReg, DstLoReg, DstHiReg); assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same"); @@ -659,13 +659,13 @@ bool AVRExpandPseudo::expand<AVR::LDWRdPtrPi>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::LDWRdPtrPd>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned OpLo, OpHi, DstLoReg, DstHiReg; - unsigned DstReg = MI.getOperand(0).getReg(); - unsigned SrcReg = MI.getOperand(1).getReg(); + Register DstLoReg, DstHiReg; + Register DstReg = MI.getOperand(0).getReg(); + Register SrcReg = MI.getOperand(1).getReg(); bool DstIsDead = MI.getOperand(0).isDead(); bool SrcIsDead = MI.getOperand(1).isKill(); - OpLo = AVR::LDRdPtrPd; - OpHi = AVR::LDRdPtrPd; + unsigned OpLo = AVR::LDRdPtrPd; + unsigned OpHi = AVR::LDRdPtrPd; TRI->splitReg(DstReg, DstLoReg, DstHiReg); assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same"); @@ -690,14 +690,14 @@ bool AVRExpandPseudo::expand<AVR::LDWRdPtrPd>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned OpLo, OpHi, DstLoReg, DstHiReg; - unsigned DstReg = MI.getOperand(0).getReg(); - unsigned TmpReg = 0; // 0 for no temporary register - unsigned SrcReg = MI.getOperand(1).getReg(); + Register DstLoReg, DstHiReg; + Register DstReg = MI.getOperand(0).getReg(); + Register TmpReg = 0; // 0 for no temporary register + Register SrcReg = MI.getOperand(1).getReg(); unsigned Imm = MI.getOperand(2).getImm(); bool SrcIsKill = MI.getOperand(1).isKill(); - OpLo = AVR::LDDRdPtrQ; - OpHi = AVR::LDDRdPtrQ; + unsigned OpLo = AVR::LDDRdPtrQ; + unsigned OpHi = AVR::LDDRdPtrQ; TRI->splitReg(DstReg, DstLoReg, DstHiReg); // Since we add 1 to the Imm value for the high byte below, and 63 is the highest Imm value @@ -708,8 +708,8 @@ bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(Block &MBB, BlockIt MBBI) { if (DstReg == SrcReg) TmpReg = scavengeGPR8(MI); - unsigned CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg; - unsigned CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg; + Register CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg; + Register CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg; // Load low byte. auto MIBLO = buildMI(MBB, MBBI, OpLo) @@ -745,21 +745,21 @@ bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::LPMWRdZ>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned OpLo, OpHi, DstLoReg, DstHiReg; - unsigned DstReg = MI.getOperand(0).getReg(); - unsigned TmpReg = 0; // 0 for no temporary register - unsigned SrcReg = MI.getOperand(1).getReg(); + Register DstLoReg, DstHiReg; + Register DstReg = MI.getOperand(0).getReg(); + Register TmpReg = 0; // 0 for no temporary register + Register SrcReg = MI.getOperand(1).getReg(); bool SrcIsKill = MI.getOperand(1).isKill(); - OpLo = AVR::LPMRdZPi; - OpHi = AVR::LPMRdZ; + unsigned OpLo = AVR::LPMRdZPi; + unsigned OpHi = AVR::LPMRdZ; TRI->splitReg(DstReg, DstLoReg, DstHiReg); // Use a temporary register if src and dst registers are the same. if (DstReg == SrcReg) TmpReg = scavengeGPR8(MI); - unsigned CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg; - unsigned CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg; + Register CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg; + Register CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg; // Load low byte. auto MIBLO = buildMI(MBB, MBBI, OpLo) @@ -862,7 +862,7 @@ bool AVRExpandPseudo::expandAtomicArithmeticOp(unsigned Width, }); } -unsigned AVRExpandPseudo::scavengeGPR8(MachineInstr &MI) { +Register AVRExpandPseudo::scavengeGPR8(MachineInstr &MI) { MachineBasicBlock &MBB = *MI.getParent(); RegScavenger RS; @@ -968,11 +968,11 @@ bool AVRExpandPseudo::expand<AVR::AtomicFence>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::STSWKRr>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned OpLo, OpHi, SrcLoReg, SrcHiReg; - unsigned SrcReg = MI.getOperand(1).getReg(); + Register SrcLoReg, SrcHiReg; + Register SrcReg = MI.getOperand(1).getReg(); bool SrcIsKill = MI.getOperand(1).isKill(); - OpLo = AVR::STSKRr; - OpHi = AVR::STSKRr; + unsigned OpLo = AVR::STSKRr; + unsigned OpHi = AVR::STSKRr; TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg); // Write the high byte first in case this address belongs to a special @@ -1014,12 +1014,12 @@ bool AVRExpandPseudo::expand<AVR::STSWKRr>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::STWPtrRr>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned OpLo, OpHi, SrcLoReg, SrcHiReg; - unsigned DstReg = MI.getOperand(0).getReg(); - unsigned SrcReg = MI.getOperand(1).getReg(); + Register SrcLoReg, SrcHiReg; + Register DstReg = MI.getOperand(0).getReg(); + Register SrcReg = MI.getOperand(1).getReg(); bool SrcIsKill = MI.getOperand(1).isKill(); - OpLo = AVR::STPtrRr; - OpHi = AVR::STDPtrQRr; + unsigned OpLo = AVR::STPtrRr; + unsigned OpHi = AVR::STDPtrQRr; TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg); //:TODO: need to reverse this order like inw and stsw? @@ -1042,14 +1042,14 @@ bool AVRExpandPseudo::expand<AVR::STWPtrRr>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::STWPtrPiRr>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned OpLo, OpHi, SrcLoReg, SrcHiReg; - unsigned DstReg = MI.getOperand(0).getReg(); - unsigned SrcReg = MI.getOperand(2).getReg(); + Register SrcLoReg, SrcHiReg; + Register DstReg = MI.getOperand(0).getReg(); + Register SrcReg = MI.getOperand(2).getReg(); unsigned Imm = MI.getOperand(3).getImm(); bool DstIsDead = MI.getOperand(0).isDead(); bool SrcIsKill = MI.getOperand(2).isKill(); - OpLo = AVR::STPtrPiRr; - OpHi = AVR::STPtrPiRr; + unsigned OpLo = AVR::STPtrPiRr; + unsigned OpHi = AVR::STPtrPiRr; TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg); assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same"); @@ -1076,14 +1076,14 @@ bool AVRExpandPseudo::expand<AVR::STWPtrPiRr>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::STWPtrPdRr>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned OpLo, OpHi, SrcLoReg, SrcHiReg; - unsigned DstReg = MI.getOperand(0).getReg(); - unsigned SrcReg = MI.getOperand(2).getReg(); + Register SrcLoReg, SrcHiReg; + Register DstReg = MI.getOperand(0).getReg(); + Register SrcReg = MI.getOperand(2).getReg(); unsigned Imm = MI.getOperand(3).getImm(); bool DstIsDead = MI.getOperand(0).isDead(); bool SrcIsKill = MI.getOperand(2).isKill(); - OpLo = AVR::STPtrPdRr; - OpHi = AVR::STPtrPdRr; + unsigned OpLo = AVR::STPtrPdRr; + unsigned OpHi = AVR::STPtrPdRr; TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg); assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same"); @@ -1110,14 +1110,14 @@ bool AVRExpandPseudo::expand<AVR::STWPtrPdRr>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::STDWPtrQRr>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned OpLo, OpHi, SrcLoReg, SrcHiReg; - unsigned DstReg = MI.getOperand(0).getReg(); - unsigned SrcReg = MI.getOperand(2).getReg(); + Register SrcLoReg, SrcHiReg; + Register DstReg = MI.getOperand(0).getReg(); + Register SrcReg = MI.getOperand(2).getReg(); unsigned Imm = MI.getOperand(1).getImm(); bool DstIsKill = MI.getOperand(0).isKill(); bool SrcIsKill = MI.getOperand(2).isKill(); - OpLo = AVR::STDPtrQRr; - OpHi = AVR::STDPtrQRr; + unsigned OpLo = AVR::STDPtrQRr; + unsigned OpHi = AVR::STDPtrQRr; TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg); // Since we add 1 to the Imm value for the high byte below, and 63 is the highest Imm value @@ -1144,12 +1144,12 @@ bool AVRExpandPseudo::expand<AVR::STDWPtrQRr>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::INWRdA>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned OpLo, OpHi, DstLoReg, DstHiReg; + Register DstLoReg, DstHiReg; unsigned Imm = MI.getOperand(1).getImm(); - unsigned DstReg = MI.getOperand(0).getReg(); + Register DstReg = MI.getOperand(0).getReg(); bool DstIsDead = MI.getOperand(0).isDead(); - OpLo = AVR::INRdA; - OpHi = AVR::INRdA; + unsigned OpLo = AVR::INRdA; + unsigned OpHi = AVR::INRdA; TRI->splitReg(DstReg, DstLoReg, DstHiReg); // Since we add 1 to the Imm value for the high byte below, and 63 is the highest Imm value @@ -1174,12 +1174,12 @@ bool AVRExpandPseudo::expand<AVR::INWRdA>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::OUTWARr>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned OpLo, OpHi, SrcLoReg, SrcHiReg; + Register SrcLoReg, SrcHiReg; unsigned Imm = MI.getOperand(0).getImm(); - unsigned SrcReg = MI.getOperand(1).getReg(); + Register SrcReg = MI.getOperand(1).getReg(); bool SrcIsKill = MI.getOperand(1).isKill(); - OpLo = AVR::OUTARr; - OpHi = AVR::OUTARr; + unsigned OpLo = AVR::OUTARr; + unsigned OpHi = AVR::OUTARr; TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg); // Since we add 1 to the Imm value for the high byte below, and 63 is the highest Imm value @@ -1205,12 +1205,12 @@ bool AVRExpandPseudo::expand<AVR::OUTWARr>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::PUSHWRr>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned OpLo, OpHi, SrcLoReg, SrcHiReg; - unsigned SrcReg = MI.getOperand(0).getReg(); + Register SrcLoReg, SrcHiReg; + Register SrcReg = MI.getOperand(0).getReg(); bool SrcIsKill = MI.getOperand(0).isKill(); unsigned Flags = MI.getFlags(); - OpLo = AVR::PUSHRr; - OpHi = AVR::PUSHRr; + unsigned OpLo = AVR::PUSHRr; + unsigned OpHi = AVR::PUSHRr; TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg); // Low part @@ -1230,11 +1230,11 @@ bool AVRExpandPseudo::expand<AVR::PUSHWRr>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::POPWRd>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned OpLo, OpHi, DstLoReg, DstHiReg; - unsigned DstReg = MI.getOperand(0).getReg(); + Register DstLoReg, DstHiReg; + Register DstReg = MI.getOperand(0).getReg(); unsigned Flags = MI.getFlags(); - OpLo = AVR::POPRd; - OpHi = AVR::POPRd; + unsigned OpLo = AVR::POPRd; + unsigned OpHi = AVR::POPRd; TRI->splitReg(DstReg, DstLoReg, DstHiReg); buildMI(MBB, MBBI, OpHi, DstHiReg).setMIFlags(Flags); // High @@ -1254,7 +1254,7 @@ bool AVRExpandPseudo::expand<AVR::ROLBRd>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; unsigned OpShift, OpCarry; - unsigned DstReg = MI.getOperand(0).getReg(); + Register DstReg = MI.getOperand(0).getReg(); bool DstIsDead = MI.getOperand(0).isDead(); OpShift = AVR::ADDRdRr; OpCarry = AVR::ADCRdRr; @@ -1291,7 +1291,7 @@ bool AVRExpandPseudo::expand<AVR::RORBRd>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; unsigned OpShiftOut, OpLoad, OpShiftIn, OpAdd; - unsigned DstReg = MI.getOperand(0).getReg(); + Register DstReg = MI.getOperand(0).getReg(); bool DstIsDead = MI.getOperand(0).isDead(); OpShiftOut = AVR::LSRRd; OpLoad = AVR::LDIRdK; @@ -1334,13 +1334,13 @@ bool AVRExpandPseudo::expand<AVR::RORBRd>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::LSLWRd>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned OpLo, OpHi, DstLoReg, DstHiReg; - unsigned DstReg = MI.getOperand(0).getReg(); + Register DstLoReg, DstHiReg; + Register DstReg = MI.getOperand(0).getReg(); bool DstIsDead = MI.getOperand(0).isDead(); bool DstIsKill = MI.getOperand(1).isKill(); bool ImpIsDead = MI.getOperand(2).isDead(); - OpLo = AVR::ADDRdRr; // ADD Rd, Rd <==> LSL Rd - OpHi = AVR::ADCRdRr; // ADC Rd, Rd <==> ROL Rd + unsigned OpLo = AVR::ADDRdRr; // ADD Rd, Rd <==> LSL Rd + unsigned OpHi = AVR::ADCRdRr; // ADC Rd, Rd <==> ROL Rd TRI->splitReg(DstReg, DstLoReg, DstHiReg); // Low part @@ -1367,13 +1367,13 @@ bool AVRExpandPseudo::expand<AVR::LSLWRd>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::LSRWRd>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned OpLo, OpHi, DstLoReg, DstHiReg; - unsigned DstReg = MI.getOperand(0).getReg(); + Register DstLoReg, DstHiReg; + Register DstReg = MI.getOperand(0).getReg(); bool DstIsDead = MI.getOperand(0).isDead(); bool DstIsKill = MI.getOperand(1).isKill(); bool ImpIsDead = MI.getOperand(2).isDead(); - OpLo = AVR::RORRd; - OpHi = AVR::LSRRd; + unsigned OpLo = AVR::RORRd; + unsigned OpHi = AVR::LSRRd; TRI->splitReg(DstReg, DstLoReg, DstHiReg); // High part @@ -1410,13 +1410,13 @@ bool AVRExpandPseudo::expand<AVR::ROLWRd>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::ASRWRd>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned OpLo, OpHi, DstLoReg, DstHiReg; - unsigned DstReg = MI.getOperand(0).getReg(); + Register DstLoReg, DstHiReg; + Register DstReg = MI.getOperand(0).getReg(); bool DstIsDead = MI.getOperand(0).isDead(); bool DstIsKill = MI.getOperand(1).isKill(); bool ImpIsDead = MI.getOperand(2).isDead(); - OpLo = AVR::RORRd; - OpHi = AVR::ASRRd; + unsigned OpLo = AVR::RORRd; + unsigned OpHi = AVR::ASRRd; TRI->splitReg(DstReg, DstLoReg, DstHiReg); // High part @@ -1440,7 +1440,7 @@ bool AVRExpandPseudo::expand<AVR::ASRWRd>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::SEXT>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned DstLoReg, DstHiReg; + Register DstLoReg, DstHiReg; // sext R17:R16, R17 // mov r16, r17 // lsl r17 @@ -1454,8 +1454,8 @@ template <> bool AVRExpandPseudo::expand<AVR::SEXT>(Block &MBB, BlockIt MBBI) { // mov r17, r16 // lsl r17 // sbc r17, r17 - unsigned DstReg = MI.getOperand(0).getReg(); - unsigned SrcReg = MI.getOperand(1).getReg(); + Register DstReg = MI.getOperand(0).getReg(); + Register SrcReg = MI.getOperand(1).getReg(); bool DstIsDead = MI.getOperand(0).isDead(); bool SrcIsKill = MI.getOperand(1).isKill(); bool ImpIsDead = MI.getOperand(2).isDead(); @@ -1499,7 +1499,7 @@ template <> bool AVRExpandPseudo::expand<AVR::SEXT>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::ZEXT>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned DstLoReg, DstHiReg; + Register DstLoReg, DstHiReg; // zext R25:R24, R20 // mov R24, R20 // eor R25, R25 @@ -1508,8 +1508,8 @@ template <> bool AVRExpandPseudo::expand<AVR::ZEXT>(Block &MBB, BlockIt MBBI) { // zext R25:R24, R25 // mov R24, R25 // eor R25, R25 - unsigned DstReg = MI.getOperand(0).getReg(); - unsigned SrcReg = MI.getOperand(1).getReg(); + Register DstReg = MI.getOperand(0).getReg(); + Register SrcReg = MI.getOperand(1).getReg(); bool DstIsDead = MI.getOperand(0).isDead(); bool SrcIsKill = MI.getOperand(1).isKill(); bool ImpIsDead = MI.getOperand(2).isDead(); @@ -1536,12 +1536,12 @@ template <> bool AVRExpandPseudo::expand<AVR::ZEXT>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::SPREAD>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned OpLo, OpHi, DstLoReg, DstHiReg; - unsigned DstReg = MI.getOperand(0).getReg(); + Register DstLoReg, DstHiReg; + Register DstReg = MI.getOperand(0).getReg(); bool DstIsDead = MI.getOperand(0).isDead(); unsigned Flags = MI.getFlags(); - OpLo = AVR::INRdA; - OpHi = AVR::INRdA; + unsigned OpLo = AVR::INRdA; + unsigned OpHi = AVR::INRdA; TRI->splitReg(DstReg, DstLoReg, DstHiReg); // Low part @@ -1563,8 +1563,8 @@ bool AVRExpandPseudo::expand<AVR::SPREAD>(Block &MBB, BlockIt MBBI) { template <> bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; - unsigned SrcLoReg, SrcHiReg; - unsigned SrcReg = MI.getOperand(1).getReg(); + Register SrcLoReg, SrcHiReg; + Register SrcReg = MI.getOperand(1).getReg(); bool SrcIsKill = MI.getOperand(1).isKill(); unsigned Flags = MI.getFlags(); TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg); diff --git a/llvm/lib/Target/AVR/AVRFrameLowering.cpp b/llvm/lib/Target/AVR/AVRFrameLowering.cpp index e6c48de5a782..c95a553b86ac 100644 --- a/llvm/lib/Target/AVR/AVRFrameLowering.cpp +++ b/llvm/lib/Target/AVR/AVRFrameLowering.cpp @@ -30,8 +30,7 @@ namespace llvm { AVRFrameLowering::AVRFrameLowering() - : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align::None(), - -2) {} + : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(1), -2) {} bool AVRFrameLowering::canSimplifyCallFramePseudos( const MachineFunction &MF) const { @@ -53,30 +52,22 @@ bool AVRFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { void AVRFrameLowering::emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const { MachineBasicBlock::iterator MBBI = MBB.begin(); - CallingConv::ID CallConv = MF.getFunction().getCallingConv(); DebugLoc DL = (MBBI != MBB.end()) ? MBBI->getDebugLoc() : DebugLoc(); const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>(); const AVRInstrInfo &TII = *STI.getInstrInfo(); + const AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>(); bool HasFP = hasFP(MF); // Interrupt handlers re-enable interrupts in function entry. - if (CallConv == CallingConv::AVR_INTR) { + if (AFI->isInterruptHandler()) { BuildMI(MBB, MBBI, DL, TII.get(AVR::BSETs)) .addImm(0x07) .setMIFlag(MachineInstr::FrameSetup); } - // Save the frame pointer if we have one. - if (HasFP) { - BuildMI(MBB, MBBI, DL, TII.get(AVR::PUSHWRr)) - .addReg(AVR::R29R28, RegState::Kill) - .setMIFlag(MachineInstr::FrameSetup); - } - // Emit special prologue code to save R1, R0 and SREG in interrupt/signal // handlers before saving any other registers. - if (CallConv == CallingConv::AVR_INTR || - CallConv == CallingConv::AVR_SIGNAL) { + if (AFI->isInterruptOrSignalHandler()) { BuildMI(MBB, MBBI, DL, TII.get(AVR::PUSHWRr)) .addReg(AVR::R1R0, RegState::Kill) .setMIFlag(MachineInstr::FrameSetup); @@ -100,7 +91,6 @@ void AVRFrameLowering::emitPrologue(MachineFunction &MF, } const MachineFrameInfo &MFI = MF.getFrameInfo(); - const AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>(); unsigned FrameSize = MFI.getStackSize() - AFI->getCalleeSavedFrameSize(); // Skip the callee-saved push instructions. @@ -143,13 +133,11 @@ void AVRFrameLowering::emitPrologue(MachineFunction &MF, void AVRFrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const { - CallingConv::ID CallConv = MF.getFunction().getCallingConv(); - bool isHandler = (CallConv == CallingConv::AVR_INTR || - CallConv == CallingConv::AVR_SIGNAL); + const AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>(); // Early exit if the frame pointer is not needed in this function except for // signal/interrupt handlers where special code generation is required. - if (!hasFP(MF) && !isHandler) { + if (!hasFP(MF) && !AFI->isInterruptOrSignalHandler()) { return; } @@ -159,14 +147,13 @@ void AVRFrameLowering::emitEpilogue(MachineFunction &MF, DebugLoc DL = MBBI->getDebugLoc(); const MachineFrameInfo &MFI = MF.getFrameInfo(); - const AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>(); unsigned FrameSize = MFI.getStackSize() - AFI->getCalleeSavedFrameSize(); const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>(); const AVRInstrInfo &TII = *STI.getInstrInfo(); // Emit special epilogue code to restore R1, R0 and SREG in interrupt/signal // handlers at the very end of the function, just before reti. - if (isHandler) { + if (AFI->isInterruptOrSignalHandler()) { BuildMI(MBB, MBBI, DL, TII.get(AVR::POPRd), AVR::R0); BuildMI(MBB, MBBI, DL, TII.get(AVR::OUTARr)) .addImm(0x3f) @@ -174,9 +161,6 @@ void AVRFrameLowering::emitEpilogue(MachineFunction &MF, BuildMI(MBB, MBBI, DL, TII.get(AVR::POPWRd), AVR::R1R0); } - if (hasFP(MF)) - BuildMI(MBB, MBBI, DL, TII.get(AVR::POPWRd), AVR::R29R28); - // Early exit if there is no need to restore the frame pointer. if (!FrameSize) { return; @@ -234,8 +218,7 @@ bool AVRFrameLowering::hasFP(const MachineFunction &MF) const { bool AVRFrameLowering::spillCalleeSavedRegisters( MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector<CalleeSavedInfo> &CSI, - const TargetRegisterInfo *TRI) const { + ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const { if (CSI.empty()) { return false; } @@ -275,8 +258,7 @@ bool AVRFrameLowering::spillCalleeSavedRegisters( bool AVRFrameLowering::restoreCalleeSavedRegisters( MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - std::vector<CalleeSavedInfo> &CSI, - const TargetRegisterInfo *TRI) const { + MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const { if (CSI.empty()) { return false; } @@ -299,15 +281,10 @@ bool AVRFrameLowering::restoreCalleeSavedRegisters( } /// Replace pseudo store instructions that pass arguments through the stack with -/// real instructions. If insertPushes is true then all instructions are -/// replaced with push instructions, otherwise regular std instructions are -/// inserted. +/// real instructions. static void fixStackStores(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const TargetInstrInfo &TII, bool insertPushes) { - const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>(); - const TargetRegisterInfo &TRI = *STI.getRegisterInfo(); - + const TargetInstrInfo &TII, Register FP) { // Iterate through the BB until we hit a call instruction or we reach the end. for (auto I = MI, E = MBB.end(); I != E && !I->isCall();) { MachineBasicBlock::iterator NextMI = std::next(I); @@ -322,29 +299,6 @@ static void fixStackStores(MachineBasicBlock &MBB, assert(MI.getOperand(0).getReg() == AVR::SP && "Invalid register, should be SP!"); - if (insertPushes) { - // Replace this instruction with a push. - Register SrcReg = MI.getOperand(2).getReg(); - bool SrcIsKill = MI.getOperand(2).isKill(); - - // We can't use PUSHWRr here because when expanded the order of the new - // instructions are reversed from what we need. Perform the expansion now. - if (Opcode == AVR::STDWSPQRr) { - BuildMI(MBB, I, MI.getDebugLoc(), TII.get(AVR::PUSHRr)) - .addReg(TRI.getSubReg(SrcReg, AVR::sub_hi), - getKillRegState(SrcIsKill)); - BuildMI(MBB, I, MI.getDebugLoc(), TII.get(AVR::PUSHRr)) - .addReg(TRI.getSubReg(SrcReg, AVR::sub_lo), - getKillRegState(SrcIsKill)); - } else { - BuildMI(MBB, I, MI.getDebugLoc(), TII.get(AVR::PUSHRr)) - .addReg(SrcReg, getKillRegState(SrcIsKill)); - } - - MI.eraseFromParent(); - I = NextMI; - continue; - } // Replace this instruction with a regular store. Use Y as the base // pointer since it is guaranteed to contain a copy of SP. @@ -352,7 +306,7 @@ static void fixStackStores(MachineBasicBlock &MBB, (Opcode == AVR::STDWSPQRr) ? AVR::STDWPtrQRr : AVR::STDPtrQRr; MI.setDesc(TII.get(STOpc)); - MI.getOperand(0).setReg(AVR::R29R28); + MI.getOperand(0).setReg(FP); I = NextMI; } @@ -368,7 +322,7 @@ MachineBasicBlock::iterator AVRFrameLowering::eliminateCallFramePseudoInstr( // function entry. Delete the call frame pseudo and replace all pseudo stores // with real store instructions. if (hasReservedCallFrame(MF)) { - fixStackStores(MBB, MI, TII, false); + fixStackStores(MBB, MI, TII, AVR::R29R28); return MBB.erase(MI); } @@ -376,18 +330,37 @@ MachineBasicBlock::iterator AVRFrameLowering::eliminateCallFramePseudoInstr( unsigned int Opcode = MI->getOpcode(); int Amount = TII.getFrameSize(*MI); - // Adjcallstackup does not need to allocate stack space for the call, instead - // we insert push instructions that will allocate the necessary stack. - // For adjcallstackdown we convert it into an 'adiw reg, <amt>' handling - // the read and write of SP in I/O space. + // ADJCALLSTACKUP and ADJCALLSTACKDOWN are converted to adiw/subi + // instructions to read and write the stack pointer in I/O space. if (Amount != 0) { - assert(getStackAlignment() == 1 && "Unsupported stack alignment"); + assert(getStackAlign() == Align(1) && "Unsupported stack alignment"); if (Opcode == TII.getCallFrameSetupOpcode()) { - fixStackStores(MBB, MI, TII, true); + // Update the stack pointer. + // In many cases this can be done far more efficiently by pushing the + // relevant values directly to the stack. However, doing that correctly + // (in the right order, possibly skipping some empty space for undef + // values, etc) is tricky and thus left to be optimized in the future. + BuildMI(MBB, MI, DL, TII.get(AVR::SPREAD), AVR::R31R30).addReg(AVR::SP); + + MachineInstr *New = BuildMI(MBB, MI, DL, TII.get(AVR::SUBIWRdK), AVR::R31R30) + .addReg(AVR::R31R30, RegState::Kill) + .addImm(Amount); + New->getOperand(3).setIsDead(); + + BuildMI(MBB, MI, DL, TII.get(AVR::SPWRITE), AVR::SP) + .addReg(AVR::R31R30, RegState::Kill); + + // Make sure the remaining stack stores are converted to real store + // instructions. + fixStackStores(MBB, MI, TII, AVR::R31R30); } else { assert(Opcode == TII.getCallFrameDestroyOpcode()); + // Note that small stack changes could be implemented more efficiently + // with a few pop instructions instead of the 8-9 instructions now + // required. + // Select the best opcode to adjust SP based on the offset size. unsigned addOpcode; if (isUInt<6>(Amount)) { @@ -419,8 +392,10 @@ void AVRFrameLowering::determineCalleeSaves(MachineFunction &MF, TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); // If we have a frame pointer, the Y register needs to be saved as well. - // We don't do that here however - the prologue and epilogue generation - // code will handle it specially. + if (hasFP(MF)) { + SavedRegs.set(AVR::R29); + SavedRegs.set(AVR::R28); + } } /// The frame analyzer pass. /// @@ -430,7 +405,7 @@ struct AVRFrameAnalyzer : public MachineFunctionPass { static char ID; AVRFrameAnalyzer() : MachineFunctionPass(ID) {} - bool runOnMachineFunction(MachineFunction &MF) { + bool runOnMachineFunction(MachineFunction &MF) override { const MachineFrameInfo &MFI = MF.getFrameInfo(); AVRMachineFunctionInfo *FuncInfo = MF.getInfo<AVRMachineFunctionInfo>(); @@ -482,7 +457,7 @@ struct AVRFrameAnalyzer : public MachineFunctionPass { return false; } - StringRef getPassName() const { return "AVR Frame Analyzer"; } + StringRef getPassName() const override { return "AVR Frame Analyzer"; } }; char AVRFrameAnalyzer::ID = 0; @@ -498,7 +473,7 @@ struct AVRDynAllocaSR : public MachineFunctionPass { static char ID; AVRDynAllocaSR() : MachineFunctionPass(ID) {} - bool runOnMachineFunction(MachineFunction &MF) { + bool runOnMachineFunction(MachineFunction &MF) override { // Early exit when there are no variable sized objects in the function. if (!MF.getFrameInfo().hasVarSizedObjects()) { return false; @@ -510,7 +485,7 @@ struct AVRDynAllocaSR : public MachineFunctionPass { MachineBasicBlock::iterator MBBI = EntryMBB.begin(); DebugLoc DL = EntryMBB.findDebugLoc(MBBI); - unsigned SPCopy = + Register SPCopy = MF.getRegInfo().createVirtualRegister(&AVR::DREGSRegClass); // Create a copy of SP in function entry before any dynallocas are @@ -531,7 +506,7 @@ struct AVRDynAllocaSR : public MachineFunctionPass { return true; } - StringRef getPassName() const { + StringRef getPassName() const override { return "AVR dynalloca stack pointer save/restore"; } }; diff --git a/llvm/lib/Target/AVR/AVRFrameLowering.h b/llvm/lib/Target/AVR/AVRFrameLowering.h index a7658438232a..a550c0efbb8e 100644 --- a/llvm/lib/Target/AVR/AVRFrameLowering.h +++ b/llvm/lib/Target/AVR/AVRFrameLowering.h @@ -24,12 +24,12 @@ public: bool hasFP(const MachineFunction &MF) const override; bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector<CalleeSavedInfo> &CSI, + ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const override; bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - std::vector<CalleeSavedInfo> &CSI, + MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const override; bool hasReservedCallFrame(const MachineFunction &MF) const override; bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override; diff --git a/llvm/lib/Target/AVR/AVRISelDAGToDAG.cpp b/llvm/lib/Target/AVR/AVRISelDAGToDAG.cpp index 4c4f4faa0508..fe31fa42c403 100644 --- a/llvm/lib/Target/AVR/AVRISelDAGToDAG.cpp +++ b/llvm/lib/Target/AVR/AVRISelDAGToDAG.cpp @@ -265,7 +265,7 @@ bool AVRDAGToDAGISel::SelectInlineAsmMemoryOperand(const SDValue &Op, if (RI.getRegClass(Reg) != &AVR::PTRDISPREGSRegClass) { SDLoc dl(CopyFromRegOp); - unsigned VReg = RI.createVirtualRegister(&AVR::PTRDISPREGSRegClass); + Register VReg = RI.createVirtualRegister(&AVR::PTRDISPREGSRegClass); SDValue CopyToReg = CurDAG->getCopyToReg(CopyFromRegOp, dl, VReg, CopyFromRegOp); @@ -294,7 +294,7 @@ bool AVRDAGToDAGISel::SelectInlineAsmMemoryOperand(const SDValue &Op, // More generic case. // Create chain that puts Op into pointer register // and return that register. - unsigned VReg = RI.createVirtualRegister(&AVR::PTRDISPREGSRegClass); + Register VReg = RI.createVirtualRegister(&AVR::PTRDISPREGSRegClass); SDValue CopyToReg = CurDAG->getCopyToReg(Op, dl, VReg, Op); SDValue CopyFromReg = diff --git a/llvm/lib/Target/AVR/AVRISelLowering.cpp b/llvm/lib/Target/AVR/AVRISelLowering.cpp index 880688807702..bf9b32e1278e 100644 --- a/llvm/lib/Target/AVR/AVRISelLowering.cpp +++ b/llvm/lib/Target/AVR/AVRISelLowering.cpp @@ -14,6 +14,7 @@ #include "AVRISelLowering.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/CodeGen/CallingConvLower.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineInstrBuilder.h" @@ -151,10 +152,12 @@ AVRTargetLowering::AVRTargetLowering(const AVRTargetMachine &TM, setOperationAction(ISD::SREM, MVT::i16, Expand); // Make division and modulus custom - for (MVT VT : MVT::integer_valuetypes()) { - setOperationAction(ISD::UDIVREM, VT, Custom); - setOperationAction(ISD::SDIVREM, VT, Custom); - } + setOperationAction(ISD::UDIVREM, MVT::i8, Custom); + setOperationAction(ISD::UDIVREM, MVT::i16, Custom); + setOperationAction(ISD::UDIVREM, MVT::i32, Custom); + setOperationAction(ISD::SDIVREM, MVT::i8, Custom); + setOperationAction(ISD::SDIVREM, MVT::i16, Custom); + setOperationAction(ISD::SDIVREM, MVT::i32, Custom); // Do not use MUL. The AVR instructions are closer to SMUL_LOHI &co. setOperationAction(ISD::MUL, MVT::i8, Expand); @@ -190,41 +193,29 @@ AVRTargetLowering::AVRTargetLowering(const AVRTargetMachine &TM, // improvements in how we treat 16-bit "registers" to be feasible. } - // Division rtlib functions (not supported) + // Division rtlib functions (not supported), use divmod functions instead setLibcallName(RTLIB::SDIV_I8, nullptr); setLibcallName(RTLIB::SDIV_I16, nullptr); setLibcallName(RTLIB::SDIV_I32, nullptr); - setLibcallName(RTLIB::SDIV_I64, nullptr); - setLibcallName(RTLIB::SDIV_I128, nullptr); setLibcallName(RTLIB::UDIV_I8, nullptr); setLibcallName(RTLIB::UDIV_I16, nullptr); setLibcallName(RTLIB::UDIV_I32, nullptr); - setLibcallName(RTLIB::UDIV_I64, nullptr); - setLibcallName(RTLIB::UDIV_I128, nullptr); - // Modulus rtlib functions (not supported) + // Modulus rtlib functions (not supported), use divmod functions instead setLibcallName(RTLIB::SREM_I8, nullptr); setLibcallName(RTLIB::SREM_I16, nullptr); setLibcallName(RTLIB::SREM_I32, nullptr); - setLibcallName(RTLIB::SREM_I64, nullptr); - setLibcallName(RTLIB::SREM_I128, nullptr); setLibcallName(RTLIB::UREM_I8, nullptr); setLibcallName(RTLIB::UREM_I16, nullptr); setLibcallName(RTLIB::UREM_I32, nullptr); - setLibcallName(RTLIB::UREM_I64, nullptr); - setLibcallName(RTLIB::UREM_I128, nullptr); // Division and modulus rtlib functions setLibcallName(RTLIB::SDIVREM_I8, "__divmodqi4"); setLibcallName(RTLIB::SDIVREM_I16, "__divmodhi4"); setLibcallName(RTLIB::SDIVREM_I32, "__divmodsi4"); - setLibcallName(RTLIB::SDIVREM_I64, "__divmoddi4"); - setLibcallName(RTLIB::SDIVREM_I128, "__divmodti4"); setLibcallName(RTLIB::UDIVREM_I8, "__udivmodqi4"); setLibcallName(RTLIB::UDIVREM_I16, "__udivmodhi4"); setLibcallName(RTLIB::UDIVREM_I32, "__udivmodsi4"); - setLibcallName(RTLIB::UDIVREM_I64, "__udivmoddi4"); - setLibcallName(RTLIB::UDIVREM_I128, "__udivmodti4"); // Several of the runtime library functions use a special calling conv setLibcallCallingConv(RTLIB::SDIVREM_I8, CallingConv::AVR_BUILTIN); @@ -259,6 +250,8 @@ const char *AVRTargetLowering::getTargetNodeName(unsigned Opcode) const { NODE(ASR); NODE(LSLLOOP); NODE(LSRLOOP); + NODE(ROLLOOP); + NODE(RORLOOP); NODE(ASRLOOP); NODE(BRCOND); NODE(CMP); @@ -282,6 +275,8 @@ SDValue AVRTargetLowering::LowerShifts(SDValue Op, SelectionDAG &DAG) const { const SDNode *N = Op.getNode(); EVT VT = Op.getValueType(); SDLoc dl(N); + assert(isPowerOf2_32(VT.getSizeInBits()) && + "Expected power-of-2 shift amount"); // Expand non-constant shifts to loops. if (!isa<ConstantSDNode>(N->getOperand(1))) { @@ -294,12 +289,20 @@ SDValue AVRTargetLowering::LowerShifts(SDValue Op, SelectionDAG &DAG) const { case ISD::SRL: return DAG.getNode(AVRISD::LSRLOOP, dl, VT, N->getOperand(0), N->getOperand(1)); - case ISD::ROTL: - return DAG.getNode(AVRISD::ROLLOOP, dl, VT, N->getOperand(0), - N->getOperand(1)); - case ISD::ROTR: - return DAG.getNode(AVRISD::RORLOOP, dl, VT, N->getOperand(0), - N->getOperand(1)); + case ISD::ROTL: { + SDValue Amt = N->getOperand(1); + EVT AmtVT = Amt.getValueType(); + Amt = DAG.getNode(ISD::AND, dl, AmtVT, Amt, + DAG.getConstant(VT.getSizeInBits() - 1, dl, AmtVT)); + return DAG.getNode(AVRISD::ROLLOOP, dl, VT, N->getOperand(0), Amt); + } + case ISD::ROTR: { + SDValue Amt = N->getOperand(1); + EVT AmtVT = Amt.getValueType(); + Amt = DAG.getNode(ISD::AND, dl, AmtVT, Amt, + DAG.getConstant(VT.getSizeInBits() - 1, dl, AmtVT)); + return DAG.getNode(AVRISD::RORLOOP, dl, VT, N->getOperand(0), Amt); + } case ISD::SRA: return DAG.getNode(AVRISD::ASRLOOP, dl, VT, N->getOperand(0), N->getOperand(1)); @@ -315,9 +318,11 @@ SDValue AVRTargetLowering::LowerShifts(SDValue Op, SelectionDAG &DAG) const { break; case ISD::ROTL: Opc8 = AVRISD::ROL; + ShiftAmount = ShiftAmount % VT.getSizeInBits(); break; case ISD::ROTR: Opc8 = AVRISD::ROR; + ShiftAmount = ShiftAmount % VT.getSizeInBits(); break; case ISD::SRL: Opc8 = AVRISD::LSR; @@ -357,12 +362,6 @@ SDValue AVRTargetLowering::LowerDivRem(SDValue Op, SelectionDAG &DAG) const { case MVT::i32: LC = IsSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32; break; - case MVT::i64: - LC = IsSigned ? RTLIB::SDIVREM_I64 : RTLIB::UDIVREM_I64; - break; - case MVT::i128: - LC = IsSigned ? RTLIB::SDIVREM_I128 : RTLIB::UDIVREM_I128; - break; } SDValue InChain = DAG.getEntryNode(); @@ -883,173 +882,145 @@ bool AVRTargetLowering::isOffsetFoldingLegal( #include "AVRGenCallingConv.inc" -/// For each argument in a function store the number of pieces it is composed -/// of. -static void parseFunctionArgs(const SmallVectorImpl<ISD::InputArg> &Ins, - SmallVectorImpl<unsigned> &Out) { - for (const ISD::InputArg &Arg : Ins) { - if(Arg.PartOffset > 0) continue; - unsigned Bytes = ((Arg.ArgVT.getSizeInBits()) + 7) / 8; - - Out.push_back((Bytes + 1) / 2); - } -} - -/// For external symbols there is no function prototype information so we -/// have to rely directly on argument sizes. -static void parseExternFuncCallArgs(const SmallVectorImpl<ISD::OutputArg> &In, - SmallVectorImpl<unsigned> &Out) { - for (unsigned i = 0, e = In.size(); i != e;) { - unsigned Size = 0; - unsigned Offset = 0; - while ((i != e) && (In[i].PartOffset == Offset)) { - Offset += In[i].VT.getStoreSize(); - ++i; - ++Size; - } - Out.push_back(Size); - } -} - -static StringRef getFunctionName(TargetLowering::CallLoweringInfo &CLI) { - SDValue Callee = CLI.Callee; - - if (const ExternalSymbolSDNode *G = dyn_cast<ExternalSymbolSDNode>(Callee)) { - return G->getSymbol(); - } - - if (const GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) { - return G->getGlobal()->getName(); - } - - llvm_unreachable("don't know how to get the name for this callee"); -} +/// Registers for calling conventions, ordered in reverse as required by ABI. +/// Both arrays must be of the same length. +static const MCPhysReg RegList8[] = { + AVR::R25, AVR::R24, AVR::R23, AVR::R22, AVR::R21, AVR::R20, + AVR::R19, AVR::R18, AVR::R17, AVR::R16, AVR::R15, AVR::R14, + AVR::R13, AVR::R12, AVR::R11, AVR::R10, AVR::R9, AVR::R8}; +static const MCPhysReg RegList16[] = { + AVR::R26R25, AVR::R25R24, AVR::R24R23, AVR::R23R22, + AVR::R22R21, AVR::R21R20, AVR::R20R19, AVR::R19R18, + AVR::R18R17, AVR::R17R16, AVR::R16R15, AVR::R15R14, + AVR::R14R13, AVR::R13R12, AVR::R12R11, AVR::R11R10, + AVR::R10R9, AVR::R9R8}; + +static_assert(array_lengthof(RegList8) == array_lengthof(RegList16), + "8-bit and 16-bit register arrays must be of equal length"); /// Analyze incoming and outgoing function arguments. We need custom C++ code -/// to handle special constraints in the ABI like reversing the order of the -/// pieces of splitted arguments. In addition, all pieces of a certain argument -/// have to be passed either using registers or the stack but never mixing both. -static void analyzeStandardArguments(TargetLowering::CallLoweringInfo *CLI, - const Function *F, const DataLayout *TD, - const SmallVectorImpl<ISD::OutputArg> *Outs, - const SmallVectorImpl<ISD::InputArg> *Ins, - CallingConv::ID CallConv, - SmallVectorImpl<CCValAssign> &ArgLocs, - CCState &CCInfo, bool IsCall, bool IsVarArg) { - static const MCPhysReg RegList8[] = {AVR::R24, AVR::R22, AVR::R20, - AVR::R18, AVR::R16, AVR::R14, - AVR::R12, AVR::R10, AVR::R8}; - static const MCPhysReg RegList16[] = {AVR::R25R24, AVR::R23R22, AVR::R21R20, - AVR::R19R18, AVR::R17R16, AVR::R15R14, - AVR::R13R12, AVR::R11R10, AVR::R9R8}; - if (IsVarArg) { - // Variadic functions do not need all the analysis below. - if (IsCall) { - CCInfo.AnalyzeCallOperands(*Outs, ArgCC_AVR_Vararg); - } else { - CCInfo.AnalyzeFormalArguments(*Ins, ArgCC_AVR_Vararg); +/// to handle special constraints in the ABI. +/// In addition, all pieces of a certain argument have to be passed either +/// using registers or the stack but never mixing both. +template <typename ArgT> +static void +analyzeArguments(TargetLowering::CallLoweringInfo *CLI, const Function *F, + const DataLayout *TD, const SmallVectorImpl<ArgT> &Args, + SmallVectorImpl<CCValAssign> &ArgLocs, CCState &CCInfo) { + unsigned NumArgs = Args.size(); + // This is the index of the last used register, in RegList*. + // -1 means R26 (R26 is never actually used in CC). + int RegLastIdx = -1; + // Once a value is passed to the stack it will always be used + bool UseStack = false; + for (unsigned i = 0; i != NumArgs;) { + MVT VT = Args[i].VT; + // We have to count the number of bytes for each function argument, that is + // those Args with the same OrigArgIndex. This is important in case the + // function takes an aggregate type. + // Current argument will be between [i..j). + unsigned ArgIndex = Args[i].OrigArgIndex; + unsigned TotalBytes = VT.getStoreSize(); + unsigned j = i + 1; + for (; j != NumArgs; ++j) { + if (Args[j].OrigArgIndex != ArgIndex) + break; + TotalBytes += Args[j].VT.getStoreSize(); } - return; - } - - // Fill in the Args array which will contain original argument sizes. - SmallVector<unsigned, 8> Args; - if (IsCall) { - parseExternFuncCallArgs(*Outs, Args); - } else { - assert(F != nullptr && "function should not be null"); - parseFunctionArgs(*Ins, Args); - } - - unsigned RegsLeft = array_lengthof(RegList8), ValNo = 0; - // Variadic functions always use the stack. - bool UsesStack = false; - for (unsigned i = 0, pos = 0, e = Args.size(); i != e; ++i) { - unsigned Size = Args[i]; - - // If we have a zero-sized argument, don't attempt to lower it. - // AVR-GCC does not support zero-sized arguments and so we need not - // worry about ABI compatibility. - if (Size == 0) continue; - - MVT LocVT = (IsCall) ? (*Outs)[pos].VT : (*Ins)[pos].VT; - - // If we have plenty of regs to pass the whole argument do it. - if (!UsesStack && (Size <= RegsLeft)) { - const MCPhysReg *RegList = (LocVT == MVT::i16) ? RegList16 : RegList8; + // Round up to even number of bytes. + TotalBytes = alignTo(TotalBytes, 2); + // Skip zero sized arguments + if (TotalBytes == 0) + continue; + // The index of the first register to be used + unsigned RegIdx = RegLastIdx + TotalBytes; + RegLastIdx = RegIdx; + // If there are not enough registers, use the stack + if (RegIdx >= array_lengthof(RegList8)) { + UseStack = true; + } + for (; i != j; ++i) { + MVT VT = Args[i].VT; - for (unsigned j = 0; j != Size; ++j) { - unsigned Reg = CCInfo.AllocateReg( - ArrayRef<MCPhysReg>(RegList, array_lengthof(RegList8))); + if (UseStack) { + auto evt = EVT(VT).getTypeForEVT(CCInfo.getContext()); + unsigned Offset = CCInfo.AllocateStack(TD->getTypeAllocSize(evt), + TD->getABITypeAlign(evt)); CCInfo.addLoc( - CCValAssign::getReg(ValNo++, LocVT, Reg, LocVT, CCValAssign::Full)); - --RegsLeft; - } - - // Reverse the order of the pieces to agree with the "big endian" format - // required in the calling convention ABI. - std::reverse(ArgLocs.begin() + pos, ArgLocs.begin() + pos + Size); - } else { - // Pass the rest of arguments using the stack. - UsesStack = true; - for (unsigned j = 0; j != Size; ++j) { - unsigned Offset = CCInfo.AllocateStack( - TD->getTypeAllocSize(EVT(LocVT).getTypeForEVT(CCInfo.getContext())), - TD->getABITypeAlignment( - EVT(LocVT).getTypeForEVT(CCInfo.getContext()))); - CCInfo.addLoc(CCValAssign::getMem(ValNo++, LocVT, Offset, LocVT, - CCValAssign::Full)); + CCValAssign::getMem(i, VT, Offset, VT, CCValAssign::Full)); + } else { + unsigned Reg; + if (VT == MVT::i8) { + Reg = CCInfo.AllocateReg(RegList8[RegIdx]); + } else if (VT == MVT::i16) { + Reg = CCInfo.AllocateReg(RegList16[RegIdx]); + } else { + llvm_unreachable( + "calling convention can only manage i8 and i16 types"); + } + assert(Reg && "register not available in calling convention"); + CCInfo.addLoc(CCValAssign::getReg(i, VT, Reg, VT, CCValAssign::Full)); + // Registers inside a particular argument are sorted in increasing order + // (remember the array is reversed). + RegIdx -= VT.getStoreSize(); } } - pos += Size; } } -static void analyzeBuiltinArguments(TargetLowering::CallLoweringInfo &CLI, - const Function *F, const DataLayout *TD, - const SmallVectorImpl<ISD::OutputArg> *Outs, - const SmallVectorImpl<ISD::InputArg> *Ins, - CallingConv::ID CallConv, - SmallVectorImpl<CCValAssign> &ArgLocs, - CCState &CCInfo, bool IsCall, bool IsVarArg) { - StringRef FuncName = getFunctionName(CLI); - - if (FuncName.startswith("__udivmod") || FuncName.startswith("__divmod")) { - CCInfo.AnalyzeCallOperands(*Outs, ArgCC_AVR_BUILTIN_DIV); - } else { - analyzeStandardArguments(&CLI, F, TD, Outs, Ins, - CallConv, ArgLocs, CCInfo, - IsCall, IsVarArg); +/// Count the total number of bytes needed to pass or return these arguments. +template <typename ArgT> +static unsigned getTotalArgumentsSizeInBytes(const SmallVectorImpl<ArgT> &Args) { + unsigned TotalBytes = 0; + + for (const ArgT& Arg : Args) { + TotalBytes += Arg.VT.getStoreSize(); } + return TotalBytes; } -static void analyzeArguments(TargetLowering::CallLoweringInfo *CLI, - const Function *F, const DataLayout *TD, - const SmallVectorImpl<ISD::OutputArg> *Outs, - const SmallVectorImpl<ISD::InputArg> *Ins, - CallingConv::ID CallConv, - SmallVectorImpl<CCValAssign> &ArgLocs, - CCState &CCInfo, bool IsCall, bool IsVarArg) { - switch (CallConv) { - case CallingConv::AVR_BUILTIN: { - analyzeBuiltinArguments(*CLI, F, TD, Outs, Ins, - CallConv, ArgLocs, CCInfo, - IsCall, IsVarArg); - return; - } - default: { - analyzeStandardArguments(CLI, F, TD, Outs, Ins, - CallConv, ArgLocs, CCInfo, - IsCall, IsVarArg); - return; +/// Analyze incoming and outgoing value of returning from a function. +/// The algorithm is similar to analyzeArguments, but there can only be +/// one value, possibly an aggregate, and it is limited to 8 bytes. +template <typename ArgT> +static void analyzeReturnValues(const SmallVectorImpl<ArgT> &Args, + CCState &CCInfo) { + unsigned NumArgs = Args.size(); + unsigned TotalBytes = getTotalArgumentsSizeInBytes(Args); + // CanLowerReturn() guarantees this assertion. + assert(TotalBytes <= 8 && "return values greater than 8 bytes cannot be lowered"); + + // GCC-ABI says that the size is rounded up to the next even number, + // but actually once it is more than 4 it will always round up to 8. + if (TotalBytes > 4) { + TotalBytes = 8; + } else { + TotalBytes = alignTo(TotalBytes, 2); + } + + // The index of the first register to use. + int RegIdx = TotalBytes - 1; + for (unsigned i = 0; i != NumArgs; ++i) { + MVT VT = Args[i].VT; + unsigned Reg; + if (VT == MVT::i8) { + Reg = CCInfo.AllocateReg(RegList8[RegIdx]); + } else if (VT == MVT::i16) { + Reg = CCInfo.AllocateReg(RegList16[RegIdx]); + } else { + llvm_unreachable("calling convention can only manage i8 and i16 types"); } + assert(Reg && "register not available in calling convention"); + CCInfo.addLoc(CCValAssign::getReg(i, VT, Reg, VT, CCValAssign::Full)); + // Registers sort in increasing order + RegIdx -= VT.getStoreSize(); } } SDValue AVRTargetLowering::LowerFormalArguments( SDValue Chain, CallingConv::ID CallConv, bool isVarArg, - const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl, SelectionDAG &DAG, - SmallVectorImpl<SDValue> &InVals) const { + const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl, + SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const { MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo &MFI = MF.getFrameInfo(); auto DL = DAG.getDataLayout(); @@ -1059,8 +1030,12 @@ SDValue AVRTargetLowering::LowerFormalArguments( CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs, *DAG.getContext()); - analyzeArguments(nullptr, &MF.getFunction(), &DL, 0, &Ins, CallConv, ArgLocs, CCInfo, - false, isVarArg); + // Variadic functions do not need all the analysis below. + if (isVarArg) { + CCInfo.AnalyzeFormalArguments(Ins, ArgCC_AVR_Vararg); + } else { + analyzeArguments(nullptr, &MF.getFunction(), &DL, Ins, ArgLocs, CCInfo); + } SDValue ArgValue; for (CCValAssign &VA : ArgLocs) { @@ -1181,8 +1156,12 @@ SDValue AVRTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, getPointerTy(DAG.getDataLayout())); } - analyzeArguments(&CLI, F, &DAG.getDataLayout(), &Outs, 0, CallConv, ArgLocs, CCInfo, - true, isVarArg); + // Variadic functions do not need all the analysis below. + if (isVarArg) { + CCInfo.AnalyzeCallOperands(Outs, ArgCC_AVR_Vararg); + } else { + analyzeArguments(&CLI, F, &DAG.getDataLayout(), Outs, ArgLocs, CCInfo); + } // Get a count of how many bytes are to be pushed on the stack. unsigned NumBytes = CCInfo.getNextStackOffset(); @@ -1319,13 +1298,10 @@ SDValue AVRTargetLowering::LowerCallResult( *DAG.getContext()); // Handle runtime calling convs. - auto CCFunction = CCAssignFnForReturn(CallConv); - CCInfo.AnalyzeCallResult(Ins, CCFunction); - - if (CallConv != CallingConv::AVR_BUILTIN && RVLocs.size() > 1) { - // Reverse splitted return values to get the "big endian" format required - // to agree with the calling convention ABI. - std::reverse(RVLocs.begin(), RVLocs.end()); + if (CallConv == CallingConv::AVR_BUILTIN) { + CCInfo.AnalyzeCallResult(Ins, RetCC_AVR_BUILTIN); + } else { + analyzeReturnValues(Ins, CCInfo); } // Copy all of the result registers out of their specified physreg. @@ -1344,26 +1320,17 @@ SDValue AVRTargetLowering::LowerCallResult( // Return Value Calling Convention Implementation //===----------------------------------------------------------------------===// -CCAssignFn *AVRTargetLowering::CCAssignFnForReturn(CallingConv::ID CC) const { - switch (CC) { - case CallingConv::AVR_BUILTIN: - return RetCC_AVR_BUILTIN; - default: - return RetCC_AVR; +bool AVRTargetLowering::CanLowerReturn( + CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const { + if (CallConv == CallingConv::AVR_BUILTIN) { + SmallVector<CCValAssign, 16> RVLocs; + CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context); + return CCInfo.CheckReturn(Outs, RetCC_AVR_BUILTIN); } -} -bool -AVRTargetLowering::CanLowerReturn(CallingConv::ID CallConv, - MachineFunction &MF, bool isVarArg, - const SmallVectorImpl<ISD::OutputArg> &Outs, - LLVMContext &Context) const -{ - SmallVector<CCValAssign, 16> RVLocs; - CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context); - - auto CCFunction = CCAssignFnForReturn(CallConv); - return CCInfo.CheckReturn(Outs, CCFunction); + unsigned TotalBytes = getTotalArgumentsSizeInBytes(Outs); + return TotalBytes <= 8; } SDValue @@ -1379,25 +1346,19 @@ AVRTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs, *DAG.getContext()); - // Analyze return values. - auto CCFunction = CCAssignFnForReturn(CallConv); - CCInfo.AnalyzeReturn(Outs, CCFunction); - - // If this is the first return lowered for this function, add the regs to - // the liveout set for the function. MachineFunction &MF = DAG.getMachineFunction(); - unsigned e = RVLocs.size(); - // Reverse splitted return values to get the "big endian" format required - // to agree with the calling convention ABI. - if (e > 1) { - std::reverse(RVLocs.begin(), RVLocs.end()); + // Analyze return values. + if (CallConv == CallingConv::AVR_BUILTIN) { + CCInfo.AnalyzeReturn(Outs, RetCC_AVR_BUILTIN); + } else { + analyzeReturnValues(Outs, CCInfo); } SDValue Flag; SmallVector<SDValue, 4> RetOps(1, Chain); // Copy the result values into the output registers. - for (unsigned i = 0; i != e; ++i) { + for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) { CCValAssign &VA = RVLocs[i]; assert(VA.isRegLoc() && "Can only return in registers!"); @@ -1415,10 +1376,12 @@ AVRTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, return Chain; } + const AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>(); + unsigned RetOpc = - (CallConv == CallingConv::AVR_INTR || CallConv == CallingConv::AVR_SIGNAL) - ? AVRISD::RETI_FLAG - : AVRISD::RET_FLAG; + AFI->isInterruptOrSignalHandler() + ? AVRISD::RETI_FLAG + : AVRISD::RET_FLAG; RetOps[0] = Chain; // Update chain. @@ -1514,8 +1477,8 @@ MachineBasicBlock *AVRTargetLowering::insertShift(MachineInstr &MI, LoopBB->addSuccessor(RemBB); LoopBB->addSuccessor(LoopBB); - unsigned ShiftAmtReg = RI.createVirtualRegister(&AVR::LD8RegClass); - unsigned ShiftAmtReg2 = RI.createVirtualRegister(&AVR::LD8RegClass); + Register ShiftAmtReg = RI.createVirtualRegister(&AVR::LD8RegClass); + Register ShiftAmtReg2 = RI.createVirtualRegister(&AVR::LD8RegClass); Register ShiftReg = RI.createVirtualRegister(RC); Register ShiftReg2 = RI.createVirtualRegister(RC); Register ShiftAmtSrcReg = MI.getOperand(2).getReg(); diff --git a/llvm/lib/Target/AVR/AVRISelLowering.h b/llvm/lib/Target/AVR/AVRISelLowering.h index aca1ea1d50e5..d1eaf53b15e9 100644 --- a/llvm/lib/Target/AVR/AVRISelLowering.h +++ b/llvm/lib/Target/AVR/AVRISelLowering.h @@ -146,10 +146,8 @@ private: SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const; SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const; - CCAssignFn *CCAssignFnForReturn(CallingConv::ID CC) const; - - bool CanLowerReturn(CallingConv::ID CallConv, - MachineFunction &MF, bool isVarArg, + bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, + bool isVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const override; diff --git a/llvm/lib/Target/AVR/AVRInstrFormats.td b/llvm/lib/Target/AVR/AVRInstrFormats.td index ef596f5cebd5..6eb49076efb0 100644 --- a/llvm/lib/Target/AVR/AVRInstrFormats.td +++ b/llvm/lib/Target/AVR/AVRInstrFormats.td @@ -148,6 +148,8 @@ class FRd<bits<4> opcode, bits<7> f, dag outs, dag ins, string asmstr, let Inst{11-9} = f{6-4}; let Inst{8-4} = d; let Inst{3-0} = f{3-0}; + + let DecoderMethod = "decodeFRd"; } //===----------------------------------------------------------------------===// @@ -235,6 +237,8 @@ class FLPMX<bit e, bit p, dag outs, dag ins, string asmstr, list<dag> pattern> let Inst{3-2} = 0b01; let Inst{1} = e; let Inst{0} = p; + + let DecoderMethod = "decodeFLPMX"; } //===----------------------------------------------------------------------===// @@ -252,6 +256,8 @@ class FMOVWRdRr<dag outs, dag ins, string asmstr, list<dag> pattern> let Inst{15-8} = 0b00000001; let Inst{7-4} = d{4-1}; let Inst{3-0} = r{4-1}; + + let DecoderMethod = "decodeFMOVWRdRr"; } //===----------------------------------------------------------------------===// @@ -270,6 +276,8 @@ class FMUL2RdRr<bit f, dag outs, dag ins, string asmstr, list<dag> pattern> let Inst{8} = f; let Inst{7-4} = rd{3-0}; let Inst{3-0} = rr{3-0}; + + let DecoderMethod = "decodeFMUL2RdRr"; } // Special encoding for the FMUL family of instructions. @@ -293,6 +301,8 @@ class FFMULRdRr<bits<2> f, dag outs, dag ins, string asmstr, list<dag> pattern> let Inst{6-4} = rd; let Inst{3} = f{0}; let Inst{2-0} = rr; + + let DecoderMethod = "decodeFFMULRdRr"; } @@ -314,6 +324,8 @@ class FWRdK<bit f, dag outs, dag ins, string asmstr, list<dag> pattern> let Inst{7-6} = k{5-4}; let Inst{5-4} = dst{2-1}; let Inst{3-0} = k{3-0}; + + let DecoderMethod = "decodeFWRdK"; } //===----------------------------------------------------------------------===// @@ -332,6 +344,8 @@ class FIORdA<dag outs, dag ins, string asmstr, list<dag> pattern> let Inst{10-9} = A{5-4}; let Inst{8-4} = d; let Inst{3-0} = A{3-0}; + + let DecoderMethod = "decodeFIORdA"; } //===----------------------------------------------------------------------===// @@ -350,6 +364,8 @@ class FIOARr<dag outs, dag ins, string asmstr, list<dag> pattern> let Inst{10-9} = A{5-4}; let Inst{8-4} = r; let Inst{3-0} = A{3-0}; + + let DecoderMethod = "decodeFIOARr"; } //===----------------------------------------------------------------------===// @@ -374,6 +390,8 @@ class FIOBIT<bits<2> t, dag outs, dag ins, string asmstr, list<dag> pattern> let Inst{3} = A{0}; let Inst{2-0} = b{2-0}; + + let DecoderMethod = "decodeFIOBIT"; } //===----------------------------------------------------------------------===// @@ -485,7 +503,7 @@ class F32BRk<bits<3> f, dag outs, dag ins, string asmstr, list<dag> pattern> } //===----------------------------------------------------------------------===// -// 32 bits direct mem instructions: <|1001|00fd|dddd|0000|kkkk|kkkk|kkkk|kkkk|> +// 32 bits direct mem instructions: <|1001|00fd|dddd|0000|kkkk|kkkk|kkkk|kkkk|> // f = secondary opcode = 1 bit // d = destination = 5 bits // k = constant address = 16 bits diff --git a/llvm/lib/Target/AVR/AVRInstrInfo.cpp b/llvm/lib/Target/AVR/AVRInstrInfo.cpp index a6832f282b31..06f07696bde3 100644 --- a/llvm/lib/Target/AVR/AVRInstrInfo.cpp +++ b/llvm/lib/Target/AVR/AVRInstrInfo.cpp @@ -48,11 +48,11 @@ void AVRInstrInfo::copyPhysReg(MachineBasicBlock &MBB, // Not all AVR devices support the 16-bit `MOVW` instruction. if (AVR::DREGSRegClass.contains(DestReg, SrcReg)) { - if (STI.hasMOVW()) { + if (STI.hasMOVW() && AVR::DREGSMOVWRegClass.contains(DestReg, SrcReg)) { BuildMI(MBB, MI, DL, get(AVR::MOVWRdRr), DestReg) .addReg(SrcReg, getKillRegState(KillSrc)); } else { - unsigned DestLo, DestHi, SrcLo, SrcHi; + Register DestLo, DestHi, SrcLo, SrcHi; TRI.splitReg(DestReg, DestLo, DestHi); TRI.splitReg(SrcReg, SrcLo, SrcHi); @@ -119,7 +119,7 @@ unsigned AVRInstrInfo::isStoreToStackSlot(const MachineInstr &MI, void AVRInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned SrcReg, bool isKill, + Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const { @@ -138,7 +138,7 @@ void AVRInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineMemOperand *MMO = MF.getMachineMemOperand( MachinePointerInfo::getFixedStack(MF, FrameIndex), MachineMemOperand::MOStore, MFI.getObjectSize(FrameIndex), - MFI.getObjectAlignment(FrameIndex)); + MFI.getObjectAlign(FrameIndex)); unsigned Opcode = 0; if (TRI->isTypeLegalForClass(*RC, MVT::i8)) { @@ -158,7 +158,7 @@ void AVRInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, void AVRInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned DestReg, int FrameIndex, + Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const { DebugLoc DL; @@ -172,7 +172,7 @@ void AVRInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, MachineMemOperand *MMO = MF.getMachineMemOperand( MachinePointerInfo::getFixedStack(MF, FrameIndex), MachineMemOperand::MOLoad, MFI.getObjectSize(FrameIndex), - MFI.getObjectAlignment(FrameIndex)); + MFI.getObjectAlign(FrameIndex)); unsigned Opcode = 0; if (TRI->isTypeLegalForClass(*RC, MVT::i8)) { diff --git a/llvm/lib/Target/AVR/AVRInstrInfo.h b/llvm/lib/Target/AVR/AVRInstrInfo.h index bb00ca8c724a..11f45865de54 100644 --- a/llvm/lib/Target/AVR/AVRInstrInfo.h +++ b/llvm/lib/Target/AVR/AVRInstrInfo.h @@ -75,12 +75,12 @@ public: const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc) const override; void storeRegToStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, unsigned SrcReg, + MachineBasicBlock::iterator MI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override; void loadRegFromStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, unsigned DestReg, + MachineBasicBlock::iterator MI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override; unsigned isLoadFromStackSlot(const MachineInstr &MI, diff --git a/llvm/lib/Target/AVR/AVRInstrInfo.td b/llvm/lib/Target/AVR/AVRInstrInfo.td index acf991dcfbb1..f03c254382b4 100644 --- a/llvm/lib/Target/AVR/AVRInstrInfo.td +++ b/llvm/lib/Target/AVR/AVRInstrInfo.td @@ -107,7 +107,9 @@ def imm_com8 : Operand<i8> { def ioaddr_XFORM : SDNodeXForm<imm, [{ - return CurDAG->getTargetConstant(uint8_t(N->getZExtValue()) - 0x20, SDLoc(N), MVT::i8); + uint8_t offset = Subtarget->getIORegisterOffset(); + return CurDAG->getTargetConstant(uint8_t(N->getZExtValue()) - offset, + SDLoc(N), MVT::i8); }]>; def iobitpos8_XFORM : SDNodeXForm<imm, @@ -124,20 +126,23 @@ def iobitposn8_XFORM : SDNodeXForm<imm, def ioaddr8 : PatLeaf<(imm), [{ - uint64_t val = N->getZExtValue(); - return val >= 0x20 && val < 0x60; + uint8_t offset = Subtarget->getIORegisterOffset(); + uint64_t val = N->getZExtValue() - offset; + return val < 0x40; }], ioaddr_XFORM>; def lowioaddr8 : PatLeaf<(imm), [{ - uint64_t val = N->getZExtValue(); - return val >= 0x20 && val < 0x40; + uint8_t offset = Subtarget->getIORegisterOffset(); + uint64_t val = N->getZExtValue() - offset; + return val < 0x20; }], ioaddr_XFORM>; def ioaddr16 : PatLeaf<(imm), [{ - uint64_t val = N->getZExtValue(); - return val >= 0x20 && val < 0x5f; + uint8_t offset = Subtarget->getIORegisterOffset(); + uint64_t val = N->getZExtValue() - offset; + return val < 0x3f; }], ioaddr_XFORM>; def iobitpos8 : PatLeaf<(imm), @@ -188,6 +193,7 @@ def brtarget_13 : Operand<OtherVT> def call_target : Operand<iPTR> { let EncoderMethod = "encodeCallTarget"; + let DecoderMethod = "decodeCallTarget"; } // A 16-bit address (which can lead to an R_AVR_16 relocation). @@ -260,58 +266,58 @@ def LDDSTDPtrReg : Operand<i16> //===----------------------------------------------------------------------===// def HasSRAM : Predicate<"Subtarget->hasSRAM()">, - AssemblerPredicate<"FeatureSRAM">; + AssemblerPredicate<(all_of FeatureSRAM)>; def HasJMPCALL : Predicate<"Subtarget->hasJMPCALL()">, - AssemblerPredicate<"FeatureJMPCALL">; + AssemblerPredicate<(all_of FeatureJMPCALL)>; def HasIJMPCALL : Predicate<"Subtarget->hasIJMPCALL()">, - AssemblerPredicate<"FeatureIJMPCALL">; + AssemblerPredicate<(all_of FeatureIJMPCALL)>; def HasEIJMPCALL : Predicate<"Subtarget->hasEIJMPCALL()">, - AssemblerPredicate<"FeatureEIJMPCALL">; + AssemblerPredicate<(all_of FeatureEIJMPCALL)>; def HasADDSUBIW : Predicate<"Subtarget->hasADDSUBIW()">, - AssemblerPredicate<"FeatureADDSUBIW">; + AssemblerPredicate<(all_of FeatureADDSUBIW)>; def HasSmallStack : Predicate<"Subtarget->HasSmallStack()">, - AssemblerPredicate<"FeatureSmallStack">; + AssemblerPredicate<(all_of FeatureSmallStack)>; def HasMOVW : Predicate<"Subtarget->hasMOVW()">, - AssemblerPredicate<"FeatureMOVW">; + AssemblerPredicate<(all_of FeatureMOVW)>; def HasLPM : Predicate<"Subtarget->hasLPM()">, - AssemblerPredicate<"FeatureLPM">; + AssemblerPredicate<(all_of FeatureLPM)>; def HasLPMX : Predicate<"Subtarget->hasLPMX()">, - AssemblerPredicate<"FeatureLPMX">; + AssemblerPredicate<(all_of FeatureLPMX)>; def HasELPM : Predicate<"Subtarget->hasELPM()">, - AssemblerPredicate<"FeatureELPM">; + AssemblerPredicate<(all_of FeatureELPM)>; def HasELPMX : Predicate<"Subtarget->hasELPMX()">, - AssemblerPredicate<"FeatureELPMX">; + AssemblerPredicate<(all_of FeatureELPMX)>; def HasSPM : Predicate<"Subtarget->hasSPM()">, - AssemblerPredicate<"FeatureSPM">; + AssemblerPredicate<(all_of FeatureSPM)>; def HasSPMX : Predicate<"Subtarget->hasSPMX()">, - AssemblerPredicate<"FeatureSPMX">; + AssemblerPredicate<(all_of FeatureSPMX)>; def HasDES : Predicate<"Subtarget->hasDES()">, - AssemblerPredicate<"FeatureDES">; + AssemblerPredicate<(all_of FeatureDES)>; def SupportsRMW : Predicate<"Subtarget->supportsRMW()">, - AssemblerPredicate<"FeatureRMW">; + AssemblerPredicate<(all_of FeatureRMW)>; def SupportsMultiplication : Predicate<"Subtarget->supportsMultiplication()">, - AssemblerPredicate<"FeatureMultiplication">; + AssemblerPredicate<(all_of FeatureMultiplication)>; def HasBREAK : Predicate<"Subtarget->hasBREAK()">, - AssemblerPredicate<"FeatureBREAK">; + AssemblerPredicate<(all_of FeatureBREAK)>; def HasTinyEncoding : Predicate<"Subtarget->hasTinyEncoding()">, - AssemblerPredicate<"FeatureTinyEncoding">; + AssemblerPredicate<(all_of FeatureTinyEncoding)>; // AVR specific condition code. These correspond to AVR_*_COND in @@ -555,7 +561,7 @@ Defs = [R1, R0, SREG] in def MULSRdRr : FMUL2RdRr<0, (outs), - (ins GPR8:$lhs, GPR8:$rhs), + (ins LD8:$lhs, LD8:$rhs), "muls\t$lhs, $rhs", []>, Requires<[SupportsMultiplication]>; @@ -563,28 +569,28 @@ Defs = [R1, R0, SREG] in def MULSURdRr : FMUL2RdRr<1, (outs), - (ins GPR8:$lhs, GPR8:$rhs), + (ins LD8lo:$lhs, LD8lo:$rhs), "mulsu\t$lhs, $rhs", []>, Requires<[SupportsMultiplication]>; def FMUL : FFMULRdRr<0b01, (outs), - (ins GPR8:$lhs, GPR8:$rhs), + (ins LD8lo:$lhs, LD8lo:$rhs), "fmul\t$lhs, $rhs", []>, Requires<[SupportsMultiplication]>; def FMULS : FFMULRdRr<0b10, (outs), - (ins GPR8:$lhs, GPR8:$rhs), + (ins LD8lo:$lhs, LD8lo:$rhs), "fmuls\t$lhs, $rhs", []>, Requires<[SupportsMultiplication]>; def FMULSU : FFMULRdRr<0b11, (outs), - (ins GPR8:$lhs, GPR8:$rhs), + (ins LD8lo:$lhs, LD8lo:$rhs), "fmulsu\t$lhs, $rhs", []>, Requires<[SupportsMultiplication]>; @@ -840,7 +846,7 @@ let isCall = 1 in //===----------------------------------------------------------------------===// let isTerminator = 1, isReturn = 1, -isBarrier = 1 in +isBarrier = 1 in { def RET : F16<0b1001010100001000, (outs), @@ -2042,8 +2048,6 @@ def : Pat<(add i16:$src1, imm:$src2), (SUBIWRdK i16:$src1, (imm16_neg_XFORM imm:$src2))>; def : Pat<(addc i16:$src1, imm:$src2), (SUBIWRdK i16:$src1, (imm16_neg_XFORM imm:$src2))>; -def : Pat<(adde i16:$src1, imm:$src2), - (SBCIWRdK i16:$src1, (imm16_neg_XFORM imm:$src2))>; def : Pat<(add i8:$src1, imm:$src2), (SUBIRdK i8:$src1, (imm8_neg_XFORM imm:$src2))>; diff --git a/llvm/lib/Target/AVR/AVRMachineFunctionInfo.h b/llvm/lib/Target/AVR/AVRMachineFunctionInfo.h index 5226e30491c3..5432fac122ef 100644 --- a/llvm/lib/Target/AVR/AVRMachineFunctionInfo.h +++ b/llvm/lib/Target/AVR/AVRMachineFunctionInfo.h @@ -31,6 +31,12 @@ class AVRMachineFunctionInfo : public MachineFunctionInfo { /// used inside the function. bool HasStackArgs; + /// Whether or not the function is an interrupt handler. + bool IsInterruptHandler; + + /// Whether or not the function is an non-blocking interrupt handler. + bool IsSignalHandler; + /// Size of the callee-saved register portion of the /// stack frame in bytes. unsigned CalleeSavedFrameSize; @@ -41,11 +47,17 @@ class AVRMachineFunctionInfo : public MachineFunctionInfo { public: AVRMachineFunctionInfo() : HasSpills(false), HasAllocas(false), HasStackArgs(false), + IsInterruptHandler(false), IsSignalHandler(false), CalleeSavedFrameSize(0), VarArgsFrameIndex(0) {} explicit AVRMachineFunctionInfo(MachineFunction &MF) : HasSpills(false), HasAllocas(false), HasStackArgs(false), - CalleeSavedFrameSize(0), VarArgsFrameIndex(0) {} + CalleeSavedFrameSize(0), VarArgsFrameIndex(0) { + unsigned CallConv = MF.getFunction().getCallingConv(); + + this->IsInterruptHandler = CallConv == CallingConv::AVR_INTR || MF.getFunction().hasFnAttribute("interrupt"); + this->IsSignalHandler = CallConv == CallingConv::AVR_SIGNAL || MF.getFunction().hasFnAttribute("signal"); + } bool getHasSpills() const { return HasSpills; } void setHasSpills(bool B) { HasSpills = B; } @@ -56,6 +68,12 @@ public: bool getHasStackArgs() const { return HasStackArgs; } void setHasStackArgs(bool B) { HasStackArgs = B; } + /// Checks if the function is some form of interrupt service routine. + bool isInterruptOrSignalHandler() const { return isInterruptHandler() || isSignalHandler(); } + + bool isInterruptHandler() const { return IsInterruptHandler; } + bool isSignalHandler() const { return IsSignalHandler; } + unsigned getCalleeSavedFrameSize() const { return CalleeSavedFrameSize; } void setCalleeSavedFrameSize(unsigned Bytes) { CalleeSavedFrameSize = Bytes; } diff --git a/llvm/lib/Target/AVR/AVRRegisterInfo.cpp b/llvm/lib/Target/AVR/AVRRegisterInfo.cpp index 8fce05c933bc..2a4905ce2461 100644 --- a/llvm/lib/Target/AVR/AVRRegisterInfo.cpp +++ b/llvm/lib/Target/AVR/AVRRegisterInfo.cpp @@ -22,6 +22,7 @@ #include "AVR.h" #include "AVRInstrInfo.h" +#include "AVRMachineFunctionInfo.h" #include "AVRTargetMachine.h" #include "MCTargetDesc/AVRMCTargetDesc.h" @@ -34,19 +35,21 @@ AVRRegisterInfo::AVRRegisterInfo() : AVRGenRegisterInfo(0) {} const uint16_t * AVRRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { - CallingConv::ID CC = MF->getFunction().getCallingConv(); + const AVRMachineFunctionInfo *AFI = MF->getInfo<AVRMachineFunctionInfo>(); - return ((CC == CallingConv::AVR_INTR || CC == CallingConv::AVR_SIGNAL) + return AFI->isInterruptOrSignalHandler() ? CSR_Interrupts_SaveList - : CSR_Normal_SaveList); + : CSR_Normal_SaveList; } const uint32_t * AVRRegisterInfo::getCallPreservedMask(const MachineFunction &MF, CallingConv::ID CC) const { - return ((CC == CallingConv::AVR_INTR || CC == CallingConv::AVR_SIGNAL) + const AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>(); + + return AFI->isInterruptOrSignalHandler() ? CSR_Interrupts_RegMask - : CSR_Normal_RegMask); + : CSR_Normal_RegMask; } BitVector AVRRegisterInfo::getReservedRegs(const MachineFunction &MF) const { @@ -95,7 +98,8 @@ AVRRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC, } /// Fold a frame offset shared between two add instructions into a single one. -static void foldFrameOffset(MachineBasicBlock::iterator &II, int &Offset, unsigned DstReg) { +static void foldFrameOffset(MachineBasicBlock::iterator &II, int &Offset, + Register DstReg) { MachineInstr &MI = *II; int Opcode = MI.getOpcode(); @@ -264,13 +268,12 @@ AVRRegisterInfo::getPointerRegClass(const MachineFunction &MF, return &AVR::PTRDISPREGSRegClass; } -void AVRRegisterInfo::splitReg(unsigned Reg, - unsigned &LoReg, - unsigned &HiReg) const { - assert(AVR::DREGSRegClass.contains(Reg) && "can only split 16-bit registers"); +void AVRRegisterInfo::splitReg(Register Reg, Register &LoReg, + Register &HiReg) const { + assert(AVR::DREGSRegClass.contains(Reg) && "can only split 16-bit registers"); - LoReg = getSubReg(Reg, AVR::sub_lo); - HiReg = getSubReg(Reg, AVR::sub_hi); + LoReg = getSubReg(Reg, AVR::sub_lo); + HiReg = getSubReg(Reg, AVR::sub_hi); } bool AVRRegisterInfo::shouldCoalesce(MachineInstr *MI, diff --git a/llvm/lib/Target/AVR/AVRRegisterInfo.h b/llvm/lib/Target/AVR/AVRRegisterInfo.h index 8e6e63af3d57..23439f2fe195 100644 --- a/llvm/lib/Target/AVR/AVRRegisterInfo.h +++ b/llvm/lib/Target/AVR/AVRRegisterInfo.h @@ -49,11 +49,7 @@ public: /// Splits a 16-bit `DREGS` register into the lo/hi register pair. /// \param Reg A 16-bit register to split. - void splitReg(unsigned Reg, unsigned &LoReg, unsigned &HiReg) const; - - bool trackLivenessAfterRegAlloc(const MachineFunction &) const override { - return true; - } + void splitReg(Register Reg, Register &LoReg, Register &HiReg) const; bool shouldCoalesce(MachineInstr *MI, const TargetRegisterClass *SrcRC, diff --git a/llvm/lib/Target/AVR/AVRRegisterInfo.td b/llvm/lib/Target/AVR/AVRRegisterInfo.td index ea38fedd22ce..ab5d02356c9d 100644 --- a/llvm/lib/Target/AVR/AVRRegisterInfo.td +++ b/llvm/lib/Target/AVR/AVRRegisterInfo.td @@ -103,6 +103,17 @@ CoveredBySubRegs = 1 in def R5R4 : AVRReg<4, "r5:r4", [R4, R5]>, DwarfRegNum<[4]>; def R3R2 : AVRReg<2, "r3:r2", [R2, R3]>, DwarfRegNum<[2]>; def R1R0 : AVRReg<0, "r1:r0", [R0, R1]>, DwarfRegNum<[0]>; + + // Pseudo registers for unaligned i16 + def R26R25 : AVRReg<25, "r26:r25", [R25, R26]>, DwarfRegNum<[25]>; + def R24R23 : AVRReg<23, "r24:r23", [R23, R24]>, DwarfRegNum<[23]>; + def R22R21 : AVRReg<21, "r22:r21", [R21, R22]>, DwarfRegNum<[21]>; + def R20R19 : AVRReg<19, "r20:r19", [R19, R20]>, DwarfRegNum<[19]>; + def R18R17 : AVRReg<17, "r18:r17", [R17, R18]>, DwarfRegNum<[17]>; + def R16R15 : AVRReg<15, "r16:r15", [R15, R16]>, DwarfRegNum<[15]>; + def R14R13 : AVRReg<13, "r14:r13", [R13, R14]>, DwarfRegNum<[13]>; + def R12R11 : AVRReg<11, "r12:r11", [R11, R12]>, DwarfRegNum<[11]>; + def R10R9 : AVRReg<9, "r10:r9", [R9, R10]>, DwarfRegNum<[9]>; } //===----------------------------------------------------------------------===// @@ -153,6 +164,22 @@ def DREGS : RegisterClass<"AVR", [i16], 8, R31R30, R27R26, // Callee saved registers. R29R28, R17R16, R15R14, R13R12, R11R10, + R9R8, R7R6, R5R4, R3R2, R1R0, + // Pseudo regs for unaligned 16-bits + R26R25, R24R23, R22R21, + R20R19, R18R17, R16R15, + R14R13, R12R11, R10R9 + )>; + +// 16-bit pair register class for movw +def DREGSMOVW : RegisterClass<"AVR", [i16], 8, + ( + // Return value and arguments. + add R25R24, R19R18, R21R20, R23R22, + // Scratch registers. + R31R30, R27R26, + // Callee saved registers. + R29R28, R17R16, R15R14, R13R12, R11R10, R9R8, R7R6, R5R4, R3R2, R1R0 )>; diff --git a/llvm/lib/Target/AVR/AVRSubtarget.cpp b/llvm/lib/Target/AVR/AVRSubtarget.cpp index 6a41036fdd6c..195ca95bc3bd 100644 --- a/llvm/lib/Target/AVR/AVRSubtarget.cpp +++ b/llvm/lib/Target/AVR/AVRSubtarget.cpp @@ -29,16 +29,19 @@ namespace llvm { AVRSubtarget::AVRSubtarget(const Triple &TT, const std::string &CPU, const std::string &FS, const AVRTargetMachine &TM) - : AVRGenSubtargetInfo(TT, CPU, FS), InstrInfo(), FrameLowering(), - TLInfo(TM, initializeSubtargetDependencies(CPU, FS, TM)), TSInfo(), + : AVRGenSubtargetInfo(TT, CPU, FS), ELFArch(0), // Subtarget features m_hasSRAM(false), m_hasJMPCALL(false), m_hasIJMPCALL(false), m_hasEIJMPCALL(false), m_hasADDSUBIW(false), m_hasSmallStack(false), - m_hasMOVW(false), m_hasLPM(false), m_hasLPMX(false), m_hasELPM(false), + m_hasMOVW(false), m_hasLPM(false), m_hasLPMX(false), m_hasELPM(false), m_hasELPMX(false), m_hasSPM(false), m_hasSPMX(false), m_hasDES(false), m_supportsRMW(false), m_supportsMultiplication(false), m_hasBREAK(false), - m_hasTinyEncoding(false), ELFArch(false), m_FeatureSetDummy(false) { + m_hasTinyEncoding(false), m_hasMemMappedGPR(false), + m_FeatureSetDummy(false), + + InstrInfo(), FrameLowering(), + TLInfo(TM, initializeSubtargetDependencies(CPU, FS, TM)), TSInfo() { // Parse features string. ParseSubtargetFeatures(CPU, FS); } diff --git a/llvm/lib/Target/AVR/AVRSubtarget.h b/llvm/lib/Target/AVR/AVRSubtarget.h index da9289af7c8d..81d883eb30d9 100644 --- a/llvm/lib/Target/AVR/AVRSubtarget.h +++ b/llvm/lib/Target/AVR/AVRSubtarget.h @@ -71,6 +71,9 @@ public: bool supportsMultiplication() const { return m_supportsMultiplication; } bool hasBREAK() const { return m_hasBREAK; } bool hasTinyEncoding() const { return m_hasTinyEncoding; } + bool hasMemMappedGPR() const { return m_hasMemMappedGPR; } + + uint8_t getIORegisterOffset() const { return hasMemMappedGPR() ? 0x20 : 0x0; } /// Gets the ELF architecture for the e_flags field /// of an ELF object file. @@ -81,10 +84,9 @@ public: } private: - AVRInstrInfo InstrInfo; - AVRFrameLowering FrameLowering; - AVRTargetLowering TLInfo; - AVRSelectionDAGInfo TSInfo; + + /// The ELF e_flags architecture. + unsigned ELFArch; // Subtarget feature settings // See AVR.td for details. @@ -106,13 +108,16 @@ private: bool m_supportsMultiplication; bool m_hasBREAK; bool m_hasTinyEncoding; - - /// The ELF e_flags architecture. - unsigned ELFArch; + bool m_hasMemMappedGPR; // Dummy member, used by FeatureSet's. We cannot have a SubtargetFeature with // no variable, so we instead bind pseudo features to this variable. bool m_FeatureSetDummy; + + AVRInstrInfo InstrInfo; + AVRFrameLowering FrameLowering; + AVRTargetLowering TLInfo; + AVRSelectionDAGInfo TSInfo; }; } // end namespace llvm diff --git a/llvm/lib/Target/AVR/AVRTargetMachine.cpp b/llvm/lib/Target/AVR/AVRTargetMachine.cpp index b33284b73d63..0c7136e6f77e 100644 --- a/llvm/lib/Target/AVR/AVRTargetMachine.cpp +++ b/llvm/lib/Target/AVR/AVRTargetMachine.cpp @@ -49,7 +49,7 @@ AVRTargetMachine::AVRTargetMachine(const Target &T, const Triple &TT, : LLVMTargetMachine(T, AVRDataLayout, TT, getCPU(CPU), FS, Options, getEffectiveRelocModel(RM), getEffectiveCodeModel(CM, CodeModel::Small), OL), - SubTarget(TT, getCPU(CPU), FS, *this) { + SubTarget(TT, std::string(getCPU(CPU)), std::string(FS), *this) { this->TLOF = std::make_unique<AVRTargetObjectFile>(); initAsmInfo(); } diff --git a/llvm/lib/Target/AVR/AVRTargetObjectFile.cpp b/llvm/lib/Target/AVR/AVRTargetObjectFile.cpp index 980096a09835..14206cdb8276 100644 --- a/llvm/lib/Target/AVR/AVRTargetObjectFile.cpp +++ b/llvm/lib/Target/AVR/AVRTargetObjectFile.cpp @@ -30,7 +30,7 @@ AVRTargetObjectFile::SelectSectionForGlobal(const GlobalObject *GO, const TargetMachine &TM) const { // Global values in flash memory are placed in the progmem.data section // unless they already have a user assigned section. - if (AVR::isProgramMemoryAddress(GO) && !GO->hasSection()) + if (AVR::isProgramMemoryAddress(GO) && !GO->hasSection() && Kind.isReadOnly()) return ProgmemDataSection; // Otherwise, we work the same way as ELF. diff --git a/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp b/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp index fc34583ae573..230bc7adc07a 100644 --- a/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp +++ b/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp @@ -53,6 +53,8 @@ class AVRAsmParser : public MCTargetAsmParser { bool MatchingInlineAsm) override; bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; + OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc, + SMLoc &EndLoc) override; bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands) override; @@ -64,7 +66,7 @@ class AVRAsmParser : public MCTargetAsmParser { bool parseOperand(OperandVector &Operands); int parseRegisterName(unsigned (*matchFn)(StringRef)); int parseRegisterName(); - int parseRegister(); + int parseRegister(bool RestoreOnFailure = false); bool tryParseRegisterOperand(OperandVector &Operands); bool tryParseExpression(OperandVector &Operands); bool tryParseRelocExpression(OperandVector &Operands); @@ -176,10 +178,10 @@ public: return isUInt<8>(Value); } - bool isReg() const { return Kind == k_Register; } - bool isImm() const { return Kind == k_Immediate; } - bool isToken() const { return Kind == k_Token; } - bool isMem() const { return Kind == k_Memri; } + bool isReg() const override { return Kind == k_Register; } + bool isImm() const override { return Kind == k_Immediate; } + bool isToken() const override { return Kind == k_Token; } + bool isMem() const override { return Kind == k_Memri; } bool isMemri() const { return Kind == k_Memri; } StringRef getToken() const { @@ -187,7 +189,7 @@ public: return Tok; } - unsigned getReg() const { + unsigned getReg() const override { assert((Kind == k_Register || Kind == k_Memri) && "Invalid access!"); return RegImm.Reg; @@ -237,10 +239,10 @@ public: RegImm = {RegNo, Imm}; } - SMLoc getStartLoc() const { return Start; } - SMLoc getEndLoc() const { return End; } + SMLoc getStartLoc() const override { return Start; } + SMLoc getEndLoc() const override { return End; } - virtual void print(raw_ostream &O) const { + void print(raw_ostream &O) const override { switch (Kind) { case k_Token: O << "Token: \"" << getToken() << "\""; @@ -307,7 +309,7 @@ bool AVRAsmParser::missingFeature(llvm::SMLoc const &Loc, bool AVRAsmParser::emit(MCInst &Inst, SMLoc const &Loc, MCStreamer &Out) const { Inst.setLoc(Loc); - Out.EmitInstruction(Inst, STI); + Out.emitInstruction(Inst, STI); return false; } @@ -359,19 +361,25 @@ int AVRAsmParser::parseRegisterName() { return RegNum; } -int AVRAsmParser::parseRegister() { +int AVRAsmParser::parseRegister(bool RestoreOnFailure) { int RegNum = AVR::NoRegister; if (Parser.getTok().is(AsmToken::Identifier)) { // Check for register pair syntax if (Parser.getLexer().peekTok().is(AsmToken::Colon)) { + AsmToken HighTok = Parser.getTok(); Parser.Lex(); + AsmToken ColonTok = Parser.getTok(); Parser.Lex(); // Eat high (odd) register and colon if (Parser.getTok().is(AsmToken::Identifier)) { // Convert lower (even) register to DREG RegNum = toDREG(parseRegisterName()); } + if (RegNum == AVR::NoRegister && RestoreOnFailure) { + getLexer().UnLex(std::move(ColonTok)); + getLexer().UnLex(std::move(HighTok)); + } } else { RegNum = parseRegisterName(); } @@ -580,12 +588,24 @@ AVRAsmParser::parseMemriOperand(OperandVector &Operands) { bool AVRAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) { StartLoc = Parser.getTok().getLoc(); - RegNo = parseRegister(); + RegNo = parseRegister(/*RestoreOnFailure=*/false); EndLoc = Parser.getTok().getLoc(); return (RegNo == AVR::NoRegister); } +OperandMatchResultTy AVRAsmParser::tryParseRegister(unsigned &RegNo, + SMLoc &StartLoc, + SMLoc &EndLoc) { + StartLoc = Parser.getTok().getLoc(); + RegNo = parseRegister(/*RestoreOnFailure=*/true); + EndLoc = Parser.getTok().getLoc(); + + if (RegNo == AVR::NoRegister) + return MatchOperand_NoMatch; + return MatchOperand_Success; +} + void AVRAsmParser::eatComma() { if (getLexer().is(AsmToken::Comma)) { Parser.Lex(); @@ -650,7 +670,7 @@ bool AVRAsmParser::parseLiteralValues(unsigned SizeInBytes, SMLoc L) { Tokens[0].getKind() == AsmToken::Minus && Tokens[1].getKind() == AsmToken::Identifier) { MCSymbol *Symbol = getContext().getOrCreateSymbol(".text"); - AVRStreamer.EmitValueForModiferKind(Symbol, SizeInBytes, L, + AVRStreamer.emitValueForModiferKind(Symbol, SizeInBytes, L, AVRMCExpr::VK_AVR_None); return false; } @@ -668,7 +688,7 @@ bool AVRAsmParser::parseLiteralValues(unsigned SizeInBytes, SMLoc L) { } MCSymbol *Symbol = getContext().getOrCreateSymbol(Parser.getTok().getString()); - AVRStreamer.EmitValueForModiferKind(Symbol, SizeInBytes, L, ModifierKind); + AVRStreamer.emitValueForModiferKind(Symbol, SizeInBytes, L, ModifierKind); return false; } @@ -676,7 +696,7 @@ bool AVRAsmParser::parseLiteralValues(unsigned SizeInBytes, SMLoc L) { const MCExpr *Value; if (Parser.parseExpression(Value)) return true; - Parser.getStreamer().EmitValue(Value, SizeInBytes, L); + Parser.getStreamer().emitValue(Value, SizeInBytes, L); return false; }; return (parseMany(parseOne)); diff --git a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp index 694aee818f7c..8e7251a74dfd 100644 --- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp +++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp @@ -57,23 +57,180 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRDisassembler() { createAVRDisassembler); } +static const uint16_t GPRDecoderTable[] = { + AVR::R0, AVR::R1, AVR::R2, AVR::R3, + AVR::R4, AVR::R5, AVR::R6, AVR::R7, + AVR::R8, AVR::R9, AVR::R10, AVR::R11, + AVR::R12, AVR::R13, AVR::R14, AVR::R15, + AVR::R16, AVR::R17, AVR::R18, AVR::R19, + AVR::R20, AVR::R21, AVR::R22, AVR::R23, + AVR::R24, AVR::R25, AVR::R26, AVR::R27, + AVR::R28, AVR::R29, AVR::R30, AVR::R31, +}; + static DecodeStatus DecodeGPR8RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { + if (RegNo > 31) + return MCDisassembler::Fail; + + unsigned Register = GPRDecoderTable[RegNo]; + Inst.addOperand(MCOperand::createReg(Register)); return MCDisassembler::Success; } static DecodeStatus DecodeLD8RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { + if (RegNo > 15) + return MCDisassembler::Fail; + + unsigned Register = GPRDecoderTable[RegNo+16]; + Inst.addOperand(MCOperand::createReg(Register)); return MCDisassembler::Success; } static DecodeStatus DecodePTRREGSRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { + // Note: this function must be defined but does not seem to be called. + assert(false && "unimplemented: PTRREGS register class"); return MCDisassembler::Success; } +static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + +static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + +static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + +static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + +static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + +static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + +static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + +static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + +static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + +static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + #include "AVRGenDisassemblerTables.inc" +static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + unsigned addr = 0; + addr |= fieldFromInstruction(Insn, 0, 4); + addr |= fieldFromInstruction(Insn, 9, 2) << 4; + unsigned reg = fieldFromInstruction(Insn, 4, 5); + Inst.addOperand(MCOperand::createImm(addr)); + if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + return MCDisassembler::Success; +} + +static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + unsigned addr = 0; + addr |= fieldFromInstruction(Insn, 0, 4); + addr |= fieldFromInstruction(Insn, 9, 2) << 4; + unsigned reg = fieldFromInstruction(Insn, 4, 5); + if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + Inst.addOperand(MCOperand::createImm(addr)); + return MCDisassembler::Success; +} + +static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + unsigned addr = fieldFromInstruction(Insn, 3, 5); + unsigned b = fieldFromInstruction(Insn, 0, 3); + Inst.addOperand(MCOperand::createImm(addr)); + Inst.addOperand(MCOperand::createImm(b)); + return MCDisassembler::Success; +} + +static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Field, + uint64_t Address, const void *Decoder) { + // Call targets need to be shifted left by one so this needs a custom + // decoder. + Inst.addOperand(MCOperand::createImm(Field << 1)); + return MCDisassembler::Success; +} + +static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + unsigned d = fieldFromInstruction(Insn, 4, 5); + if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + return MCDisassembler::Success; +} + +static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + if (decodeFRd(Inst, Insn, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + Inst.addOperand(MCOperand::createReg(AVR::R31R30)); + return MCDisassembler::Success; +} + +static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + unsigned d = fieldFromInstruction(Insn, 4, 3) + 16; + unsigned r = fieldFromInstruction(Insn, 0, 3) + 16; + if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + return MCDisassembler::Success; +} + +static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + unsigned r = fieldFromInstruction(Insn, 4, 4) * 2; + unsigned d = fieldFromInstruction(Insn, 0, 4) * 2; + if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + return MCDisassembler::Success; +} + +static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + unsigned d = fieldFromInstruction(Insn, 4, 2) * 2 + 24; // starts at r24:r25 + unsigned k = 0; + k |= fieldFromInstruction(Insn, 0, 4); + k |= fieldFromInstruction(Insn, 6, 2) << 4; + if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + Inst.addOperand(MCOperand::createImm(k)); + return MCDisassembler::Success; +} + +static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + unsigned rd = fieldFromInstruction(Insn, 4, 4) + 16; + unsigned rr = fieldFromInstruction(Insn, 0, 4) + 16; + if (DecodeGPR8RegisterClass(Inst, rd, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + if (DecodeGPR8RegisterClass(Inst, rr, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + return MCDisassembler::Success; +} + static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address, uint64_t &Size, uint32_t &Insn) { if (Bytes.size() < 2) { @@ -96,7 +253,7 @@ static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address, } Size = 4; - Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) | (Bytes[3] << 24); + Insn = (Bytes[0] << 16) | (Bytes[1] << 24) | (Bytes[2] << 0) | (Bytes[3] << 8); return MCDisassembler::Success; } diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp b/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp index e92b16c8ee9d..ac72abe0d9f6 100644 --- a/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp +++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp @@ -34,8 +34,9 @@ namespace adjust { using namespace llvm; -void signed_width(unsigned Width, uint64_t Value, std::string Description, - const MCFixup &Fixup, MCContext *Ctx = nullptr) { +static void signed_width(unsigned Width, uint64_t Value, + std::string Description, const MCFixup &Fixup, + MCContext *Ctx = nullptr) { if (!isIntN(Width, Value)) { std::string Diagnostic = "out of range " + Description; @@ -53,8 +54,9 @@ void signed_width(unsigned Width, uint64_t Value, std::string Description, } } -void unsigned_width(unsigned Width, uint64_t Value, std::string Description, - const MCFixup &Fixup, MCContext *Ctx = nullptr) { +static void unsigned_width(unsigned Width, uint64_t Value, + std::string Description, const MCFixup &Fixup, + MCContext *Ctx = nullptr) { if (!isUIntN(Width, Value)) { std::string Diagnostic = "out of range " + Description; @@ -72,8 +74,8 @@ void unsigned_width(unsigned Width, uint64_t Value, std::string Description, } /// Adjusts the value of a branch target before fixup application. -void adjustBranch(unsigned Size, const MCFixup &Fixup, uint64_t &Value, - MCContext *Ctx = nullptr) { +static void adjustBranch(unsigned Size, const MCFixup &Fixup, uint64_t &Value, + MCContext *Ctx = nullptr) { // We have one extra bit of precision because the value is rightshifted by // one. unsigned_width(Size + 1, Value, std::string("branch target"), Fixup, Ctx); @@ -83,14 +85,12 @@ void adjustBranch(unsigned Size, const MCFixup &Fixup, uint64_t &Value, } /// Adjusts the value of a relative branch target before fixup application. -void adjustRelativeBranch(unsigned Size, const MCFixup &Fixup, uint64_t &Value, - MCContext *Ctx = nullptr) { +static void adjustRelativeBranch(unsigned Size, const MCFixup &Fixup, + uint64_t &Value, MCContext *Ctx = nullptr) { // We have one extra bit of precision because the value is rightshifted by // one. signed_width(Size + 1, Value, std::string("branch target"), Fixup, Ctx); - Value -= 2; - // Rightshifts the value by one. AVR::fixups::adjustBranchTarget(Value); } @@ -101,8 +101,8 @@ void adjustRelativeBranch(unsigned Size, const MCFixup &Fixup, uint64_t &Value, /// 1001 kkkk 010k kkkk kkkk kkkk 111k kkkk /// /// Offset of 0 (so the result is left shifted by 3 bits before application). -void fixup_call(unsigned Size, const MCFixup &Fixup, uint64_t &Value, - MCContext *Ctx = nullptr) { +static void fixup_call(unsigned Size, const MCFixup &Fixup, uint64_t &Value, + MCContext *Ctx = nullptr) { adjustBranch(Size, Fixup, Value, Ctx); auto top = Value & (0xf00000 << 6); // the top four bits @@ -117,8 +117,8 @@ void fixup_call(unsigned Size, const MCFixup &Fixup, uint64_t &Value, /// Resolves to: /// 0000 00kk kkkk k000 /// Offset of 0 (so the result is left shifted by 3 bits before application). -void fixup_7_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value, - MCContext *Ctx = nullptr) { +static void fixup_7_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value, + MCContext *Ctx = nullptr) { adjustRelativeBranch(Size, Fixup, Value, Ctx); // Because the value may be negative, we must mask out the sign bits @@ -131,21 +131,33 @@ void fixup_7_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value, /// Resolves to: /// 0000 kkkk kkkk kkkk /// Offset of 0 (so the result isn't left-shifted before application). -void fixup_13_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value, - MCContext *Ctx = nullptr) { +static void fixup_13_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value, + MCContext *Ctx = nullptr) { adjustRelativeBranch(Size, Fixup, Value, Ctx); // Because the value may be negative, we must mask out the sign bits Value &= 0xfff; } +/// 6-bit fixup for the immediate operand of the STD/LDD family of +/// instructions. +/// +/// Resolves to: +/// 10q0 qq10 0000 1qqq +static void fixup_6(const MCFixup &Fixup, uint64_t &Value, + MCContext *Ctx = nullptr) { + unsigned_width(6, Value, std::string("immediate"), Fixup, Ctx); + + Value = ((Value & 0x20) << 8) | ((Value & 0x18) << 7) | (Value & 0x07); +} + /// 6-bit fixup for the immediate operand of the ADIW family of /// instructions. /// /// Resolves to: /// 0000 0000 kk00 kkkk -void fixup_6_adiw(const MCFixup &Fixup, uint64_t &Value, - MCContext *Ctx = nullptr) { +static void fixup_6_adiw(const MCFixup &Fixup, uint64_t &Value, + MCContext *Ctx = nullptr) { unsigned_width(6, Value, std::string("immediate"), Fixup, Ctx); Value = ((Value & 0x30) << 2) | (Value & 0x0f); @@ -155,8 +167,8 @@ void fixup_6_adiw(const MCFixup &Fixup, uint64_t &Value, /// /// Resolves to: /// 0000 0000 AAAA A000 -void fixup_port5(const MCFixup &Fixup, uint64_t &Value, - MCContext *Ctx = nullptr) { +static void fixup_port5(const MCFixup &Fixup, uint64_t &Value, + MCContext *Ctx = nullptr) { unsigned_width(5, Value, std::string("port number"), Fixup, Ctx); Value &= 0x1f; @@ -168,8 +180,8 @@ void fixup_port5(const MCFixup &Fixup, uint64_t &Value, /// /// Resolves to: /// 1011 0AAd dddd AAAA -void fixup_port6(const MCFixup &Fixup, uint64_t &Value, - MCContext *Ctx = nullptr) { +static void fixup_port6(const MCFixup &Fixup, uint64_t &Value, + MCContext *Ctx = nullptr) { unsigned_width(6, Value, std::string("port number"), Fixup, Ctx); Value = ((Value & 0x30) << 5) | (Value & 0x0f); @@ -177,9 +189,7 @@ void fixup_port6(const MCFixup &Fixup, uint64_t &Value, /// Adjusts a program memory address. /// This is a simple right-shift. -void pm(uint64_t &Value) { - Value >>= 1; -} +static void pm(uint64_t &Value) { Value >>= 1; } /// Fixups relating to the LDI instruction. namespace ldi { @@ -189,36 +199,36 @@ namespace ldi { /// Resolves to: /// 0000 KKKK 0000 KKKK /// Offset of 0 (so the result isn't left-shifted before application). -void fixup(unsigned Size, const MCFixup &Fixup, uint64_t &Value, - MCContext *Ctx = nullptr) { +static void fixup(unsigned Size, const MCFixup &Fixup, uint64_t &Value, + MCContext *Ctx = nullptr) { uint64_t upper = Value & 0xf0; uint64_t lower = Value & 0x0f; Value = (upper << 4) | lower; } -void neg(uint64_t &Value) { Value *= -1; } +static void neg(uint64_t &Value) { Value *= -1; } -void lo8(unsigned Size, const MCFixup &Fixup, uint64_t &Value, - MCContext *Ctx = nullptr) { +static void lo8(unsigned Size, const MCFixup &Fixup, uint64_t &Value, + MCContext *Ctx = nullptr) { Value &= 0xff; ldi::fixup(Size, Fixup, Value, Ctx); } -void hi8(unsigned Size, const MCFixup &Fixup, uint64_t &Value, - MCContext *Ctx = nullptr) { +static void hi8(unsigned Size, const MCFixup &Fixup, uint64_t &Value, + MCContext *Ctx = nullptr) { Value = (Value & 0xff00) >> 8; ldi::fixup(Size, Fixup, Value, Ctx); } -void hh8(unsigned Size, const MCFixup &Fixup, uint64_t &Value, - MCContext *Ctx = nullptr) { +static void hh8(unsigned Size, const MCFixup &Fixup, uint64_t &Value, + MCContext *Ctx = nullptr) { Value = (Value & 0xff0000) >> 16; ldi::fixup(Size, Fixup, Value, Ctx); } -void ms8(unsigned Size, const MCFixup &Fixup, uint64_t &Value, - MCContext *Ctx = nullptr) { +static void ms8(unsigned Size, const MCFixup &Fixup, uint64_t &Value, + MCContext *Ctx = nullptr) { Value = (Value & 0xff000000) >> 24; ldi::fixup(Size, Fixup, Value, Ctx); } @@ -237,17 +247,6 @@ void AVRAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Size = AVRAsmBackend::getFixupKindInfo(Fixup.getKind()).TargetSize; unsigned Kind = Fixup.getKind(); - - // Parsed LLVM-generated temporary labels are already - // adjusted for instruction size, but normal labels aren't. - // - // To handle both cases, we simply un-adjust the temporary label - // case so it acts like all other labels. - if (const MCSymbolRefExpr *A = Target.getSymA()) { - if (A->getSymbol().isTemporary()) - Value += 2; - } - switch (Kind) { default: llvm_unreachable("unhandled fixup"); @@ -326,6 +325,9 @@ void AVRAsmBackend::adjustFixupValue(const MCFixup &Fixup, Value &= 0xffff; break; + case AVR::fixup_6: + adjust::fixup_6(Fixup, Value, Ctx); + break; case AVR::fixup_6_adiw: adjust::fixup_6_adiw(Fixup, Value, Ctx); break; diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.h b/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.h index 1e713db38145..9e150f120dd4 100644 --- a/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.h +++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.h @@ -22,9 +22,6 @@ namespace llvm { class MCAssembler; -class MCObjectWriter; -class Target; - struct MCFixupKindInfo; /// Utilities for manipulating generated AVR machine code. @@ -62,9 +59,6 @@ public: return false; } - void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, - MCInst &Res) const override {} - bool writeNopData(raw_ostream &OS, uint64_t Count) const override; bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRFixupKinds.h b/llvm/lib/Target/AVR/MCTargetDesc/AVRFixupKinds.h index b3504b89e4d3..a0dd1dc8ac3e 100644 --- a/llvm/lib/Target/AVR/MCTargetDesc/AVRFixupKinds.h +++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRFixupKinds.h @@ -137,7 +137,7 @@ namespace fixups { /// of the fact that all instructions are aligned to addresses of size /// 2, so bit 0 of an address is always 0. This gives us another bit /// of precision. -/// \param[in,out] The target to adjust. +/// \param [in,out] val The target to adjust. template <typename T> inline void adjustBranchTarget(T &val) { val >>= 1; } } // end of namespace fixups diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.cpp b/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.cpp index 832112406155..42fac5e2e000 100644 --- a/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.cpp +++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.cpp @@ -78,7 +78,7 @@ void AVRInstPrinter::printInst(const MCInst *MI, uint64_t Address, printOperand(MI, 2, O); break; default: - if (!printAliasInstr(MI, O)) + if (!printAliasInstr(MI, Address, O)) printInstruction(MI, Address, O); printAnnotation(O, Annot); @@ -100,8 +100,25 @@ const char *AVRInstPrinter::getPrettyRegisterName(unsigned RegNum, void AVRInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) { - const MCOperand &Op = MI->getOperand(OpNo); const MCOperandInfo &MOI = this->MII.get(MI->getOpcode()).OpInfo[OpNo]; + if (MOI.RegClass == AVR::ZREGRegClassID) { + // Special case for the Z register, which sometimes doesn't have an operand + // in the MCInst. + O << "Z"; + return; + } + + if (OpNo >= MI->size()) { + // Not all operands are correctly disassembled at the moment. This means + // that some machine instructions won't have all the necessary operands + // set. + // To avoid asserting, print <unknown> instead until the necessary support + // has been implemented. + O << "<unknown>"; + return; + } + + const MCOperand &Op = MI->getOperand(OpNo); if (Op.isReg()) { bool isPtrReg = (MOI.RegClass == AVR::PTRREGSRegClassID) || @@ -114,7 +131,7 @@ void AVRInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, O << getPrettyRegisterName(Op.getReg(), MRI); } } else if (Op.isImm()) { - O << Op.getImm(); + O << formatImm(Op.getImm()); } else { assert(Op.isExpr() && "Unknown operand kind in printOperand"); O << *Op.getExpr(); @@ -125,6 +142,16 @@ void AVRInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, /// being encoded as a pc-relative value. void AVRInstPrinter::printPCRelImm(const MCInst *MI, unsigned OpNo, raw_ostream &O) { + if (OpNo >= MI->size()) { + // Not all operands are correctly disassembled at the moment. This means + // that some machine instructions won't have all the necessary operands + // set. + // To avoid asserting, print <unknown> instead until the necessary support + // has been implemented. + O << "<unknown>"; + return; + } + const MCOperand &Op = MI->getOperand(OpNo); if (Op.isImm()) { diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.h b/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.h index 247e9fc83989..910fd3455dee 100644 --- a/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.h +++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.h @@ -38,13 +38,18 @@ private: void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); void printPCRelImm(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printPCRelImm(const MCInst *MI, uint64_t /*Address*/, unsigned OpNo, + raw_ostream &O) { + printPCRelImm(MI, OpNo, O); + } void printMemri(const MCInst *MI, unsigned OpNo, raw_ostream &O); // Autogenerated by TableGen. void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O); - bool printAliasInstr(const MCInst *MI, raw_ostream &O); - void printCustomAliasOperand(const MCInst *MI, unsigned OpIdx, - unsigned PrintMethodIdx, raw_ostream &O); + bool printAliasInstr(const MCInst *MI, uint64_t Address, raw_ostream &O); + void printCustomAliasOperand(const MCInst *MI, uint64_t Address, + unsigned OpIdx, unsigned PrintMethodIdx, + raw_ostream &O); }; } // end namespace llvm diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRMCAsmInfo.cpp b/llvm/lib/Target/AVR/MCTargetDesc/AVRMCAsmInfo.cpp index c25a2b232013..b11ee42bfcd6 100644 --- a/llvm/lib/Target/AVR/MCTargetDesc/AVRMCAsmInfo.cpp +++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRMCAsmInfo.cpp @@ -21,8 +21,8 @@ AVRMCAsmInfo::AVRMCAsmInfo(const Triple &TT, const MCTargetOptions &Options) { CalleeSaveStackSlotSize = 2; CommentString = ";"; PrivateGlobalPrefix = ".L"; + PrivateLabelPrefix = ".L"; UsesELFSectionDirectiveForBSS = true; - UseIntegratedAssembler = true; SupportsDebugInformation = true; } diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRMCELFStreamer.cpp b/llvm/lib/Target/AVR/MCTargetDesc/AVRMCELFStreamer.cpp index d9169f90a765..77b49931843b 100644 --- a/llvm/lib/Target/AVR/MCTargetDesc/AVRMCELFStreamer.cpp +++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRMCELFStreamer.cpp @@ -20,7 +20,7 @@ using namespace llvm; -void AVRMCELFStreamer::EmitValueForModiferKind( +void AVRMCELFStreamer::emitValueForModiferKind( const MCSymbol *Sym, unsigned SizeInBytes, SMLoc Loc, AVRMCExpr::VariantKind ModifierKind) { MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_AVR_NONE; @@ -36,7 +36,7 @@ void AVRMCELFStreamer::EmitValueForModiferKind( Kind = MCSymbolRefExpr::VK_AVR_HI8; else if (ModifierKind == AVRMCExpr::VK_AVR_HH8) Kind = MCSymbolRefExpr::VK_AVR_HLO8; - MCELFStreamer::EmitValue(MCSymbolRefExpr::create(Sym, Kind, getContext()), + MCELFStreamer::emitValue(MCSymbolRefExpr::create(Sym, Kind, getContext()), SizeInBytes, Loc); } diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRMCELFStreamer.h b/llvm/lib/Target/AVR/MCTargetDesc/AVRMCELFStreamer.h index 37a610bc4248..1d05b8d56d93 100644 --- a/llvm/lib/Target/AVR/MCTargetDesc/AVRMCELFStreamer.h +++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRMCELFStreamer.h @@ -41,7 +41,7 @@ public: std::move(Emitter)), MCII(createAVRMCInstrInfo()) {} - void EmitValueForModiferKind( + void emitValueForModiferKind( const MCSymbol *Sym, unsigned SizeInBytes, SMLoc Loc = SMLoc(), AVRMCExpr::VariantKind ModifierKind = AVRMCExpr::VK_AVR_None); }; diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.h b/llvm/lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.h index 470db01ff468..ef116793d326 100644 --- a/llvm/lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.h +++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.h @@ -27,10 +27,7 @@ class MCObjectTargetWriter; class MCRegisterInfo; class MCSubtargetInfo; class MCTargetOptions; -class StringRef; class Target; -class Triple; -class raw_pwrite_stream; MCInstrInfo *createAVRMCInstrInfo(); diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.cpp b/llvm/lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.cpp index 3487a2bbb864..eccd343d79ab 100644 --- a/llvm/lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.cpp +++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.cpp @@ -32,11 +32,11 @@ void AVRTargetStreamer::finish() { OS.emitRawComment(" Declaring this symbol tells the CRT that it should"); OS.emitRawComment("copy all variables from program memory to RAM on startup"); - OS.EmitSymbolAttribute(DoCopyData, MCSA_Global); + OS.emitSymbolAttribute(DoCopyData, MCSA_Global); OS.emitRawComment(" Declaring this symbol tells the CRT that it should"); OS.emitRawComment("clear the zeroed data section on startup"); - OS.EmitSymbolAttribute(DoClearBss, MCSA_Global); + OS.emitSymbolAttribute(DoClearBss, MCSA_Global); } } // end namespace llvm |