@@ -21,16 +21,33 @@ multiclass BULK_I<dag oops_r, dag iops_r, dag oops_s, dag iops_s,
21
21
}
22
22
23
23
// Bespoke types and nodes for bulk memory ops
24
+
25
+ // memory.copy (may trap on empty ranges)
26
+ def wasm_memory_copy_t : SDTypeProfile<0, 5,
27
+ [SDTCisInt<0>, SDTCisInt<1>, SDTCisPtrTy<2>, SDTCisPtrTy<3>, SDTCisInt<4>]
28
+ >;
29
+ def wasm_memory_copy : SDNode<"WebAssemblyISD::MEMORY_COPY", wasm_memory_copy_t,
30
+ [SDNPHasChain, SDNPMayLoad, SDNPMayStore]>;
31
+
32
+ // memory.copy with a branch to avoid trapping
24
33
def wasm_memcpy_t : SDTypeProfile<0, 5,
25
34
[SDTCisInt<0>, SDTCisInt<1>, SDTCisPtrTy<2>, SDTCisPtrTy<3>, SDTCisInt<4>]
26
35
>;
27
- def wasm_memcpy : SDNode<"WebAssemblyISD::MEMORY_COPY ", wasm_memcpy_t,
36
+ def wasm_memcpy : SDNode<"WebAssemblyISD::MEMCPY ", wasm_memcpy_t,
28
37
[SDNPHasChain, SDNPMayLoad, SDNPMayStore]>;
29
38
39
+ // memory.fill (may trap on empty ranges)
40
+ def wasm_memory_fill_t : SDTypeProfile<0, 4,
41
+ [SDTCisInt<0>, SDTCisPtrTy<1>, SDTCisInt<2>, SDTCisInt<3>]
42
+ >;
43
+ def wasm_memory_fill : SDNode<"WebAssemblyISD::MEMORY_FILL", wasm_memory_fill_t,
44
+ [SDNPHasChain, SDNPMayStore]>;
45
+
46
+ // memory.fill with a branch to avoid trapping
30
47
def wasm_memset_t : SDTypeProfile<0, 4,
31
48
[SDTCisInt<0>, SDTCisPtrTy<1>, SDTCisInt<2>, SDTCisInt<3>]
32
49
>;
33
- def wasm_memset : SDNode<"WebAssemblyISD::MEMORY_FILL ", wasm_memset_t,
50
+ def wasm_memset : SDNode<"WebAssemblyISD::MEMSET ", wasm_memset_t,
34
51
[SDNPHasChain, SDNPMayStore]>;
35
52
36
53
multiclass BulkMemoryOps<WebAssemblyRegClass rc, string B> {
@@ -51,25 +68,83 @@ defm DATA_DROP :
51
68
[],
52
69
"data.drop\t$seg", "data.drop\t$seg", 0x09>;
53
70
71
+ }
72
+
73
+ defm : BulkMemoryOps<I32, "32">;
74
+ defm : BulkMemoryOps<I64, "64">;
75
+
76
+ // Define copy/fill manually instead of using the `BulkMemoryOps` multiclass
77
+ // because when a multiclass defines opcodes, it gives them anonymous names
78
+ // and we need opcodes with names so that we can handle them with custom code.
79
+
54
80
let mayLoad = 1, mayStore = 1 in
55
- defm MEMORY_COPY_A#B :
81
+ defm MEMORY_COPY_A32 :
56
82
BULK_I<(outs), (ins i32imm_op:$src_idx, i32imm_op:$dst_idx,
57
- rc :$dst, rc :$src, rc :$len),
83
+ I32 :$dst, I32 :$src, I32 :$len),
58
84
(outs), (ins i32imm_op:$src_idx, i32imm_op:$dst_idx),
59
- [(wasm_memcpy (i32 imm:$src_idx), (i32 imm:$dst_idx),
60
- rc :$dst, rc :$src, rc :$len
85
+ [(wasm_memory_copy (i32 imm:$src_idx), (i32 imm:$dst_idx),
86
+ I32 :$dst, I32 :$src, I32 :$len
61
87
)],
62
88
"memory.copy\t$src_idx, $dst_idx, $dst, $src, $len",
63
89
"memory.copy\t$src_idx, $dst_idx", 0x0a>;
64
90
65
91
let mayStore = 1 in
66
- defm MEMORY_FILL_A#B :
67
- BULK_I<(outs), (ins i32imm_op:$idx, rc :$dst, I32:$value, rc :$size),
92
+ defm MEMORY_FILL_A32 :
93
+ BULK_I<(outs), (ins i32imm_op:$idx, I32 :$dst, I32:$value, I32 :$size),
68
94
(outs), (ins i32imm_op:$idx),
69
- [(wasm_memset (i32 imm:$idx), rc :$dst, I32:$value, rc :$size)],
95
+ [(wasm_memory_fill (i32 imm:$idx), I32 :$dst, I32:$value, I32 :$size)],
70
96
"memory.fill\t$idx, $dst, $value, $size",
71
97
"memory.fill\t$idx", 0x0b>;
72
- }
73
98
74
- defm : BulkMemoryOps<I32, "32">;
75
- defm : BulkMemoryOps<I64, "64">;
99
+ let mayLoad = 1, mayStore = 1 in
100
+ defm MEMORY_COPY_A64 :
101
+ BULK_I<(outs), (ins i32imm_op:$src_idx, i32imm_op:$dst_idx,
102
+ I64:$dst, I64:$src, I64:$len),
103
+ (outs), (ins i32imm_op:$src_idx, i32imm_op:$dst_idx),
104
+ [(wasm_memory_copy (i32 imm:$src_idx), (i32 imm:$dst_idx),
105
+ I64:$dst, I64:$src, I64:$len
106
+ )],
107
+ "memory.copy\t$src_idx, $dst_idx, $dst, $src, $len",
108
+ "memory.copy\t$src_idx, $dst_idx", 0x0a>;
109
+
110
+ let mayStore = 1 in
111
+ defm MEMORY_FILL_A64 :
112
+ BULK_I<(outs), (ins i32imm_op:$idx, I64:$dst, I32:$value, I64:$size),
113
+ (outs), (ins i32imm_op:$idx),
114
+ [(wasm_memory_fill (i32 imm:$idx), I64:$dst, I32:$value, I64:$size)],
115
+ "memory.fill\t$idx, $dst, $value, $size",
116
+ "memory.fill\t$idx", 0x0b>;
117
+
118
+ let usesCustomInserter = 1, isCodeGenOnly = 1, mayLoad = 1, mayStore = 1 in
119
+ defm MEMCPY_A32 : I<(outs), (ins i32imm_op:$src_idx, i32imm_op:$dst_idx,
120
+ I32:$dst, I32:$src, I32:$len),
121
+ (outs), (ins i32imm_op:$src_idx, i32imm_op:$dst_idx),
122
+ [(wasm_memcpy (i32 imm:$src_idx), (i32 imm:$dst_idx),
123
+ I32:$dst, I32:$src, I32:$len
124
+ )],
125
+ "", "", 0>,
126
+ Requires<[HasBulkMemory]>;
127
+
128
+ let usesCustomInserter = 1, isCodeGenOnly = 1, mayStore = 1 in
129
+ defm MEMSET_A32 : I<(outs), (ins i32imm_op:$idx, I32:$dst, I32:$value, I32:$size),
130
+ (outs), (ins i32imm_op:$idx),
131
+ [(wasm_memset (i32 imm:$idx), I32:$dst, I32:$value, I32:$size)],
132
+ "", "", 0>,
133
+ Requires<[HasBulkMemory]>;
134
+
135
+ let usesCustomInserter = 1, isCodeGenOnly = 1, mayLoad = 1, mayStore = 1 in
136
+ defm MEMCPY_A64 : I<(outs), (ins i32imm_op:$src_idx, i32imm_op:$dst_idx,
137
+ I64:$dst, I64:$src, I64:$len),
138
+ (outs), (ins i32imm_op:$src_idx, i32imm_op:$dst_idx),
139
+ [(wasm_memcpy (i32 imm:$src_idx), (i32 imm:$dst_idx),
140
+ I64:$dst, I64:$src, I64:$len
141
+ )],
142
+ "", "", 0>,
143
+ Requires<[HasBulkMemory]>;
144
+
145
+ let usesCustomInserter = 1, isCodeGenOnly = 1, mayStore = 1 in
146
+ defm MEMSET_A64 : I<(outs), (ins i32imm_op:$idx, I64:$dst, I32:$value, I64:$size),
147
+ (outs), (ins i32imm_op:$idx),
148
+ [(wasm_memset (i32 imm:$idx), I64:$dst, I32:$value, I64:$size)],
149
+ "", "", 0>,
150
+ Requires<[HasBulkMemory]>;
0 commit comments