• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
18let 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.
22let Uses = [SP32, SP64], Defs = [SP32, SP64], isCodeGenOnly = 1 in {
23defm ADJCALLSTACKDOWN : NRI<(outs), (ins i32imm:$amt, i32imm:$amt2),
24                            [(WebAssemblycallseq_start timm:$amt, timm:$amt2)]>;
25defm ADJCALLSTACKUP : NRI<(outs), (ins i32imm:$amt, i32imm:$amt2),
26                          [(WebAssemblycallseq_end timm:$amt, timm:$amt2)]>;
27} // isCodeGenOnly = 1
28
29multiclass 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
54multiclass 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
85let 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.
121def : Pat<(i32 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
122          (CALL_I32 tglobaladdr:$callee)>;
123def : Pat<(i64 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
124          (CALL_I64 tglobaladdr:$callee)>;
125def : Pat<(f32 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
126          (CALL_F32 tglobaladdr:$callee)>;
127def : Pat<(f64 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
128          (CALL_F64 tglobaladdr:$callee)>;
129def : Pat<(v16i8 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
130          (CALL_v16i8 tglobaladdr:$callee)>, Requires<[HasSIMD128]>;
131def : Pat<(v8i16 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
132          (CALL_v8i16 tglobaladdr:$callee)>, Requires<[HasSIMD128]>;
133def : Pat<(v4i32 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
134          (CALL_v4i32 tglobaladdr:$callee)>, Requires<[HasSIMD128]>;
135def : Pat<(v4f32 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
136          (CALL_v4f32 tglobaladdr:$callee)>, Requires<[HasSIMD128]>;
137def : Pat<(ExceptRef
138           (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
139          (CALL_EXCEPT_REF tglobaladdr:$callee)>;
140def : Pat<(WebAssemblycall0 (WebAssemblywrapper tglobaladdr:$callee)),
141          (CALL_VOID tglobaladdr:$callee)>;
142
143// Patterns for matching a direct call to an external symbol.
144def : Pat<(i32 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
145          (CALL_I32 texternalsym:$callee)>;
146def : Pat<(i64 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
147          (CALL_I64 texternalsym:$callee)>;
148def : Pat<(f32 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
149          (CALL_F32 texternalsym:$callee)>;
150def : Pat<(f64 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
151          (CALL_F64 texternalsym:$callee)>;
152def : Pat<(v16i8 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
153          (CALL_v16i8 texternalsym:$callee)>, Requires<[HasSIMD128]>;
154def : Pat<(v8i16 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
155          (CALL_v8i16 texternalsym:$callee)>, Requires<[HasSIMD128]>;
156def : Pat<(v4i32 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
157          (CALL_v4i32 texternalsym:$callee)>, Requires<[HasSIMD128]>;
158def : Pat<(v4f32 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
159          (CALL_v4f32 texternalsym:$callee)>, Requires<[HasSIMD128]>;
160def : Pat<(ExceptRef
161           (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
162          (CALL_EXCEPT_REF texternalsym:$callee)>;
163def : Pat<(WebAssemblycall0 (WebAssemblywrapper texternalsym:$callee)),
164          (CALL_VOID texternalsym:$callee)>;
165