diff options
Diffstat (limited to 'lib/Target/SystemZ/SystemZInstrInfo.td')
-rw-r--r-- | lib/Target/SystemZ/SystemZInstrInfo.td | 67 |
1 files changed, 64 insertions, 3 deletions
diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td index 7ceb948a35..decc9268ac 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/lib/Target/SystemZ/SystemZInstrInfo.td @@ -14,13 +14,33 @@ include "SystemZInstrFormats.td" //===----------------------------------------------------------------------===// +// Type Constraints. +//===----------------------------------------------------------------------===// +class SDTCisI8<int OpNum> : SDTCisVT<OpNum, i8>; +class SDTCisI16<int OpNum> : SDTCisVT<OpNum, i16>; +class SDTCisI32<int OpNum> : SDTCisVT<OpNum, i32>; +class SDTCisI64<int OpNum> : SDTCisVT<OpNum, i64>; + +//===----------------------------------------------------------------------===// +// Type Profiles. +//===----------------------------------------------------------------------===// +def SDT_SystemZCall : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>; +def SDT_SystemZCallSeqStart : SDCallSeqStart<[SDTCisI64<0>]>; +def SDT_SystemZCallSeqEnd : SDCallSeqEnd<[SDTCisI64<0>, SDTCisI64<1>]>; + +//===----------------------------------------------------------------------===// // SystemZ Specific Node Definitions. //===----------------------------------------------------------------------===// def SystemZretflag : SDNode<"SystemZISD::RET_FLAG", SDTNone, [SDNPHasChain, SDNPOptInFlag]>; - -let neverHasSideEffects = 1 in -def NOP : Pseudo<(outs), (ins), "# no-op", []>; +def SystemZcall : SDNode<"SystemZISD::CALL", SDT_SystemZCall, + [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>; +def SystemZcallseq_start : + SDNode<"ISD::CALLSEQ_START", SDT_SystemZCallSeqStart, + [SDNPHasChain, SDNPOutFlag]>; +def SystemZcallseq_end : + SDNode<"ISD::CALLSEQ_END", SDT_SystemZCallSeqEnd, + [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; //===----------------------------------------------------------------------===// // Instruction Pattern Stuff. @@ -172,6 +192,23 @@ def laaddr : Operand<i64>, let MIOperandInfo = (ops ADDR64:$base, i64imm:$disp, ADDR64:$index); } +//===----------------------------------------------------------------------===// +// Instruction list.. + +// ADJCALLSTACKDOWN/UP implicitly use/def SP because they may be expanded into +// a stack adjustment and the codegen must know that they may modify the stack +// pointer before prolog-epilog rewriting occurs. +// Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become +// sub / add which can clobber R15D. +let Defs = [R15D], Uses = [R15D] in { +def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i64imm:$amt), + "#ADJCALLSTACKDOWN", + [(SystemZcallseq_start timm:$amt)]>; +def ADJCALLSTACKUP : Pseudo<(outs), (ins i64imm:$amt1, i64imm:$amt2), + "#ADJCALLSTACKUP", + [(SystemZcallseq_end timm:$amt1, timm:$amt2)]>; +} + //===----------------------------------------------------------------------===// // Control Flow Instructions... @@ -182,6 +219,22 @@ let isReturn = 1, isTerminator = 1, Uses = [R14D] in { def RET : Pseudo<(outs), (ins), "br\t%r14", [(SystemZretflag)]>; } +//===----------------------------------------------------------------------===// +// Call Instructions... +// + +let isCall = 1 in + // All calls clobber the non-callee saved registers. R15 is marked as + // a use to prevent stack-pointer assignments that appear immediately + // before calls from potentially appearing dead. Uses for argument + // registers are added manually. + let Defs = [R0D, R1D, R3D, R4D, R5D, R14D, R15D], + Uses = [R15D] in { + def CALLi : Pseudo<(outs), (ins i64imm:$dst, variable_ops), + "brasl\t%r14, $dst", [(SystemZcall imm:$dst)]>; + def CALLr : Pseudo<(outs), (ins ADDR64:$dst, variable_ops), + "brasl\t%r14, $dst", [(SystemZcall ADDR64:$dst)]>; + } //===----------------------------------------------------------------------===// // Miscellaneous Instructions. @@ -193,6 +246,8 @@ def LA64r : Pseudo<(outs GR64:$dst), (ins laaddr:$src), "lay\t{$dst, $src}", [(set GR64:$dst, laaddr:$src)]>; +let neverHasSideEffects = 1 in +def NOP : Pseudo<(outs), (ins), "# no-op", []>; //===----------------------------------------------------------------------===// // Move Instructions @@ -525,3 +580,9 @@ def : Pat<(sext_inreg GR64:$src, i32), def : Pat<(extloadi64i8 rriaddr:$src), (MOVZX64rm8 rriaddr:$src)>; def : Pat<(extloadi64i16 rriaddr:$src), (MOVZX64rm16 rriaddr:$src)>; def : Pat<(extloadi64i32 rriaddr:$src), (MOVZX64rm32 rriaddr:$src)>; + +// calls +def : Pat<(SystemZcall (i64 tglobaladdr:$dst)), + (CALLi tglobaladdr:$dst)>; +def : Pat<(SystemZcall (i64 texternalsym:$dst)), + (CALLi texternalsym:$dst)>; |