summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
blob: f0b4ce7caf5199f55e42eac844f1ba6faa71a82f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// WebAssemblyInstrInfo.td-Describe the WebAssembly Instructions-*- tablegen -*-
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief WebAssembly Instruction definitions.
///
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// WebAssembly Instruction Predicate Definitions.
//===----------------------------------------------------------------------===//

def HasAddr32 : Predicate<"!Subtarget->hasAddr64()">;
def HasAddr64 : Predicate<"Subtarget->hasAddr64()">;
def HasSIMD128 : Predicate<"Subtarget->hasSIMD128()">,
                           AssemblerPredicate<"FeatureSIMD128", "simd128">;

//===----------------------------------------------------------------------===//
// WebAssembly-specific DAG Node Types.
//===----------------------------------------------------------------------===//

def SDT_WebAssemblyCallSeqStart : SDCallSeqStart<[SDTCisVT<0, iPTR>]>;
def SDT_WebAssemblyCallSeqEnd :
    SDCallSeqEnd<[SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>;
def SDT_WebAssemblyCall0    : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>;
def SDT_WebAssemblyCall1    : SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>;
def SDT_WebAssemblyTableswitch : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>;
def SDT_WebAssemblyArgument : SDTypeProfile<1, 1, [SDTCisVT<1, i32>]>;
def SDT_WebAssemblyReturn   : SDTypeProfile<0, -1, []>;
def SDT_WebAssemblyWrapper  : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>,
                                                   SDTCisPtrTy<0>]>;

//===----------------------------------------------------------------------===//
// WebAssembly-specific DAG Nodes.
//===----------------------------------------------------------------------===//

def WebAssemblycallseq_start :
    SDNode<"ISD::CALLSEQ_START", SDT_WebAssemblyCallSeqStart,
           [SDNPHasChain, SDNPOutGlue]>;
def WebAssemblycallseq_end :
    SDNode<"ISD::CALLSEQ_END", SDT_WebAssemblyCallSeqEnd,
           [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
def WebAssemblycall0 : SDNode<"WebAssemblyISD::CALL0",
                              SDT_WebAssemblyCall0,
                              [SDNPHasChain, SDNPVariadic]>;
def WebAssemblycall1 : SDNode<"WebAssemblyISD::CALL1",
                              SDT_WebAssemblyCall1,
                              [SDNPHasChain, SDNPVariadic]>;
def WebAssemblytableswitch : SDNode<"WebAssemblyISD::TABLESWITCH",
                                    SDT_WebAssemblyTableswitch,
                                    [SDNPHasChain, SDNPVariadic]>;
def WebAssemblyargument : SDNode<"WebAssemblyISD::ARGUMENT",
                                 SDT_WebAssemblyArgument>;
def WebAssemblyreturn   : SDNode<"WebAssemblyISD::RETURN",
                                 SDT_WebAssemblyReturn, [SDNPHasChain]>;
def WebAssemblywrapper  : SDNode<"WebAssemblyISD::Wrapper",
                                 SDT_WebAssemblyWrapper>;

//===----------------------------------------------------------------------===//
// WebAssembly-specific Operands.
//===----------------------------------------------------------------------===//

def bb_op : Operand<OtherVT>;

//===----------------------------------------------------------------------===//
// WebAssembly Instruction Format Definitions.
//===----------------------------------------------------------------------===//

include "WebAssemblyInstrFormats.td"

//===----------------------------------------------------------------------===//
// Additional instructions.
//===----------------------------------------------------------------------===//

multiclass ARGUMENT<WebAssemblyRegClass vt> {
  let hasSideEffects = 1, Uses = [ARGUMENTS], isCodeGenOnly = 1 in
  def ARGUMENT_#vt : I<(outs vt:$res), (ins i32imm:$argno),
                       [(set vt:$res, (WebAssemblyargument timm:$argno))]>;
}
defm : ARGUMENT<I32>;
defm : ARGUMENT<I64>;
defm : ARGUMENT<F32>;
defm : ARGUMENT<F64>;

let Defs = [ARGUMENTS] in {

// get_local and set_local are not generated by instruction selection; they
// are implied by virtual register uses and defs in most contexts. However,
// they are explicitly emitted for special purposes.
multiclass LOCAL<WebAssemblyRegClass vt> {
  def GET_LOCAL_#vt : I<(outs vt:$res), (ins i32imm:$regno), [],
                        "get_local\t$res, $regno">;
  // TODO: set_local returns its operand value
  def SET_LOCAL_#vt : I<(outs), (ins i32imm:$regno, vt:$src), [],
                        "set_local\t$regno, $src">;

  // COPY_LOCAL is not an actual instruction in wasm, but since we allow
  // get_local and set_local to be implicit, we can have a COPY_LOCAL which
  // is actually a no-op because all the work is done in the implied
  // get_local and set_local.
  let isAsCheapAsAMove = 1 in
  def COPY_LOCAL_#vt : I<(outs vt:$res), (ins vt:$src), [],
                         "copy_local\t$res, $src">;
}
defm : LOCAL<I32>;
defm : LOCAL<I64>;
defm : LOCAL<F32>;
defm : LOCAL<F64>;

let isMoveImm = 1 in {
def CONST_I32 : I<(outs I32:$res), (ins i32imm:$imm),
                  [(set I32:$res, imm:$imm)],
                  "i32.const\t$res, $imm">;
def CONST_I64 : I<(outs I64:$res), (ins i64imm:$imm),
                  [(set I64:$res, imm:$imm)],
                  "i64.const\t$res, $imm">;
def CONST_F32 : I<(outs F32:$res), (ins f32imm:$imm),
                  [(set F32:$res, fpimm:$imm)],
                  "f32.const\t$res, $imm">;
def CONST_F64 : I<(outs F64:$res), (ins f64imm:$imm),
                  [(set F64:$res, fpimm:$imm)],
                  "f64.const\t$res, $imm">;
} // isMoveImm = 1

} // Defs = [ARGUMENTS]

def : Pat<(i32 (WebAssemblywrapper tglobaladdr:$dst)),
          (CONST_I32 tglobaladdr:$dst)>;
def : Pat<(i32 (WebAssemblywrapper texternalsym:$dst)),
          (CONST_I32 texternalsym:$dst)>;
def : Pat<(i32 (WebAssemblywrapper tjumptable:$dst)),
          (CONST_I32 tjumptable:$dst)>;

let Defs = [ARGUMENTS] in {

// Function signature and local variable declaration "instructions".
def PARAM  : I<(outs), (ins variable_ops), [], ".param  \t">;
def RESULT : I<(outs), (ins variable_ops), [], ".result \t">;
def LOCAL  : I<(outs), (ins variable_ops), [], ".local  \t">;

} // Defs = [ARGUMENTS]

//===----------------------------------------------------------------------===//
// Additional sets of instructions.
//===----------------------------------------------------------------------===//

include "WebAssemblyInstrMemory.td"
include "WebAssemblyInstrCall.td"
include "WebAssemblyInstrControl.td"
include "WebAssemblyInstrInteger.td"
include "WebAssemblyInstrConv.td"
include "WebAssemblyInstrFloat.td"
include "WebAssemblyInstrAtomics.td"
include "WebAssemblyInstrSIMD.td"
OpenPOWER on IntegriCloud