19
19
#include " Z80MachineFunctionInfo.h"
20
20
#include " Z80RegisterInfo.h"
21
21
#include " Z80Subtarget.h"
22
+ #include " llvm/ADT/StringSwitch.h"
22
23
#include " llvm/CodeGen/Analysis.h"
23
24
#include " llvm/CodeGen/GlobalISel/MIPatternMatch.h"
24
25
#include " llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
@@ -425,12 +426,18 @@ bool Z80CallLowering::isEligibleForTailCallOptimization(
425
426
if (!Info.IsTailCall )
426
427
return false ;
427
428
429
+ const Function *CalleeF = Info.CB ? Info.CB ->getCalledFunction () : nullptr ;
428
430
CallingConv::ID CalleeCC = Info.CallConv ;
429
- MachineFunction &MF = MIRBuilder.getMF ();
430
- const Function &CallerF = MF .getFunction ();
431
+ MachineFunction &CallerMF = MIRBuilder.getMF ();
432
+ const Function &CallerF = CallerMF .getFunction ();
431
433
432
434
LLVM_DEBUG (dbgs () << " Attempting to lower call as tail call\n " );
433
435
436
+ if (CalleeF && CalleeF->hasFnAttribute (" interrupt" )) {
437
+ LLVM_DEBUG (dbgs () << " ... Cannot tail call interrupt handlers.\n " );
438
+ return false ;
439
+ }
440
+
434
441
if (Info.SwiftErrorVReg ) {
435
442
// TODO: We should handle this.
436
443
// Note that this is also handled by the check for no outgoing arguments.
@@ -465,7 +472,7 @@ bool Z80CallLowering::isEligibleForTailCallOptimization(
465
472
}
466
473
467
474
// If we have -tailcallopt, then we're done.
468
- if (MF .getTarget ().Options .GuaranteedTailCallOpt )
475
+ if (CallerMF .getTarget ().Options .GuaranteedTailCallOpt )
469
476
return canGuaranteeTCO (CalleeCC) && CalleeCC == CallerF.getCallingConv ();
470
477
471
478
// We don't have -tailcallopt, so we're allowed to change the ABI (sibcall).
@@ -478,14 +485,14 @@ bool Z80CallLowering::isEligibleForTailCallOptimization(
478
485
479
486
// Verify that the incoming and outgoing arguments from the callee are
480
487
// safe to tail call.
481
- if (!doCallerAndCalleePassArgsTheSameWay (Info, MF , InArgs)) {
488
+ if (!doCallerAndCalleePassArgsTheSameWay (Info, CallerMF , InArgs)) {
482
489
LLVM_DEBUG (
483
490
dbgs ()
484
491
<< " ... Caller and callee have incompatible calling conventions.\n " );
485
492
return false ;
486
493
}
487
494
488
- if (!areCalleeOutgoingArgsTailCallable (Info, MF , OutArgs))
495
+ if (!areCalleeOutgoingArgsTailCallable (Info, CallerMF , OutArgs))
489
496
return false ;
490
497
491
498
LLVM_DEBUG (dbgs () << " ... Call is eligible for tail call optimization.\n " );
@@ -506,14 +513,6 @@ bool Z80CallLowering::lowerTailCall(MachineIRBuilder &MIRBuilder,
506
513
// True when we're tail calling, but without -tailcallopt.
507
514
bool IsSibCall = !MF.getTarget ().Options .GuaranteedTailCallOpt ;
508
515
509
- // TODO: Right now, regbankselect doesn't know how to handle the rtcGPR64
510
- // register class. Until we can do that, we should fall back here.
511
- if (F.hasFnAttribute (" branch-target-enforcement" )) {
512
- LLVM_DEBUG (
513
- dbgs () << " Cannot lower indirect tail calls with BTI enabled yet.\n " );
514
- return false ;
515
- }
516
-
517
516
MachineInstrBuilder CallSeqStart;
518
517
if (!IsSibCall)
519
518
CallSeqStart = MIRBuilder.buildInstr (TII.getCallFrameSetupOpcode ());
@@ -779,11 +778,17 @@ bool Z80CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
779
778
FunctionLoweringInfo &FLI) const {
780
779
assert (!Val == VRegs.empty () && " Return value without a vreg" );
781
780
MachineFunction &MF = MIRBuilder.getMF ();
781
+ const Function &F = MF.getFunction ();
782
782
LLVMContext &Ctx = MF.getFunction ().getContext ();
783
783
auto &FuncInfo = *MF.getInfo <Z80MachineFunctionInfo>();
784
784
const auto &STI = MF.getSubtarget <Z80Subtarget>();
785
- auto MIB =
786
- MIRBuilder.buildInstrNoInsert (STI.is24Bit () ? Z80::RET24 : Z80::RET16);
785
+
786
+ bool Is24Bit = STI.is24Bit ();
787
+ auto MIB = MIRBuilder.buildInstrNoInsert (
788
+ StringSwitch<unsigned >(F.getFnAttribute (" interrupt" ).getValueAsString ())
789
+ .Cases (" Generic" , " Nested" , Is24Bit ? Z80::RETI24 : Z80::RETI16)
790
+ .Case (" NMI" , Is24Bit ? Z80::RETN24 : Z80::RETN16)
791
+ .Default (Is24Bit ? Z80::RET24 : Z80::RET16));
787
792
788
793
Register SRetReturnReg = FuncInfo.getSRetReturnReg ();
789
794
assert ((!SRetReturnReg || VRegs.empty ()) &&
0 commit comments