|  | 
| 15 | 15 | #include "MCTargetDesc/SystemZGNUInstPrinter.h" | 
| 16 | 16 | #include "MCTargetDesc/SystemZHLASMInstPrinter.h" | 
| 17 | 17 | #include "MCTargetDesc/SystemZMCExpr.h" | 
|  | 18 | +#include "MCTargetDesc/SystemZMCTargetDesc.h" | 
| 18 | 19 | #include "SystemZConstantPoolValue.h" | 
| 19 | 20 | #include "SystemZMCInstLower.h" | 
| 20 | 21 | #include "TargetInfo/SystemZTargetInfo.h" | 
| @@ -662,6 +663,23 @@ void SystemZAsmPrinter::emitInstruction(const MachineInstr *MI) { | 
| 662 | 663 |  LowerPATCHPOINT(*MI, Lower); | 
| 663 | 664 |  return; | 
| 664 | 665 | 
 | 
|  | 666 | + case TargetOpcode::PATCHABLE_FUNCTION_ENTER: | 
|  | 667 | + LowerPATCHABLE_FUNCTION_ENTER(*MI, Lower); | 
|  | 668 | + return; | 
|  | 669 | + | 
|  | 670 | + case TargetOpcode::PATCHABLE_RET: | 
|  | 671 | + LowerPATCHABLE_RET(*MI, Lower); | 
|  | 672 | + return; | 
|  | 673 | + | 
|  | 674 | + case TargetOpcode::PATCHABLE_FUNCTION_EXIT: | 
|  | 675 | + llvm_unreachable("PATCHABLE_FUNCTION_EXIT should never be emitted"); | 
|  | 676 | + | 
|  | 677 | + case TargetOpcode::PATCHABLE_TAIL_CALL: | 
|  | 678 | + // TODO: Define a trampoline `__xray_FunctionTailExit` and differentiate a | 
|  | 679 | + // normal function exit from a tail exit. | 
|  | 680 | + llvm_unreachable("Tail call is handled in the normal case. See comments " | 
|  | 681 | + "around this assert."); | 
|  | 682 | + | 
| 665 | 683 |  case SystemZ::EXRL_Pseudo: { | 
| 666 | 684 |  unsigned TargetInsOpc = MI->getOperand(0).getImm(); | 
| 667 | 685 |  Register LenMinus1Reg = MI->getOperand(1).getReg(); | 
| @@ -844,6 +862,84 @@ void SystemZAsmPrinter::LowerPATCHPOINT(const MachineInstr &MI, | 
| 844 | 862 |  getSubtargetInfo()); | 
| 845 | 863 | } | 
| 846 | 864 | 
 | 
|  | 865 | +void SystemZAsmPrinter::LowerPATCHABLE_FUNCTION_ENTER( | 
|  | 866 | + const MachineInstr &MI, SystemZMCInstLower &Lower) { | 
|  | 867 | + // .begin: | 
|  | 868 | + // j .end # -> stmg %r2, %r15, 16(%r15) | 
|  | 869 | + // nop | 
|  | 870 | + // llilf %2, FuncID | 
|  | 871 | + // brasl %r14, __xray_FunctionEntry@GOT | 
|  | 872 | + // .end: | 
|  | 873 | + // | 
|  | 874 | + // Update compiler-rt/lib/xray/xray_s390x.cpp accordingly when number | 
|  | 875 | + // of instructions change. | 
|  | 876 | + bool HasVectorFeature = | 
|  | 877 | + TM.getMCSubtargetInfo()->hasFeature(SystemZ::FeatureVector) && | 
|  | 878 | + !TM.getMCSubtargetInfo()->hasFeature(SystemZ::FeatureSoftFloat); | 
|  | 879 | + MCSymbol *FuncEntry = OutContext.getOrCreateSymbol( | 
|  | 880 | + HasVectorFeature ? "__xray_FunctionEntryVec" : "__xray_FunctionEntry"); | 
|  | 881 | + MCSymbol *BeginOfSled = OutContext.createTempSymbol("xray_sled_", true); | 
|  | 882 | + MCSymbol *EndOfSled = OutContext.createTempSymbol(); | 
|  | 883 | + OutStreamer->emitLabel(BeginOfSled); | 
|  | 884 | + EmitToStreamer(*OutStreamer, | 
|  | 885 | + MCInstBuilder(SystemZ::J) | 
|  | 886 | + .addExpr(MCSymbolRefExpr::create(EndOfSled, OutContext))); | 
|  | 887 | + EmitNop(OutContext, *OutStreamer, 2, getSubtargetInfo()); | 
|  | 888 | + EmitToStreamer(*OutStreamer, | 
|  | 889 | + MCInstBuilder(SystemZ::LLILF).addReg(SystemZ::R2D).addImm(0)); | 
|  | 890 | + EmitToStreamer(*OutStreamer, | 
|  | 891 | + MCInstBuilder(SystemZ::BRASL) | 
|  | 892 | + .addReg(SystemZ::R14D) | 
|  | 893 | + .addExpr(MCSymbolRefExpr::create( | 
|  | 894 | + FuncEntry, MCSymbolRefExpr::VK_PLT, OutContext))); | 
|  | 895 | + OutStreamer->emitLabel(EndOfSled); | 
|  | 896 | + recordSled(BeginOfSled, MI, SledKind::FUNCTION_ENTER, 2); | 
|  | 897 | +} | 
|  | 898 | + | 
|  | 899 | +void SystemZAsmPrinter::LowerPATCHABLE_RET(const MachineInstr &MI, | 
|  | 900 | + SystemZMCInstLower &Lower) { | 
|  | 901 | + unsigned OpCode = MI.getOperand(0).getImm(); | 
|  | 902 | + MCSymbol *FallthroughLabel = nullptr; | 
|  | 903 | + if (OpCode == SystemZ::CondReturn) { | 
|  | 904 | + FallthroughLabel = OutContext.createTempSymbol(); | 
|  | 905 | + int64_t Cond0 = MI.getOperand(1).getImm(); | 
|  | 906 | + int64_t Cond1 = MI.getOperand(2).getImm(); | 
|  | 907 | + EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BRC) | 
|  | 908 | + .addImm(Cond0) | 
|  | 909 | + .addImm(Cond1 ^ Cond0) | 
|  | 910 | + .addExpr(MCSymbolRefExpr::create( | 
|  | 911 | + FallthroughLabel, OutContext))); | 
|  | 912 | + } | 
|  | 913 | + // .begin: | 
|  | 914 | + // br %r14 # -> stmg %r2, %r15, 24(%r15) | 
|  | 915 | + // nop | 
|  | 916 | + // nop | 
|  | 917 | + // llilf %2,FuncID | 
|  | 918 | + // j __xray_FunctionExit@GOT | 
|  | 919 | + // | 
|  | 920 | + // Update compiler-rt/lib/xray/xray_s390x.cpp accordingly when number | 
|  | 921 | + // of instructions change. | 
|  | 922 | + bool HasVectorFeature = | 
|  | 923 | + TM.getMCSubtargetInfo()->hasFeature(SystemZ::FeatureVector) && | 
|  | 924 | + !TM.getMCSubtargetInfo()->hasFeature(SystemZ::FeatureSoftFloat); | 
|  | 925 | + MCSymbol *FuncExit = OutContext.getOrCreateSymbol( | 
|  | 926 | + HasVectorFeature ? "__xray_FunctionExitVec" : "__xray_FunctionExit"); | 
|  | 927 | + MCSymbol *BeginOfSled = OutContext.createTempSymbol("xray_sled_", true); | 
|  | 928 | + OutStreamer->emitLabel(BeginOfSled); | 
|  | 929 | + EmitToStreamer(*OutStreamer, | 
|  | 930 | + MCInstBuilder(SystemZ::BR).addReg(SystemZ::R14D)); | 
|  | 931 | + EmitNop(OutContext, *OutStreamer, 4, getSubtargetInfo()); | 
|  | 932 | + EmitToStreamer(*OutStreamer, | 
|  | 933 | + MCInstBuilder(SystemZ::LLILF).addReg(SystemZ::R2D).addImm(0)); | 
|  | 934 | + EmitToStreamer(*OutStreamer, | 
|  | 935 | + MCInstBuilder(SystemZ::J) | 
|  | 936 | + .addExpr(MCSymbolRefExpr::create( | 
|  | 937 | + FuncExit, MCSymbolRefExpr::VK_PLT, OutContext))); | 
|  | 938 | + if (FallthroughLabel) | 
|  | 939 | + OutStreamer->emitLabel(FallthroughLabel); | 
|  | 940 | + recordSled(BeginOfSled, MI, SledKind::FUNCTION_EXIT, 2); | 
|  | 941 | +} | 
|  | 942 | + | 
| 847 | 943 | // The *alignment* of 128-bit vector types is different between the software | 
| 848 | 944 | // and hardware vector ABIs. If the there is an externally visible use of a | 
| 849 | 945 | // vector type in the module it should be annotated with an attribute. | 
|  | 
0 commit comments