|
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