llvm.org GIT mirror llvm / 1e06bcb
Sparc: No functionality change. Cleanup whitespaces, comment formatting etc., git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@183243 91177308-0d34-0410-b5e6-96231b3b80d8 Venkatraman Govindaraju 6 years ago
19 changed file(s) with 157 addition(s) and 154 deletion(s). Raw diff Collapse all Expand all
4141 const TargetInstrInfo *TII;
4242
4343 static char ID;
44 Filler(TargetMachine &tm)
44 Filler(TargetMachine &tm)
4545 : MachineFunctionPass(ID), TM(tm), TII(tm.getInstrInfo()) { }
4646
4747 virtual const char *getPassName() const {
106106 MachineBasicBlock::iterator MI = I;
107107 ++I;
108108
109 //If MI is restore, try combining it with previous inst.
109 // If MI is restore, try combining it with previous inst.
110110 if (!DisableDelaySlotFiller &&
111111 (MI->getOpcode() == SP::RESTORErr
112112 || MI->getOpcode() == SP::RESTOREri)) {
114114 continue;
115115 }
116116
117 //If MI has no delay slot, skip
117 // If MI has no delay slot, skip.
118118 if (!MI->hasDelaySlot())
119119 continue;
120120
134134 unsigned structSize = 0;
135135 if (needsUnimp(MI, structSize)) {
136136 MachineBasicBlock::iterator J = MI;
137 ++J; //skip the delay filler.
137 ++J; // skip the delay filler.
138138 assert (J != MBB.end() && "MI needs a delay instruction.");
139139 BuildMI(MBB, ++J, I->getDebugLoc(),
140140 TII->get(SP::UNIMP)).addImm(structSize);
164164
165165 if (J->getOpcode() == SP::RESTORErr
166166 || J->getOpcode() == SP::RESTOREri) {
167 //change retl to ret
167 // change retl to ret.
168168 slot->setDesc(TII->get(SP::RET));
169169 return J;
170170 }
171171 }
172172
173 //Call's delay filler can def some of call's uses.
173 // Call's delay filler can def some of call's uses.
174174 if (slot->isCall())
175175 insertCallDefsUses(slot, RegDefs, RegUses);
176176 else
240240 unsigned Reg = MO.getReg();
241241
242242 if (MO.isDef()) {
243 //check whether Reg is defined or used before delay slot.
243 // check whether Reg is defined or used before delay slot.
244244 if (IsRegInSet(RegDefs, Reg) || IsRegInSet(RegUses, Reg))
245245 return true;
246246 }
247247 if (MO.isUse()) {
248 //check whether Reg is defined before delay slot.
248 // check whether Reg is defined before delay slot.
249249 if (IsRegInSet(RegDefs, Reg))
250250 return true;
251251 }
258258 SmallSet& RegDefs,
259259 SmallSet& RegUses)
260260 {
261 //Call defines o7, which is visible to the instruction in delay slot.
261 // Call defines o7, which is visible to the instruction in delay slot.
262262 RegDefs.insert(SP::O7);
263263
264264 switch(MI->getOpcode()) {
282282 }
283283 }
284284
285 //Insert Defs and Uses of MI into the sets RegDefs and RegUses.
285 // Insert Defs and Uses of MI into the sets RegDefs and RegUses.
286286 void Filler::insertDefsUses(MachineBasicBlock::iterator MI,
287287 SmallSet& RegDefs,
288288 SmallSet& RegUses)
298298 if (MO.isDef())
299299 RegDefs.insert(Reg);
300300 if (MO.isUse()) {
301 //Implicit register uses of retl are return values and
302 //retl does not use them.
301 // Implicit register uses of retl are return values and
302 // retl does not use them.
303303 if (MO.isImplicit() && MI->getOpcode() == SP::RETL)
304304 continue;
305305 RegUses.insert(Reg);
307307 }
308308 }
309309
310 //returns true if the Reg or its alias is in the RegSet.
310 // returns true if the Reg or its alias is in the RegSet.
311311 bool Filler::IsRegInSet(SmallSet& RegSet, unsigned Reg)
312312 {
313313 // Check Reg and all aliased Registers.
354354 MachineBasicBlock::iterator AddMI,
355355 const TargetInstrInfo *TII)
356356 {
357 //Before: add , , %i[0-7]
358 // restore %g0, %g0, %i[0-7]
357 // Before: add , , %i[0-7]
358 // restore %g0, %g0, %i[0-7]
359359 //
360 //After : restore , , %o[0-7]
360 // After : restore , , %o[0-7]
361361
362362 unsigned reg = AddMI->getOperand(0).getReg();
363363 if (reg < SP::I0 || reg > SP::I7)
364364 return false;
365365
366 //Erase RESTORE
366 // Erase RESTORE.
367367 RestoreMI->eraseFromParent();
368368
369 //Change ADD to RESTORE
369 // Change ADD to RESTORE.
370370 AddMI->setDesc(TII->get((AddMI->getOpcode() == SP::ADDrr)
371371 ? SP::RESTORErr
372372 : SP::RESTOREri));
373373
374 //map the destination register
374 // Map the destination register.
375375 AddMI->getOperand(0).setReg(reg - SP::I0 + SP::O0);
376376
377377 return true;
381381 MachineBasicBlock::iterator OrMI,
382382 const TargetInstrInfo *TII)
383383 {
384 //Before: or , , %i[0-7]
385 // restore %g0, %g0, %i[0-7]
386 // and or is zero,
384 // Before: or , , %i[0-7]
385 // restore %g0, %g0, %i[0-7]
386 // and or is zero,
387387 //
388 //After : restore , , %o[0-7]
388 // After : restore , , %o[0-7]
389389
390390 unsigned reg = OrMI->getOperand(0).getReg();
391391 if (reg < SP::I0 || reg > SP::I7)
392392 return false;
393393
394 //check whether it is a copy
394 // check whether it is a copy.
395395 if (OrMI->getOpcode() == SP::ORrr
396396 && OrMI->getOperand(1).getReg() != SP::G0
397397 && OrMI->getOperand(2).getReg() != SP::G0)
402402 && (!OrMI->getOperand(2).isImm() || OrMI->getOperand(2).getImm() != 0))
403403 return false;
404404
405 //Erase RESTORE
405 // Erase RESTORE.
406406 RestoreMI->eraseFromParent();
407407
408 //Change OR to RESTORE
408 // Change OR to RESTORE.
409409 OrMI->setDesc(TII->get((OrMI->getOpcode() == SP::ORrr)
410410 ? SP::RESTORErr
411411 : SP::RESTOREri));
412412
413 //map the destination register
413 // Map the destination register.
414414 OrMI->getOperand(0).setReg(reg - SP::I0 + SP::O0);
415415
416416 return true;
420420 MachineBasicBlock::iterator SetHiMI,
421421 const TargetInstrInfo *TII)
422422 {
423 //Before: sethi imm3, %i[0-7]
424 // restore %g0, %g0, %g0
423 // Before: sethi imm3, %i[0-7]
424 // restore %g0, %g0, %g0
425425 //
426 //After : restore %g0, (imm3<<10), %o[0-7]
426 // After : restore %g0, (imm3<<10), %o[0-7]
427427
428428 unsigned reg = SetHiMI->getOperand(0).getReg();
429429 if (reg < SP::I0 || reg > SP::I7)
434434
435435 int64_t imm = SetHiMI->getOperand(1).getImm();
436436
437 //is it a 3 bit immediate?
437 // Is it a 3 bit immediate?
438438 if (!isInt<3>(imm))
439439 return false;
440440
441 //make it a 13 bit immediate
441 // Make it a 13 bit immediate.
442442 imm = (imm << 10) & 0x1FFF;
443443
444444 assert(RestoreMI->getOpcode() == SP::RESTORErr);
450450 RestoreMI->getOperand(2).ChangeToImmediate(imm);
451451
452452
453 //Erase the original SETHI
453 // Erase the original SETHI.
454454 SetHiMI->eraseFromParent();
455455
456456 return true;
459459 bool Filler::tryCombineRestoreWithPrevInst(MachineBasicBlock &MBB,
460460 MachineBasicBlock::iterator MBBI)
461461 {
462 //No previous instruction
462 // No previous instruction.
463463 if (MBBI == MBB.begin())
464464 return false;
465465
466 //asssert that MBBI is "restore %g0, %g0, %g0"
466 // assert that MBBI is a "restore %g0, %g0, %g0".
467467 assert(MBBI->getOpcode() == SP::RESTORErr
468468 && MBBI->getOperand(0).getReg() == SP::G0
469469 && MBBI->getOperand(1).getReg() == SP::G0
471471
472472 MachineBasicBlock::iterator PrevInst = MBBI; --PrevInst;
473473
474 //Cannot combine with a delay filler
474 // It cannot combine with a delay filler.
475475 if (isDelayFiller(MBB, PrevInst))
476476 return false;
477477
483483 case SP::ORri: return combineRestoreOR(MBBI, PrevInst, TII); break;
484484 case SP::SETHIi: return combineRestoreSETHIi(MBBI, PrevInst, TII); break;
485485 }
486 //Cannot combine with the previous instruction
486 // It cannot combine with the previous instruction.
487487 return false;
488488 }
3232 /// layout, etc.
3333 ///
3434 TargetMachine &TM;
35
35
3636 static char ID;
37 explicit FPMover(TargetMachine &tm)
37 explicit FPMover(TargetMachine &tm)
3838 : MachineFunctionPass(ID), TM(tm) { }
3939
4040 virtual const char *getPassName() const {
9696 ++NoopFpDs;
9797 continue;
9898 }
99
99
100100 unsigned EvenSrcReg = 0, OddSrcReg = 0, EvenDestReg = 0, OddDestReg = 0;
101101 getDoubleRegPair(DestDReg, EvenDestReg, OddDestReg);
102102 getDoubleRegPair(SrcDReg, EvenSrcReg, OddSrcReg);
110110 MI->setDesc(TII->get(SP::FABSS));
111111 else
112112 llvm_unreachable("Unknown opcode!");
113
113
114114 MI->getOperand(0).setReg(EvenDestReg);
115115 MI->getOperand(1).setReg(EvenSrcReg);
116116 DEBUG(errs() << "FPMover: the modified instr is: " << *MI);
131131 // emitted. Avoid a scan of the instructions to improve compile time.
132132 if (TM.getSubtarget().isV9())
133133 return false;
134
134
135135 bool Changed = false;
136136 for (MachineFunction::iterator FI = F.begin(), FE = F.end();
137137 FI != FE; ++FI)
2727 type = Library
2828 name = SparcCodeGen
2929 parent = Sparc
30 required_libraries = AsmPrinter CodeGen Core MC SelectionDAG SparcDesc SparcInfo Support Target
30 required_libraries = AsmPrinter CodeGen Core MC SelectionDAG SparcDesc
31 SparcInfo Support Target
3132 add_to_library_groups = Sparc
3737
3838 1) should be replaced with a brz in V9 mode.
3939
40 * Same as above, but emit conditional move on register zero (p192) in V9
40 * Same as above, but emit conditional move on register zero (p192) in V9
4141 mode. Testcase:
4242
4343 int %t1(int %a, int %b) {
4646 ret int %D
4747 }
4848
49 * Emit MULX/[SU]DIVX instructions in V9 mode instead of fiddling
49 * Emit MULX/[SU]DIVX instructions in V9 mode instead of fiddling
5050 with the Y register, if they are faster.
5151
5252 * Codegen bswap(load)/store(bswap) -> load/store ASI
5353
54 * Implement frame pointer elimination, e.g. eliminate save/restore for
54 * Implement frame pointer elimination, e.g. eliminate save/restore for
5555 leaf fns.
5656 * Fill delay slots
5757
5050 ICC_NEG = 6 , // Negative
5151 ICC_VC = 15 , // Overflow Clear
5252 ICC_VS = 7 , // Overflow Set
53
53
5454 //FCC_A = 8+16, // Always
5555 //FCC_N = 0+16, // Never
5656 FCC_U = 7+16, // Unordered
6969 FCC_O = 15+16 // Ordered
7070 };
7171 }
72
72
7373 inline static const char *SPARCCondCodeToString(SPCC::CondCodes CC) {
7474 switch (CC) {
7575 case SPCC::ICC_NE: return "ne";
1818 //===----------------------------------------------------------------------===//
1919 // SPARC Subtarget features.
2020 //
21
21
2222 def FeatureV9
2323 : SubtargetFeature<"v9", "IsV9", "true",
2424 "Enable SPARC-V9 instructions">;
5959 raw_ostream &O);
6060
6161 bool printGetPCX(const MachineInstr *MI, unsigned OpNo, raw_ostream &OS);
62
62
6363 virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB)
6464 const;
6565
166166 case MachineOperand::MO_Register:
167167 assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
168168 "Operand is not a physical register ");
169 assert(MO.getReg() != SP::O7 &&
169 assert(MO.getReg() != SP::O7 &&
170170 "%o7 is assigned as destination for getpcx!");
171171 operand = "%" + StringRef(getRegisterName(MO.getReg())).lower();
172172 break;
179179 O << "\tcall\t.LLGETPC" << mfNum << '_' << bbNum << '\n' ;
180180
181181 O << "\t sethi\t"
182 << "%hi(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << mfNum << '_' << bbNum
182 << "%hi(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << mfNum << '_' << bbNum
183183 << ")), " << operand << '\n' ;
184184
185185 O << ".LLGETPC" << mfNum << '_' << bbNum << ":\n" ;
186 O << "\tor\t" << operand
186 O << "\tor\t" << operand
187187 << ", %lo(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << mfNum << '_' << bbNum
188188 << ")), " << operand << '\n';
189 O << "\tadd\t" << operand << ", %o7, " << operand << '\n';
190
189 O << "\tadd\t" << operand << ", %o7, " << operand << '\n';
190
191191 return true;
192192 }
193193
245245 // then nothing falls through to it.
246246 if (MBB->isLandingPad() || MBB->pred_empty())
247247 return false;
248
248
249249 // If there isn't exactly one predecessor, it can't be a fall through.
250250 MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI;
251251 ++PI2;
252252 if (PI2 != MBB->pred_end())
253253 return false;
254
254
255255 // The predecessor has to be immediately before this block.
256256 const MachineBasicBlock *Pred = *PI;
257
257
258258 if (!Pred->isLayoutSuccessor(MBB))
259259 return false;
260
260
261261 // Check if the last terminator is an unconditional branch.
262262 MachineBasicBlock::const_iterator I = Pred->end();
263263 while (I != Pred->begin() && !(--I)->isTerminator())
275275 }
276276
277277 // Force static initialization.
278 extern "C" void LLVMInitializeSparcAsmPrinter() {
278 extern "C" void LLVMInitializeSparcAsmPrinter() {
279279 RegisterAsmPrinter X(TheSparcTarget);
280280 RegisterAsmPrinter Y(TheSparcV9Target);
281281 }
1515 //===----------------------------------------------------------------------===//
1616
1717 def CC_Sparc32 : CallingConv<[
18 //Custom assign SRet to [sp+64].
18 // Custom assign SRet to [sp+64].
1919 CCIfSRet>,
2020 // i32 f32 arguments get passed in integer registers if there is space.
2121 CCIfType<[i32, f32], CCAssignToReg<[I0, I1, I2, I3, I4, I5]>>,
129129 }
130130
131131 bool SparcFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
132 //Reserve call frame if there are no variable sized objects on the stack
132 // Reserve call frame if there are no variable sized objects on the stack.
133133 return !MF.getFrameInfo()->hasVarSizedObjects();
134134 }
135135
173173
174174 MachineRegisterInfo &MRI = MF.getRegInfo();
175175
176 //remap %i[0-7] to %o[0-7]
176 // Remap %i[0-7] to %o[0-7].
177177 for (unsigned reg = SP::I0; reg <= SP::I7; ++reg) {
178178 if (!MRI.isPhysRegUsed(reg))
179179 continue;
180180 unsigned mapped_reg = (reg - SP::I0 + SP::O0);
181181 assert(!MRI.isPhysRegUsed(mapped_reg));
182182
183 //Replace I register with O register
183 // Replace I register with O register.
184184 MRI.replaceRegWith(reg, mapped_reg);
185185
186 //mark the reg unused.
186 // Mark the reg unused.
187187 MRI.setPhysRegUnused(reg);
188188 }
189189
4343 RegScavenger *RS = NULL) const;
4444
4545 private:
46 //Remap input registers to output registers for leaf procedure.
46 // Remap input registers to output registers for leaf procedure.
4747 void remapRegsForLeafProc(MachineFunction &MF) const;
4848
49 //Returns true if MF is a leaf procedure.
49 // Returns true if MF is a leaf procedure.
5050 bool isLeafProc(MachineFunction &MF) const;
5151 };
5252
3939 {
4040 assert (ArgFlags.isSRet());
4141
42 //Assign SRet argument
42 // Assign SRet argument.
4343 State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
4444 0,
4545 LocVT, LocInfo));
5353 static const uint16_t RegList[] = {
5454 SP::I0, SP::I1, SP::I2, SP::I3, SP::I4, SP::I5
5555 };
56 //Try to get first reg
56 // Try to get first reg.
5757 if (unsigned Reg = State.AllocateReg(RegList, 6)) {
5858 State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
5959 } else {
60 //Assign whole thing in stack
60 // Assign whole thing in stack.
6161 State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
6262 State.AllocateStack(8,4),
6363 LocVT, LocInfo));
6464 return true;
6565 }
6666
67 //Try to get second reg
67 // Try to get second reg.
6868 if (unsigned Reg = State.AllocateReg(RegList, 6))
6969 State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
7070 else
205205 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
206206 }
207207
208 unsigned RetAddrOffset = 8; //Call Inst + Delay Slot
208 unsigned RetAddrOffset = 8; // Call Inst + Delay Slot
209209 // If the function returns a struct, copy the SRetReturnReg to I0
210210 if (MF.getFunction()->hasStructRetAttr()) {
211211 SparcMachineFunctionInfo *SFI = MF.getInfo();
350350 CCValAssign &VA = ArgLocs[i];
351351
352352 if (i == 0 && Ins[i].Flags.isSRet()) {
353 //Get SRet from [%fp+64]
353 // Get SRet from [%fp+64].
354354 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, 64, true);
355355 SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
356356 SDValue Arg = DAG.getLoad(MVT::i32, dl, Chain, FIPtr,
409409
410410 if (VA.needsCustom()) {
411411 assert(VA.getValVT() == MVT::f64);
412 //If it is double-word aligned, just load.
412 // If it is double-word aligned, just load.
413413 if (Offset % 8 == 0) {
414414 int FI = MF.getFrameInfo()->CreateFixedObject(8,
415415 Offset,
469469 }
470470
471471 if (MF.getFunction()->hasStructRetAttr()) {
472 //Copy the SRet Argument to SRetReturnReg
472 // Copy the SRet Argument to SRetReturnReg.
473473 SparcMachineFunctionInfo *SFI = MF.getInfo();
474474 unsigned Reg = SFI->getSRetReturnReg();
475475 if (!Reg) {
679679
680680 MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
681681
682 //Create local copies for byval args.
682 // Create local copies for byval args.
683683 SmallVector ByValArgs;
684684 for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
685685 ISD::ArgFlagsTy Flags = Outs[i].Flags;
695695 SDValue SizeNode = DAG.getConstant(Size, MVT::i32);
696696
697697 Chain = DAG.getMemcpy(Chain, dl, FIPtr, Arg, SizeNode, Align,
698 false, //isVolatile,
699 (Size <= 32), //AlwaysInline if size <= 32
698 false, // isVolatile,
699 (Size <= 32), // AlwaysInline if size <= 32
700700 MachinePointerInfo(), MachinePointerInfo());
701701 ByValArgs.push_back(FIPtr);
702702 }
718718
719719 ISD::ArgFlagsTy Flags = Outs[realArgIdx].Flags;
720720
721 //Use local copy if it is a byval arg.
721 // Use local copy if it is a byval arg.
722722 if (Flags.isByVal())
723723 Arg = ByValArgs[byvalArgIdx++];
724724
758758
759759 if (VA.isMemLoc()) {
760760 unsigned Offset = VA.getLocMemOffset() + StackOffset;
761 //if it is double-word aligned, just store.
761 // if it is double-word aligned, just store.
762762 if (Offset % 8 == 0) {
763763 SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
764764 SDValue PtrOff = DAG.getIntPtrConstant(Offset);
791791 if (NextVA.isRegLoc()) {
792792 RegsToPass.push_back(std::make_pair(NextVA.getLocReg(), Lo));
793793 } else {
794 //Store the low part in stack.
794 // Store the low part in stack.
795795 unsigned Offset = NextVA.getLocMemOffset() + StackOffset;
796796 SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
797797 SDValue PtrOff = DAG.getIntPtrConstant(Offset);
13971397 /// isMaskedValueZeroForTargetNode - Return true if 'Op & Mask' is known to
13981398 /// be zero. Op is expected to be a target specific node. Used by DAG
13991399 /// combiner.
1400 void SparcTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op,
1401 APInt &KnownZero,
1402 APInt &KnownOne,
1403 const SelectionDAG &DAG,
1404 unsigned Depth) const {
1400 void SparcTargetLowering::computeMaskedBitsForTargetNode
1401 (const SDValue Op,
1402 APInt &KnownZero,
1403 APInt &KnownOne,
1404 const SelectionDAG &DAG,
1405 unsigned Depth) const {
14051406 APInt KnownZero2, KnownOne2;
14061407 KnownZero = KnownOne = APInt(KnownZero.getBitWidth(), 0);
14071408
16241625 MachineFunction &MF = DAG.getMachineFunction();
16251626 SparcMachineFunctionInfo *FuncInfo = MF.getInfo();
16261627
1627 //Need frame address to find the address of VarArgsFrameIndex
1628 // Need frame address to find the address of VarArgsFrameIndex.
16281629 MF.getFrameInfo()->setFrameAddressIsTaken(true);
16291630
16301631 // vastart just stores the address of the VarArgsFrameIndex slot into the
17331734 if (depth == 0)
17341735 RetAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, RetReg, VT);
17351736 else {
1736 //Need frame address to find return address of the caller
1737 // Need frame address to find return address of the caller.
17371738 MFI->setFrameAddressIsTaken(true);
17381739
17391740 // flush first to make sure the windowed registers' values are in stack
66 //
77 //===----------------------------------------------------------------------===//
88
9 class InstSP pattern> : Instruction {
9 class InstSP pattern>
10 : Instruction {
1011 field bits<32> Inst;
1112
1213 let Namespace = "SP";
1314
1415 bits<2> op;
1516 let Inst{31-30} = op; // Top two bits are the 'op' field
16
17
1718 dag OutOperandList = outs;
1819 dag InOperandList = ins;
1920 let AsmString = asmstr;
4546 let Inst{29-25} = rd;
4647 }
4748
48 class F2_2 condVal, bits<3> op2Val, dag outs, dag ins, string asmstr,
49 class F2_2 condVal, bits<3> op2Val, dag outs, dag ins, string asmstr,
4950 list pattern> : F2 {
5051 bits<4> cond;
5152 bit annul = 0; // currently unused
8788 let Inst{4-0} = rs2;
8889 }
8990
90 class F3_2 opVal, bits<6> op3val, dag outs, dag ins,
91 class F3_2 opVal, bits<6> op3val, dag outs, dag ins,
9192 string asmstr, list pattern> : F3 {
9293 bits<13> simm13;
9394
140140 if (I->isDebugValue())
141141 continue;
142142
143 //When we see a non-terminator, we are done
143 // When we see a non-terminator, we are done.
144144 if (!isUnpredicatedTerminator(I))
145145 break;
146146
147 //Terminator is not a branch
147 // Terminator is not a branch.
148148 if (!I->isBranch())
149149 return true;
150150
151 //Handle Unconditional branches
151 // Handle Unconditional branches.
152152 if (I->getOpcode() == SP::BA) {
153153 UnCondBrIter = I;
154154
177177
178178 unsigned Opcode = I->getOpcode();
179179 if (Opcode != SP::BCOND && Opcode != SP::FBCOND)
180 return true; //Unknown Opcode
180 return true; // Unknown Opcode.
181181
182182 SPCC::CondCodes BranchCode = (SPCC::CondCodes)I->getOperand(1).getImm();
183183
186186 if (AllowModify && UnCondBrIter != MBB.end() &&
187187 MBB.isLayoutSuccessor(TargetBB)) {
188188
189 //Transform the code
189 // Transform the code
190190 //
191191 // brCC L1
192192 // ba L2
220220 Cond.push_back(MachineOperand::CreateImm(BranchCode));
221221 continue;
222222 }
223 //FIXME: Handle subsequent conditional branches
224 //For now, we can't handle multiple conditional branches
223 // FIXME: Handle subsequent conditional branches.
224 // For now, we can't handle multiple conditional branches.
225225 return true;
226226 }
227227 return false;
242242 return 1;
243243 }
244244
245 //Conditional branch
245 // Conditional branch
246246 unsigned CC = Cond[0].getImm();
247247
248248 if (IsIntegerCC(CC))
5252 /// any side effects other than loading from the stack slot.
5353 virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
5454 int &FrameIndex) const;
55
55
5656 /// isStoreToStackSlot - If the specified machine instruction is a direct
5757 /// store to a stack slot, return the virtual or physical register number of
5858 /// the source reg along with the FrameIndex of the loaded stack slot. If
8585 MachineBasicBlock::iterator I, DebugLoc DL,
8686 unsigned DestReg, unsigned SrcReg,
8787 bool KillSrc) const;
88
88
8989 virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
9090 MachineBasicBlock::iterator MBBI,
9191 unsigned SrcReg, bool isKill, int FrameIndex,
9797 unsigned DestReg, int FrameIndex,
9898 const TargetRegisterClass *RC,
9999 const TargetRegisterInfo *TRI) const;
100
100
101101 unsigned getGlobalBaseReg(MachineFunction *MF) const;
102102 };
103103
8888 let PrintMethod = "printCCOperand" in
8989 def CCOp : Operand;
9090
91 def SDTSPcmpfcc :
91 def SDTSPcmpfcc :
9292 SDTypeProfile<0, 2, [SDTCisFP<0>, SDTCisSameAs<0, 1>]>;
93 def SDTSPbrcc :
93 def SDTSPbrcc :
9494 SDTypeProfile<0, 2, [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>;
9595 def SDTSPselectcc :
9696 SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisVT<3, i32>]>;
185185
186186 /// F3_12 multiclass - Define a normal F3_1/F3_2 pattern in one shot.
187187 multiclass F3_12 Op3Val, SDNode OpNode> {
188 def rr : F3_1<2, Op3Val,
188 def rr : F3_1<2, Op3Val,
189189 (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
190190 !strconcat(OpcStr, " $b, $c, $dst"),
191191 [(set i32:$dst, (OpNode i32:$b, i32:$c))]>;
198198 /// F3_12np multiclass - Define a normal F3_1/F3_2 pattern in one shot, with no
199199 /// pattern.
200200 multiclass F3_12np Op3Val> {
201 def rr : F3_1<2, Op3Val,
201 def rr : F3_1<2, Op3Val,
202202 (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
203203 !strconcat(OpcStr, " $b, $c, $dst"), []>;
204204 def ri : F3_2<2, Op3Val,
242242 def UNIMP : F2_1<0b000, (outs), (ins i32imm:$val),
243243 "unimp $val", []>;
244244
245 // FpMOVD/FpNEGD/FpABSD - These are lowered to single-precision ops by the
245 // FpMOVD/FpNEGD/FpABSD - These are lowered to single-precision ops by the
246246 // fpmover pass.
247247 let Predicates = [HasNoV9] in { // Only emit these in V8 mode.
248248 def FpMOVD : Pseudo<(outs DFPRegs:$dst), (ins DFPRegs:$src),
258258 // SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded after
259259 // instruction selection into a branch sequence. This has to handle all
260260 // permutations of selection between i32/f32/f64 on ICC and FCC.
261 // Expanded after instruction selection.
262 let Uses = [ICC], usesCustomInserter = 1 in {
261 // Expanded after instruction selection.
262 let Uses = [ICC], usesCustomInserter = 1 in {
263263 def SELECT_CC_Int_ICC
264264 : Pseudo<(outs IntRegs:$dst), (ins IntRegs:$T, IntRegs:$F, i32imm:$Cond),
265265 "; SELECT_CC_Int_ICC PSEUDO!",
464464 "add ${addr:arith}, $dst",
465465 [(set iPTR:$dst, ADDRri:$addr)]>;
466466
467 let Defs = [ICC] in
467 let Defs = [ICC] in
468468 defm ADDCC : F3_12<"addcc", 0b010000, addc>;
469469
470470 let Uses = [ICC] in
472472
473473 // Section B.15 - Subtract Instructions, p. 110
474474 defm SUB : F3_12 <"sub" , 0b000100, sub>;
475 let Uses = [ICC] in
475 let Uses = [ICC] in
476476 defm SUBX : F3_12 <"subx" , 0b001100, sube>;
477477
478 let Defs = [ICC] in
478 let Defs = [ICC] in
479479 defm SUBCC : F3_12 <"subcc", 0b010100, SPcmpicc>;
480480
481481 let Uses = [ICC], Defs = [ICC] in
482 def SUBXCCrr: F3_1<2, 0b011100,
482 def SUBXCCrr: F3_1<2, 0b011100,
483483 (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
484484 "subxcc $b, $c, $dst", []>;
485485
515515 "ba $dst",
516516 [(br bb:$dst)]>;
517517
518 //Indirect Branch
518 // Indirect branch instructions.
519519 let isTerminator = 1, isBarrier = 1,
520520 hasDelaySlot = 1, isBranch =1,
521521 isIndirectBranch = 1 in {
566566 let op = 1;
567567 let Inst{29-0} = disp;
568568 }
569
569
570570 // indirect calls
571571 def JMPLrr : F3_1<2, 0b111000,
572572 (outs), (ins MEMrr:$ptr, variable_ops),
579579 }
580580
581581 // Section B.28 - Read State Register Instructions
582 let Uses = [Y] in
582 let Uses = [Y] in
583583 def RDY : F3_1<2, 0b101000,
584584 (outs IntRegs:$dst), (ins),
585585 "rd %y, $dst", []>;
598598 (outs FPRegs:$dst), (ins FPRegs:$src),
599599 "fitos $src, $dst",
600600 [(set FPRegs:$dst, (SPitof FPRegs:$src))]>;
601 def FITOD : F3_3<2, 0b110100, 0b011001000,
601 def FITOD : F3_3<2, 0b110100, 0b011001000,
602602 (outs DFPRegs:$dst), (ins FPRegs:$src),
603603 "fitod $src, $dst",
604604 [(set DFPRegs:$dst, (SPitof FPRegs:$src))]>;
614614 [(set FPRegs:$dst, (SPftoi DFPRegs:$src))]>;
615615
616616 // Convert between Floating-point Formats Instructions, p. 143
617 def FSTOD : F3_3<2, 0b110100, 0b011001001,
617 def FSTOD : F3_3<2, 0b110100, 0b011001001,
618618 (outs DFPRegs:$dst), (ins FPRegs:$src),
619619 "fstod $src, $dst",
620620 [(set f64:$dst, (fextend f32:$src))]>;
627627 def FMOVS : F3_3<2, 0b110100, 0b000000001,
628628 (outs FPRegs:$dst), (ins FPRegs:$src),
629629 "fmovs $src, $dst", []>;
630 def FNEGS : F3_3<2, 0b110100, 0b000000101,
630 def FNEGS : F3_3<2, 0b110100, 0b000000101,
631631 (outs FPRegs:$dst), (ins FPRegs:$src),
632632 "fnegs $src, $dst",
633633 [(set f32:$dst, (fneg f32:$src))]>;
634 def FABSS : F3_3<2, 0b110100, 0b000001001,
634 def FABSS : F3_3<2, 0b110100, 0b000001001,
635635 (outs FPRegs:$dst), (ins FPRegs:$src),
636636 "fabss $src, $dst",
637637 [(set f32:$dst, (fabs f32:$src))]>;
638638
639639
640640 // Floating-point Square Root Instructions, p.145
641 def FSQRTS : F3_3<2, 0b110100, 0b000101001,
641 def FSQRTS : F3_3<2, 0b110100, 0b000101001,
642642 (outs FPRegs:$dst), (ins FPRegs:$src),
643643 "fsqrts $src, $dst",
644644 [(set f32:$dst, (fsqrt f32:$src))]>;
645 def FSQRTD : F3_3<2, 0b110100, 0b000101010,
645 def FSQRTD : F3_3<2, 0b110100, 0b000101010,
646646 (outs DFPRegs:$dst), (ins DFPRegs:$src),
647647 "fsqrtd $src, $dst",
648648 [(set f64:$dst, (fsqrt f64:$src))]>;
765765 def FMOVD : F3_3<2, 0b110100, 0b000000010,
766766 (outs DFPRegs:$dst), (ins DFPRegs:$src),
767767 "fmovd $src, $dst", []>;
768 def FNEGD : F3_3<2, 0b110100, 0b000000110,
768 def FNEGD : F3_3<2, 0b110100, 0b000000110,
769769 (outs DFPRegs:$dst), (ins DFPRegs:$src),
770770 "fnegd $src, $dst",
771771 [(set f64:$dst, (fneg f64:$src))]>;
772 def FABSD : F3_3<2, 0b110100, 0b000001010,
772 def FABSD : F3_3<2, 0b110100, 0b000001010,
773773 (outs DFPRegs:$dst), (ins DFPRegs:$src),
774774 "fabsd $src, $dst",
775775 [(set f64:$dst, (fabs f64:$src))]>;
777777
778778 // POPCrr - This does a ctpop of a 64-bit register. As such, we have to clear
779779 // the top 32-bits before using it. To do this clearing, we use a SLLri X,0.
780 def POPCrr : F3_1<2, 0b101110,
780 def POPCrr : F3_1<2, 0b101110,
781781 (outs IntRegs:$dst), (ins IntRegs:$src),
782782 "popc $src, $dst", []>, Requires<[HasV9]>;
783783 def : Pat<(ctpop i32:$src),
816816 def : Pat<(add iPTR:$r, (SPlo tblockaddress:$in)),
817817 (ADDri $r, tblockaddress:$in)>;
818818
819 // Calls:
819 // Calls:
820820 def : Pat<(call tglobaladdr:$dst),
821821 (CALL tglobaladdr:$dst)>;
822822 def : Pat<(call texternalsym:$dst),
4949 // FIXME: G1 reserved for now for large imm generation by frame code.
5050 Reserved.set(SP::G1);
5151
52 //G1-G4 can be used in applications.
52 // G1-G4 can be used in applications.
5353 if (ReserveAppRegisters) {
5454 Reserved.set(SP::G2);
5555 Reserved.set(SP::G3);
5656 Reserved.set(SP::G4);
5757 }
58 //G5 is not reserved in 64 bit mode.
58 // G5 is not reserved in 64 bit mode.
5959 if (!Subtarget.is64Bit())
6060 Reserved.set(SP::G5);
6161
9292 SparcMachineFunctionInfo *FuncInfo = MF.getInfo();
9393 unsigned FramePtr = SP::I6;
9494 if (FuncInfo->isLeafProc()) {
95 //Use %sp and adjust offset if needed.
95 // Use %sp and adjust offset if needed.
9696 FramePtr = SP::O6;
9797 int stackSize = MF.getFrameInfo()->getStackSize();
9898 Offset += (stackSize) ? Subtarget.getAdjustedFrameSize(stackSize) : 0 ;
105105 MI.getOperand(FIOperandNum).ChangeToRegister(FramePtr, false);
106106 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
107107 } else {
108 // Otherwise, emit a G1 = SETHI %hi(offset). FIXME: it would be better to
108 // Otherwise, emit a G1 = SETHI %hi(offset). FIXME: it would be better to
109109 // scavenge a register here instead of reserving G1 all of the time.
110110 unsigned OffHi = (unsigned)Offset >> 10U;
111111 BuildMI(*MI.getParent(), II, dl, TII.get(SP::SETHIi), SP::G1).addImm(OffHi);
77 //===----------------------------------------------------------------------===//
88
99 //===----------------------------------------------------------------------===//
10 // Declarations that describe the Sparc register file
10 // Declarations that describe the Sparc register file
1111 //===----------------------------------------------------------------------===//
1212
1313 class SparcReg : Register {
5151 // Integer registers
5252 def G0 : Ri< 0, "G0">, DwarfRegNum<[0]>;
5353 def G1 : Ri< 1, "G1">, DwarfRegNum<[1]>;
54 def G2 : Ri< 2, "G2">, DwarfRegNum<[2]>;
54 def G2 : Ri< 2, "G2">, DwarfRegNum<[2]>;
5555 def G3 : Ri< 3, "G3">, DwarfRegNum<[3]>;
5656 def G4 : Ri< 4, "G4">, DwarfRegNum<[4]>;
57 def G5 : Ri< 5, "G5">, DwarfRegNum<[5]>;
57 def G5 : Ri< 5, "G5">, DwarfRegNum<[5]>;
5858 def G6 : Ri< 6, "G6">, DwarfRegNum<[6]>;
5959 def G7 : Ri< 7, "G7">, DwarfRegNum<[7]>;
6060 def O0 : Ri< 8, "O0">, DwarfRegNum<[8]>;
6161 def O1 : Ri< 9, "O1">, DwarfRegNum<[9]>;
62 def O2 : Ri<10, "O2">, DwarfRegNum<[10]>;
62 def O2 : Ri<10, "O2">, DwarfRegNum<[10]>;
6363 def O3 : Ri<11, "O3">, DwarfRegNum<[11]>;
6464 def O4 : Ri<12, "O4">, DwarfRegNum<[12]>;
65 def O5 : Ri<13, "O5">, DwarfRegNum<[13]>;
65 def O5 : Ri<13, "O5">, DwarfRegNum<[13]>;
6666 def O6 : Ri<14, "SP">, DwarfRegNum<[14]>;
6767 def O7 : Ri<15, "O7">, DwarfRegNum<[15]>;
6868 def L0 : Ri<16, "L0">, DwarfRegNum<[16]>;
6969 def L1 : Ri<17, "L1">, DwarfRegNum<[17]>;
70 def L2 : Ri<18, "L2">, DwarfRegNum<[18]>;
70 def L2 : Ri<18, "L2">, DwarfRegNum<[18]>;
7171 def L3 : Ri<19, "L3">, DwarfRegNum<[19]>;
7272 def L4 : Ri<20, "L4">, DwarfRegNum<[20]>;
73 def L5 : Ri<21, "L5">, DwarfRegNum<[21]>;
73 def L5 : Ri<21, "L5">, DwarfRegNum<[21]>;
7474 def L6 : Ri<22, "L6">, DwarfRegNum<[22]>;
7575 def L7 : Ri<23, "L7">, DwarfRegNum<[23]>;
7676 def I0 : Ri<24, "I0">, DwarfRegNum<[24]>;
7777 def I1 : Ri<25, "I1">, DwarfRegNum<[25]>;
78 def I2 : Ri<26, "I2">, DwarfRegNum<[26]>;
78 def I2 : Ri<26, "I2">, DwarfRegNum<[26]>;
7979 def I3 : Ri<27, "I3">, DwarfRegNum<[27]>;
8080 def I4 : Ri<28, "I4">, DwarfRegNum<[28]>;
81 def I5 : Ri<29, "I5">, DwarfRegNum<[29]>;
81 def I5 : Ri<29, "I5">, DwarfRegNum<[29]>;
8282 def I6 : Ri<30, "FP">, DwarfRegNum<[30]>;
8383 def I7 : Ri<31, "I7">, DwarfRegNum<[31]>;
8484
8585 // Floating-point registers
8686 def F0 : Rf< 0, "F0">, DwarfRegNum<[32]>;
8787 def F1 : Rf< 1, "F1">, DwarfRegNum<[33]>;
88 def F2 : Rf< 2, "F2">, DwarfRegNum<[34]>;
88 def F2 : Rf< 2, "F2">, DwarfRegNum<[34]>;
8989 def F3 : Rf< 3, "F3">, DwarfRegNum<[35]>;
9090 def F4 : Rf< 4, "F4">, DwarfRegNum<[36]>;
91 def F5 : Rf< 5, "F5">, DwarfRegNum<[37]>;
91 def F5 : Rf< 5, "F5">, DwarfRegNum<[37]>;
9292 def F6 : Rf< 6, "F6">, DwarfRegNum<[38]>;
9393 def F7 : Rf< 7, "F7">, DwarfRegNum<[39]>;
94 def F8 : Rf< 8, "F8">, DwarfRegNum<[40]>;
94 def F8 : Rf< 8, "F8">, DwarfRegNum<[40]>;
9595 def F9 : Rf< 9, "F9">, DwarfRegNum<[41]>;
9696 def F10 : Rf<10, "F10">, DwarfRegNum<[42]>;
97 def F11 : Rf<11, "F11">, DwarfRegNum<[43]>;
97 def F11 : Rf<11, "F11">, DwarfRegNum<[43]>;
9898 def F12 : Rf<12, "F12">, DwarfRegNum<[44]>;
9999 def F13 : Rf<13, "F13">, DwarfRegNum<[45]>;
100 def F14 : Rf<14, "F14">, DwarfRegNum<[46]>;
100 def F14 : Rf<14, "F14">, DwarfRegNum<[46]>;
101101 def F15 : Rf<15, "F15">, DwarfRegNum<[47]>;
102102 def F16 : Rf<16, "F16">, DwarfRegNum<[48]>;
103 def F17 : Rf<17, "F17">, DwarfRegNum<[49]>;
103 def F17 : Rf<17, "F17">, DwarfRegNum<[49]>;
104104 def F18 : Rf<18, "F18">, DwarfRegNum<[50]>;
105105 def F19 : Rf<19, "F19">, DwarfRegNum<[51]>;
106 def F20 : Rf<20, "F20">, DwarfRegNum<[52]>;
106 def F20 : Rf<20, "F20">, DwarfRegNum<[52]>;
107107 def F21 : Rf<21, "F21">, DwarfRegNum<[53]>;
108108 def F22 : Rf<22, "F22">, DwarfRegNum<[54]>;
109109 def F23 : Rf<23, "F23">, DwarfRegNum<[55]>;
110110 def F24 : Rf<24, "F24">, DwarfRegNum<[56]>;
111111 def F25 : Rf<25, "F25">, DwarfRegNum<[57]>;
112 def F26 : Rf<26, "F26">, DwarfRegNum<[58]>;
112 def F26 : Rf<26, "F26">, DwarfRegNum<[58]>;
113113 def F27 : Rf<27, "F27">, DwarfRegNum<[59]>;
114114 def F28 : Rf<28, "F28">, DwarfRegNum<[60]>;
115 def F29 : Rf<29, "F29">, DwarfRegNum<[61]>;
115 def F29 : Rf<29, "F29">, DwarfRegNum<[61]>;
116116 def F30 : Rf<30, "F30">, DwarfRegNum<[62]>;
117117 def F31 : Rf<31, "F31">, DwarfRegNum<[63]>;
118118
3030 V8DeprecatedInsts(false),
3131 IsVIS(false),
3232 Is64Bit(is64Bit) {
33
33
3434 // Determine default and user specified characteristics
3535 std::string CPUName = CPU;
3636 if (CPUName.empty()) {
2828 bool V8DeprecatedInsts;
2929 bool IsVIS;
3030 bool Is64Bit;
31
31
3232 public:
3333 SparcSubtarget(const std::string &TT, const std::string &CPU,
3434 const std::string &FS, bool is64bit);
3636 bool isV9() const { return IsV9; }
3737 bool isVIS() const { return IsVIS; }
3838 bool useDeprecatedV8Instructions() const { return V8DeprecatedInsts; }
39
40 /// ParseSubtargetFeatures - Parses features string setting specified
39
40 /// ParseSubtargetFeatures - Parses features string setting specified
4141 /// subtarget options. Definition of function is auto generated by tblgen.
4242 void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
43
43
4444 bool is64Bit() const { return Is64Bit; }
4545 std::string getDataLayout() const {
4646 const char *p;