llvm.org GIT mirror llvm / 5ae73c3
Backporting r325653: ------------------------------------------------------------------------ r325653 | sdardis | 2018-02-21 00:06:53 +0000 (Wed, 21 Feb 2018) | 31 lines [mips] Spectre variant two mitigation for MIPSR2 This patch provides mitigation for CVE-2017-5715, Spectre variant two, which affects the P5600 and P6600. It implements the LLVM part of -mindirect-jump=hazard. It is _not_ enabled by default for the P5600. The migitation strategy suggested by MIPS for these processors is to use hazard barrier instructions. 'jalr.hb' and 'jr.hb' are hazard barrier variants of the 'jalr' and 'jr' instructions respectively. These instructions impede the execution of instruction stream until architecturally defined hazards (changes to the instruction stream, privileged registers which may affect execution) are cleared. These instructions in MIPS' designs are not speculated past. These instructions are used with the attribute +use-indirect-jump-hazard when branching indirectly and for indirect function calls. These instructions are defined by the MIPS32R2 ISA, so this mitigation method is not compatible with processors which implement an earlier revision of the MIPS ISA. Performance benchmarking of this option with -fpic and lld using -z hazardplt shows a difference of overall 10%~ time increase for the LLVM testsuite. Certain benchmarks such as methcall show a substantially larger increase in time due to their nature. Reviewers: atanasyan, zoran.jovanovic Differential Revision: https://reviews.llvm.org/D43486 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_50@327751 91177308-0d34-0410-b5e6-96231b3b80d8 Simon Dardis 1 year, 5 months ago
25 changed file(s) with 1476 addition(s) and 42 deletion(s). Raw diff Collapse all Expand all
51325132 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
51335133 // and registers Rd and Base for microMIPS lwp instruction
51345134 case Mips::JALR_HB:
5135 case Mips::JALR_HB64:
51355136 case Mips::JALRC_HB_MMR6:
51365137 case Mips::JALRC_MMR6:
51375138 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
18771877 def : StoreRegImmPat, FGR_64, ISA_MICROMIPS32R6;
18781878 }
18791879
1880 def TAILCALL_MMR6 : TailCall, ISA_MICROMIPS32R6;
1880 def TAILCALL_MMR6 : TailCall, ISA_MICROMIPS64R6;
1881
1882 def TAILCALLREG_MMR6 : TailCallReg, ISA_MICROMIPS32R6;
1883
1884 def PseudoIndirectBranch_MMR6 : PseudoIndirectBranchBase
1885 GPR32Opnd>,
1886 ISA_MICROMIPS32R6;
1887
1888 def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
1889 (TAILCALL_MMR6 tglobaladdr:$dst)>, ISA_MICROMIPS32R6;
1890
1891 def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
1892 (TAILCALL_MMR6 texternalsym:$dst)>, ISA_MICROMIPS32R6;
351351 bit IsPCRelativeLoad = 1;
352352 }
353353
354 class JRC16_64_MMR6_DESC : JRC16_MMR6_DESC_BASE<"jrc16", GPR64Opnd>;
355
354356 //===----------------------------------------------------------------------===//
355357 //
356358 // Instruction Definitions
464466 def LWUPC_MM64R6 : R6MMR6Rel, LWUPC_MM64R6_ENC, LWUPC_MM64R6_DESC,
465467 ISA_MICROMIPS64R6;
466468 }
469 let DecoderNamespace = "MicroMips64r6" in
470 def JRC16_64_MMR6 : R6MMR6Rel, JRC16_64_MMR6_DESC, JRC16_MMR6_ENC,
471 ISA_MICROMIPS64R6;
467472
468473 let AdditionalPredicates = [InMicroMips] in
469474 defm : MaterializeImms;
503508 (DSUBU_MM64R6 GPR64:$lhs, GPR64:$rhs)>, ISA_MICROMIPS64R6;
504509
505510 def : MipsPat<(atomic_load_64 addr:$a), (LD_MM64R6 addr:$a)>, ISA_MICROMIPS64R6;
511
512 def TAILCALLREG64_MMR6 : TailCallReg,
513 ISA_MICROMIPS64R6;
506514
507515 //===----------------------------------------------------------------------===//
508516 //
991991 }
992992
993993 def TAILCALL_MM : TailCall, ISA_MIPS1_NOT_32R6_64R6;
994
995 def TAILCALLREG_MM : TailCallReg,
996 ISA_MICROMIPS32_NOT_MIPS32R6;
997
998 def PseudoIndirectBranch_MM : PseudoIndirectBranchBase,
999 ISA_MICROMIPS32_NOT_MIPS32R6;
9941000
9951001 let DecoderNamespace = "MicroMips" in {
9961002 def RDHWR_MM : MMRel, R6MMR6Rel, ReadHardware,
192192 def FeatureLongCalls : SubtargetFeature<"long-calls", "UseLongCalls", "true",
193193 "Disable use of the jal instruction">;
194194
195 def FeatureUseIndirectJumpsHazard : SubtargetFeature<"use-indirect-jump-hazard",
196 "UseIndirectJumpsHazard",
197 "true", "Use indirect jump"
198 " guards to prevent certain speculation based attacks">;
195199 //===----------------------------------------------------------------------===//
196200 // Mips processors supported.
197201 //===----------------------------------------------------------------------===//
10071007 (SELEQZ i32:$f, i32:$cond)>,
10081008 ISA_MIPS32R6;
10091009 }
1010
1011 // Pseudo instructions
1012 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
1013 hasExtraSrcRegAllocReq = 1, isCTI = 1, Defs = [AT] in {
1014 class TailCallRegR6 :
1015 PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>,
1016 PseudoInstExpansion<(JumpInst RT:$rt, RO:$rs)>;
1017 }
1018
1019 class PseudoIndirectBranchBaseR6
1020 RegisterOperand RO> :
1021 MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)],
1022 II_IndirectBranchPseudo>,
1023 PseudoInstExpansion<(JumpInst RT:$rt, RO:$rs)> {
1024 let isTerminator=1;
1025 let isBarrier=1;
1026 let hasDelaySlot = 1;
1027 let isBranch = 1;
1028 let isIndirectBranch = 1;
1029 bit isCTI = 1;
1030 }
1031
1032
1033 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
1034 NoIndirectJumpGuards] in {
1035 def TAILCALLR6REG : TailCallRegR6, ISA_MIPS32R6;
1036 def PseudoIndirectBranchR6 : PseudoIndirectBranchBaseR6
1037 GPR32Opnd>,
1038 ISA_MIPS32R6;
1039 }
1040
1041 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
1042 UseIndirectJumpsHazard] in {
1043 def TAILCALLHBR6REG : TailCallReg, ISA_MIPS32R6;
1044 def PseudoIndrectHazardBranchR6 : PseudoIndirectBranchBase
1045 GPR32Opnd>,
1046 ISA_MIPS32R6;
1047 }
1048
235235 def BGTZ64 : CBranchZero<"bgtz", brtarget, setgt, GPR64Opnd>, BGEZ_FM<7, 0>;
236236 def BLEZ64 : CBranchZero<"blez", brtarget, setle, GPR64Opnd>, BGEZ_FM<6, 0>;
237237 def BLTZ64 : CBranchZero<"bltz", brtarget, setlt, GPR64Opnd>, BGEZ_FM<1, 0>;
238 def JALR64Pseudo : JumpLinkRegPseudo;
239 }
240
241 def TAILCALLREG64 : TailCallReg;
242
238 let AdditionalPredicates = [NoIndirectJumpGuards] in
239 def JALR64Pseudo : JumpLinkRegPseudo;
240 }
241 let AdditionalPredicates = [NotInMicroMips],
242 DecoderNamespace = "Mips64" in {
243 def JR_HB64 : JR_HB_DESC, JR_HB_ENC, ISA_MIPS32_NOT_32R6_64R6;
244 def JALR_HB64 : JALR_HB_DESC, JALR_HB_ENC, ISA_MIPS32R2;
245 }
243246 def PseudoReturn64 : PseudoReturnBase;
244 def PseudoIndirectBranch64 : PseudoIndirectBranchBase;
247
248 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
249 NoIndirectJumpGuards] in {
250 def TAILCALLREG64 : TailCallReg, ISA_MIPS3_NOT_32R6_64R6,
251 PTR_64;
252 def PseudoIndirectBranch64 : PseudoIndirectBranchBase,
253 ISA_MIPS3_NOT_32R6_64R6;
254 }
255
256 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
257 UseIndirectJumpsHazard] in {
258 def TAILCALLREGHB64 : TailCallReg,
259 ISA_MIPS32R2_NOT_32R6_64R6, PTR_64;
260 def PseudoIndirectHazardBranch64 : PseudoIndirectBranchBase
261 GPR64Opnd>,
262 ISA_MIPS32R2_NOT_32R6_64R6;
263 }
245264
246265 /// Multiply and Divide Instructions.
247266 let AdditionalPredicates = [NotInMicroMips] in {
513532 def DMTC2 : MTC3OP<"dmtc2", COP2Opnd, GPR64Opnd, II_DMTC2>, MFC3OP_FM<0x12, 5>,
514533 ISA_MIPS3;
515534 }
535
536
537 let AdditionalPredicates = [UseIndirectJumpsHazard] in
538 def JALRHB64Pseudo : JumpLinkRegPseudo;
516539
517540 //===----------------------------------------------------------------------===//
518541 // Arbitrary patterns that map to one or more instructions
802825 (DSLLV GPR64Opnd:$rd, GPR64Opnd:$rd, GPR32Opnd:$rt), 0>,
803826 ISA_MIPS3;
804827
828 def : MipsInstAlias<"jalr.hb $rs", (JALR_HB64 RA_64, GPR64Opnd:$rs), 1>,
829 ISA_MIPS64;
805830 // Two operand (implicit 0 selector) versions:
806831 def : MipsInstAlias<"dmtc0 $rt, $rd",
807832 (DMTC0 COP0Opnd:$rd, GPR64Opnd:$rt, 0), 0>;
103103
104104 class LL64_R6_DESC : LL_R6_DESC_BASE<"ll", GPR32Opnd, mem_simm9, II_LL>;
105105 class SC64_R6_DESC : SC_R6_DESC_BASE<"sc", GPR32Opnd, II_SC>;
106
107 class JR_HB64_R6_DESC : JR_HB_DESC_BASE<"jr.hb", GPR64Opnd> {
108 bit isBranch = 1;
109 bit isIndirectBranch = 1;
110 bit hasDelaySlot = 1;
111 bit isTerminator=1;
112 bit isBarrier=1;
113 bit isCTI = 1;
114 InstrItinClass Itinerary = II_JR_HB;
115 }
106116 //===----------------------------------------------------------------------===//
107117 //
108118 // Instruction Definitions
135145 let DecoderNamespace = "Mips32r6_64r6_GP64" in {
136146 def SELEQZ64 : SELEQZ_ENC, SELEQZ64_DESC, ISA_MIPS32R6, GPR_64;
137147 def SELNEZ64 : SELNEZ_ENC, SELNEZ64_DESC, ISA_MIPS32R6, GPR_64;
148 def JR_HB64_R6 : JR_HB_R6_ENC, JR_HB64_R6_DESC, ISA_MIPS32R6;
138149 }
139150 let AdditionalPredicates = [NotInMicroMips],
140151 DecoderNamespace = "Mips32r6_64r6_PTR64" in {
276287 def : MipsPat<(select (i32 (seteq i32:$cond, immz)), immz, i64:$f),
277288 (SELNEZ64 i64:$f, (SLL64_32 i32:$cond))>,
278289 ISA_MIPS64R6;
290
291 // Pseudo instructions
292
293 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
294 NoIndirectJumpGuards] in {
295 def TAILCALL64R6REG : TailCallRegR6, ISA_MIPS64R6;
296 def PseudoIndirectBranch64R6 : PseudoIndirectBranchBaseR6
297 GPR64Opnd>,
298 ISA_MIPS64R6;
299 }
300
301 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
302 UseIndirectJumpsHazard] in {
303 def TAILCALLHB64R6REG : TailCallReg,
304 ISA_MIPS64R6;
305 def PseudoIndrectHazardBranch64R6 : PseudoIndirectBranchBase
306 GPR64Opnd>,
307 ISA_MIPS64R6;
308 }
5252
5353 class PseudoDSP pattern,
5454 InstrItinClass itin = IIPseudo>
55 : MipsPseudo, PredicateControl {
55 : MipsPseudo {
5656 let InsnPredicates = [HasDSP];
5757 }
5858
127127 // Mips Pseudo Instructions Format
128128 class MipsPseudo pattern,
129129 InstrItinClass itin = IIPseudo> :
130 MipsInst {
130 MipsInst, PredicateControl {
131131 let isCodeGenOnly = 1;
132132 let isPseudo = 1;
133133 }
135135 // Mips32/64 Pseudo Instruction Format
136136 class PseudoSE pattern,
137137 InstrItinClass itin = IIPseudo> :
138 MipsPseudo, PredicateControl {
138 MipsPseudo {
139139 let EncodingPredicates = [HasStdEnc];
140140 }
141141
285285 case Mips::JR:
286286 case Mips::PseudoReturn:
287287 case Mips::PseudoIndirectBranch:
288 case Mips::TAILCALLREG:
288 case Mips::PseudoIndirectBranch_MM:
289289 canUseShortMicroMipsCTI = true;
290290 break;
291291 }
364364 // For MIPSR6, the instruction 'jic' can be used for these cases. Some
365365 // tools will accept 'jrc reg' as an alias for 'jic 0, $reg'.
366366 case Mips::JR:
367 case Mips::PseudoIndirectBranchR6:
368 case Mips::PseudoIndirectBranch_MM:
367369 case Mips::PseudoReturn:
368 case Mips::PseudoIndirectBranch:
369 case Mips::TAILCALLREG:
370 case Mips::TAILCALLR6REG:
370371 if (canUseShortMicroMipsCTI)
371372 return Mips::JRC16_MM;
372373 return Mips::JIC;
373374 case Mips::JALRPseudo:
374375 return Mips::JIALC;
375376 case Mips::JR64:
377 case Mips::PseudoIndirectBranch64R6:
376378 case Mips::PseudoReturn64:
377 case Mips::PseudoIndirectBranch64:
378 case Mips::TAILCALLREG64:
379 case Mips::TAILCALL64R6REG:
379380 return Mips::JIC64;
380381 case Mips::JALR64Pseudo:
381382 return Mips::JIALC64;
525526 }
526527 return TargetInstrInfo::findCommutedOpIndices(MI, SrcOpIdx1, SrcOpIdx2);
527528 }
529
530 // Perform target specific instruction verification.
531 bool MipsInstrInfo::verifyInstruction(const MachineInstr &MI,
532 StringRef &ErrInfo) const {
533 switch (MI.getOpcode()) {
534 case Mips::TAILCALLREG:
535 case Mips::PseudoIndirectBranch:
536 case Mips::JR:
537 case Mips::JR64:
538 case Mips::JALR:
539 case Mips::JALR64:
540 case Mips::JALRPseudo:
541 if (!Subtarget.useIndirectJumpsHazard())
542 return true;
543
544 ErrInfo = "invalid instruction when using jump guards!";
545 return false;
546 default:
547 return true;
548 }
549
550 return true;
551 }
137137 bool findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1,
138138 unsigned &SrcOpIdx2) const override;
139139
140 /// Perform target specific instruction verification.
141 bool verifyInstruction(const MachineInstr &MI,
142 StringRef &ErrInfo) const override;
143
140144 protected:
141145 bool isZeroImm(const MachineOperand &op) const;
142146
211211 AssemblerPredicate<"FeatureMicroMips,FeatureMips64r6">;
212212 def InMips16Mode : Predicate<"Subtarget->inMips16Mode()">,
213213 AssemblerPredicate<"FeatureMips16">;
214 def NotInMips16Mode : Predicate<"!Subtarget->inMips16Mode()">,
215 AssemblerPredicate<"!FeatureMips16">;
214216 def HasCnMips : Predicate<"Subtarget->hasCnMips()">,
215217 AssemblerPredicate<"FeatureCnMips">;
216218 def NotCnMips : Predicate<"!Subtarget->hasCnMips()">,
241243 AssemblerPredicate<"!FeatureMadd4">;
242244 def HasMT : Predicate<"Subtarget->hasMT()">,
243245 AssemblerPredicate<"FeatureMT">;
244
246 def UseIndirectJumpsHazard : Predicate<"Subtarget->useIndirectJumpsHazard()">,
247 AssemblerPredicate<"FeatureUseIndirectJumpsHazard">;
248 def NoIndirectJumpGuards : Predicate<"!Subtarget->useIndirectJumpsHazard()">,
249 AssemblerPredicate<"!FeatureUseIndirectJumpsHazard">;
245250 //===----------------------------------------------------------------------===//
246251 // Mips GPR size adjectives.
247252 // They are mutually exclusive.
14791484 PseudoSE<(outs), (ins calltarget:$target), [], II_J>,
14801485 PseudoInstExpansion<(JumpInst Opnd:$target)>;
14811486
1482 class TailCallReg :
1483 MipsPseudo<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>;
1487 class TailCallReg :
1488 PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>,
1489 PseudoInstExpansion<(JumpInst RO:$rs)>;
14841490 }
14851491
14861492 class BAL_BR_Pseudo :
20042010 def B : UncondBranch;
20052011
20062012 def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>;
2007 let AdditionalPredicates = [NotInMicroMips] in {
2013 let AdditionalPredicates = [NotInMicroMips, NoIndirectJumpGuards] in {
20082014 def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM;
20092015 def JALRPseudo : JumpLinkRegPseudo;
20102016 }
20242030 let Predicates = [NotInMicroMips] in {
20252031 def TAILCALL : TailCall;
20262032 }
2027
2028 def TAILCALLREG : TailCallReg;
2033 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2034 NoIndirectJumpGuards] in
2035 def TAILCALLREG : TailCallReg, ISA_MIPS1_NOT_32R6_64R6;
20292036
20302037 // Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64
20312038 // then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA.
2032 class PseudoIndirectBranchBase<RegisterOperand RO> :
2039 class PseudoIndirectBranchBase<Instruction JumpInst, RegisterOperand RO> :
20332040 MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)],
2034 II_IndirectBranchPseudo> {
2041 II_IndirectBranchPseudo>,
2042 PseudoInstExpansion<(JumpInst RO:$rs)> {
20352043 let isTerminator=1;
20362044 let isBarrier=1;
20372045 let hasDelaySlot = 1;
20402048 bit isCTI = 1;
20412049 }
20422050
2043 def PseudoIndirectBranch : PseudoIndirectBranchBase;
2051 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2052 NoIndirectJumpGuards] in
2053 def PseudoIndirectBranch : PseudoIndirectBranchBase,
2054 ISA_MIPS1_NOT_32R6_64R6;
20442055
20452056 // Return instructions are matched as a RetRA instruction, then are expanded
20462057 // into PseudoReturn/PseudoReturn64 after register allocation. Finally,
22122223 list Pattern = [];
22132224 }
22142225
2215 class JR_HB_DESC : InstSE<(outs), (ins), "", [], II_JR_HB, FrmJ>,
2216 JR_HB_DESC_BASE<"jr.hb", GPR32Opnd> {
2226 class JR_HB_DESC :
2227 InstSE<(outs), (ins), "", [], II_JR_HB, FrmJ>, JR_HB_DESC_BASE<"jr.hb", RO> {
22172228 let isBranch=1;
22182229 let isIndirectBranch=1;
22192230 let hasDelaySlot=1;
22222233 bit isCTI = 1;
22232234 }
22242235
2225 class JALR_HB_DESC : InstSE<(outs), (ins), "", [], II_JALR_HB, FrmJ>,
2226 JALR_HB_DESC_BASE<"jalr.hb", GPR32Opnd> {
2236 class JALR_HB_DESC :
2237 InstSE<(outs), (ins), "", [], II_JALR_HB, FrmJ>, JALR_HB_DESC_BASE<"jalr.hb",
2238 RO> {
22272239 let isIndirectBranch=1;
22282240 let hasDelaySlot=1;
22292241 bit isCTI = 1;
22322244 class JR_HB_ENC : JR_HB_FM<8>;
22332245 class JALR_HB_ENC : JALR_HB_FM<9>;
22342246
2235 def JR_HB : JR_HB_DESC, JR_HB_ENC, ISA_MIPS32_NOT_32R6_64R6;
2236 def JALR_HB : JALR_HB_DESC, JALR_HB_ENC, ISA_MIPS32;
2247 def JR_HB : JR_HB_DESC, JR_HB_ENC, ISA_MIPS32R2_NOT_32R6_64R6;
2248 def JALR_HB : JALR_HB_DESC, JALR_HB_ENC, ISA_MIPS32;
2249
2250 let AdditionalPredicates = [NotInMicroMips, UseIndirectJumpsHazard] in
2251 def JALRHBPseudo : JumpLinkRegPseudo;
2252
2253
2254 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2255 UseIndirectJumpsHazard] in {
2256 def TAILCALLREGHB : TailCallReg, ISA_MIPS32_NOT_32R6_64R6;
2257 def PseudoIndirectHazardBranch : PseudoIndirectBranchBase,
2258 ISA_MIPS32R2_NOT_32R6_64R6;
2259 }
22372260
22382261 class TLB :
22392262 InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
23672390 let Predicates = [NotInMicroMips] in {
23682391 def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
23692392 }
2370 def : MipsInstAlias<"jalr.hb $rs", (JALR_HB RA, GPR32Opnd:$rs), 1>, ISA_MIPS32;
2393 def : MipsInstAlias<"jalr.hb $rs", (JALR_HB RA, GPR32Opnd:$rs), 1>,
2394 ISA_MIPS32;
23712395 def : MipsInstAlias<"neg $rt, $rs",
23722396 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
23732397 def : MipsInstAlias<"neg $rt",
340340 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)
341341 .addReg(Mips::SP).addImm(8);
342342
343 if (Subtarget.hasMips32r6())
343 if (Subtarget.hasMips32r6() && !Subtarget.useIndirectJumpsHazard())
344344 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JALR))
345345 .addReg(Mips::ZERO).addReg(Mips::AT);
346 else
347 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JR)).addReg(Mips::AT);
346 else {
347 unsigned JROp =
348 Subtarget.useIndirectJumpsHazard()
349 ? (Subtarget.hasMips32r6() ? Mips::JR_HB_R6 : Mips::JR_HB)
350 : Mips::JR;
351 BuildMI(*BalTgtMBB, Pos, DL, TII->get(JROp)).addReg(Mips::AT);
352 }
348353
349354 if (Subtarget.isTargetNaCl()) {
350355 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::NOP));
413418 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LD), Mips::RA_64)
414419 .addReg(Mips::SP_64).addImm(0);
415420
416 if (Subtarget.hasMips64r6())
421 if (Subtarget.hasMips64r6() && !Subtarget.useIndirectJumpsHazard())
417422 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JALR64))
418 .addReg(Mips::ZERO_64).addReg(Mips::AT_64);
419 else
420 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JR64)).addReg(Mips::AT_64);
423 .addReg(Mips::ZERO_64)
424 .addReg(Mips::AT_64);
425 else {
426 unsigned JROp =
427 Subtarget.useIndirectJumpsHazard()
428 ? (Subtarget.hasMips32r6() ? Mips::JR_HB64_R6 : Mips::JR_HB64)
429 : Mips::JR64;
430 BuildMI(*BalTgtMBB, Pos, DL, TII->get(JROp)).addReg(Mips::AT_64);
431 }
421432
422433 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64)
423 .addReg(Mips::SP_64).addImm(16);
434 .addReg(Mips::SP_64)
435 .addImm(16);
424436 BalTgtMBB->rbegin()->bundleWithPred();
425437 }
426438
6969 InMips16HardFloat(Mips16HardFloat), InMicroMipsMode(false), HasDSP(false),
7070 HasDSPR2(false), HasDSPR3(false), AllowMixed16_32(Mixed16_32 | Mips_Os16),
7171 Os16(Mips_Os16), HasMSA(false), UseTCCInDIV(false), HasSym32(false),
72 HasEVA(false), DisableMadd4(false), HasMT(false), TM(TM),
73 TargetTriple(TT), TSInfo(),
72 HasEVA(false), DisableMadd4(false), HasMT(false),
73 UseIndirectJumpsHazard(false), TM(TM), TargetTriple(TT), TSInfo(),
7474 InstrInfo(
7575 MipsInstrInfo::create(initializeSubtargetDependencies(CPU, FS, TM))),
7676 FrameLowering(MipsFrameLowering::create(*this)),
101101
102102 if (IsFPXX && (isABI_N32() || isABI_N64()))
103103 report_fatal_error("FPXX is not permitted for the N32/N64 ABI's.", false);
104
105 if (UseIndirectJumpsHazard) {
106 if (InMicroMipsMode)
107 report_fatal_error(
108 "cannot combine indirect jumps with hazard barriers and microMIPS");
109 if (!hasMips32r2())
110 report_fatal_error(
111 "indirect jumps with hazard barriers requires MIPS32R2 or later");
112 }
104113
105114 if (hasMips32r6()) {
106115 StringRef ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
150150
151151 // HasMT -- support MT ASE.
152152 bool HasMT;
153
154 // Use hazard variants of the jump register instructions for indirect
155 // function calls and jump tables.
156 bool UseIndirectJumpsHazard;
153157
154158 // Disable use of the `jal` instruction.
155159 bool UseLongCalls = false;
265269 bool disableMadd4() const { return DisableMadd4; }
266270 bool hasEVA() const { return HasEVA; }
267271 bool hasMT() const { return HasMT; }
272 bool useIndirectJumpsHazard() const {
273 return UseIndirectJumpsHazard && hasMips32r2();
274 }
268275 bool useSmallSection() const { return UseSmallSection; }
269276
270277 bool hasStandardEncoding() const { return !inMips16Mode(); }
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc < %s -mtriple=mips-mti-linux-gnu -relocation-model=static \
2 ; RUN: -mips-tail-calls=1 -mcpu=mips32r2 -mattr=+use-indirect-jump-hazard \
3 ; RUN: -verify-machineinstrs | FileCheck %s --check-prefix=MIPS32R2
4 ; RUN: llc < %s -mtriple=mips-img-linux-gnu -relocation-model=static \
5 ; RUN: -mips-tail-calls=1 -mcpu=mips32r6 -mattr=+use-indirect-jump-hazard \
6 ; RUN: -verify-machineinstrs | FileCheck %s --check-prefix=MIPS32R6
7 ; RUN: llc < %s -mtriple=mips64-mti-linux-gnu -relocation-model=static \
8 ; RUN: -mips-tail-calls=1 -mcpu=mips64r2 -mattr=+use-indirect-jump-hazard \
9 ; RUN: -verify-machineinstrs | FileCheck %s --check-prefix=MIPS64R2
10 ; RUN: llc < %s -mtriple=mips64-img-linux-gnu -relocation-model=static \
11 ; RUN: -mips-tail-calls=1 -mcpu=mips64r6 -mattr=+use-indirect-jump-hazard \
12 ; RUN: -verify-machineinstrs | FileCheck %s --check-prefix=MIPS64R6
13
14 ; RUN: llc < %s -mtriple=mips-mti-linux-gnu -relocation-model=pic \
15 ; RUN: -mips-tail-calls=1 -mcpu=mips32r2 -mattr=+use-indirect-jump-hazard \
16 ; RUN: -verify-machineinstrs | FileCheck %s --check-prefix=PIC-MIPS32R2
17 ; RUN: llc < %s -mtriple=mips-img-linux-gnu -relocation-model=pic \
18 ; RUN: -mips-tail-calls=1 -mcpu=mips32r6 -mattr=+use-indirect-jump-hazard \
19 ; RUN: -verify-machineinstrs | FileCheck %s --check-prefix=PIC-MIPS32R6
20 ; RUN: llc < %s -mtriple=mips64-mti-linux-gnu -relocation-model=pic \
21 ; RUN: -mips-tail-calls=1 -mcpu=mips64r2 -mattr=+use-indirect-jump-hazard \
22 ; RUN: -verify-machineinstrs | FileCheck %s --check-prefix=PIC-MIPS64R2
23 ; RUN: llc < %s -mtriple=mips64-img-linux-gnu -relocation-model=pic \
24 ; RUN: -mips-tail-calls=1 -mcpu=mips64r6 -mattr=+use-indirect-jump-hazard \
25 ; RUN: -verify-machineinstrs | FileCheck %s --check-prefix=PIC-MIPS64R6
26
27 define void @fooNonTail(void (i32)* nocapture %f1) nounwind {
28 ; MIPS32R2-LABEL: fooNonTail:
29 ; MIPS32R2: # BB#0: # %entry
30 ; MIPS32R2-NEXT: addiu $sp, $sp, -24
31 ; MIPS32R2-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill
32 ; MIPS32R2-NEXT: move $1, $4
33 ; MIPS32R2-NEXT: move $25, $1
34 ; MIPS32R2-NEXT: jalr.hb $25
35 ; MIPS32R2-NEXT: addiu $4, $zero, 13
36 ; MIPS32R2-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload
37 ; MIPS32R2-NEXT: jr $ra
38 ; MIPS32R2-NEXT: addiu $sp, $sp, 24
39 ;
40 ; MIPS32R6-LABEL: fooNonTail:
41 ; MIPS32R6: # BB#0: # %entry
42 ; MIPS32R6-NEXT: addiu $sp, $sp, -24
43 ; MIPS32R6-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill
44 ; MIPS32R6-NEXT: move $1, $4
45 ; MIPS32R6-NEXT: move $25, $1
46 ; MIPS32R6-NEXT: jalr.hb $25
47 ; MIPS32R6-NEXT: addiu $4, $zero, 13
48 ; MIPS32R6-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload
49 ; MIPS32R6-NEXT: jr $ra
50 ; MIPS32R6-NEXT: addiu $sp, $sp, 24
51 ;
52 ; MIPS64R2-LABEL: fooNonTail:
53 ; MIPS64R2: # BB#0: # %entry
54 ; MIPS64R2-NEXT: daddiu $sp, $sp, -16
55 ; MIPS64R2-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill
56 ; MIPS64R2-NEXT: move $1, $4
57 ; MIPS64R2-NEXT: move $25, $1
58 ; MIPS64R2-NEXT: jalr.hb $25
59 ; MIPS64R2-NEXT: daddiu $4, $zero, 13
60 ; MIPS64R2-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload
61 ; MIPS64R2-NEXT: jr $ra
62 ; MIPS64R2-NEXT: daddiu $sp, $sp, 16
63 ;
64 ; MIPS64R6-LABEL: fooNonTail:
65 ; MIPS64R6: # BB#0: # %entry
66 ; MIPS64R6-NEXT: daddiu $sp, $sp, -16
67 ; MIPS64R6-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill
68 ; MIPS64R6-NEXT: move $1, $4
69 ; MIPS64R6-NEXT: move $25, $1
70 ; MIPS64R6-NEXT: jalr.hb $25
71 ; MIPS64R6-NEXT: daddiu $4, $zero, 13
72 ; MIPS64R6-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload
73 ; MIPS64R6-NEXT: jr $ra
74 ; MIPS64R6-NEXT: daddiu $sp, $sp, 16
75 ;
76 ; PIC-MIPS32R2-LABEL: fooNonTail:
77 ; PIC-MIPS32R2: # BB#0: # %entry
78 ; PIC-MIPS32R2-NEXT: addiu $sp, $sp, -24
79 ; PIC-MIPS32R2-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill
80 ; PIC-MIPS32R2-NEXT: move $1, $4
81 ; PIC-MIPS32R2-NEXT: move $25, $1
82 ; PIC-MIPS32R2-NEXT: jalr.hb $25
83 ; PIC-MIPS32R2-NEXT: addiu $4, $zero, 13
84 ; PIC-MIPS32R2-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload
85 ; PIC-MIPS32R2-NEXT: jr $ra
86 ; PIC-MIPS32R2-NEXT: addiu $sp, $sp, 24
87 ;
88 ; PIC-MIPS32R6-LABEL: fooNonTail:
89 ; PIC-MIPS32R6: # BB#0: # %entry
90 ; PIC-MIPS32R6-NEXT: addiu $sp, $sp, -24
91 ; PIC-MIPS32R6-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill
92 ; PIC-MIPS32R6-NEXT: move $1, $4
93 ; PIC-MIPS32R6-NEXT: move $25, $1
94 ; PIC-MIPS32R6-NEXT: jalr.hb $25
95 ; PIC-MIPS32R6-NEXT: addiu $4, $zero, 13
96 ; PIC-MIPS32R6-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload
97 ; PIC-MIPS32R6-NEXT: jr $ra
98 ; PIC-MIPS32R6-NEXT: addiu $sp, $sp, 24
99 ;
100 ; PIC-MIPS64R2-LABEL: fooNonTail:
101 ; PIC-MIPS64R2: # BB#0: # %entry
102 ; PIC-MIPS64R2-NEXT: daddiu $sp, $sp, -16
103 ; PIC-MIPS64R2-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill
104 ; PIC-MIPS64R2-NEXT: move $1, $4
105 ; PIC-MIPS64R2-NEXT: move $25, $1
106 ; PIC-MIPS64R2-NEXT: jalr.hb $25
107 ; PIC-MIPS64R2-NEXT: daddiu $4, $zero, 13
108 ; PIC-MIPS64R2-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload
109 ; PIC-MIPS64R2-NEXT: jr $ra
110 ; PIC-MIPS64R2-NEXT: daddiu $sp, $sp, 16
111 ;
112 ; PIC-MIPS64R6-LABEL: fooNonTail:
113 ; PIC-MIPS64R6: # BB#0: # %entry
114 ; PIC-MIPS64R6-NEXT: daddiu $sp, $sp, -16
115 ; PIC-MIPS64R6-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill
116 ; PIC-MIPS64R6-NEXT: move $1, $4
117 ; PIC-MIPS64R6-NEXT: move $25, $1
118 ; PIC-MIPS64R6-NEXT: jalr.hb $25
119 ; PIC-MIPS64R6-NEXT: daddiu $4, $zero, 13
120 ; PIC-MIPS64R6-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload
121 ; PIC-MIPS64R6-NEXT: jr $ra
122 ; PIC-MIPS64R6-NEXT: daddiu $sp, $sp, 16
123 entry:
124 call void %f1(i32 13) nounwind
125 ret void
126 }
127
128 define i32 @fooTail(i32 (i32)* nocapture %f1) nounwind {
129 ; MIPS32R2-LABEL: fooTail:
130 ; MIPS32R2: # BB#0: # %entry
131 ; MIPS32R2-NEXT: move $1, $4
132 ; MIPS32R2-NEXT: move $25, $1
133 ; MIPS32R2-NEXT: jr.hb $25
134 ; MIPS32R2-NEXT: addiu $4, $zero, 14
135 ;
136 ; MIPS32R6-LABEL: fooTail:
137 ; MIPS32R6: # BB#0: # %entry
138 ; MIPS32R6-NEXT: move $1, $4
139 ; MIPS32R6-NEXT: move $25, $1
140 ; MIPS32R6-NEXT: jr.hb $25
141 ; MIPS32R6-NEXT: addiu $4, $zero, 14
142 ;
143 ; MIPS64R2-LABEL: fooTail:
144 ; MIPS64R2: # BB#0: # %entry
145 ; MIPS64R2-NEXT: move $1, $4
146 ; MIPS64R2-NEXT: move $25, $1
147 ; MIPS64R2-NEXT: jr.hb $25
148 ; MIPS64R2-NEXT: daddiu $4, $zero, 14
149 ;
150 ; MIPS64R6-LABEL: fooTail:
151 ; MIPS64R6: # BB#0: # %entry
152 ; MIPS64R6-NEXT: move $1, $4
153 ; MIPS64R6-NEXT: move $25, $1
154 ; MIPS64R6-NEXT: jr.hb $25
155 ; MIPS64R6-NEXT: daddiu $4, $zero, 14
156 ;
157 ; PIC-MIPS32R2-LABEL: fooTail:
158 ; PIC-MIPS32R2: # BB#0: # %entry
159 ; PIC-MIPS32R2-NEXT: move $1, $4
160 ; PIC-MIPS32R2-NEXT: move $25, $1
161 ; PIC-MIPS32R2-NEXT: jr.hb $25
162 ; PIC-MIPS32R2-NEXT: addiu $4, $zero, 14
163 ;
164 ; PIC-MIPS32R6-LABEL: fooTail:
165 ; PIC-MIPS32R6: # BB#0: # %entry
166 ; PIC-MIPS32R6-NEXT: move $1, $4
167 ; PIC-MIPS32R6-NEXT: move $25, $1
168 ; PIC-MIPS32R6-NEXT: jr.hb $25
169 ; PIC-MIPS32R6-NEXT: addiu $4, $zero, 14
170 ;
171 ; PIC-MIPS64R2-LABEL: fooTail:
172 ; PIC-MIPS64R2: # BB#0: # %entry
173 ; PIC-MIPS64R2-NEXT: move $1, $4
174 ; PIC-MIPS64R2-NEXT: move $25, $1
175 ; PIC-MIPS64R2-NEXT: jr.hb $25
176 ; PIC-MIPS64R2-NEXT: daddiu $4, $zero, 14
177 ;
178 ; PIC-MIPS64R6-LABEL: fooTail:
179 ; PIC-MIPS64R6: # BB#0: # %entry
180 ; PIC-MIPS64R6-NEXT: move $1, $4
181 ; PIC-MIPS64R6-NEXT: move $25, $1
182 ; PIC-MIPS64R6-NEXT: jr.hb $25
183 ; PIC-MIPS64R6-NEXT: daddiu $4, $zero, 14
184 entry:
185 %0 = tail call i32 %f1(i32 14) nounwind
186 ret i32 %0
187 }
0 # RUN: not llc -mtriple=mips-mti-linux-gnu -mcpu=mips32r2 %s \
1 # RUN: -start-after=expand-isel-pseudos -stop-after=expand-isel-pseudos \
2 # RUN: -verify-machineinstrs -mattr=+use-indirect-jump-hazard -o - 2>&1 \
3 # RUN: | FileCheck %s
4
5 # Test that calls are checked when using indirect jumps guards (hazard variant).
6
7 # CHECK: Bad machine code: invalid instruction when using jump guards!
8 --- |
9 define i32 @fooTail(i32 (i32)* nocapture %f1) {
10 entry:
11 %0 = tail call i32 %f1(i32 14)
12 ret i32 %0
13 }
14 ...
15 ---
16 name: fooTail
17 alignment: 2
18 exposesReturnsTwice: false
19 legalized: false
20 regBankSelected: false
21 selected: false
22 tracksRegLiveness: true
23 registers:
24 - { id: 0, class: gpr32, preferred-register: '' }
25 - { id: 1, class: gpr32, preferred-register: '' }
26 liveins:
27 - { reg: '%a0', virtual-reg: '%0' }
28 frameInfo:
29 isFrameAddressTaken: false
30 isReturnAddressTaken: false
31 hasStackMap: false
32 hasPatchPoint: false
33 stackSize: 0
34 offsetAdjustment: 0
35 maxAlignment: 1
36 adjustsStack: false
37 hasCalls: false
38 stackProtector: ''
39 maxCallFrameSize: 4294967295
40 hasOpaqueSPAdjustment: false
41 hasVAStart: false
42 hasMustTailInVarArgFunc: false
43 savePoint: ''
44 restorePoint: ''
45 fixedStack:
46 stack:
47 constants:
48 body: |
49 bb.0.entry:
50 liveins: %a0
51
52 %0:gpr32 = COPY %a0
53 %1:gpr32 = ADDiu %zero, 14
54 %a0 = COPY %1
55 TAILCALLREG %0, csr_o32, implicit-def dead %at, implicit %a0
56
57 ...
0 # RUN: not llc -mtriple=mips-mti-linux-gnu -mcpu=mips32r2 %s \
1 # RUN: -start-after=expand-isel-pseudos -stop-after=expand-isel-pseudos \
2 # RUN: -verify-machineinstrs -mattr=+use-indirect-jump-hazard -o - 2>&1 \
3 # RUN: | FileCheck %s
4
5 # That that tail calls are checked when using indirect jump guards (hazard variant).
6
7 # CHECK: Bad machine code: invalid instruction when using jump guards!
8 --- |
9 define i32 @fooTail(i32 (i32)* nocapture %f1) {
10 entry:
11 %0 = tail call i32 %f1(i32 14)
12 ret i32 %0
13 }
14
15 ...
16 ---
17 name: fooTail
18 alignment: 2
19 exposesReturnsTwice: false
20 legalized: false
21 regBankSelected: false
22 selected: false
23 tracksRegLiveness: true
24 registers:
25 - { id: 0, class: gpr32, preferred-register: '' }
26 - { id: 1, class: gpr32, preferred-register: '' }
27 liveins:
28 - { reg: '%a0', virtual-reg: '%0' }
29 frameInfo:
30 isFrameAddressTaken: false
31 isReturnAddressTaken: false
32 hasStackMap: false
33 hasPatchPoint: false
34 stackSize: 0
35 offsetAdjustment: 0
36 maxAlignment: 1
37 adjustsStack: false
38 hasCalls: false
39 stackProtector: ''
40 maxCallFrameSize: 4294967295
41 hasOpaqueSPAdjustment: false
42 hasVAStart: false
43 hasMustTailInVarArgFunc: false
44 savePoint: ''
45 restorePoint: ''
46 fixedStack:
47 stack:
48 constants:
49 body: |
50 bb.0.entry:
51 liveins: %a0
52
53 %0:gpr32 = COPY %a0
54 %1:gpr32 = ADDiu %zero, 14
55 %a0 = COPY %1
56 TAILCALLREG %0, csr_o32, implicit-def dead %at, implicit %a0
57
58 ...
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc < %s -mtriple=mips-mti-linux-gnu -relocation-model=static \
2 ; RUN: -mips-tail-calls=1 -mcpu=mips32r2 -mattr=+use-indirect-jump-hazard \
3 ; RUN: -verify-machineinstrs | FileCheck %s --check-prefix=MIPS32R2
4 ; RUN: llc < %s -mtriple=mips-img-linux-gnu -relocation-model=static \
5 ; RUN: -mips-tail-calls=1 -mcpu=mips32r6 -mattr=+use-indirect-jump-hazard \
6 ; RUN: -verify-machineinstrs | FileCheck %s --check-prefix=MIPS32R6
7 ; RUN: llc < %s -mtriple=mips64-mti-linux-gnu -relocation-model=static \
8 ; RUN: -mips-tail-calls=1 -mcpu=mips64r2 -mattr=+use-indirect-jump-hazard \
9 ; RUN: -verify-machineinstrs | FileCheck %s --check-prefix=MIPS64R2
10 ; RUN: llc < %s -mtriple=mips64-img-linux-gnu -relocation-model=static \
11 ; RUN: -mips-tail-calls=1 -mcpu=mips64r6 -mattr=+use-indirect-jump-hazard \
12 ; RUN: -verify-machineinstrs | FileCheck %s --check-prefix=MIPS64R6
13
14 ; RUN: llc < %s -mtriple=mips-mti-linux-gnu -relocation-model=pic \
15 ; RUN: -mips-tail-calls=1 -mcpu=mips32r2 -mattr=+use-indirect-jump-hazard \
16 ; RUN: -verify-machineinstrs | FileCheck %s --check-prefix=PIC-MIPS32R2
17 ; RUN: llc < %s -mtriple=mips-img-linux-gnu -relocation-model=pic \
18 ; RUN: -mips-tail-calls=1 -mcpu=mips32r6 -mattr=+use-indirect-jump-hazard \
19 ; RUN: -verify-machineinstrs | FileCheck %s --check-prefix=PIC-MIPS32R6
20 ; RUN: llc < %s -mtriple=mips64-mti-linux-gnu -relocation-model=pic \
21 ; RUN: -mips-tail-calls=1 -mcpu=mips64r2 -mattr=+use-indirect-jump-hazard \
22 ; RUN: -verify-machineinstrs | FileCheck %s --check-prefix=PIC-MIPS64R2
23 ; RUN: llc < %s -mtriple=mips64-img-linux-gnu -relocation-model=pic \
24 ; RUN: -mips-tail-calls=1 -mcpu=mips64r6 -mattr=+use-indirect-jump-hazard \
25 ; RUN: -verify-machineinstrs | FileCheck %s --check-prefix=PIC-MIPS64R6
26
27 @.str = private unnamed_addr constant [2 x i8] c"A\00", align 1
28 @.str.1 = private unnamed_addr constant [2 x i8] c"B\00", align 1
29 @.str.2 = private unnamed_addr constant [2 x i8] c"C\00", align 1
30 @.str.3 = private unnamed_addr constant [2 x i8] c"D\00", align 1
31 @.str.4 = private unnamed_addr constant [2 x i8] c"E\00", align 1
32 @.str.5 = private unnamed_addr constant [2 x i8] c"F\00", align 1
33 @.str.6 = private unnamed_addr constant [2 x i8] c"G\00", align 1
34 @.str.7 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
35
36 define i8* @_Z3fooi(i32 signext %Letter) {
37 ; MIPS32R2-LABEL: _Z3fooi:
38 ; MIPS32R2: # BB#0: # %entry
39 ; MIPS32R2-NEXT: addiu $sp, $sp, -16
40 ; MIPS32R2-NEXT: $cfi0:
41 ; MIPS32R2-NEXT: .cfi_def_cfa_offset 16
42 ; MIPS32R2-NEXT: sltiu $1, $4, 7
43 ; MIPS32R2-NEXT: beqz $1, $BB0_3
44 ; MIPS32R2-NEXT: sw $4, 4($sp)
45 ; MIPS32R2-NEXT: $BB0_1: # %entry
46 ; MIPS32R2-NEXT: sll $1, $4, 2
47 ; MIPS32R2-NEXT: lui $2, %hi($JTI0_0)
48 ; MIPS32R2-NEXT: addu $1, $1, $2
49 ; MIPS32R2-NEXT: lw $1, %lo($JTI0_0)($1)
50 ; MIPS32R2-NEXT: jr.hb $1
51 ; MIPS32R2-NEXT: nop
52 ; MIPS32R2-NEXT: $BB0_2: # %sw.bb
53 ; MIPS32R2-NEXT: lui $1, %hi($.str)
54 ; MIPS32R2-NEXT: addiu $1, $1, %lo($.str)
55 ; MIPS32R2-NEXT: j $BB0_10
56 ; MIPS32R2-NEXT: sw $1, 8($sp)
57 ; MIPS32R2-NEXT: $BB0_3: # %sw.epilog
58 ; MIPS32R2-NEXT: lui $1, %hi($.str.7)
59 ; MIPS32R2-NEXT: addiu $1, $1, %lo($.str.7)
60 ; MIPS32R2-NEXT: j $BB0_10
61 ; MIPS32R2-NEXT: sw $1, 8($sp)
62 ; MIPS32R2-NEXT: $BB0_4: # %sw.bb1
63 ; MIPS32R2-NEXT: lui $1, %hi($.str.1)
64 ; MIPS32R2-NEXT: addiu $1, $1, %lo($.str.1)
65 ; MIPS32R2-NEXT: j $BB0_10
66 ; MIPS32R2-NEXT: sw $1, 8($sp)
67 ; MIPS32R2-NEXT: $BB0_5: # %sw.bb2
68 ; MIPS32R2-NEXT: lui $1, %hi($.str.2)
69 ; MIPS32R2-NEXT: addiu $1, $1, %lo($.str.2)
70 ; MIPS32R2-NEXT: j $BB0_10
71 ; MIPS32R2-NEXT: sw $1, 8($sp)
72 ; MIPS32R2-NEXT: $BB0_6: # %sw.bb3
73 ; MIPS32R2-NEXT: lui $1, %hi($.str.3)
74 ; MIPS32R2-NEXT: addiu $1, $1, %lo($.str.3)
75 ; MIPS32R2-NEXT: j $BB0_10
76 ; MIPS32R2-NEXT: sw $1, 8($sp)
77 ; MIPS32R2-NEXT: $BB0_7: # %sw.bb4
78 ; MIPS32R2-NEXT: lui $1, %hi($.str.4)
79 ; MIPS32R2-NEXT: addiu $1, $1, %lo($.str.4)
80 ; MIPS32R2-NEXT: j $BB0_10
81 ; MIPS32R2-NEXT: sw $1, 8($sp)
82 ; MIPS32R2-NEXT: $BB0_8: # %sw.bb5
83 ; MIPS32R2-NEXT: lui $1, %hi($.str.5)
84 ; MIPS32R2-NEXT: addiu $1, $1, %lo($.str.5)
85 ; MIPS32R2-NEXT: j $BB0_10
86 ; MIPS32R2-NEXT: sw $1, 8($sp)
87 ; MIPS32R2-NEXT: $BB0_9: # %sw.bb6
88 ; MIPS32R2-NEXT: lui $1, %hi($.str.6)
89 ; MIPS32R2-NEXT: addiu $1, $1, %lo($.str.6)
90 ; MIPS32R2-NEXT: sw $1, 8($sp)
91 ; MIPS32R2-NEXT: $BB0_10: # %return
92 ; MIPS32R2-NEXT: lw $2, 8($sp)
93 ; MIPS32R2-NEXT: jr $ra
94 ; MIPS32R2-NEXT: addiu $sp, $sp, 16
95 ;
96 ; MIPS32R6-LABEL: _Z3fooi:
97 ; MIPS32R6: # BB#0: # %entry
98 ; MIPS32R6-NEXT: addiu $sp, $sp, -16
99 ; MIPS32R6-NEXT: $cfi0:
100 ; MIPS32R6-NEXT: .cfi_def_cfa_offset 16
101 ; MIPS32R6-NEXT: sltiu $1, $4, 7
102 ; MIPS32R6-NEXT: beqz $1, $BB0_3
103 ; MIPS32R6-NEXT: sw $4, 4($sp)
104 ; MIPS32R6-NEXT: $BB0_1: # %entry
105 ; MIPS32R6-NEXT: sll $1, $4, 2
106 ; MIPS32R6-NEXT: lui $2, %hi($JTI0_0)
107 ; MIPS32R6-NEXT: addu $1, $1, $2
108 ; MIPS32R6-NEXT: lw $1, %lo($JTI0_0)($1)
109 ; MIPS32R6-NEXT: jr.hb $1
110 ; MIPS32R6-NEXT: nop
111 ; MIPS32R6-NEXT: $BB0_2: # %sw.bb
112 ; MIPS32R6-NEXT: lui $1, %hi($.str)
113 ; MIPS32R6-NEXT: addiu $1, $1, %lo($.str)
114 ; MIPS32R6-NEXT: j $BB0_10
115 ; MIPS32R6-NEXT: sw $1, 8($sp)
116 ; MIPS32R6-NEXT: $BB0_3: # %sw.epilog
117 ; MIPS32R6-NEXT: lui $1, %hi($.str.7)
118 ; MIPS32R6-NEXT: addiu $1, $1, %lo($.str.7)
119 ; MIPS32R6-NEXT: j $BB0_10
120 ; MIPS32R6-NEXT: sw $1, 8($sp)
121 ; MIPS32R6-NEXT: $BB0_4: # %sw.bb1
122 ; MIPS32R6-NEXT: lui $1, %hi($.str.1)
123 ; MIPS32R6-NEXT: addiu $1, $1, %lo($.str.1)
124 ; MIPS32R6-NEXT: j $BB0_10
125 ; MIPS32R6-NEXT: sw $1, 8($sp)
126 ; MIPS32R6-NEXT: $BB0_5: # %sw.bb2
127 ; MIPS32R6-NEXT: lui $1, %hi($.str.2)
128 ; MIPS32R6-NEXT: addiu $1, $1, %lo($.str.2)
129 ; MIPS32R6-NEXT: j $BB0_10
130 ; MIPS32R6-NEXT: sw $1, 8($sp)
131 ; MIPS32R6-NEXT: $BB0_6: # %sw.bb3
132 ; MIPS32R6-NEXT: lui $1, %hi($.str.3)
133 ; MIPS32R6-NEXT: addiu $1, $1, %lo($.str.3)
134 ; MIPS32R6-NEXT: j $BB0_10
135 ; MIPS32R6-NEXT: sw $1, 8($sp)
136 ; MIPS32R6-NEXT: $BB0_7: # %sw.bb4
137 ; MIPS32R6-NEXT: lui $1, %hi($.str.4)
138 ; MIPS32R6-NEXT: addiu $1, $1, %lo($.str.4)
139 ; MIPS32R6-NEXT: j $BB0_10
140 ; MIPS32R6-NEXT: sw $1, 8($sp)
141 ; MIPS32R6-NEXT: $BB0_8: # %sw.bb5
142 ; MIPS32R6-NEXT: lui $1, %hi($.str.5)
143 ; MIPS32R6-NEXT: addiu $1, $1, %lo($.str.5)
144 ; MIPS32R6-NEXT: j $BB0_10
145 ; MIPS32R6-NEXT: sw $1, 8($sp)
146 ; MIPS32R6-NEXT: $BB0_9: # %sw.bb6
147 ; MIPS32R6-NEXT: lui $1, %hi($.str.6)
148 ; MIPS32R6-NEXT: addiu $1, $1, %lo($.str.6)
149 ; MIPS32R6-NEXT: sw $1, 8($sp)
150 ; MIPS32R6-NEXT: $BB0_10: # %return
151 ; MIPS32R6-NEXT: lw $2, 8($sp)
152 ; MIPS32R6-NEXT: jr $ra
153 ; MIPS32R6-NEXT: addiu $sp, $sp, 16
154 ;
155 ; MIPS64R2-LABEL: _Z3fooi:
156 ; MIPS64R2: # BB#0: # %entry
157 ; MIPS64R2-NEXT: daddiu $sp, $sp, -16
158 ; MIPS64R2-NEXT: .Lcfi0:
159 ; MIPS64R2-NEXT: .cfi_def_cfa_offset 16
160 ; MIPS64R2-NEXT: sw $4, 4($sp)
161 ; MIPS64R2-NEXT: lwu $2, 4($sp)
162 ; MIPS64R2-NEXT: sltiu $1, $2, 7
163 ; MIPS64R2-NEXT: beqz $1, .LBB0_3
164 ; MIPS64R2-NEXT: nop
165 ; MIPS64R2-NEXT: .LBB0_1: # %entry
166 ; MIPS64R2-NEXT: daddiu $1, $zero, 8
167 ; MIPS64R2-NEXT: dmult $2, $1
168 ; MIPS64R2-NEXT: mflo $1
169 ; MIPS64R2-NEXT: lui $2, %highest(.LJTI0_0)
170 ; MIPS64R2-NEXT: daddiu $2, $2, %higher(.LJTI0_0)
171 ; MIPS64R2-NEXT: dsll $2, $2, 16
172 ; MIPS64R2-NEXT: daddiu $2, $2, %hi(.LJTI0_0)
173 ; MIPS64R2-NEXT: dsll $2, $2, 16
174 ; MIPS64R2-NEXT: daddu $1, $1, $2
175 ; MIPS64R2-NEXT: ld $1, %lo(.LJTI0_0)($1)
176 ; MIPS64R2-NEXT: jr.hb $1
177 ; MIPS64R2-NEXT: nop
178 ; MIPS64R2-NEXT: .LBB0_2: # %sw.bb
179 ; MIPS64R2-NEXT: lui $1, %highest(.L.str)
180 ; MIPS64R2-NEXT: daddiu $1, $1, %higher(.L.str)
181 ; MIPS64R2-NEXT: dsll $1, $1, 16
182 ; MIPS64R2-NEXT: daddiu $1, $1, %hi(.L.str)
183 ; MIPS64R2-NEXT: dsll $1, $1, 16
184 ; MIPS64R2-NEXT: daddiu $1, $1, %lo(.L.str)
185 ; MIPS64R2-NEXT: j .LBB0_10
186 ; MIPS64R2-NEXT: sd $1, 8($sp)
187 ; MIPS64R2-NEXT: .LBB0_3: # %sw.epilog
188 ; MIPS64R2-NEXT: lui $1, %highest(.L.str.7)
189 ; MIPS64R2-NEXT: daddiu $1, $1, %higher(.L.str.7)
190 ; MIPS64R2-NEXT: dsll $1, $1, 16
191 ; MIPS64R2-NEXT: daddiu $1, $1, %hi(.L.str.7)
192 ; MIPS64R2-NEXT: dsll $1, $1, 16
193 ; MIPS64R2-NEXT: daddiu $1, $1, %lo(.L.str.7)
194 ; MIPS64R2-NEXT: j .LBB0_10
195 ; MIPS64R2-NEXT: sd $1, 8($sp)
196 ; MIPS64R2-NEXT: .LBB0_4: # %sw.bb1
197 ; MIPS64R2-NEXT: lui $1, %highest(.L.str.1)
198 ; MIPS64R2-NEXT: daddiu $1, $1, %higher(.L.str.1)
199 ; MIPS64R2-NEXT: dsll $1, $1, 16
200 ; MIPS64R2-NEXT: daddiu $1, $1, %hi(.L.str.1)
201 ; MIPS64R2-NEXT: dsll $1, $1, 16
202 ; MIPS64R2-NEXT: daddiu $1, $1, %lo(.L.str.1)
203 ; MIPS64R2-NEXT: j .LBB0_10
204 ; MIPS64R2-NEXT: sd $1, 8($sp)
205 ; MIPS64R2-NEXT: .LBB0_5: # %sw.bb2
206 ; MIPS64R2-NEXT: lui $1, %highest(.L.str.2)
207 ; MIPS64R2-NEXT: daddiu $1, $1, %higher(.L.str.2)
208 ; MIPS64R2-NEXT: dsll $1, $1, 16
209 ; MIPS64R2-NEXT: daddiu $1, $1, %hi(.L.str.2)
210 ; MIPS64R2-NEXT: dsll $1, $1, 16
211 ; MIPS64R2-NEXT: daddiu $1, $1, %lo(.L.str.2)
212 ; MIPS64R2-NEXT: j .LBB0_10
213 ; MIPS64R2-NEXT: sd $1, 8($sp)
214 ; MIPS64R2-NEXT: .LBB0_6: # %sw.bb3
215 ; MIPS64R2-NEXT: lui $1, %highest(.L.str.3)
216 ; MIPS64R2-NEXT: daddiu $1, $1, %higher(.L.str.3)
217 ; MIPS64R2-NEXT: dsll $1, $1, 16
218 ; MIPS64R2-NEXT: daddiu $1, $1, %hi(.L.str.3)
219 ; MIPS64R2-NEXT: dsll $1, $1, 16
220 ; MIPS64R2-NEXT: daddiu $1, $1, %lo(.L.str.3)
221 ; MIPS64R2-NEXT: j .LBB0_10
222 ; MIPS64R2-NEXT: sd $1, 8($sp)
223 ; MIPS64R2-NEXT: .LBB0_7: # %sw.bb4
224 ; MIPS64R2-NEXT: lui $1, %highest(.L.str.4)
225 ; MIPS64R2-NEXT: daddiu $1, $1, %higher(.L.str.4)
226 ; MIPS64R2-NEXT: dsll $1, $1, 16
227 ; MIPS64R2-NEXT: daddiu $1, $1, %hi(.L.str.4)
228 ; MIPS64R2-NEXT: dsll $1, $1, 16
229 ; MIPS64R2-NEXT: daddiu $1, $1, %lo(.L.str.4)
230 ; MIPS64R2-NEXT: j .LBB0_10
231 ; MIPS64R2-NEXT: sd $1, 8($sp)
232 ; MIPS64R2-NEXT: .LBB0_8: # %sw.bb5
233 ; MIPS64R2-NEXT: lui $1, %highest(.L.str.5)
234 ; MIPS64R2-NEXT: daddiu $1, $1, %higher(.L.str.5)
235 ; MIPS64R2-NEXT: dsll $1, $1, 16
236 ; MIPS64R2-NEXT: daddiu $1, $1, %hi(.L.str.5)
237 ; MIPS64R2-NEXT: dsll $1, $1, 16
238 ; MIPS64R2-NEXT: daddiu $1, $1, %lo(.L.str.5)
239 ; MIPS64R2-NEXT: j .LBB0_10
240 ; MIPS64R2-NEXT: sd $1, 8($sp)
241 ; MIPS64R2-NEXT: .LBB0_9: # %sw.bb6
242 ; MIPS64R2-NEXT: lui $1, %highest(.L.str.6)
243 ; MIPS64R2-NEXT: daddiu $1, $1, %higher(.L.str.6)
244 ; MIPS64R2-NEXT: dsll $1, $1, 16
245 ; MIPS64R2-NEXT: daddiu $1, $1, %hi(.L.str.6)
246 ; MIPS64R2-NEXT: dsll $1, $1, 16
247 ; MIPS64R2-NEXT: daddiu $1, $1, %lo(.L.str.6)
248 ; MIPS64R2-NEXT: sd $1, 8($sp)
249 ; MIPS64R2-NEXT: .LBB0_10: # %return
250 ; MIPS64R2-NEXT: ld $2, 8($sp)
251 ; MIPS64R2-NEXT: jr $ra
252 ; MIPS64R2-NEXT: daddiu $sp, $sp, 16
253 ;
254 ; MIPS64R6-LABEL: _Z3fooi:
255 ; MIPS64R6: # BB#0: # %entry
256 ; MIPS64R6-NEXT: daddiu $sp, $sp, -16
257 ; MIPS64R6-NEXT: .Lcfi0:
258 ; MIPS64R6-NEXT: .cfi_def_cfa_offset 16
259 ; MIPS64R6-NEXT: sw $4, 4($sp)
260 ; MIPS64R6-NEXT: lwu $2, 4($sp)
261 ; MIPS64R6-NEXT: sltiu $1, $2, 7
262 ; MIPS64R6-NEXT: beqzc $1, .LBB0_3
263 ; MIPS64R6-NEXT: .LBB0_1: # %entry
264 ; MIPS64R6-NEXT: dsll $1, $2, 3
265 ; MIPS64R6-NEXT: lui $2, %highest(.LJTI0_0)
266 ; MIPS64R6-NEXT: daddiu $2, $2, %higher(.LJTI0_0)
267 ; MIPS64R6-NEXT: dsll $2, $2, 16
268 ; MIPS64R6-NEXT: daddiu $2, $2, %hi(.LJTI0_0)
269 ; MIPS64R6-NEXT: dsll $2, $2, 16
270 ; MIPS64R6-NEXT: daddu $1, $1, $2
271 ; MIPS64R6-NEXT: ld $1, %lo(.LJTI0_0)($1)
272 ; MIPS64R6-NEXT: jr.hb $1
273 ; MIPS64R6-NEXT: nop
274 ; MIPS64R6-NEXT: .LBB0_2: # %sw.bb
275 ; MIPS64R6-NEXT: lui $1, %highest(.L.str)
276 ; MIPS64R6-NEXT: daddiu $1, $1, %higher(.L.str)
277 ; MIPS64R6-NEXT: dsll $1, $1, 16
278 ; MIPS64R6-NEXT: daddiu $1, $1, %hi(.L.str)
279 ; MIPS64R6-NEXT: dsll $1, $1, 16
280 ; MIPS64R6-NEXT: daddiu $1, $1, %lo(.L.str)
281 ; MIPS64R6-NEXT: j .LBB0_10
282 ; MIPS64R6-NEXT: sd $1, 8($sp)
283 ; MIPS64R6-NEXT: .LBB0_3: # %sw.epilog
284 ; MIPS64R6-NEXT: lui $1, %highest(.L.str.7)
285 ; MIPS64R6-NEXT: daddiu $1, $1, %higher(.L.str.7)
286 ; MIPS64R6-NEXT: dsll $1, $1, 16
287 ; MIPS64R6-NEXT: daddiu $1, $1, %hi(.L.str.7)
288 ; MIPS64R6-NEXT: dsll $1, $1, 16
289 ; MIPS64R6-NEXT: daddiu $1, $1, %lo(.L.str.7)
290 ; MIPS64R6-NEXT: j .LBB0_10
291 ; MIPS64R6-NEXT: sd $1, 8($sp)
292 ; MIPS64R6-NEXT: .LBB0_4: # %sw.bb1
293 ; MIPS64R6-NEXT: lui $1, %highest(.L.str.1)
294 ; MIPS64R6-NEXT: daddiu $1, $1, %higher(.L.str.1)
295 ; MIPS64R6-NEXT: dsll $1, $1, 16
296 ; MIPS64R6-NEXT: daddiu $1, $1, %hi(.L.str.1)
297 ; MIPS64R6-NEXT: dsll $1, $1, 16
298 ; MIPS64R6-NEXT: daddiu $1, $1, %lo(.L.str.1)
299 ; MIPS64R6-NEXT: j .LBB0_10
300 ; MIPS64R6-NEXT: sd $1, 8($sp)
301 ; MIPS64R6-NEXT: .LBB0_5: # %sw.bb2
302 ; MIPS64R6-NEXT: lui $1, %highest(.L.str.2)
303 ; MIPS64R6-NEXT: daddiu $1, $1, %higher(.L.str.2)
304 ; MIPS64R6-NEXT: dsll $1, $1, 16
305 ; MIPS64R6-NEXT: daddiu $1, $1, %hi(.L.str.2)
306 ; MIPS64R6-NEXT: dsll $1, $1, 16
307 ; MIPS64R6-NEXT: daddiu $1, $1, %lo(.L.str.2)
308 ; MIPS64R6-NEXT: j .LBB0_10
309 ; MIPS64R6-NEXT: sd $1, 8($sp)
310 ; MIPS64R6-NEXT: .LBB0_6: # %sw.bb3
311 ; MIPS64R6-NEXT: lui $1, %highest(.L.str.3)
312 ; MIPS64R6-NEXT: daddiu $1, $1, %higher(.L.str.3)
313 ; MIPS64R6-NEXT: dsll $1, $1, 16
314 ; MIPS64R6-NEXT: daddiu $1, $1, %hi(.L.str.3)
315 ; MIPS64R6-NEXT: dsll $1, $1, 16
316 ; MIPS64R6-NEXT: daddiu $1, $1, %lo(.L.str.3)
317 ; MIPS64R6-NEXT: j .LBB0_10
318 ; MIPS64R6-NEXT: sd $1, 8($sp)
319 ; MIPS64R6-NEXT: .LBB0_7: # %sw.bb4
320 ; MIPS64R6-NEXT: lui $1, %highest(.L.str.4)
321 ; MIPS64R6-NEXT: daddiu $1, $1, %higher(.L.str.4)
322 ; MIPS64R6-NEXT: dsll $1, $1, 16
323 ; MIPS64R6-NEXT: daddiu $1, $1, %hi(.L.str.4)
324 ; MIPS64R6-NEXT: dsll $1, $1, 16
325 ; MIPS64R6-NEXT: daddiu $1, $1, %lo(.L.str.4)
326 ; MIPS64R6-NEXT: j .LBB0_10
327 ; MIPS64R6-NEXT: sd $1, 8($sp)
328 ; MIPS64R6-NEXT: .LBB0_8: # %sw.bb5
329 ; MIPS64R6-NEXT: lui $1, %highest(.L.str.5)
330 ; MIPS64R6-NEXT: daddiu $1, $1, %higher(.L.str.5)
331 ; MIPS64R6-NEXT: dsll $1, $1, 16
332 ; MIPS64R6-NEXT: daddiu $1, $1, %hi(.L.str.5)
333 ; MIPS64R6-NEXT: dsll $1, $1, 16
334 ; MIPS64R6-NEXT: daddiu $1, $1, %lo(.L.str.5)
335 ; MIPS64R6-NEXT: j .LBB0_10
336 ; MIPS64R6-NEXT: sd $1, 8($sp)
337 ; MIPS64R6-NEXT: .LBB0_9: # %sw.bb6
338 ; MIPS64R6-NEXT: lui $1, %highest(.L.str.6)
339 ; MIPS64R6-NEXT: daddiu $1, $1, %higher(.L.str.6)
340 ; MIPS64R6-NEXT: dsll $1, $1, 16
341 ; MIPS64R6-NEXT: daddiu $1, $1, %hi(.L.str.6)
342 ; MIPS64R6-NEXT: dsll $1, $1, 16
343 ; MIPS64R6-NEXT: daddiu $1, $1, %lo(.L.str.6)
344 ; MIPS64R6-NEXT: sd $1, 8($sp)
345 ; MIPS64R6-NEXT: .LBB0_10: # %return
346 ; MIPS64R6-NEXT: ld $2, 8($sp)
347 ; MIPS64R6-NEXT: jr $ra
348 ; MIPS64R6-NEXT: daddiu $sp, $sp, 16
349 ;
350 ; PIC-MIPS32R2-LABEL: _Z3fooi:
351 ; PIC-MIPS32R2: # BB#0: # %entry
352 ; PIC-MIPS32R2-NEXT: lui $2, %hi(_gp_disp)
353 ; PIC-MIPS32R2-NEXT: addiu $2, $2, %lo(_gp_disp)
354 ; PIC-MIPS32R2-NEXT: addiu $sp, $sp, -16
355 ; PIC-MIPS32R2-NEXT: $cfi0:
356 ; PIC-MIPS32R2-NEXT: .cfi_def_cfa_offset 16
357 ; PIC-MIPS32R2-NEXT: addu $2, $2, $25
358 ; PIC-MIPS32R2-NEXT: sltiu $1, $4, 7
359 ; PIC-MIPS32R2-NEXT: beqz $1, $BB0_3
360 ; PIC-MIPS32R2-NEXT: sw $4, 4($sp)
361 ; PIC-MIPS32R2-NEXT: $BB0_1: # %entry
362 ; PIC-MIPS32R2-NEXT: sll $1, $4, 2
363 ; PIC-MIPS32R2-NEXT: lw $3, %got($JTI0_0)($2)
364 ; PIC-MIPS32R2-NEXT: addu $1, $1, $3
365 ; PIC-MIPS32R2-NEXT: lw $1, %lo($JTI0_0)($1)
366 ; PIC-MIPS32R2-NEXT: addu $1, $1, $2
367 ; PIC-MIPS32R2-NEXT: jr.hb $1
368 ; PIC-MIPS32R2-NEXT: nop
369 ; PIC-MIPS32R2-NEXT: $BB0_2: # %sw.bb
370 ; PIC-MIPS32R2-NEXT: lw $1, %got($.str)($2)
371 ; PIC-MIPS32R2-NEXT: addiu $1, $1, %lo($.str)
372 ; PIC-MIPS32R2-NEXT: b $BB0_10
373 ; PIC-MIPS32R2-NEXT: sw $1, 8($sp)
374 ; PIC-MIPS32R2-NEXT: $BB0_3: # %sw.epilog
375 ; PIC-MIPS32R2-NEXT: lw $1, %got($.str.7)($2)
376 ; PIC-MIPS32R2-NEXT: addiu $1, $1, %lo($.str.7)
377 ; PIC-MIPS32R2-NEXT: b $BB0_10
378 ; PIC-MIPS32R2-NEXT: sw $1, 8($sp)
379 ; PIC-MIPS32R2-NEXT: $BB0_4: # %sw.bb1
380 ; PIC-MIPS32R2-NEXT: lw $1, %got($.str.1)($2)
381 ; PIC-MIPS32R2-NEXT: addiu $1, $1, %lo($.str.1)
382 ; PIC-MIPS32R2-NEXT: b $BB0_10
383 ; PIC-MIPS32R2-NEXT: sw $1, 8($sp)
384 ; PIC-MIPS32R2-NEXT: $BB0_5: # %sw.bb2
385 ; PIC-MIPS32R2-NEXT: lw $1, %got($.str.2)($2)
386 ; PIC-MIPS32R2-NEXT: addiu $1, $1, %lo($.str.2)
387 ; PIC-MIPS32R2-NEXT: b $BB0_10
388 ; PIC-MIPS32R2-NEXT: sw $1, 8($sp)
389 ; PIC-MIPS32R2-NEXT: $BB0_6: # %sw.bb3
390 ; PIC-MIPS32R2-NEXT: lw $1, %got($.str.3)($2)
391 ; PIC-MIPS32R2-NEXT: addiu $1, $1, %lo($.str.3)
392 ; PIC-MIPS32R2-NEXT: b $BB0_10
393 ; PIC-MIPS32R2-NEXT: sw $1, 8($sp)
394 ; PIC-MIPS32R2-NEXT: $BB0_7: # %sw.bb4
395 ; PIC-MIPS32R2-NEXT: lw $1, %got($.str.4)($2)
396 ; PIC-MIPS32R2-NEXT: addiu $1, $1, %lo($.str.4)
397 ; PIC-MIPS32R2-NEXT: b $BB0_10
398 ; PIC-MIPS32R2-NEXT: sw $1, 8($sp)
399 ; PIC-MIPS32R2-NEXT: $BB0_8: # %sw.bb5
400 ; PIC-MIPS32R2-NEXT: lw $1, %got($.str.5)($2)
401 ; PIC-MIPS32R2-NEXT: addiu $1, $1, %lo($.str.5)
402 ; PIC-MIPS32R2-NEXT: b $BB0_10
403 ; PIC-MIPS32R2-NEXT: sw $1, 8($sp)
404 ; PIC-MIPS32R2-NEXT: $BB0_9: # %sw.bb6
405 ; PIC-MIPS32R2-NEXT: lw $1, %got($.str.6)($2)
406 ; PIC-MIPS32R2-NEXT: addiu $1, $1, %lo($.str.6)
407 ; PIC-MIPS32R2-NEXT: sw $1, 8($sp)
408 ; PIC-MIPS32R2-NEXT: $BB0_10: # %return
409 ; PIC-MIPS32R2-NEXT: lw $2, 8($sp)
410 ; PIC-MIPS32R2-NEXT: jr $ra
411 ; PIC-MIPS32R2-NEXT: addiu $sp, $sp, 16
412 ;
413 ; PIC-MIPS32R6-LABEL: _Z3fooi:
414 ; PIC-MIPS32R6: # BB#0: # %entry
415 ; PIC-MIPS32R6-NEXT: lui $2, %hi(_gp_disp)
416 ; PIC-MIPS32R6-NEXT: addiu $2, $2, %lo(_gp_disp)
417 ; PIC-MIPS32R6-NEXT: addiu $sp, $sp, -16
418 ; PIC-MIPS32R6-NEXT: $cfi0:
419 ; PIC-MIPS32R6-NEXT: .cfi_def_cfa_offset 16
420 ; PIC-MIPS32R6-NEXT: addu $2, $2, $25
421 ; PIC-MIPS32R6-NEXT: sltiu $1, $4, 7
422 ; PIC-MIPS32R6-NEXT: beqz $1, $BB0_3
423 ; PIC-MIPS32R6-NEXT: sw $4, 4($sp)
424 ; PIC-MIPS32R6-NEXT: $BB0_1: # %entry
425 ; PIC-MIPS32R6-NEXT: sll $1, $4, 2
426 ; PIC-MIPS32R6-NEXT: lw $3, %got($JTI0_0)($2)
427 ; PIC-MIPS32R6-NEXT: addu $1, $1, $3
428 ; PIC-MIPS32R6-NEXT: lw $1, %lo($JTI0_0)($1)
429 ; PIC-MIPS32R6-NEXT: addu $1, $1, $2
430 ; PIC-MIPS32R6-NEXT: jr.hb $1
431 ; PIC-MIPS32R6-NEXT: nop
432 ; PIC-MIPS32R6-NEXT: $BB0_2: # %sw.bb
433 ; PIC-MIPS32R6-NEXT: lw $1, %got($.str)($2)
434 ; PIC-MIPS32R6-NEXT: addiu $1, $1, %lo($.str)
435 ; PIC-MIPS32R6-NEXT: b $BB0_10
436 ; PIC-MIPS32R6-NEXT: sw $1, 8($sp)
437 ; PIC-MIPS32R6-NEXT: $BB0_3: # %sw.epilog
438 ; PIC-MIPS32R6-NEXT: lw $1, %got($.str.7)($2)
439 ; PIC-MIPS32R6-NEXT: addiu $1, $1, %lo($.str.7)
440 ; PIC-MIPS32R6-NEXT: b $BB0_10
441 ; PIC-MIPS32R6-NEXT: sw $1, 8($sp)
442 ; PIC-MIPS32R6-NEXT: $BB0_4: # %sw.bb1
443 ; PIC-MIPS32R6-NEXT: lw $1, %got($.str.1)($2)
444 ; PIC-MIPS32R6-NEXT: addiu $1, $1, %lo($.str.1)
445 ; PIC-MIPS32R6-NEXT: b $BB0_10
446 ; PIC-MIPS32R6-NEXT: sw $1, 8($sp)
447 ; PIC-MIPS32R6-NEXT: $BB0_5: # %sw.bb2
448 ; PIC-MIPS32R6-NEXT: lw $1, %got($.str.2)($2)
449 ; PIC-MIPS32R6-NEXT: addiu $1, $1, %lo($.str.2)
450 ; PIC-MIPS32R6-NEXT: b $BB0_10
451 ; PIC-MIPS32R6-NEXT: sw $1, 8($sp)
452 ; PIC-MIPS32R6-NEXT: $BB0_6: # %sw.bb3
453 ; PIC-MIPS32R6-NEXT: lw $1, %got($.str.3)($2)
454 ; PIC-MIPS32R6-NEXT: addiu $1, $1, %lo($.str.3)
455 ; PIC-MIPS32R6-NEXT: b $BB0_10
456 ; PIC-MIPS32R6-NEXT: sw $1, 8($sp)
457 ; PIC-MIPS32R6-NEXT: $BB0_7: # %sw.bb4
458 ; PIC-MIPS32R6-NEXT: lw $1, %got($.str.4)($2)
459 ; PIC-MIPS32R6-NEXT: addiu $1, $1, %lo($.str.4)
460 ; PIC-MIPS32R6-NEXT: b $BB0_10
461 ; PIC-MIPS32R6-NEXT: sw $1, 8($sp)
462 ; PIC-MIPS32R6-NEXT: $BB0_8: # %sw.bb5
463 ; PIC-MIPS32R6-NEXT: lw $1, %got($.str.5)($2)
464 ; PIC-MIPS32R6-NEXT: addiu $1, $1, %lo($.str.5)
465 ; PIC-MIPS32R6-NEXT: b $BB0_10
466 ; PIC-MIPS32R6-NEXT: sw $1, 8($sp)
467 ; PIC-MIPS32R6-NEXT: $BB0_9: # %sw.bb6
468 ; PIC-MIPS32R6-NEXT: lw $1, %got($.str.6)($2)
469 ; PIC-MIPS32R6-NEXT: addiu $1, $1, %lo($.str.6)
470 ; PIC-MIPS32R6-NEXT: sw $1, 8($sp)
471 ; PIC-MIPS32R6-NEXT: $BB0_10: # %return
472 ; PIC-MIPS32R6-NEXT: lw $2, 8($sp)
473 ; PIC-MIPS32R6-NEXT: jr $ra
474 ; PIC-MIPS32R6-NEXT: addiu $sp, $sp, 16
475 ;
476 ; PIC-MIPS64R2-LABEL: _Z3fooi:
477 ; PIC-MIPS64R2: # BB#0: # %entry
478 ; PIC-MIPS64R2-NEXT: daddiu $sp, $sp, -16
479 ; PIC-MIPS64R2-NEXT: .Lcfi0:
480 ; PIC-MIPS64R2-NEXT: .cfi_def_cfa_offset 16
481 ; PIC-MIPS64R2-NEXT: lui $1, %hi(%neg(%gp_rel(_Z3fooi)))
482 ; PIC-MIPS64R2-NEXT: daddu $1, $1, $25
483 ; PIC-MIPS64R2-NEXT: daddiu $2, $1, %lo(%neg(%gp_rel(_Z3fooi)))
484 ; PIC-MIPS64R2-NEXT: sw $4, 4($sp)
485 ; PIC-MIPS64R2-NEXT: lwu $3, 4($sp)
486 ; PIC-MIPS64R2-NEXT: sltiu $1, $3, 7
487 ; PIC-MIPS64R2-NEXT: beqz $1, .LBB0_3
488 ; PIC-MIPS64R2-NEXT: nop
489 ; PIC-MIPS64R2-NEXT: .LBB0_1: # %entry
490 ; PIC-MIPS64R2-NEXT: daddiu $1, $zero, 8
491 ; PIC-MIPS64R2-NEXT: dmult $3, $1
492 ; PIC-MIPS64R2-NEXT: mflo $1
493 ; PIC-MIPS64R2-NEXT: ld $3, %got_page(.LJTI0_0)($2)
494 ; PIC-MIPS64R2-NEXT: daddu $1, $1, $3
495 ; PIC-MIPS64R2-NEXT: ld $1, %got_ofst(.LJTI0_0)($1)
496 ; PIC-MIPS64R2-NEXT: daddu $1, $1, $2
497 ; PIC-MIPS64R2-NEXT: jr.hb $1
498 ; PIC-MIPS64R2-NEXT: nop
499 ; PIC-MIPS64R2-NEXT: .LBB0_2: # %sw.bb
500 ; PIC-MIPS64R2-NEXT: ld $1, %got_page(.L.str)($2)
501 ; PIC-MIPS64R2-NEXT: daddiu $1, $1, %got_ofst(.L.str)
502 ; PIC-MIPS64R2-NEXT: b .LBB0_10
503 ; PIC-MIPS64R2-NEXT: sd $1, 8($sp)
504 ; PIC-MIPS64R2-NEXT: .LBB0_3: # %sw.epilog
505 ; PIC-MIPS64R2-NEXT: ld $1, %got_page(.L.str.7)($2)
506 ; PIC-MIPS64R2-NEXT: daddiu $1, $1, %got_ofst(.L.str.7)
507 ; PIC-MIPS64R2-NEXT: b .LBB0_10
508 ; PIC-MIPS64R2-NEXT: sd $1, 8($sp)
509 ; PIC-MIPS64R2-NEXT: .LBB0_4: # %sw.bb1
510 ; PIC-MIPS64R2-NEXT: ld $1, %got_page(.L.str.1)($2)
511 ; PIC-MIPS64R2-NEXT: daddiu $1, $1, %got_ofst(.L.str.1)
512 ; PIC-MIPS64R2-NEXT: b .LBB0_10
513 ; PIC-MIPS64R2-NEXT: sd $1, 8($sp)
514 ; PIC-MIPS64R2-NEXT: .LBB0_5: # %sw.bb2
515 ; PIC-MIPS64R2-NEXT: ld $1, %got_page(.L.str.2)($2)
516 ; PIC-MIPS64R2-NEXT: daddiu $1, $1, %got_ofst(.L.str.2)
517 ; PIC-MIPS64R2-NEXT: b .LBB0_10
518 ; PIC-MIPS64R2-NEXT: sd $1, 8($sp)
519 ; PIC-MIPS64R2-NEXT: .LBB0_6: # %sw.bb3
520 ; PIC-MIPS64R2-NEXT: ld $1, %got_page(.L.str.3)($2)
521 ; PIC-MIPS64R2-NEXT: daddiu $1, $1, %got_ofst(.L.str.3)
522 ; PIC-MIPS64R2-NEXT: b .LBB0_10
523 ; PIC-MIPS64R2-NEXT: sd $1, 8($sp)
524 ; PIC-MIPS64R2-NEXT: .LBB0_7: # %sw.bb4
525 ; PIC-MIPS64R2-NEXT: ld $1, %got_page(.L.str.4)($2)
526 ; PIC-MIPS64R2-NEXT: daddiu $1, $1, %got_ofst(.L.str.4)
527 ; PIC-MIPS64R2-NEXT: b .LBB0_10
528 ; PIC-MIPS64R2-NEXT: sd $1, 8($sp)
529 ; PIC-MIPS64R2-NEXT: .LBB0_8: # %sw.bb5
530 ; PIC-MIPS64R2-NEXT: ld $1, %got_page(.L.str.5)($2)
531 ; PIC-MIPS64R2-NEXT: daddiu $1, $1, %got_ofst(.L.str.5)
532 ; PIC-MIPS64R2-NEXT: b .LBB0_10
533 ; PIC-MIPS64R2-NEXT: sd $1, 8($sp)
534 ; PIC-MIPS64R2-NEXT: .LBB0_9: # %sw.bb6
535 ; PIC-MIPS64R2-NEXT: ld $1, %got_page(.L.str.6)($2)
536 ; PIC-MIPS64R2-NEXT: daddiu $1, $1, %got_ofst(.L.str.6)
537 ; PIC-MIPS64R2-NEXT: sd $1, 8($sp)
538 ; PIC-MIPS64R2-NEXT: .LBB0_10: # %return
539 ; PIC-MIPS64R2-NEXT: ld $2, 8($sp)
540 ; PIC-MIPS64R2-NEXT: jr $ra
541 ; PIC-MIPS64R2-NEXT: daddiu $sp, $sp, 16
542 ;
543 ; PIC-MIPS64R6-LABEL: _Z3fooi:
544 ; PIC-MIPS64R6: # BB#0: # %entry
545 ; PIC-MIPS64R6-NEXT: daddiu $sp, $sp, -16
546 ; PIC-MIPS64R6-NEXT: .Lcfi0:
547 ; PIC-MIPS64R6-NEXT: .cfi_def_cfa_offset 16
548 ; PIC-MIPS64R6-NEXT: lui $1, %hi(%neg(%gp_rel(_Z3fooi)))
549 ; PIC-MIPS64R6-NEXT: daddu $1, $1, $25
550 ; PIC-MIPS64R6-NEXT: daddiu $2, $1, %lo(%neg(%gp_rel(_Z3fooi)))
551 ; PIC-MIPS64R6-NEXT: sw $4, 4($sp)
552 ; PIC-MIPS64R6-NEXT: lwu $3, 4($sp)
553 ; PIC-MIPS64R6-NEXT: sltiu $1, $3, 7
554 ; PIC-MIPS64R6-NEXT: beqzc $1, .LBB0_3
555 ; PIC-MIPS64R6-NEXT: .LBB0_1: # %entry
556 ; PIC-MIPS64R6-NEXT: dsll $1, $3, 3
557 ; PIC-MIPS64R6-NEXT: ld $3, %got_page(.LJTI0_0)($2)
558 ; PIC-MIPS64R6-NEXT: daddu $1, $1, $3
559 ; PIC-MIPS64R6-NEXT: ld $1, %got_ofst(.LJTI0_0)($1)
560 ; PIC-MIPS64R6-NEXT: daddu $1, $1, $2
561 ; PIC-MIPS64R6-NEXT: jr.hb $1
562 ; PIC-MIPS64R6-NEXT: nop
563 ; PIC-MIPS64R6-NEXT: .LBB0_2: # %sw.bb
564 ; PIC-MIPS64R6-NEXT: ld $1, %got_page(.L.str)($2)
565 ; PIC-MIPS64R6-NEXT: daddiu $1, $1, %got_ofst(.L.str)
566 ; PIC-MIPS64R6-NEXT: b .LBB0_10
567 ; PIC-MIPS64R6-NEXT: sd $1, 8($sp)
568 ; PIC-MIPS64R6-NEXT: .LBB0_3: # %sw.epilog
569 ; PIC-MIPS64R6-NEXT: ld $1, %got_page(.L.str.7)($2)
570 ; PIC-MIPS64R6-NEXT: daddiu $1, $1, %got_ofst(.L.str.7)
571 ; PIC-MIPS64R6-NEXT: b .LBB0_10
572 ; PIC-MIPS64R6-NEXT: sd $1, 8($sp)
573 ; PIC-MIPS64R6-NEXT: .LBB0_4: # %sw.bb1
574 ; PIC-MIPS64R6-NEXT: ld $1, %got_page(.L.str.1)($2)
575 ; PIC-MIPS64R6-NEXT: daddiu $1, $1, %got_ofst(.L.str.1)
576 ; PIC-MIPS64R6-NEXT: b .LBB0_10
577 ; PIC-MIPS64R6-NEXT: sd $1, 8($sp)
578 ; PIC-MIPS64R6-NEXT: .LBB0_5: # %sw.bb2
579 ; PIC-MIPS64R6-NEXT: ld $1, %got_page(.L.str.2)($2)
580 ; PIC-MIPS64R6-NEXT: daddiu $1, $1, %got_ofst(.L.str.2)
581 ; PIC-MIPS64R6-NEXT: b .LBB0_10
582 ; PIC-MIPS64R6-NEXT: sd $1, 8($sp)
583 ; PIC-MIPS64R6-NEXT: .LBB0_6: # %sw.bb3
584 ; PIC-MIPS64R6-NEXT: ld $1, %got_page(.L.str.3)($2)
585 ; PIC-MIPS64R6-NEXT: daddiu $1, $1, %got_ofst(.L.str.3)
586 ; PIC-MIPS64R6-NEXT: b .LBB0_10
587 ; PIC-MIPS64R6-NEXT: sd $1, 8($sp)
588 ; PIC-MIPS64R6-NEXT: .LBB0_7: # %sw.bb4
589 ; PIC-MIPS64R6-NEXT: ld $1, %got_page(.L.str.4)($2)
590 ; PIC-MIPS64R6-NEXT: daddiu $1, $1, %got_ofst(.L.str.4)
591 ; PIC-MIPS64R6-NEXT: b .LBB0_10
592 ; PIC-MIPS64R6-NEXT: sd $1, 8($sp)
593 ; PIC-MIPS64R6-NEXT: .LBB0_8: # %sw.bb5
594 ; PIC-MIPS64R6-NEXT: ld $1, %got_page(.L.str.5)($2)
595 ; PIC-MIPS64R6-NEXT: daddiu $1, $1, %got_ofst(.L.str.5)
596 ; PIC-MIPS64R6-NEXT: b .LBB0_10
597 ; PIC-MIPS64R6-NEXT: sd $1, 8($sp)
598 ; PIC-MIPS64R6-NEXT: .LBB0_9: # %sw.bb6
599 ; PIC-MIPS64R6-NEXT: ld $1, %got_page(.L.str.6)($2)
600 ; PIC-MIPS64R6-NEXT: daddiu $1, $1, %got_ofst(.L.str.6)
601 ; PIC-MIPS64R6-NEXT: sd $1, 8($sp)
602 ; PIC-MIPS64R6-NEXT: .LBB0_10: # %return
603 ; PIC-MIPS64R6-NEXT: ld $2, 8($sp)
604 ; PIC-MIPS64R6-NEXT: jr $ra
605 ; PIC-MIPS64R6-NEXT: daddiu $sp, $sp, 16
606 entry:
607 %retval = alloca i8*, align 8
608 %Letter.addr = alloca i32, align 4
609 store i32 %Letter, i32* %Letter.addr, align 4
610 %0 = load i32, i32* %Letter.addr, align 4
611 switch i32 %0, label %sw.epilog [
612 i32 0, label %sw.bb
613 i32 1, label %sw.bb1
614 i32 2, label %sw.bb2
615 i32 3, label %sw.bb3
616 i32 4, label %sw.bb4
617 i32 5, label %sw.bb5
618 i32 6, label %sw.bb6
619 ]
620
621 sw.bb:
622 store i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i32 0, i32 0), i8** %retval, align 8
623 br label %return
624
625 sw.bb1:
626 store i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i32 0, i32 0), i8** %retval, align 8
627 br label %return
628
629 sw.bb2:
630 store i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.2, i32 0, i32 0), i8** %retval, align 8
631 br label %return
632
633 sw.bb3:
634 store i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i32 0, i32 0), i8** %retval, align 8
635 br label %return
636
637 sw.bb4:
638 store i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.4, i32 0, i32 0), i8** %retval, align 8
639 br label %return
640
641 sw.bb5:
642 store i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.5, i32 0, i32 0), i8** %retval, align 8
643 br label %return
644
645 sw.bb6:
646 store i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.6, i32 0, i32 0), i8** %retval, align 8
647 br label %return
648
649 sw.epilog:
650 store i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.7, i32 0, i32 0), i8** %retval, align 8
651 br label %return
652
653 return:
654 %1 = load i8*, i8** %retval, align 8
655 ret i8* %1
656 }
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; Except for the NACL version which isn't parsed by update_llc_test_checks.py
2
3 ; RUN: llc -mtriple=mipsel-unknown-linux-gnu -force-mips-long-branch -O3 \
4 ; RUN: -mcpu=mips32r2 -mattr=+use-indirect-jump-hazard -relocation-model=pic \
5 ; RUN: -verify-machineinstrs < %s | FileCheck %s -check-prefix=O32-PIC
6
7 ; RUN: llc -mtriple=mipsel-unknown-linux-gnu -mcpu=mips32r6 \
8 ; RUN: -force-mips-long-branch -O3 -mattr=+use-indirect-jump-hazard \
9 ; RUN: -relocation-model=pic -verify-machineinstrs < %s \
10 ; RUN: | FileCheck %s -check-prefix=O32-R6-PIC
11
12 ; RUN: llc -mtriple=mips64el-unknown-linux-gnu -mcpu=mips64r2 -target-abi=n64 \
13 ; RUN: -force-mips-long-branch -O3 -relocation-model=pic \
14 ; RUN: -mattr=+use-indirect-jump-hazard -verify-machineinstrs \
15 ; RUN: < %s | FileCheck %s -check-prefix=MIPS64
16
17 ; RUN: llc -mtriple=mips64el-unknown-linux-gnu -mcpu=mips64r6 -target-abi=n64 \
18 ; RUN: -force-mips-long-branch -O3 -mattr=+use-indirect-jump-hazard \
19 ; RUN: -relocation-model=pic -verify-machineinstrs < %s \
20 ; RUN: | FileCheck %s -check-prefix=N64-R6
21
22 ; Test that the long branches also get changed to their hazard variants.
23
24 @x = external global i32
25
26 define void @test1(i32 signext %s) {
27 ; O32-PIC-LABEL: test1:
28 ; O32-PIC: # BB#0: # %entry
29 ; O32-PIC-NEXT: lui $2, %hi(_gp_disp)
30 ; O32-PIC-NEXT: addiu $2, $2, %lo(_gp_disp)
31 ; O32-PIC-NEXT: bnez $4, $BB0_3
32 ; O32-PIC-NEXT: addu $2, $2, $25
33 ; O32-PIC-NEXT: # BB#1: # %entry
34 ; O32-PIC-NEXT: addiu $sp, $sp, -8
35 ; O32-PIC-NEXT: sw $ra, 0($sp)
36 ; O32-PIC-NEXT: lui $1, %hi(($BB0_4)-($BB0_2))
37 ; O32-PIC-NEXT: bal $BB0_2
38 ; O32-PIC-NEXT: addiu $1, $1, %lo(($BB0_4)-($BB0_2))
39 ; O32-PIC-NEXT: $BB0_2: # %entry
40 ; O32-PIC-NEXT: addu $1, $ra, $1
41 ; O32-PIC-NEXT: lw $ra, 0($sp)
42 ; O32-PIC-NEXT: jr.hb $1
43 ; O32-PIC-NEXT: addiu $sp, $sp, 8
44 ; O32-PIC-NEXT: $BB0_3: # %then
45 ; O32-PIC-NEXT: lw $1, %got(x)($2)
46 ; O32-PIC-NEXT: addiu $2, $zero, 1
47 ; O32-PIC-NEXT: sw $2, 0($1)
48 ; O32-PIC-NEXT: $BB0_4: # %end
49 ; O32-PIC-NEXT: jr $ra
50 ; O32-PIC-NEXT: nop
51 ;
52 ; O32-R6-PIC-LABEL: test1:
53 ; O32-R6-PIC: # BB#0: # %entry
54 ; O32-R6-PIC-NEXT: lui $2, %hi(_gp_disp)
55 ; O32-R6-PIC-NEXT: addiu $2, $2, %lo(_gp_disp)
56 ; O32-R6-PIC-NEXT: bnez $4, $BB0_3
57 ; O32-R6-PIC-NEXT: addu $2, $2, $25
58 ; O32-R6-PIC-NEXT: # BB#1: # %entry
59 ; O32-R6-PIC-NEXT: addiu $sp, $sp, -8
60 ; O32-R6-PIC-NEXT: sw $ra, 0($sp)
61 ; O32-R6-PIC-NEXT: lui $1, %hi(($BB0_4)-($BB0_2))
62 ; O32-R6-PIC-NEXT: bal $BB0_2
63 ; O32-R6-PIC-NEXT: addiu $1, $1, %lo(($BB0_4)-($BB0_2))
64 ; O32-R6-PIC-NEXT: $BB0_2: # %entry
65 ; O32-R6-PIC-NEXT: addu $1, $ra, $1
66 ; O32-R6-PIC-NEXT: lw $ra, 0($sp)
67 ; O32-R6-PIC-NEXT: jr.hb $1
68 ; O32-R6-PIC-NEXT: addiu $sp, $sp, 8
69 ; O32-R6-PIC-NEXT: $BB0_3: # %then
70 ; O32-R6-PIC-NEXT: lw $1, %got(x)($2)
71 ; O32-R6-PIC-NEXT: addiu $2, $zero, 1
72 ; O32-R6-PIC-NEXT: sw $2, 0($1)
73 ; O32-R6-PIC-NEXT: $BB0_4: # %end
74 ; O32-R6-PIC-NEXT: jrc $ra
75 ;
76 ; MIPS64-LABEL: test1:
77 ; MIPS64: # BB#0: # %entry
78 ; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(test1)))
79 ; MIPS64-NEXT: bnez $4, .LBB0_3
80 ; MIPS64-NEXT: daddu $2, $1, $25
81 ; MIPS64-NEXT: # BB#1: # %entry
82 ; MIPS64-NEXT: daddiu $sp, $sp, -16
83 ; MIPS64-NEXT: sd $ra, 0($sp)
84 ; MIPS64-NEXT: daddiu $1, $zero, %hi(.LBB0_4-.LBB0_2)
85 ; MIPS64-NEXT: dsll $1, $1, 16
86 ; MIPS64-NEXT: bal .LBB0_2
87 ; MIPS64-NEXT: daddiu $1, $1, %lo(.LBB0_4-.LBB0_2)
88 ; MIPS64-NEXT: .LBB0_2: # %entry
89 ; MIPS64-NEXT: daddu $1, $ra, $1
90 ; MIPS64-NEXT: ld $ra, 0($sp)
91 ; MIPS64-NEXT: jr.hb $1
92 ; MIPS64-NEXT: daddiu $sp, $sp, 16
93 ; MIPS64-NEXT: .LBB0_3: # %then
94 ; MIPS64-NEXT: daddiu $1, $2, %lo(%neg(%gp_rel(test1)))
95 ; MIPS64-NEXT: addiu $2, $zero, 1
96 ; MIPS64-NEXT: ld $1, %got_disp(x)($1)
97 ; MIPS64-NEXT: sw $2, 0($1)
98 ; MIPS64-NEXT: .LBB0_4: # %end
99 ; MIPS64-NEXT: jr $ra
100 ; MIPS64-NEXT: nop
101 ;
102 ; N64-R6-LABEL: test1:
103 ; N64-R6: # BB#0: # %entry
104 ; N64-R6-NEXT: lui $1, %hi(%neg(%gp_rel(test1)))
105 ; N64-R6-NEXT: bnez $4, .LBB0_3
106 ; N64-R6-NEXT: daddu $2, $1, $25
107 ; N64-R6-NEXT: # BB#1: # %entry
108 ; N64-R6-NEXT: daddiu $sp, $sp, -16
109 ; N64-R6-NEXT: sd $ra, 0($sp)
110 ; N64-R6-NEXT: daddiu $1, $zero, %hi(.LBB0_4-.LBB0_2)
111 ; N64-R6-NEXT: dsll $1, $1, 16
112 ; N64-R6-NEXT: bal .LBB0_2
113 ; N64-R6-NEXT: daddiu $1, $1, %lo(.LBB0_4-.LBB0_2)
114 ; N64-R6-NEXT: .LBB0_2: # %entry
115 ; N64-R6-NEXT: daddu $1, $ra, $1
116 ; N64-R6-NEXT: ld $ra, 0($sp)
117 ; N64-R6-NEXT: jr.hb $1
118 ; N64-R6-NEXT: daddiu $sp, $sp, 16
119 ; N64-R6-NEXT: .LBB0_3: # %then
120 ; N64-R6-NEXT: daddiu $1, $2, %lo(%neg(%gp_rel(test1)))
121 ; N64-R6-NEXT: addiu $2, $zero, 1
122 ; N64-R6-NEXT: ld $1, %got_disp(x)($1)
123 ; N64-R6-NEXT: sw $2, 0($1)
124 ; N64-R6-NEXT: .LBB0_4: # %end
125 ; N64-R6-NEXT: jrc $ra
126 entry:
127 %cmp = icmp eq i32 %s, 0
128 br i1 %cmp, label %end, label %then
129
130 then:
131 store i32 1, i32* @x, align 4
132 br label %end
133
134 end:
135 ret void
136
137 }
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc -mtriple=mips-unknwon-linux-gnu -mcpu=mips32r2 \
2 ; RUN: -mattr=+use-indirect-jump-hazard,+long-calls,+noabicalls %s -o - \
3 ; RUN: -verify-machineinstrs | FileCheck -check-prefix=O32 %s
4
5 ; RUN: llc -mtriple=mips64-unknown-linux-gnu -mcpu=mips64r2 -target-abi n32 \
6 ; RUN: -mattr=+use-indirect-jump-hazard,+long-calls,+noabicalls %s -o - \
7 ; RUN: -verify-machineinstrs | FileCheck -check-prefix=N32 %s
8
9 ; RUN: llc -mtriple=mips64-unknown-linux-gnu -mcpu=mips64r2 -target-abi n64 \
10 ; RUN: -mattr=+use-indirect-jump-hazard,+long-calls,+noabicalls %s -o - \
11 ; RUN: -verify-machineinstrs | FileCheck -check-prefix=N64 %s
12
13 declare void @callee()
14 declare void @llvm.memset.p0i8.i32(i8* nocapture writeonly, i8, i32, i32, i1)
15
16 @val = internal unnamed_addr global [20 x i32] zeroinitializer, align 4
17
18 ; Test that the long call sequence uses the hazard barrier instruction variant.
19 define void @caller() {
20 ; O32-LABEL: caller:
21 ; O32: # BB#0:
22 ; O32-NEXT: addiu $sp, $sp, -24
23 ; O32-NEXT: $cfi0:
24 ; O32-NEXT: .cfi_def_cfa_offset 24
25 ; O32-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill
26 ; O32-NEXT: $cfi1:
27 ; O32-NEXT: .cfi_offset 31, -4
28 ; O32-NEXT: lui $1, %hi(callee)
29 ; O32-NEXT: addiu $25, $1, %lo(callee)
30 ; O32-NEXT: jalr.hb $25
31 ; O32-NEXT: nop
32 ; O32-NEXT: lui $1, %hi(val)
33 ; O32-NEXT: addiu $1, $1, %lo(val)
34 ; O32-NEXT: lui $2, 20560
35 ; O32-NEXT: ori $2, $2, 20560
36 ; O32-NEXT: sw $2, 96($1)
37 ; O32-NEXT: sw $2, 92($1)
38 ; O32-NEXT: sw $2, 88($1)
39 ; O32-NEXT: sw $2, 84($1)
40 ; O32-NEXT: sw $2, 80($1)
41 ; O32-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload
42 ; O32-NEXT: jr $ra
43 ; O32-NEXT: addiu $sp, $sp, 24
44 ;
45 ; N32-LABEL: caller:
46 ; N32: # BB#0:
47 ; N32-NEXT: addiu $sp, $sp, -16
48 ; N32-NEXT: .Lcfi0:
49 ; N32-NEXT: .cfi_def_cfa_offset 16
50 ; N32-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill
51 ; N32-NEXT: .Lcfi1:
52 ; N32-NEXT: .cfi_offset 31, -8
53 ; N32-NEXT: lui $1, %hi(callee)
54 ; N32-NEXT: addiu $25, $1, %lo(callee)
55 ; N32-NEXT: jalr.hb $25
56 ; N32-NEXT: nop
57 ; N32-NEXT: lui $1, %hi(val)
58 ; N32-NEXT: addiu $1, $1, %lo(val)
59 ; N32-NEXT: lui $2, 1285
60 ; N32-NEXT: daddiu $2, $2, 1285
61 ; N32-NEXT: dsll $2, $2, 16
62 ; N32-NEXT: daddiu $2, $2, 1285
63 ; N32-NEXT: dsll $2, $2, 20
64 ; N32-NEXT: daddiu $2, $2, 20560
65 ; N32-NEXT: sdl $2, 88($1)
66 ; N32-NEXT: sdl $2, 80($1)
67 ; N32-NEXT: lui $3, 20560
68 ; N32-NEXT: ori $3, $3, 20560
69 ; N32-NEXT: sw $3, 96($1)
70 ; N32-NEXT: sdr $2, 95($1)
71 ; N32-NEXT: sdr $2, 87($1)
72 ; N32-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload
73 ; N32-NEXT: jr $ra
74 ; N32-NEXT: addiu $sp, $sp, 16
75 ;
76 ; N64-LABEL: caller:
77 ; N64: # BB#0:
78 ; N64-NEXT: daddiu $sp, $sp, -16
79 ; N64-NEXT: .Lcfi0:
80 ; N64-NEXT: .cfi_def_cfa_offset 16
81 ; N64-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill
82 ; N64-NEXT: .Lcfi1:
83 ; N64-NEXT: .cfi_offset 31, -8
84 ; N64-NEXT: lui $1, %highest(callee)
85 ; N64-NEXT: daddiu $1, $1, %higher(callee)
86 ; N64-NEXT: dsll $1, $1, 16
87 ; N64-NEXT: daddiu $1, $1, %hi(callee)
88 ; N64-NEXT: dsll $1, $1, 16
89 ; N64-NEXT: daddiu $25, $1, %lo(callee)
90 ; N64-NEXT: jalr.hb $25
91 ; N64-NEXT: nop
92 ; N64-NEXT: lui $1, %highest(val)
93 ; N64-NEXT: daddiu $1, $1, %higher(val)
94 ; N64-NEXT: dsll $1, $1, 16
95 ; N64-NEXT: daddiu $1, $1, %hi(val)
96 ; N64-NEXT: dsll $1, $1, 16
97 ; N64-NEXT: daddiu $1, $1, %lo(val)
98 ; N64-NEXT: lui $2, 1285
99 ; N64-NEXT: daddiu $2, $2, 1285
100 ; N64-NEXT: dsll $2, $2, 16
101 ; N64-NEXT: daddiu $2, $2, 1285
102 ; N64-NEXT: dsll $2, $2, 20
103 ; N64-NEXT: daddiu $2, $2, 20560
104 ; N64-NEXT: lui $3, 20560
105 ; N64-NEXT: sdl $2, 88($1)
106 ; N64-NEXT: sdl $2, 80($1)
107 ; N64-NEXT: ori $3, $3, 20560
108 ; N64-NEXT: sw $3, 96($1)
109 ; N64-NEXT: sdr $2, 95($1)
110 ; N64-NEXT: sdr $2, 87($1)
111 ; N64-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload
112 ; N64-NEXT: jr $ra
113 ; N64-NEXT: daddiu $sp, $sp, 16
114 call void @callee()
115 call void @llvm.memset.p0i8.i32(i8* bitcast (i32* getelementptr inbounds ([20 x i32], [20 x i32]* @val, i64 1, i32 0) to i8*), i8 80, i32 20, i32 4, i1 false)
116 ret void
117 }
118
0 ; RUN: not llc -mtriple=mips-unknown-linux -mcpu=mips32r2 -mattr=+micromips,+use-indirect-jump-hazard %s 2>&1 | FileCheck %s
1
2 ; Test that microMIPS and indirect jump with hazard barriers is not supported.
3
4 ; CHECK: LLVM ERROR: cannot combine indirect jumps with hazard barriers and microMIPS
0 ; RUN: not llc -mtriple=mips-unknown-linux -mcpu=mips32 -mattr=+use-indirect-jump-hazard %s 2>&1 | FileCheck %s
1
2 ; Test that mips32 and indirect jump with hazard barriers is not supported.
3
4 ; CHECK: LLVM ERROR: indirect jumps with hazard barriers requires MIPS32R2 or later
162162 ; STATIC32: j
163163 ; PIC64: jr $25
164164 ; PIC64R6: jrc $25
165 ; PIC64R6MM: jr $25
165 ; PIC64R6MM: jrc16 $25
166166 ; STATIC64: j
167167 ; PIC16: jalrc
168168