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/// \brief WebAssembly Call operand code-gen constructs.
12///
13//===----------------------------------------------------------------------===//
14
15// TODO: addr64: These currently assume the callee address is 32-bit.
16
17let Defs = [ARGUMENTS] in {
18
19// Call sequence markers. These have an immediate which represents the amount of
20// stack space to allocate or free, which is used for varargs lowering.
21let Uses = [SP32, SP64], Defs = [SP32, SP64], isCodeGenOnly = 1 in {
22def ADJCALLSTACKDOWN : I<(outs), (ins i32imm:$amt),
23                         [(WebAssemblycallseq_start timm:$amt)]>;
24def ADJCALLSTACKUP : I<(outs), (ins i32imm:$amt, i32imm:$amt2),
25                       [(WebAssemblycallseq_end timm:$amt, timm:$amt2)]>;
26} // isCodeGenOnly = 1
27
28multiclass CALL<WebAssemblyRegClass vt, string prefix> {
29  def CALL_#vt : I<(outs vt:$dst), (ins i32imm:$callee, variable_ops),
30                   [(set vt:$dst, (WebAssemblycall1 (i32 imm:$callee)))],
31                   !strconcat(prefix, "call\t$dst, $callee")>;
32  let isCodeGenOnly = 1 in {
33    def PCALL_INDIRECT_#vt : I<(outs vt:$dst), (ins I32:$callee, variable_ops),
34                              [(set vt:$dst, (WebAssemblycall1 I32:$callee))],
35                              "PSEUDO CALL INDIRECT\t$callee">;
36  } // isCodeGenOnly = 1
37  def CALL_INDIRECT_#vt : I<(outs vt:$dst), (ins variable_ops),
38                            [],
39                            !strconcat(prefix, "call_indirect\t$dst")>;
40}
41
42multiclass SIMD_CALL<ValueType vt, string prefix> {
43  def CALL_#vt : SIMD_I<(outs V128:$dst), (ins i32imm:$callee, variable_ops),
44                         [(set (vt V128:$dst),
45                               (WebAssemblycall1 (i32 imm:$callee)))],
46                         !strconcat(prefix, "call\t$dst, $callee")>;
47  let isCodeGenOnly = 1 in {
48    def PCALL_INDIRECT_#vt : SIMD_I<(outs V128:$dst),
49                                    (ins I32:$callee, variable_ops),
50                                    [(set (vt V128:$dst),
51                                          (WebAssemblycall1 I32:$callee))],
52                                    "PSEUDO CALL INDIRECT\t$callee">;
53  } // isCodeGenOnly = 1
54  def CALL_INDIRECT_#vt : SIMD_I<(outs V128:$dst),
55                                  (ins variable_ops),
56                                  [],
57                                  !strconcat(prefix, "call_indirect\t$dst")>;
58}
59
60let Uses = [SP32, SP64], isCall = 1 in {
61  defm : CALL<I32, "i32.">;
62  defm : CALL<I64, "i64.">;
63  defm : CALL<F32, "f32.">;
64  defm : CALL<F64, "f64.">;
65  defm : SIMD_CALL<v16i8, "i8x16.">;
66  defm : SIMD_CALL<v8i16, "i16x8.">;
67  defm : SIMD_CALL<v4i32, "i32x4.">;
68  defm : SIMD_CALL<v4f32, "f32x4.">;
69
70  def CALL_VOID : I<(outs), (ins i32imm:$callee, variable_ops),
71                    [(WebAssemblycall0 (i32 imm:$callee))],
72                    "call    \t$callee">;
73  let isCodeGenOnly = 1 in {
74    def PCALL_INDIRECT_VOID : I<(outs), (ins I32:$callee, variable_ops),
75                      [(WebAssemblycall0 I32:$callee)],
76                      "PSEUDO CALL INDIRECT\t$callee">;
77  } // isCodeGenOnly = 1
78  def CALL_INDIRECT_VOID : I<(outs), (ins variable_ops),
79                             [],
80                             "call_indirect\t">;
81} // Uses = [SP32,SP64], isCall = 1
82
83} // Defs = [ARGUMENTS]
84
85// Patterns for matching a direct call to a global address.
86def : Pat<(i32 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
87          (CALL_I32 tglobaladdr:$callee)>;
88def : Pat<(i64 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
89          (CALL_I64 tglobaladdr:$callee)>;
90def : Pat<(f32 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
91          (CALL_F32 tglobaladdr:$callee)>;
92def : Pat<(f64 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
93          (CALL_F64 tglobaladdr:$callee)>;
94def : Pat<(v16i8 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
95          (CALL_v16i8 tglobaladdr:$callee)>, Requires<[HasSIMD128]>;
96def : Pat<(v8i16 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
97          (CALL_v8i16 tglobaladdr:$callee)>, Requires<[HasSIMD128]>;
98def : Pat<(v4i32 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
99          (CALL_v4i32 tglobaladdr:$callee)>, Requires<[HasSIMD128]>;
100def : Pat<(v4f32 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
101          (CALL_v4f32 tglobaladdr:$callee)>, Requires<[HasSIMD128]>;
102def : Pat<(WebAssemblycall0 (WebAssemblywrapper tglobaladdr:$callee)),
103          (CALL_VOID tglobaladdr:$callee)>;
104
105// Patterns for matching a direct call to an external symbol.
106def : Pat<(i32 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
107          (CALL_I32 texternalsym:$callee)>;
108def : Pat<(i64 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
109          (CALL_I64 texternalsym:$callee)>;
110def : Pat<(f32 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
111          (CALL_F32 texternalsym:$callee)>;
112def : Pat<(f64 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
113          (CALL_F64 texternalsym:$callee)>;
114def : Pat<(v16i8 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
115          (CALL_v16i8 texternalsym:$callee)>, Requires<[HasSIMD128]>;
116def : Pat<(v8i16 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
117          (CALL_v8i16 texternalsym:$callee)>, Requires<[HasSIMD128]>;
118def : Pat<(v4i32 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
119          (CALL_v4i32 texternalsym:$callee)>, Requires<[HasSIMD128]>;
120def : Pat<(v4f32 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
121          (CALL_v4f32 texternalsym:$callee)>, Requires<[HasSIMD128]>;
122def : Pat<(WebAssemblycall0 (WebAssemblywrapper texternalsym:$callee)),
123          (CALL_VOID texternalsym:$callee)>;
124