]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/Target/WebAssembly/WebAssemblyInstrCall.td
Vendor import of llvm trunk r338150:
[FreeBSD/FreeBSD.git] / lib / Target / WebAssembly / WebAssemblyInstrCall.td
1 //===- WebAssemblyInstrCall.td-WebAssembly Call codegen support -*- tablegen -*-
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// WebAssembly Call operand code-gen constructs.
12 ///
13 //===----------------------------------------------------------------------===//
14
15 // TODO: addr64: These currently assume the callee address is 32-bit.
16 // FIXME: add $type to first call_indirect asmstr (and maybe $flags)
17
18 let Defs = [ARGUMENTS] in {
19
20 // Call sequence markers. These have an immediate which represents the amount of
21 // stack space to allocate or free, which is used for varargs lowering.
22 let Uses = [SP32, SP64], Defs = [SP32, SP64], isCodeGenOnly = 1 in {
23 defm ADJCALLSTACKDOWN : NRI<(outs), (ins i32imm:$amt, i32imm:$amt2),
24                             [(WebAssemblycallseq_start timm:$amt, timm:$amt2)]>;
25 defm ADJCALLSTACKUP : NRI<(outs), (ins i32imm:$amt, i32imm:$amt2),
26                           [(WebAssemblycallseq_end timm:$amt, timm:$amt2)]>;
27 } // isCodeGenOnly = 1
28
29 multiclass CALL<WebAssemblyRegClass vt, string prefix> {
30   defm CALL_#vt : I<(outs vt:$dst), (ins function32_op:$callee, variable_ops),
31                     (outs), (ins function32_op:$callee),
32                     [(set vt:$dst, (WebAssemblycall1 (i32 imm:$callee)))],
33                     !strconcat(prefix, "call\t$dst, $callee"),
34                     !strconcat(prefix, "call\t$callee"),
35                     0x10>;
36
37   let isCodeGenOnly = 1 in {
38     defm PCALL_INDIRECT_#vt : I<(outs vt:$dst), (ins I32:$callee, variable_ops),
39                                 (outs), (ins I32:$callee),
40                                [(set vt:$dst, (WebAssemblycall1 I32:$callee))],
41                                "PSEUDO CALL INDIRECT\t$callee",
42                                "PSEUDO CALL INDIRECT\t$callee">;
43   } // isCodeGenOnly = 1
44
45   defm CALL_INDIRECT_#vt : I<(outs vt:$dst),
46                              (ins TypeIndex:$type, i32imm:$flags, variable_ops),
47                              (outs), (ins TypeIndex:$type, i32imm:$flags),
48                              [],
49                              !strconcat(prefix, "call_indirect\t$dst"),
50                              !strconcat(prefix, "call_indirect\t$type"),
51                              0x11>;
52 }
53
54 multiclass SIMD_CALL<ValueType vt, string prefix> {
55   defm CALL_#vt : SIMD_I<(outs V128:$dst), (ins function32_op:$callee,
56                            variable_ops),
57                          (outs), (ins function32_op:$callee),
58                          [(set (vt V128:$dst),
59                             (WebAssemblycall1 (i32 imm:$callee)))],
60                          !strconcat(prefix, "call\t$dst, $callee"),
61                          !strconcat(prefix, "call\t$callee"),
62                          0x10>;
63
64   let isCodeGenOnly = 1 in {
65     defm PCALL_INDIRECT_#vt : SIMD_I<(outs V128:$dst),
66                                      (ins I32:$callee, variable_ops),
67                                      (outs), (ins I32:$callee),
68                                      [(set (vt V128:$dst),
69                                            (WebAssemblycall1 I32:$callee))],
70                                      "PSEUDO CALL INDIRECT\t$callee",
71                                      "PSEUDO CALL INDIRECT\t$callee">;
72   } // isCodeGenOnly = 1
73
74   defm CALL_INDIRECT_#vt : SIMD_I<(outs V128:$dst),
75                                   (ins TypeIndex:$type, i32imm:$flags,
76                                         variable_ops),
77                                   (outs), (ins TypeIndex:$type, i32imm:$flags),
78                                   [],
79                                   !strconcat(prefix,
80                                     "call_indirect\t$dst"),
81                                   !strconcat(prefix, "call_indirect\t$type"),
82                                   0x11>;
83 }
84
85 let Uses = [SP32, SP64], isCall = 1 in {
86   defm "" : CALL<I32, "i32.">;
87   defm "" : CALL<I64, "i64.">;
88   defm "" : CALL<F32, "f32.">;
89   defm "" : CALL<F64, "f64.">;
90   defm "" : CALL<EXCEPT_REF, "except_ref.">;
91   defm "" : SIMD_CALL<v16i8, "i8x16.">;
92   defm "" : SIMD_CALL<v8i16, "i16x8.">;
93   defm "" : SIMD_CALL<v4i32, "i32x4.">;
94   defm "" : SIMD_CALL<v4f32, "f32x4.">;
95
96   defm CALL_VOID : I<(outs), (ins function32_op:$callee, variable_ops),
97                      (outs), (ins function32_op:$callee),
98                      [(WebAssemblycall0 (i32 imm:$callee))],
99                      "call    \t$callee", "call\t$callee", 0x10>;
100
101   let isCodeGenOnly = 1 in {
102     defm PCALL_INDIRECT_VOID : I<(outs), (ins I32:$callee, variable_ops),
103                                  (outs), (ins I32:$callee),
104                                  [(WebAssemblycall0 I32:$callee)],
105                                  "PSEUDO CALL INDIRECT\t$callee",
106                                  "PSEUDO CALL INDIRECT\t$callee">;
107   } // isCodeGenOnly = 1
108
109   defm CALL_INDIRECT_VOID : I<(outs),
110                               (ins TypeIndex:$type, i32imm:$flags,
111                                 variable_ops),
112                               (outs), (ins TypeIndex:$type, i32imm:$flags),
113                               [],
114                               "call_indirect\t", "call_indirect\t$type",
115                               0x11>;
116 } // Uses = [SP32,SP64], isCall = 1
117
118 } // Defs = [ARGUMENTS]
119
120 // Patterns for matching a direct call to a global address.
121 def : Pat<(i32 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
122           (CALL_I32 tglobaladdr:$callee)>;
123 def : Pat<(i64 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
124           (CALL_I64 tglobaladdr:$callee)>;
125 def : Pat<(f32 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
126           (CALL_F32 tglobaladdr:$callee)>;
127 def : Pat<(f64 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
128           (CALL_F64 tglobaladdr:$callee)>;
129 def : Pat<(v16i8 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
130           (CALL_v16i8 tglobaladdr:$callee)>, Requires<[HasSIMD128]>;
131 def : Pat<(v8i16 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
132           (CALL_v8i16 tglobaladdr:$callee)>, Requires<[HasSIMD128]>;
133 def : Pat<(v4i32 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
134           (CALL_v4i32 tglobaladdr:$callee)>, Requires<[HasSIMD128]>;
135 def : Pat<(v4f32 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
136           (CALL_v4f32 tglobaladdr:$callee)>, Requires<[HasSIMD128]>;
137 def : Pat<(ExceptRef
138            (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
139           (CALL_EXCEPT_REF tglobaladdr:$callee)>;
140 def : Pat<(WebAssemblycall0 (WebAssemblywrapper tglobaladdr:$callee)),
141           (CALL_VOID tglobaladdr:$callee)>;
142
143 // Patterns for matching a direct call to an external symbol.
144 def : Pat<(i32 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
145           (CALL_I32 texternalsym:$callee)>;
146 def : Pat<(i64 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
147           (CALL_I64 texternalsym:$callee)>;
148 def : Pat<(f32 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
149           (CALL_F32 texternalsym:$callee)>;
150 def : Pat<(f64 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
151           (CALL_F64 texternalsym:$callee)>;
152 def : Pat<(v16i8 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
153           (CALL_v16i8 texternalsym:$callee)>, Requires<[HasSIMD128]>;
154 def : Pat<(v8i16 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
155           (CALL_v8i16 texternalsym:$callee)>, Requires<[HasSIMD128]>;
156 def : Pat<(v4i32 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
157           (CALL_v4i32 texternalsym:$callee)>, Requires<[HasSIMD128]>;
158 def : Pat<(v4f32 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
159           (CALL_v4f32 texternalsym:$callee)>, Requires<[HasSIMD128]>;
160 def : Pat<(ExceptRef
161            (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
162           (CALL_EXCEPT_REF texternalsym:$callee)>;
163 def : Pat<(WebAssemblycall0 (WebAssemblywrapper texternalsym:$callee)),
164           (CALL_VOID texternalsym:$callee)>;