blob: 6b45839c14b0e43c6df170d3ee430c20863c711b [file] [log] [blame]
JF Bastien5ca0bac2015-07-10 18:23:10 +00001//===- 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
Dan Gohmane2a7a822015-12-05 20:41:36 +000015// TODO: addr64: These currently assume the callee address is 32-bit.
16
Dan Gohmanfb3e0592015-11-25 19:36:19 +000017let Defs = [ARGUMENTS] in {
18
Dan Gohman905bef52015-12-05 19:43:19 +000019// 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.
Derek Schuff5a143062015-12-11 18:55:34 +000021let Uses = [SP32, SP64], Defs = [SP32, SP64], isCodeGenOnly = 1 in {
Serge Pavlovd526b132017-05-09 13:35:13 +000022def ADJCALLSTACKDOWN : I<(outs), (ins i32imm:$amt, i32imm:$amt2),
23 [(WebAssemblycallseq_start timm:$amt, timm:$amt2)]>;
Derek Schuff8bb5f292015-12-16 23:21:30 +000024def ADJCALLSTACKUP : I<(outs), (ins i32imm:$amt, i32imm:$amt2),
25 [(WebAssemblycallseq_end timm:$amt, timm:$amt2)]>;
JF Bastienaf111db2015-08-24 22:16:48 +000026} // isCodeGenOnly = 1
27
Dan Gohmanc7c04452015-12-14 22:56:51 +000028multiclass CALL<WebAssemblyRegClass vt, string prefix> {
Dan Gohman00d734d2016-12-23 03:23:52 +000029 def CALL_#vt : I<(outs vt:$dst), (ins function32_op:$callee, variable_ops),
Dan Gohmane2a7a822015-12-05 20:41:36 +000030 [(set vt:$dst, (WebAssemblycall1 (i32 imm:$callee)))],
Dan Gohman3acb1872016-10-24 23:27:49 +000031 !strconcat(prefix, "call\t$dst, $callee"),
32 0x10>;
Dan Gohmand934cb82017-02-24 23:18:00 +000033
Derek Schuff6f697832016-10-21 16:38:07 +000034 let isCodeGenOnly = 1 in {
35 def PCALL_INDIRECT_#vt : I<(outs vt:$dst), (ins I32:$callee, variable_ops),
36 [(set vt:$dst, (WebAssemblycall1 I32:$callee))],
37 "PSEUDO CALL INDIRECT\t$callee">;
38 } // isCodeGenOnly = 1
Dan Gohmanf50d9642016-10-25 16:55:52 +000039
Dan Gohmand934cb82017-02-24 23:18:00 +000040 def CALL_INDIRECT_#vt : I<(outs vt:$dst),
41 (ins TypeIndex:$type, i32imm:$flags, variable_ops),
Derek Schuff6f697832016-10-21 16:38:07 +000042 [],
Dan Gohman3acb1872016-10-24 23:27:49 +000043 !strconcat(prefix, "call_indirect\t$dst"),
44 0x11>;
JF Bastienaf111db2015-08-24 22:16:48 +000045}
Derek Schuff39bf39f2016-08-02 23:16:09 +000046
47multiclass SIMD_CALL<ValueType vt, string prefix> {
Dan Gohman00d734d2016-12-23 03:23:52 +000048 def CALL_#vt : SIMD_I<(outs V128:$dst), (ins function32_op:$callee, variable_ops),
Derek Schuff39bf39f2016-08-02 23:16:09 +000049 [(set (vt V128:$dst),
50 (WebAssemblycall1 (i32 imm:$callee)))],
Dan Gohman3acb1872016-10-24 23:27:49 +000051 !strconcat(prefix, "call\t$dst, $callee"),
52 0x10>;
Dan Gohmand934cb82017-02-24 23:18:00 +000053
Derek Schuff6f697832016-10-21 16:38:07 +000054 let isCodeGenOnly = 1 in {
55 def PCALL_INDIRECT_#vt : SIMD_I<(outs V128:$dst),
56 (ins I32:$callee, variable_ops),
57 [(set (vt V128:$dst),
58 (WebAssemblycall1 I32:$callee))],
59 "PSEUDO CALL INDIRECT\t$callee">;
60 } // isCodeGenOnly = 1
Dan Gohmanf50d9642016-10-25 16:55:52 +000061
Derek Schuff39bf39f2016-08-02 23:16:09 +000062 def CALL_INDIRECT_#vt : SIMD_I<(outs V128:$dst),
Dan Gohmand934cb82017-02-24 23:18:00 +000063 (ins TypeIndex:$type, i32imm:$flags,
64 variable_ops),
Derek Schuff6f697832016-10-21 16:38:07 +000065 [],
Dan Gohman3acb1872016-10-24 23:27:49 +000066 !strconcat(prefix, "call_indirect\t$dst"),
67 0x11>;
Derek Schuff39bf39f2016-08-02 23:16:09 +000068}
69
JF Bastienaf111db2015-08-24 22:16:48 +000070let Uses = [SP32, SP64], isCall = 1 in {
Dan Gohmanc7c04452015-12-14 22:56:51 +000071 defm : CALL<I32, "i32.">;
72 defm : CALL<I64, "i64.">;
73 defm : CALL<F32, "f32.">;
74 defm : CALL<F64, "f64.">;
Derek Schuff39bf39f2016-08-02 23:16:09 +000075 defm : SIMD_CALL<v16i8, "i8x16.">;
76 defm : SIMD_CALL<v8i16, "i16x8.">;
77 defm : SIMD_CALL<v4i32, "i32x4.">;
78 defm : SIMD_CALL<v4f32, "f32x4.">;
Dan Gohmanf71abef2015-09-09 16:13:47 +000079
Dan Gohman00d734d2016-12-23 03:23:52 +000080 def CALL_VOID : I<(outs), (ins function32_op:$callee, variable_ops),
Dan Gohmane2a7a822015-12-05 20:41:36 +000081 [(WebAssemblycall0 (i32 imm:$callee))],
Dan Gohman3acb1872016-10-24 23:27:49 +000082 "call \t$callee", 0x10>;
Dan Gohmand934cb82017-02-24 23:18:00 +000083
Derek Schuff6f697832016-10-21 16:38:07 +000084 let isCodeGenOnly = 1 in {
85 def PCALL_INDIRECT_VOID : I<(outs), (ins I32:$callee, variable_ops),
86 [(WebAssemblycall0 I32:$callee)],
87 "PSEUDO CALL INDIRECT\t$callee">;
88 } // isCodeGenOnly = 1
Dan Gohmanf50d9642016-10-25 16:55:52 +000089
Dan Gohmand934cb82017-02-24 23:18:00 +000090 def CALL_INDIRECT_VOID : I<(outs),
91 (ins TypeIndex:$type, i32imm:$flags, variable_ops),
Derek Schuff6f697832016-10-21 16:38:07 +000092 [],
Dan Gohman3acb1872016-10-24 23:27:49 +000093 "call_indirect\t", 0x11>;
JF Bastienaf111db2015-08-24 22:16:48 +000094} // Uses = [SP32,SP64], isCall = 1
Dan Gohmanfb3e0592015-11-25 19:36:19 +000095
96} // Defs = [ARGUMENTS]
Dan Gohmane2a7a822015-12-05 20:41:36 +000097
98// Patterns for matching a direct call to a global address.
99def : Pat<(i32 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
100 (CALL_I32 tglobaladdr:$callee)>;
101def : Pat<(i64 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
102 (CALL_I64 tglobaladdr:$callee)>;
103def : Pat<(f32 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
104 (CALL_F32 tglobaladdr:$callee)>;
105def : Pat<(f64 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
106 (CALL_F64 tglobaladdr:$callee)>;
Derek Schuff39bf39f2016-08-02 23:16:09 +0000107def : Pat<(v16i8 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
108 (CALL_v16i8 tglobaladdr:$callee)>, Requires<[HasSIMD128]>;
109def : Pat<(v8i16 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
110 (CALL_v8i16 tglobaladdr:$callee)>, Requires<[HasSIMD128]>;
111def : Pat<(v4i32 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
112 (CALL_v4i32 tglobaladdr:$callee)>, Requires<[HasSIMD128]>;
113def : Pat<(v4f32 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
114 (CALL_v4f32 tglobaladdr:$callee)>, Requires<[HasSIMD128]>;
Dan Gohmane2a7a822015-12-05 20:41:36 +0000115def : Pat<(WebAssemblycall0 (WebAssemblywrapper tglobaladdr:$callee)),
116 (CALL_VOID tglobaladdr:$callee)>;
117
118// Patterns for matching a direct call to an external symbol.
119def : Pat<(i32 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
120 (CALL_I32 texternalsym:$callee)>;
121def : Pat<(i64 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
122 (CALL_I64 texternalsym:$callee)>;
123def : Pat<(f32 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
124 (CALL_F32 texternalsym:$callee)>;
125def : Pat<(f64 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
126 (CALL_F64 texternalsym:$callee)>;
Derek Schuff39bf39f2016-08-02 23:16:09 +0000127def : Pat<(v16i8 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
128 (CALL_v16i8 texternalsym:$callee)>, Requires<[HasSIMD128]>;
129def : Pat<(v8i16 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
130 (CALL_v8i16 texternalsym:$callee)>, Requires<[HasSIMD128]>;
131def : Pat<(v4i32 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
132 (CALL_v4i32 texternalsym:$callee)>, Requires<[HasSIMD128]>;
133def : Pat<(v4f32 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
134 (CALL_v4f32 texternalsym:$callee)>, Requires<[HasSIMD128]>;
Dan Gohmane2a7a822015-12-05 20:41:36 +0000135def : Pat<(WebAssemblycall0 (WebAssemblywrapper texternalsym:$callee)),
136 (CALL_VOID texternalsym:$callee)>;