@@ -28,6 +28,10 @@ using namespace llvm;
2828#define GET_INSTRINFO_CTOR_DTOR
2929#include " SparcGenInstrInfo.inc"
3030
31+ static cl::opt<unsigned > BPccDisplacementBits (
32+ " sparc-bpcc-offset-bits" , cl::Hidden, cl::init(19 ),
33+ cl::desc(" Restrict range of BPcc/FBPfcc instructions (DEBUG)" ));
34+
3135// Pin the vtable to this file.
3236void SparcInstrInfo::anchor () {}
3337
@@ -73,11 +77,6 @@ unsigned SparcInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
7377 return 0 ;
7478}
7579
76- static bool IsIntegerCC (unsigned CC)
77- {
78- return (CC <= SPCC::ICC_VC);
79- }
80-
8180static SPCC::CondCodes GetOppositeBranchCondition (SPCC::CondCodes CC)
8281{
8382 switch (CC) {
@@ -155,9 +154,7 @@ static SPCC::CondCodes GetOppositeBranchCondition(SPCC::CondCodes CC)
155154 llvm_unreachable (" Invalid cond code" );
156155}
157156
158- static bool isUncondBranchOpcode (int Opc) {
159- return Opc == SP::BA || Opc == SP::BPA;
160- }
157+ static bool isUncondBranchOpcode (int Opc) { return Opc == SP::BA; }
161158
162159static bool isI32CondBranchOpcode (int Opc) {
163160 return Opc == SP::BCOND || Opc == SP::BPICC || Opc == SP::BPICCA ||
@@ -169,7 +166,10 @@ static bool isI64CondBranchOpcode(int Opc) {
169166 Opc == SP::BPXCCANT;
170167}
171168
172- static bool isFCondBranchOpcode (int Opc) { return Opc == SP::FBCOND; }
169+ static bool isFCondBranchOpcode (int Opc) {
170+ return Opc == SP::FBCOND || Opc == SP::FBCONDA || Opc == SP::FBCOND_V9 ||
171+ Opc == SP::FBCONDA_V9;
172+ }
173173
174174static bool isCondBranchOpcode (int Opc) {
175175 return isI32CondBranchOpcode (Opc) || isI64CondBranchOpcode (Opc) ||
@@ -193,6 +193,34 @@ static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target,
193193 Target = LastInst->getOperand (0 ).getMBB ();
194194}
195195
196+ MachineBasicBlock *
197+ SparcInstrInfo::getBranchDestBlock (const MachineInstr &MI) const {
198+ switch (MI.getOpcode ()) {
199+ default :
200+ llvm_unreachable (" unexpected opcode!" );
201+ case SP::BA:
202+ case SP::BCOND:
203+ case SP::BCONDA:
204+ case SP::FBCOND:
205+ case SP::FBCONDA:
206+ case SP::BPICC:
207+ case SP::BPICCA:
208+ case SP::BPICCNT:
209+ case SP::BPICCANT:
210+ case SP::BPXCC:
211+ case SP::BPXCCA:
212+ case SP::BPXCCNT:
213+ case SP::BPXCCANT:
214+ case SP::BPFCC:
215+ case SP::BPFCCA:
216+ case SP::BPFCCNT:
217+ case SP::BPFCCANT:
218+ case SP::FBCOND_V9:
219+ case SP::FBCONDA_V9:
220+ return MI.getOperand (0 ).getMBB ();
221+ }
222+ }
223+
196224bool SparcInstrInfo::analyzeBranch (MachineBasicBlock &MBB,
197225 MachineBasicBlock *&TBB,
198226 MachineBasicBlock *&FBB,
@@ -285,36 +313,37 @@ unsigned SparcInstrInfo::insertBranch(MachineBasicBlock &MBB,
285313 assert (TBB && " insertBranch must not be told to insert a fallthrough" );
286314 assert ((Cond.size () <= 2 ) &&
287315 " Sparc branch conditions should have at most two components!" );
288- assert (!BytesAdded && " code size not handled" );
289316
290317 if (Cond.empty ()) {
291318 assert (!FBB && " Unconditional branch with multiple successors!" );
292- BuildMI (&MBB, DL, get (Subtarget.isV9 () ? SP::BPA : SP::BA)).addMBB (TBB);
319+ BuildMI (&MBB, DL, get (SP::BA)).addMBB (TBB);
320+ if (BytesAdded)
321+ *BytesAdded = 8 ;
293322 return 1 ;
294323 }
295324
296325 // Conditional branch
297326 unsigned Opc = Cond[0 ].getImm ();
298327 unsigned CC = Cond[1 ].getImm ();
328+ BuildMI (&MBB, DL, get (Opc)).addMBB (TBB).addImm (CC);
299329
300- if (IsIntegerCC (CC)) {
301- BuildMI (&MBB, DL, get (Opc)).addMBB (TBB).addImm (CC);
302- } else {
303- BuildMI (&MBB, DL, get (SP::FBCOND)).addMBB (TBB).addImm (CC);
304- }
305- if (!FBB)
330+ if (!FBB) {
331+ if (BytesAdded)
332+ *BytesAdded = 8 ;
306333 return 1 ;
334+ }
307335
308- BuildMI (&MBB, DL, get (Subtarget.isV9 () ? SP::BPA : SP::BA)).addMBB (FBB);
336+ BuildMI (&MBB, DL, get (SP::BA)).addMBB (FBB);
337+ if (BytesAdded)
338+ *BytesAdded = 16 ;
309339 return 2 ;
310340}
311341
312342unsigned SparcInstrInfo::removeBranch (MachineBasicBlock &MBB,
313343 int *BytesRemoved) const {
314- assert (!BytesRemoved && " code size not handled" );
315-
316344 MachineBasicBlock::iterator I = MBB.end ();
317345 unsigned Count = 0 ;
346+ int Removed = 0 ;
318347 while (I != MBB.begin ()) {
319348 --I;
320349
@@ -326,9 +355,13 @@ unsigned SparcInstrInfo::removeBranch(MachineBasicBlock &MBB,
326355 break ; // Not a branch
327356
328357 I->eraseFromParent ();
358+ Removed += getInstSizeInBytes (*I);
329359 I = MBB.end ();
330360 ++Count;
331361 }
362+
363+ if (BytesRemoved)
364+ *BytesRemoved = Removed;
332365 return Count;
333366}
334367
@@ -340,6 +373,37 @@ bool SparcInstrInfo::reverseBranchCondition(
340373 return false ;
341374}
342375
376+ bool SparcInstrInfo::isBranchOffsetInRange (unsigned BranchOpc,
377+ int64_t Offset) const {
378+ assert ((Offset & 0b11 ) == 0 && " Malformed branch offset" );
379+ switch (BranchOpc) {
380+ case SP::BA:
381+ case SP::BCOND:
382+ case SP::BCONDA:
383+ case SP::FBCOND:
384+ case SP::FBCONDA:
385+ return isIntN (22 , Offset >> 2 );
386+
387+ case SP::BPICC:
388+ case SP::BPICCA:
389+ case SP::BPICCNT:
390+ case SP::BPICCANT:
391+ case SP::BPXCC:
392+ case SP::BPXCCA:
393+ case SP::BPXCCNT:
394+ case SP::BPXCCANT:
395+ case SP::BPFCC:
396+ case SP::BPFCCA:
397+ case SP::BPFCCNT:
398+ case SP::BPFCCANT:
399+ case SP::FBCOND_V9:
400+ case SP::FBCONDA_V9:
401+ return isIntN (BPccDisplacementBits, Offset >> 2 );
402+ }
403+
404+ llvm_unreachable (" Unknown branch instruction!" );
405+ }
406+
343407void SparcInstrInfo::copyPhysReg (MachineBasicBlock &MBB,
344408 MachineBasicBlock::iterator I,
345409 const DebugLoc &DL, MCRegister DestReg,
@@ -530,6 +594,23 @@ Register SparcInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
530594 return GlobalBaseReg;
531595}
532596
597+ unsigned SparcInstrInfo::getInstSizeInBytes (const MachineInstr &MI) const {
598+ unsigned Opcode = MI.getOpcode ();
599+
600+ if (MI.isInlineAsm ()) {
601+ const MachineFunction *MF = MI.getParent ()->getParent ();
602+ const char *AsmStr = MI.getOperand (0 ).getSymbolName ();
603+ return getInlineAsmLength (AsmStr, *MF->getTarget ().getMCAsmInfo ());
604+ }
605+
606+ // If the instruction has a delay slot, be conservative and also include
607+ // it for sizing purposes. This is done so that the BranchRelaxation pass
608+ // will not mistakenly mark out-of-range branches as in-range.
609+ if (MI.hasDelaySlot ())
610+ return get (Opcode).getSize () * 2 ;
611+ return get (Opcode).getSize ();
612+ }
613+
533614bool SparcInstrInfo::expandPostRAPseudo (MachineInstr &MI) const {
534615 switch (MI.getOpcode ()) {
535616 case TargetOpcode::LOAD_STACK_GUARD: {
0 commit comments