kompiler 0.3.0.pre.4 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/kompile +230 -33
- data/lib/kompiler/arch_manager.rb +10 -1
- data/lib/kompiler/architecture.rb +5 -1
- data/lib/kompiler/architectures/armv8a/instructions.rb +76 -27
- data/lib/kompiler/architectures/armv8a/load.rb +3 -1
- data/lib/kompiler/architectures/armv8a/simd_fp_instructions.rb +1308 -0
- data/lib/kompiler/architectures/armv8a/simd_fp_registers.rb +23 -0
- data/lib/kompiler/architectures/armv8a/sys_registers.rb +3 -0
- data/lib/kompiler/compiler_functions.rb +32 -8
- data/lib/kompiler/config.rb +12 -1
- data/lib/kompiler/directives.rb +13 -0
- data/lib/kompiler/math_ast.rb +29 -1
- data/lib/kompiler/mc_builder.rb +48 -0
- data/lib/kompiler/parsers.rb +21 -0
- data/lib/kompiler/wrappers/elf_wrapper.rb +499 -0
- data/lib/kompiler/wrappers/packed_bytes.rb +68 -0
- data/lib/kompiler/wrappers.rb +1 -0
- data/lib/kompiler.rb +2 -1
- metadata +8 -3
@@ -0,0 +1,1308 @@
|
|
1
|
+
# Copyright 2024 Kyrylo Shyshko
|
2
|
+
# Licensed under the Apache License, Version 2.0. See LICENSE file for details.
|
3
|
+
|
4
|
+
module Kompiler
|
5
|
+
|
6
|
+
module ARMv8A
|
7
|
+
|
8
|
+
|
9
|
+
def self.simd_fp_instructions
|
10
|
+
@simd_fp_instructions
|
11
|
+
end
|
12
|
+
|
13
|
+
@simd_fp_instructions = [
|
14
|
+
# {
|
15
|
+
# keyword: "add",
|
16
|
+
# name: "Add (vector)",
|
17
|
+
# description: "Adds corresponding elements in two source SIMD&FP vector registers, and writes the result vector to the destination SIMD&FP register.",
|
18
|
+
# operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 1"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 2"}],
|
19
|
+
# mc_constructor: [
|
20
|
+
# ["ensure_eq", ["get_operand_key", 0, :vec_type], ["get_operand_key", 1, :vec_type], ["get_operand_key", 2, :vec_type], "add (vector) Error: Vectors are of different sizes"],
|
21
|
+
#
|
22
|
+
#
|
23
|
+
# ["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
24
|
+
# ["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
25
|
+
#
|
26
|
+
# ["bits", 1, 0,0,0,0,1],
|
27
|
+
#
|
28
|
+
# ["get_bits", ["get_operand_key", 2, :re_num], 0, 5],
|
29
|
+
#
|
30
|
+
# ["bits", 1],
|
31
|
+
#
|
32
|
+
# ["get_bits", ["get_operand_key", 0, :re_size], 0, 2],
|
33
|
+
# ["bits", 0,1,1,1,0, 0],
|
34
|
+
# ["get_bits", ["get_operand_key", 0, :re_q], 0, 1],
|
35
|
+
# ["bits", 0],
|
36
|
+
# ],
|
37
|
+
# bitsize: 32
|
38
|
+
# },
|
39
|
+
# {
|
40
|
+
# keyword: "add.4s",
|
41
|
+
# operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 1"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 2"}],
|
42
|
+
# mc_constructor: [
|
43
|
+
# ["alias", "add", ["encode_imm_operand", 0], ["encode_imm_operand", 0], ["get_operand", 0], ["get_operand", 1], ["get_operand", 2]],
|
44
|
+
# ],
|
45
|
+
# bitsize: 32,
|
46
|
+
# }
|
47
|
+
|
48
|
+
]
|
49
|
+
|
50
|
+
sizes = [
|
51
|
+
{suffix: "8b", enc_size: 0b00, enc_q: 0b0},
|
52
|
+
{suffix: "16b", enc_size: 0b00, enc_q: 0b1},
|
53
|
+
{suffix: "4h", enc_size: 0b01, enc_q: 0b0},
|
54
|
+
{suffix: "8h", enc_size: 0b01, enc_q: 0b1},
|
55
|
+
{suffix: "2s", enc_size: 0b10, enc_q: 0b0},
|
56
|
+
{suffix: "4s", enc_size: 0b10, enc_q: 0b1},
|
57
|
+
{suffix: "2d", enc_size: 0b11, enc_q: 0b1},
|
58
|
+
]
|
59
|
+
|
60
|
+
half_and_full_sizes = [{suffix: "8b", q: 0}, {suffix: "16b", q: 1}]
|
61
|
+
|
62
|
+
sizes.each do |size|
|
63
|
+
@simd_fp_instructions << {
|
64
|
+
keyword: "add.#{size[:suffix]}",
|
65
|
+
name: "Add (vector, #{size[:suffix]})",
|
66
|
+
description: "Adds corresponding integer elements in two source NEON vector registers, and writes the result vector to the destination SIMD&FP register.",
|
67
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 1"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 2"}],
|
68
|
+
mc_constructor: [
|
69
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
70
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
71
|
+
|
72
|
+
["bits", 1, 0,0,0,0,1],
|
73
|
+
|
74
|
+
["get_bits", ["get_operand_key", 2, :re_num], 0, 5],
|
75
|
+
|
76
|
+
["bits", 1],
|
77
|
+
|
78
|
+
["get_bits", size[:enc_size], 0, 2],
|
79
|
+
["bits", 0,1,1,1,0, 0],
|
80
|
+
["get_bits", size[:enc_q], 0, 1],
|
81
|
+
["bits", 0],
|
82
|
+
],
|
83
|
+
bitsize: 32
|
84
|
+
}
|
85
|
+
|
86
|
+
end
|
87
|
+
@simd_fp_instructions << {
|
88
|
+
keyword: "add.1d",
|
89
|
+
name: "Add (scalar, 1d)",
|
90
|
+
description: "Adds the 64-bit integer values of two source SIMD&FP registers, and writes the result to the destination SIMD&FP register.",
|
91
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 1"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 2"}],
|
92
|
+
mc_constructor: [
|
93
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
94
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
95
|
+
|
96
|
+
["bits", 1, 0,0,0,0,1],
|
97
|
+
|
98
|
+
["get_bits", ["get_operand_key", 2, :re_num], 0, 5],
|
99
|
+
|
100
|
+
["bits", 1, 1,1, 0,1,1,1,1, 0, 1,0],
|
101
|
+
],
|
102
|
+
bitsize: 32
|
103
|
+
}
|
104
|
+
|
105
|
+
|
106
|
+
sizes.each do |size|
|
107
|
+
@simd_fp_instructions << {
|
108
|
+
keyword: "sub.#{size[:suffix]}",
|
109
|
+
name: "Subtract (vector, #{size[:suffix]})",
|
110
|
+
description: "Subtracts each integer vector element in the second source SIMD&FP register from the corresponding integer vector element in the first source SIMD&FP register, and writes the result vector to the destination SIMD&FP register.",
|
111
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 1"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 2"}],
|
112
|
+
mc_constructor: [
|
113
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
114
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
115
|
+
|
116
|
+
["bits", 1, 0,0,0,0,1],
|
117
|
+
|
118
|
+
["get_bits", ["get_operand_key", 2, :re_num], 0, 5],
|
119
|
+
|
120
|
+
["bits", 1],
|
121
|
+
|
122
|
+
["get_bits", size[:enc_size], 0, 2],
|
123
|
+
["bits", 0,1,1,1,0, 1],
|
124
|
+
["get_bits", size[:enc_q], 0, 1],
|
125
|
+
["bits", 0],
|
126
|
+
],
|
127
|
+
bitsize: 32
|
128
|
+
}
|
129
|
+
|
130
|
+
end
|
131
|
+
@simd_fp_instructions << {
|
132
|
+
keyword: "sub.1d",
|
133
|
+
name: "Subtract (scalar, 1d)",
|
134
|
+
description: "Subtracts the 64-bit integer value of the second source SIMD&FP register from the corresponding integer value of the first source SIMD&FP register, and writes the result vector to the destination SIMD&FP register.",
|
135
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 1"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 2"}],
|
136
|
+
mc_constructor: [
|
137
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
138
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
139
|
+
|
140
|
+
["bits", 1, 0,0,0,0,1],
|
141
|
+
|
142
|
+
["get_bits", ["get_operand_key", 2, :re_num], 0, 5],
|
143
|
+
|
144
|
+
["bits", 1, 1,1, 0,1,1,1,1, 1, 1,0],
|
145
|
+
],
|
146
|
+
bitsize: 32
|
147
|
+
}
|
148
|
+
|
149
|
+
|
150
|
+
|
151
|
+
|
152
|
+
# Floating point sizes for vector operations
|
153
|
+
fp_sizes = [
|
154
|
+
{suffix: "4s", enc_size: 0b0, enc_q: 0b1},
|
155
|
+
{suffix: "2s", enc_size: 0b0, enc_q: 0b0},
|
156
|
+
{suffix: "2d", enc_size: 0b1, enc_q: 0b1},
|
157
|
+
]
|
158
|
+
|
159
|
+
|
160
|
+
# Floating point, half-precision sizes for vector operations
|
161
|
+
fp_hp_sizes = [
|
162
|
+
{suffix: "4h", enc_q: 0},
|
163
|
+
{suffix: "8h", enc_q: 1},
|
164
|
+
]
|
165
|
+
|
166
|
+
ftypes = [
|
167
|
+
{suffix: "1h", enc_ftype: 0b11},
|
168
|
+
{suffix: "1s", enc_ftype: 0b00},
|
169
|
+
{suffix: "1d", enc_ftype: 0b01},
|
170
|
+
]
|
171
|
+
|
172
|
+
ftypes_no_hp = [
|
173
|
+
{suffix: "1s", enc_ftype: 0b00},
|
174
|
+
{suffix: "1d", enc_ftype: 0b01},
|
175
|
+
]
|
176
|
+
|
177
|
+
|
178
|
+
ftypes_no_length = [
|
179
|
+
{suffix: "h", enc_ftype: 0b11},
|
180
|
+
{suffix: "s", enc_ftype: 0b00},
|
181
|
+
{suffix: "d", enc_ftype: 0b01},
|
182
|
+
]
|
183
|
+
|
184
|
+
ftypes_no_hp_no_length = [
|
185
|
+
{suffix: "s", enc_ftype: 0b00},
|
186
|
+
{suffix: "d", enc_ftype: 0b01},
|
187
|
+
]
|
188
|
+
|
189
|
+
|
190
|
+
fp_sizes.each do |size|
|
191
|
+
@simd_fp_instructions << {
|
192
|
+
keyword: "fadd.#{size[:suffix]}",
|
193
|
+
name: "Floating-point add (vector, #{size[:suffix]})",
|
194
|
+
description: "Adds corresponding floating-point elements in two source NEON vector registers, and writes the result vector to the destination SIMD&FP register.",
|
195
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 1"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 2"}],
|
196
|
+
mc_constructor: [
|
197
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
198
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
199
|
+
|
200
|
+
["bits", 1, 0,1,0,1,1],
|
201
|
+
|
202
|
+
["get_bits", ["get_operand_key", 2, :re_num], 0, 5],
|
203
|
+
|
204
|
+
["bits", 1],
|
205
|
+
|
206
|
+
["get_bits", size[:enc_size], 0, 1],
|
207
|
+
["bits", 0, 0,1,1,1,0, 0],
|
208
|
+
["get_bits", size[:enc_q], 0, 1],
|
209
|
+
["bits", 0],
|
210
|
+
],
|
211
|
+
bitsize: 32
|
212
|
+
}
|
213
|
+
end
|
214
|
+
|
215
|
+
fp_hp_sizes.each do |size|
|
216
|
+
@simd_fp_instructions << {
|
217
|
+
keyword: "fadd.#{size[:suffix]}",
|
218
|
+
name: "Floating-point add (vector, #{size[:suffix]})",
|
219
|
+
description: "Adds corresponding floating-point elements in two source NEON vector registers, and writes the result vector to the destination SIMD&FP register.",
|
220
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 1"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 2"}],
|
221
|
+
mc_constructor: [
|
222
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
223
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
224
|
+
|
225
|
+
["bits", 1, 0,1,0,0,0],
|
226
|
+
|
227
|
+
["get_bits", ["get_operand_key", 2, :re_num], 0, 5],
|
228
|
+
|
229
|
+
["bits", 0,1, 0, 0,1,1,1,0, 0],
|
230
|
+
|
231
|
+
["get_bits", size[:enc_q], 0, 1],
|
232
|
+
["bits", 0],
|
233
|
+
],
|
234
|
+
bitsize: 32
|
235
|
+
}
|
236
|
+
end
|
237
|
+
|
238
|
+
|
239
|
+
ftypes.each do |ftype|
|
240
|
+
@simd_fp_instructions << {
|
241
|
+
keyword: "fadd.#{ftype[:suffix]}",
|
242
|
+
name: "Floating-point add (scalar, #{ftype[:suffix]})",
|
243
|
+
description: "Adds corresponding floating-point values of two source NEON vector registers, and writes the result to the destination SIMD&FP register.",
|
244
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 1"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 2"}],
|
245
|
+
mc_constructor: [
|
246
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
247
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
248
|
+
|
249
|
+
["bits", 0,1, 0, 1,0,0],
|
250
|
+
|
251
|
+
["get_bits", ["get_operand_key", 2, :re_num], 0, 5],
|
252
|
+
|
253
|
+
["bits", 1],
|
254
|
+
|
255
|
+
["get_bits", ftype[:enc_ftype], 0, 2],
|
256
|
+
["bits", 0,1,1,1,1, 0, 0, 0],
|
257
|
+
],
|
258
|
+
bitsize: 32
|
259
|
+
}
|
260
|
+
end
|
261
|
+
|
262
|
+
ins_gp_sizes = [
|
263
|
+
{suffix: "b", size_bits: [1], n_index_bits: 4, source_gp_reg_size: 32},
|
264
|
+
{suffix: "h", size_bits: [0, 1], n_index_bits: 3, source_gp_reg_size: 32},
|
265
|
+
{suffix: "s", size_bits: [0, 0, 1], n_index_bits: 2, source_gp_reg_size: 32},
|
266
|
+
{suffix: "d", size_bits: [0, 0, 0, 1], n_index_bits: 1, source_gp_reg_size: 64},
|
267
|
+
]
|
268
|
+
|
269
|
+
ins_gp_sizes.each do |ins_size|
|
270
|
+
@simd_fp_instructions << {
|
271
|
+
keyword: "ins.#{ins_size[:suffix]}",
|
272
|
+
name: "Insert vector element (from general, #{ins_size[:suffix]})",
|
273
|
+
description: "Copies the contents of the source general-purpose register to the specified vector element in the destination SIMD&FP register.",
|
274
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "immediate", restrictions: {}, name: "Destination element index"}, {type: "register", restrictions: {reg_type: "gpr", reg_size: ins_size[:source_gp_reg_size]}, name: "Source general-purpose register"}],
|
275
|
+
mc_constructor: [
|
276
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
277
|
+
["get_bits", ["get_operand_key", 2, :reg_value], 0, 5],
|
278
|
+
|
279
|
+
["bits", 1, 1,1,0,0, 0],
|
280
|
+
|
281
|
+
["bits"] + ins_size[:size_bits],
|
282
|
+
|
283
|
+
["get_bits", ["get_operand", 1], 0, ins_size[:n_index_bits]],
|
284
|
+
|
285
|
+
["bits", 0,0,0,0,1,1,1,0, 0, 1, 0],
|
286
|
+
],
|
287
|
+
bitsize: 32
|
288
|
+
}
|
289
|
+
end
|
290
|
+
|
291
|
+
|
292
|
+
|
293
|
+
ins_simd_sizes = [
|
294
|
+
{suffix: "b", imm5_pre_bits: [1], n_index1_bits: 4, imm4_pre_bits: [], n_index2_bits: 4},
|
295
|
+
{suffix: "h", imm5_pre_bits: [0, 1], n_index1_bits: 3, imm4_pre_bits: [0], n_index2_bits: 3},
|
296
|
+
{suffix: "s", imm5_pre_bits: [0, 0, 1], n_index1_bits: 2, imm4_pre_bits: [0,0], n_index2_bits: 2},
|
297
|
+
{suffix: "d", imm5_pre_bits: [0, 0, 0, 1], n_index1_bits: 1, imm4_pre_bits: [0,0,0], n_index2_bits: 1},
|
298
|
+
]
|
299
|
+
|
300
|
+
ins_simd_sizes.each do |size|
|
301
|
+
@simd_fp_instructions << {
|
302
|
+
keyword: "ins.#{size[:suffix]}",
|
303
|
+
name: "Insert vector element (from SIMD&FP, #{size[:suffix]})",
|
304
|
+
description: "Copies the specified vector element in the source SIMD&FP register to the specified vector element in the destination SIMD&FP register.",
|
305
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "immediate", restrictions: {}, name: "Destination element index"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register"}, {type: "immediate", restrictions: {}, name: "Source element index"}],
|
306
|
+
mc_constructor: [
|
307
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
308
|
+
["get_bits", ["get_operand_key", 2, :re_num], 0, 5],
|
309
|
+
|
310
|
+
["bits", 1],
|
311
|
+
|
312
|
+
["bits"] + size[:imm4_pre_bits],
|
313
|
+
["get_bits", ["get_operand", 3], 0, size[:n_index2_bits]],
|
314
|
+
|
315
|
+
["bits", 0],
|
316
|
+
|
317
|
+
["bits"] + size[:imm5_pre_bits],
|
318
|
+
|
319
|
+
["get_bits", ["get_operand", 1], 0, size[:n_index1_bits]],
|
320
|
+
|
321
|
+
["bits", 0,0,0,0,1,1,1,0, 1, 1, 0],
|
322
|
+
],
|
323
|
+
bitsize: 32
|
324
|
+
}
|
325
|
+
end
|
326
|
+
|
327
|
+
|
328
|
+
mov_to_gp_sizes = [
|
329
|
+
{suffix: "s", reg_size: 32, imm5_size_bits: [0,0,1], n_index_bits: 2, q: 0},
|
330
|
+
{suffix: "d", reg_size: 64, imm5_size_bits: [0,0,0,1], n_index_bits: 1, q: 1},
|
331
|
+
]
|
332
|
+
|
333
|
+
mov_to_gp_sizes.each do |size|
|
334
|
+
@simd_fp_instructions << {
|
335
|
+
keyword: "mov.#{size[:suffix]}",
|
336
|
+
name: "Move vector element (to general, #{size[:suffix]})",
|
337
|
+
description: "Reads the specified unsigned integer element from the source SIMD&FP register, zero extends to 32 or 64 bits, and writes the result to the destination general-purpose register.",
|
338
|
+
operands: [{type: "register", restrictions: {reg_type: "gpr", reg_size: size[:reg_size]}, name: "Destination general-purpose register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP register"}, {type: "immediate", restrictions: {}, name: "Source vector element index"}],
|
339
|
+
mc_constructor: [
|
340
|
+
["get_bits", ["get_operand_key", 0, :reg_value], 0, 5],
|
341
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
342
|
+
|
343
|
+
["bits", 1, 1, 1, 1,0, 0],
|
344
|
+
|
345
|
+
["bits"] + size[:imm5_size_bits],
|
346
|
+
|
347
|
+
["get_bits", ["get_operand", 2], 0, size[:n_index_bits]],
|
348
|
+
|
349
|
+
["bits", 0,0,0,0,1,1,1,0, 0, size[:q], 0],
|
350
|
+
],
|
351
|
+
bitsize: 32
|
352
|
+
}
|
353
|
+
end
|
354
|
+
|
355
|
+
|
356
|
+
|
357
|
+
fp_sizes.each do |size|
|
358
|
+
@simd_fp_instructions << {
|
359
|
+
keyword: "fsub.#{size[:suffix]}",
|
360
|
+
name: "Floating-point subtract (vector, #{size[:suffix]})",
|
361
|
+
description: "Subtracts floating-point vector elements in the second source SIMD&FP register, from the corresponding elements in the first source SIMD&FP registers. and writes the result vector to the destination SIMD&FP register.",
|
362
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 1"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 2"}],
|
363
|
+
mc_constructor: [
|
364
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
365
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
366
|
+
|
367
|
+
["bits", 1, 0,1,0,1,1],
|
368
|
+
|
369
|
+
["get_bits", ["get_operand_key", 2, :re_num], 0, 5],
|
370
|
+
|
371
|
+
["bits", 1],
|
372
|
+
|
373
|
+
["get_bits", size[:enc_size], 0, 1],
|
374
|
+
["bits", 1, 0,1,1,1,0, 0],
|
375
|
+
["get_bits", size[:enc_q], 0, 1],
|
376
|
+
["bits", 0],
|
377
|
+
],
|
378
|
+
bitsize: 32
|
379
|
+
}
|
380
|
+
end
|
381
|
+
fp_hp_sizes.each do |size|
|
382
|
+
@simd_fp_instructions << {
|
383
|
+
keyword: "fsub.#{size[:suffix]}",
|
384
|
+
name: "Floating-point subtract (vector, #{size[:suffix]})",
|
385
|
+
description: "Subtracts floating-point vector elements in the second source SIMD&FP register, from the corresponding elements in the first source SIMD&FP registers. and writes the result vector to the destination SIMD&FP register.",
|
386
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 1"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 2"}],
|
387
|
+
mc_constructor: [
|
388
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
389
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
390
|
+
|
391
|
+
["bits", 1, 0,1,0, 0,0],
|
392
|
+
|
393
|
+
["get_bits", ["get_operand_key", 2, :re_num], 0, 5],
|
394
|
+
|
395
|
+
["bits", 0,1, 1, 0,1,1,1,0, 0],
|
396
|
+
|
397
|
+
["get_bits", size[:enc_q], 0, 1],
|
398
|
+
["bits", 0],
|
399
|
+
],
|
400
|
+
bitsize: 32
|
401
|
+
}
|
402
|
+
end
|
403
|
+
ftypes.each do |size|
|
404
|
+
@simd_fp_instructions << {
|
405
|
+
keyword: "fsub.#{size[:suffix]}",
|
406
|
+
name: "Floating-point subtract (scalar, #{size[:suffix]})",
|
407
|
+
description: "Subtracts the floating-point value of the second source SIMD&FP register from the floating-point value of the first source SIMD&FP register, and writes the result to the destination SIMD&FP register",
|
408
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 1"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 2"}],
|
409
|
+
mc_constructor: [
|
410
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
411
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
412
|
+
|
413
|
+
["bits", 0,1, 1, 1,0,0],
|
414
|
+
|
415
|
+
["get_bits", ["get_operand_key", 2, :re_num], 0, 5],
|
416
|
+
|
417
|
+
["bits", 1],
|
418
|
+
|
419
|
+
["get_bits", size[:enc_ftype], 0, 2],
|
420
|
+
["bits", 0, 1,1,1,1, 0, 0, 0],
|
421
|
+
],
|
422
|
+
bitsize: 32
|
423
|
+
}
|
424
|
+
end
|
425
|
+
|
426
|
+
|
427
|
+
|
428
|
+
|
429
|
+
fp_sizes.each do |size|
|
430
|
+
@simd_fp_instructions << {
|
431
|
+
keyword: "fsqrt.#{size[:suffix]}",
|
432
|
+
name: "Floating-point square root (vector, #{size[:suffix]})",
|
433
|
+
description: "Calculates the square root of each floating-point vector element in the source SIMD&FP register, and writes the result to the destination SIMD&FP register.",
|
434
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector registe"}],
|
435
|
+
mc_constructor: [
|
436
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
437
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
438
|
+
|
439
|
+
["bits", 0,1, 1,1,1,1,1, 0,0,0,0,1],
|
440
|
+
|
441
|
+
["get_bits", size[:enc_size], 0, 1],
|
442
|
+
["bits", 1, 0,1,1,1,0, 1],
|
443
|
+
["get_bits", size[:enc_q], 0, 1],
|
444
|
+
["bits", 0],
|
445
|
+
],
|
446
|
+
bitsize: 32
|
447
|
+
}
|
448
|
+
end
|
449
|
+
fp_hp_sizes.each do |size|
|
450
|
+
@simd_fp_instructions << {
|
451
|
+
keyword: "fsqrt.#{size[:suffix]}",
|
452
|
+
name: "Floating-point square root (vector, #{size[:suffix]})",
|
453
|
+
description: "Calculates the square root of each floating-point vector element in the source SIMD&FP register, and writes the result to the destination SIMD&FP register.",
|
454
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector registe"}],
|
455
|
+
mc_constructor: [
|
456
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
457
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
458
|
+
|
459
|
+
["bits", 0,1, 1,1,1,1,1, 0,0,1,1,1,1, 1, 0,1,1,1,0, 1],
|
460
|
+
|
461
|
+
["get_bits", size[:enc_q], 0, 1],
|
462
|
+
["bits", 0],
|
463
|
+
],
|
464
|
+
bitsize: 32
|
465
|
+
}
|
466
|
+
end
|
467
|
+
ftypes.each do |size|
|
468
|
+
@simd_fp_instructions << {
|
469
|
+
keyword: "fsqrt.#{size[:suffix]}",
|
470
|
+
name: "Floating-point square root (scalar, #{size[:suffix]})",
|
471
|
+
description: "Calculates the square root of the value in the source SIMD&FP register, and writes the result to the destination SIMD&FP register.",
|
472
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector registe"}],
|
473
|
+
mc_constructor: [
|
474
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
475
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
476
|
+
|
477
|
+
["bits", 0,0,0,0,1, 1,1, 0,0,0,0, 1],
|
478
|
+
|
479
|
+
["get_bits", size[:enc_ftype], 0, 2],
|
480
|
+
["bits", 0, 1,1,1,1, 0, 0, 0],
|
481
|
+
],
|
482
|
+
bitsize: 32
|
483
|
+
}
|
484
|
+
end
|
485
|
+
|
486
|
+
|
487
|
+
|
488
|
+
|
489
|
+
|
490
|
+
fp_sizes.each do |size|
|
491
|
+
@simd_fp_instructions << {
|
492
|
+
keyword: "fmul.#{size[:suffix]}",
|
493
|
+
name: "Floating-point multiply (vector, #{size[:suffix]})",
|
494
|
+
description: "Multiplies the corresponding floating-point elements in two source SIMD&FP registers, and writes the result to the destination SIMD&FP register.",
|
495
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 1"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 2"}],
|
496
|
+
mc_constructor: [
|
497
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
498
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
499
|
+
|
500
|
+
["bits", 1, 1,1,0,1,1],
|
501
|
+
|
502
|
+
["get_bits", ["get_operand_key", 2, :re_num], 0, 5],
|
503
|
+
|
504
|
+
["bits", 1],
|
505
|
+
|
506
|
+
["get_bits", size[:enc_size], 0, 1],
|
507
|
+
["bits", 0, 0,1,1,1,0, 1],
|
508
|
+
["get_bits", size[:enc_q], 0, 1],
|
509
|
+
["bits", 0],
|
510
|
+
],
|
511
|
+
bitsize: 32
|
512
|
+
}
|
513
|
+
end
|
514
|
+
fp_hp_sizes.each do |size|
|
515
|
+
@simd_fp_instructions << {
|
516
|
+
keyword: "fmul.#{size[:suffix]}",
|
517
|
+
name: "Floating-point multiply (vector, #{size[:suffix]})",
|
518
|
+
description: "Multiplies the corresponding floating-point elements in two source SIMD&FP registers, and writes the result to the destination SIMD&FP register.",
|
519
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 1"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 2"}],
|
520
|
+
mc_constructor: [
|
521
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
522
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
523
|
+
|
524
|
+
["bits", 1, 1,1,0, 0,0],
|
525
|
+
|
526
|
+
["get_bits", ["get_operand_key", 2, :re_num], 0, 5],
|
527
|
+
|
528
|
+
["bits", 0,1, 0, 0,1,1,1,0, 1],
|
529
|
+
|
530
|
+
["get_bits", size[:enc_q], 0, 1],
|
531
|
+
["bits", 0],
|
532
|
+
],
|
533
|
+
bitsize: 32
|
534
|
+
}
|
535
|
+
end
|
536
|
+
ftypes.each do |size|
|
537
|
+
@simd_fp_instructions << {
|
538
|
+
keyword: "fmul.#{size[:suffix]}",
|
539
|
+
name: "Floating-point multiply (scalar, #{size[:suffix]})",
|
540
|
+
description: "Multiplies the floating-point values of two source SIMD&FP registers, and writes the result to the destination SIMD&FP register.",
|
541
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 1"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 2"}],
|
542
|
+
mc_constructor: [
|
543
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
544
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
545
|
+
|
546
|
+
["bits", 0,1, 0,0,0, 0],
|
547
|
+
|
548
|
+
["get_bits", ["get_operand_key", 2, :re_num], 0, 5],
|
549
|
+
|
550
|
+
["bits", 1],
|
551
|
+
|
552
|
+
["get_bits", size[:enc_ftype], 0, 2],
|
553
|
+
["bits", 0,1,1,1,1, 0, 0, 0],
|
554
|
+
],
|
555
|
+
bitsize: 32
|
556
|
+
}
|
557
|
+
end
|
558
|
+
|
559
|
+
ftypes.each do |ftype_1|
|
560
|
+
ftypes.each do |ftype_2|
|
561
|
+
next if ftype_1 == ftype_2
|
562
|
+
|
563
|
+
@simd_fp_instructions << {
|
564
|
+
keyword: "fcvt.#{ftype_1[:suffix]}_to_#{ftype_2[:suffix]}",
|
565
|
+
name: "Floating-point convert precision (scalar, #{ftype_1[:suffix]} to #{ftype_2[:suffix]})",
|
566
|
+
description: "Converts the floating-point value in the SIMD&FP source register to the precision of the destination data type using the rounding mode determined by the FPCR system register, and writes the result to the destination SIMD&FP register.",
|
567
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register"}],
|
568
|
+
mc_constructor: [
|
569
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
570
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
571
|
+
|
572
|
+
["bits", 0,0,0,0,1],
|
573
|
+
|
574
|
+
["get_bits", ftype_2[:enc_ftype], 0, 2],
|
575
|
+
|
576
|
+
["bits", 1,0,0,0, 1],
|
577
|
+
|
578
|
+
["get_bits", ftype_1[:enc_ftype], 0, 2],
|
579
|
+
["bits", 0,1,1,1,1, 0, 0, 0],
|
580
|
+
],
|
581
|
+
bitsize: 32
|
582
|
+
}
|
583
|
+
end
|
584
|
+
end
|
585
|
+
|
586
|
+
|
587
|
+
# ftypes.each do |ftype|
|
588
|
+
# [{reg_size: 32, sf: 0}, {reg_size: 64, sf: 1}].each do |reg_size|
|
589
|
+
# @simd_fp_instructions << {
|
590
|
+
# keyword: "fcvt.#{ftype_1[:suffix]}_to_#{ftype_2[:suffix]}",
|
591
|
+
# name: "Floating-point convert precision (scalar, #{ftype_1[:suffix]} to #{ftype_2[:suffix]})",
|
592
|
+
# description: "Converts the floating-point value in the SIMD&FP source register to the precision of the destination data type using the rounding mode determined by the FPCR system register, and writes the result to the destination SIMD&FP register.",
|
593
|
+
# operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register"}],
|
594
|
+
# mc_constructor: [
|
595
|
+
# ["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
596
|
+
# ["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
597
|
+
#
|
598
|
+
# ["bits", 0,0,0,0,1],
|
599
|
+
#
|
600
|
+
# ["get_bits", ftype_2[:enc_ftype], 0, 2],
|
601
|
+
#
|
602
|
+
# ["bits", 1,0,0,0, 1],
|
603
|
+
#
|
604
|
+
# ["get_bits", ftype_1[:enc_ftype], 0, 2],
|
605
|
+
# ["bits", 0,1,1,1,1, 0, 0, 0],
|
606
|
+
# ],
|
607
|
+
# bitsize: 32
|
608
|
+
# }
|
609
|
+
# end
|
610
|
+
# end
|
611
|
+
|
612
|
+
@simd_fp_instructions << {
|
613
|
+
keyword: "faddp.h",
|
614
|
+
name: "Floating-point add pair of elements (scalar, h)",
|
615
|
+
description: "Adds two floating-point vector elements in the source SIMD&FP register and writes the scalar result to the destination SIMD&FP register.",
|
616
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register"}],
|
617
|
+
mc_constructor: [
|
618
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
619
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
620
|
+
|
621
|
+
["bits", 0,1, 1,0,1,1,0, 0,0,0,1,1],
|
622
|
+
|
623
|
+
["bits", 0], # sz
|
624
|
+
|
625
|
+
["bits", 0, 0,1,1,1,1, 0, 1,0],
|
626
|
+
],
|
627
|
+
bitsize: 32
|
628
|
+
}
|
629
|
+
|
630
|
+
[{suffix: "s", sz: 0}, {suffix: "d", sz: 1}].each do |size|
|
631
|
+
@simd_fp_instructions << {
|
632
|
+
keyword: "faddp.#{size[:suffix]}",
|
633
|
+
name: "Floating-point add pair of elements (scalar, #{size[:suffix]})",
|
634
|
+
description: "Adds two floating-point vector elements in the source SIMD&FP register and writes the scalar result to the destination SIMD&FP register.",
|
635
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register"}],
|
636
|
+
mc_constructor: [
|
637
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
638
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
639
|
+
|
640
|
+
["bits", 0,1, 1,0,1,1,0, 0,0,0,1,1],
|
641
|
+
|
642
|
+
["bits", size[:sz]], # sz
|
643
|
+
|
644
|
+
["bits", 0, 0,1,1,1,1, 1, 1,0],
|
645
|
+
],
|
646
|
+
bitsize: 32
|
647
|
+
}
|
648
|
+
end
|
649
|
+
|
650
|
+
|
651
|
+
ftypes.each do |size|
|
652
|
+
@simd_fp_instructions << {
|
653
|
+
keyword: "fcmp.#{size[:suffix]}",
|
654
|
+
name: "Floating-point compare (scalar, #{size[:suffix]})",
|
655
|
+
description: "Compares the floating-point values of two source SIMD&FP registers, and updates the PSTATE N, Z, C, V flags based on the result.",
|
656
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP register 1"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP register 2"}],
|
657
|
+
mc_constructor: [
|
658
|
+
["bits", 0,0,0, 0,0],
|
659
|
+
|
660
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
661
|
+
|
662
|
+
["bits", 0,0,0,1, 0,0],
|
663
|
+
|
664
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
665
|
+
|
666
|
+
["bits", 1],
|
667
|
+
|
668
|
+
["get_bits", size[:enc_ftype], 0, 2],
|
669
|
+
["bits", 0, 1,1,1,1, 0, 0, 0],
|
670
|
+
],
|
671
|
+
bitsize: 32
|
672
|
+
}
|
673
|
+
end
|
674
|
+
|
675
|
+
ftypes.each do |size|
|
676
|
+
@simd_fp_instructions << {
|
677
|
+
keyword: "fcmpz.#{size[:suffix]}",
|
678
|
+
name: "Floating-point compare to zero (scalar, #{size[:suffix]})",
|
679
|
+
description: "Compares the floating-point value of the source SIMD&FP register with zero, and updates the PSTATE N, Z, C, V flags based on the result.",
|
680
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP register"}],
|
681
|
+
mc_constructor: [
|
682
|
+
["bits", 0,0,0, 1,0],
|
683
|
+
|
684
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
685
|
+
|
686
|
+
["bits", 0,0,0,1, 0,0],
|
687
|
+
|
688
|
+
["get_bits", 0, 0, 5], # Rm = 0
|
689
|
+
|
690
|
+
["bits", 1],
|
691
|
+
|
692
|
+
["get_bits", size[:enc_ftype], 0, 2],
|
693
|
+
["bits", 0, 1,1,1,1, 0, 0, 0],
|
694
|
+
],
|
695
|
+
bitsize: 32
|
696
|
+
}
|
697
|
+
end
|
698
|
+
|
699
|
+
|
700
|
+
ftypes_no_length.each do |size|
|
701
|
+
@simd_fp_instructions << {
|
702
|
+
keyword: "scvtf.#{size[:suffix]}",
|
703
|
+
name: "Signed integer convert to floating-point (scalar, #{size[:suffix]})",
|
704
|
+
description: "Converts the signed integer in the source general-purpose register to a floating-point value using the rounding mode specified by the FPCR system register, and writes the result to the destination SIMD&FP register.",
|
705
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP register"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Source general-purpose register"}],
|
706
|
+
mc_constructor: [
|
707
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
708
|
+
["get_bits", ["get_operand_key", 1, :reg_value], 0, 5],
|
709
|
+
|
710
|
+
["bits", 0,0,0,0,0,0, 0,1,0, 0,0, 1],
|
711
|
+
|
712
|
+
["get_bits", size[:enc_ftype], 0, 2],
|
713
|
+
|
714
|
+
["bits", 0,1,1,1,1, 0, 0],
|
715
|
+
|
716
|
+
["case", ["get_key", ["get_operand", 1], :reg_size], 64, ["bits", 1], 32, ["bits", 0], 0],
|
717
|
+
],
|
718
|
+
bitsize: 32
|
719
|
+
}
|
720
|
+
end
|
721
|
+
|
722
|
+
|
723
|
+
|
724
|
+
fp_sizes.each do |size|
|
725
|
+
@simd_fp_instructions << {
|
726
|
+
keyword: "scvtf.#{size[:suffix]}",
|
727
|
+
name: "Signed integer convert to floating-point (vector, #{size[:suffix]})",
|
728
|
+
description: "Converts each signed integer element in the source SIMD&FP register to floating-point elements using the rounding mode specified in FPCR, and writes the result to the destination SIMD&FP register.",
|
729
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register"}],
|
730
|
+
mc_constructor: [
|
731
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
732
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
733
|
+
|
734
|
+
["bits", 0,1, 1,0,1,1,1, 0,0,0,0,1],
|
735
|
+
|
736
|
+
["get_bits", size[:enc_size], 0, 1],
|
737
|
+
["bits", 0, 0,1,1,1,0, 0],
|
738
|
+
["get_bits", size[:enc_q], 0, 1],
|
739
|
+
|
740
|
+
["bits", 0],
|
741
|
+
],
|
742
|
+
bitsize: 32
|
743
|
+
}
|
744
|
+
end
|
745
|
+
fp_hp_sizes.each do |size|
|
746
|
+
@simd_fp_instructions << {
|
747
|
+
keyword: "scvtf.#{size[:suffix]}",
|
748
|
+
name: "Signed integer convert to floating-point (vector, #{size[:suffix]})",
|
749
|
+
description: "Converts each signed integer element in the source SIMD&FP register to floating-point elements using the rounding mode specified in FPCR, and writes the result to the destination SIMD&FP register.",
|
750
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register"}],
|
751
|
+
mc_constructor: [
|
752
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
753
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
754
|
+
|
755
|
+
["bits", 0,1, 1,0,1,1,1, 0,0,1,1,1,1, 0, 0,1,1,1,0, 0],
|
756
|
+
|
757
|
+
["get_bits", size[:enc_q], 0, 1],
|
758
|
+
["bits", 0],
|
759
|
+
],
|
760
|
+
bitsize: 32
|
761
|
+
}
|
762
|
+
end
|
763
|
+
ftypes_no_hp.each do |size|
|
764
|
+
@simd_fp_instructions << {
|
765
|
+
keyword: "scvtf.#{size[:suffix]}",
|
766
|
+
name: "Signed integer convert to floating-point (vector, #{size[:suffix]})",
|
767
|
+
description: "Converts each signed integer element in the source SIMD&FP register to floating-point elements using the rounding mode specified in FPCR, and writes the result to the destination SIMD&FP register.",
|
768
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register"}],
|
769
|
+
mc_constructor: [
|
770
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
771
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
772
|
+
|
773
|
+
["bits", 0,1, 1,0,1,1,1, 0,0,0,0,1],
|
774
|
+
|
775
|
+
["get_bits", size[:enc_ftype], 0, 1],
|
776
|
+
["bits", 0, 0,1,1,1,1, 0, 1,0],
|
777
|
+
],
|
778
|
+
bitsize: 32
|
779
|
+
}
|
780
|
+
end
|
781
|
+
@simd_fp_instructions << {
|
782
|
+
keyword: "scvtf.1h",
|
783
|
+
name: "Signed integer convert to floating-point (vector, 1h)",
|
784
|
+
description: "Converts each signed integer element in the source SIMD&FP register to floating-point elements using the rounding mode specified in FPCR, and writes the result to the destination SIMD&FP register.",
|
785
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register"}],
|
786
|
+
mc_constructor: [
|
787
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
788
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
789
|
+
|
790
|
+
["bits", 0,1, 1,0,1,1,1, 0,0,1,1,1,1, 0, 0,1,1,1,1, 0, 1,0],
|
791
|
+
],
|
792
|
+
bitsize: 32
|
793
|
+
}
|
794
|
+
|
795
|
+
|
796
|
+
[{suffix: "8b", q: 0}, {suffix: "16b", q: 1}].each do |size|
|
797
|
+
@simd_fp_instructions << {
|
798
|
+
keyword: "mov.#{size[:suffix]}",
|
799
|
+
name: "Move vector (#{size[:suffix]})",
|
800
|
+
description: "Copies the vector in the source SIMD&FP register into the destination SIMD&FP register.",
|
801
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register"}],
|
802
|
+
mc_constructor: [
|
803
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
804
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
805
|
+
|
806
|
+
["bits", 1],
|
807
|
+
["bits", 1,1,0,0,0],
|
808
|
+
|
809
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
810
|
+
|
811
|
+
["bits", 1, 0,1, 0,1,1,1,0, 0],
|
812
|
+
|
813
|
+
["bits", size[:q], 0],
|
814
|
+
],
|
815
|
+
bitsize: 32
|
816
|
+
}
|
817
|
+
end
|
818
|
+
|
819
|
+
|
820
|
+
|
821
|
+
|
822
|
+
|
823
|
+
@simd_fp_instructions << {
|
824
|
+
keyword: "fcvts.n.1h",
|
825
|
+
name: "Floating-point convert to signed integer (vector, 1h)",
|
826
|
+
description: "Converts each floating-point element in the source SIMD&FP register to a signed integer using the \"Round to Nearest\" rounding mode, and writes the result to the destination SIMD&FP register.",
|
827
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register"}],
|
828
|
+
mc_constructor: [
|
829
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
830
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
831
|
+
|
832
|
+
["bits", 0,1, 0, 1,0,1,1, 0,0,1,1,1,1, 0, 0,1,1,1,1, 0, 1,0],
|
833
|
+
],
|
834
|
+
bitsize: 32
|
835
|
+
}
|
836
|
+
ftypes_no_hp.each do |size|
|
837
|
+
@simd_fp_instructions << {
|
838
|
+
keyword: "fcvts.n.#{size[:suffix]}",
|
839
|
+
name: "Floating-point convert to signed integer (vector, #{size[:suffix]})",
|
840
|
+
description: "Converts each floating-point element in the source SIMD&FP register to a signed integer using the \"Round to Nearest\" rounding mode, and writes the result to the destination SIMD&FP register.",
|
841
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register"}],
|
842
|
+
mc_constructor: [
|
843
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
844
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
845
|
+
|
846
|
+
["bits", 0,1, 0, 1,0,1,1, 0,0,0,0,1],
|
847
|
+
|
848
|
+
["get_bits", size[:enc_ftype], 0, 1],
|
849
|
+
|
850
|
+
["bits", 0, 0,1,1,1,1, 0, 1,0],
|
851
|
+
],
|
852
|
+
bitsize: 32
|
853
|
+
}
|
854
|
+
end
|
855
|
+
fp_hp_sizes.each do |size|
|
856
|
+
@simd_fp_instructions << {
|
857
|
+
keyword: "fcvts.n.#{size[:suffix]}",
|
858
|
+
name: "Floating-point convert to signed integer (vector, #{size[:suffix]})",
|
859
|
+
description: "Converts each floating-point element in the source SIMD&FP register to a signed integer using the \"Round to Nearest\" rounding mode, and writes the result to the destination SIMD&FP register.",
|
860
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register"}],
|
861
|
+
mc_constructor: [
|
862
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
863
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
864
|
+
|
865
|
+
["bits", 0,1, 0, 1,0,1,1, 0,0,1,1,1,1, 0, 0,1,1,1,0, 0],
|
866
|
+
|
867
|
+
["get_bits", size[:enc_q], 0, 1],
|
868
|
+
|
869
|
+
["bits", 0],
|
870
|
+
],
|
871
|
+
bitsize: 32
|
872
|
+
}
|
873
|
+
end
|
874
|
+
fp_sizes.each do |size|
|
875
|
+
@simd_fp_instructions << {
|
876
|
+
keyword: "fcvts.n.#{size[:suffix]}",
|
877
|
+
name: "Floating-point convert to signed integer (vector, #{size[:suffix]})",
|
878
|
+
description: "Converts each floating-point element in the source SIMD&FP register to a signed integer using the \"Round to Nearest\" rounding mode, and writes the result to the destination SIMD&FP register.",
|
879
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register"}],
|
880
|
+
mc_constructor: [
|
881
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
882
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
883
|
+
|
884
|
+
["bits", 0,1, 0, 1,0,1,1, 0,0,0,0,1],
|
885
|
+
|
886
|
+
["get_bits", size[:enc_size], 0, 1],
|
887
|
+
|
888
|
+
["bits", 0, 0,1,1,1,0, 0],
|
889
|
+
|
890
|
+
["get_bits", size[:enc_q], 0, 1],
|
891
|
+
|
892
|
+
["bits", 0],
|
893
|
+
],
|
894
|
+
bitsize: 32
|
895
|
+
}
|
896
|
+
end
|
897
|
+
|
898
|
+
|
899
|
+
|
900
|
+
|
901
|
+
|
902
|
+
fp_sizes.each do |size|
|
903
|
+
@simd_fp_instructions << {
|
904
|
+
keyword: "fdiv.#{size[:suffix]}",
|
905
|
+
name: "Floating-point divide (vector, #{size[:suffix]})",
|
906
|
+
description: "Divides the floating-point elements in the elements in the first source SIMD&FP register by the elements in the second source SIMD&FP register, and writes the result to the destination SIMD&FP register.",
|
907
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 1"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 2"}],
|
908
|
+
mc_constructor: [
|
909
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
910
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
911
|
+
|
912
|
+
["bits", 1, 1,1,1,1,1],
|
913
|
+
|
914
|
+
["get_bits", ["get_operand_key", 2, :re_num], 0, 5],
|
915
|
+
|
916
|
+
["bits", 1],
|
917
|
+
|
918
|
+
["get_bits", size[:enc_size], 0, 1],
|
919
|
+
["bits", 0, 0,1,1,1,0, 1],
|
920
|
+
["get_bits", size[:enc_q], 0, 1],
|
921
|
+
["bits", 0],
|
922
|
+
],
|
923
|
+
bitsize: 32
|
924
|
+
}
|
925
|
+
end
|
926
|
+
fp_hp_sizes.each do |size|
|
927
|
+
@simd_fp_instructions << {
|
928
|
+
keyword: "fdiv.#{size[:suffix]}",
|
929
|
+
name: "Floating-point divide (vector, #{size[:suffix]})",
|
930
|
+
description: "Divides the floating-point elements in the elements in the first source SIMD&FP register by the elements in the second source SIMD&FP register, and writes the result to the destination SIMD&FP register.",
|
931
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 1"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 2"}],
|
932
|
+
mc_constructor: [
|
933
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
934
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
935
|
+
|
936
|
+
["bits", 1, 1,1,1, 0,0],
|
937
|
+
|
938
|
+
["get_bits", ["get_operand_key", 2, :re_num], 0, 5],
|
939
|
+
|
940
|
+
["bits", 0,1, 0, 0,1,1,1,0, 1],
|
941
|
+
|
942
|
+
["get_bits", size[:enc_q], 0, 1],
|
943
|
+
["bits", 0],
|
944
|
+
],
|
945
|
+
bitsize: 32
|
946
|
+
}
|
947
|
+
end
|
948
|
+
ftypes.each do |size|
|
949
|
+
@simd_fp_instructions << {
|
950
|
+
keyword: "fdiv.#{size[:suffix]}",
|
951
|
+
name: "Floating-point divide (scalar, #{size[:suffix]})",
|
952
|
+
description: "Divides the floating-point elements in the elements in the first source SIMD&FP register by the elements in the second source SIMD&FP register, and writes the result to the destination SIMD&FP register.",
|
953
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 1"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 2"}],
|
954
|
+
mc_constructor: [
|
955
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
956
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
957
|
+
|
958
|
+
["bits", 0,1, 1,0,0,0],
|
959
|
+
|
960
|
+
["get_bits", ["get_operand_key", 2, :re_num], 0, 5],
|
961
|
+
|
962
|
+
["bits", 1],
|
963
|
+
|
964
|
+
["get_bits", size[:enc_ftype], 0, 2],
|
965
|
+
["bits", 0,1,1,1,1, 0, 0, 0],
|
966
|
+
],
|
967
|
+
bitsize: 32
|
968
|
+
}
|
969
|
+
end
|
970
|
+
|
971
|
+
|
972
|
+
|
973
|
+
half_and_full_sizes.each do |size|
|
974
|
+
@simd_fp_instructions << {
|
975
|
+
keyword: "eor.#{size[:suffix]}",
|
976
|
+
name: "Bitwise exclusive-OR (#{size[:suffix]})",
|
977
|
+
description: "Performs a bitwise exclusive-OR operation between the two source SIMD&FP registers, and writes the result to the destination SIMD&FP register.",
|
978
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 1"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 2"}],
|
979
|
+
mc_constructor: [
|
980
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
981
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
982
|
+
|
983
|
+
["bits", 1, 1,1,0,0,0],
|
984
|
+
|
985
|
+
["get_bits", ["get_operand_key", 2, :re_num], 0, 5],
|
986
|
+
|
987
|
+
["bits", 1, 0,0, 0,1,1,1,0, 1],
|
988
|
+
|
989
|
+
["get_bits", size[:q], 0, 2],
|
990
|
+
["bits", 0],
|
991
|
+
],
|
992
|
+
bitsize: 32
|
993
|
+
}
|
994
|
+
end
|
995
|
+
|
996
|
+
|
997
|
+
|
998
|
+
|
999
|
+
fp_hp_sizes.each do |size|
|
1000
|
+
@simd_fp_instructions << {
|
1001
|
+
keyword: "fmla.#{size[:suffix]}",
|
1002
|
+
name: "Floating-point multiply-add to accumulator (vector, #{size[:suffix]})",
|
1003
|
+
description: "Multiplies the corresponding floating-point elements in the first and second source SIMD&FP registers, adds the result and the corresponding floating-point elements in the destination SIMD&FP register (accumulates), and writes the result to the destination SIMD&FP register.",
|
1004
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register (accumulator)"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 1"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 2"}],
|
1005
|
+
mc_constructor: [
|
1006
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
1007
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
1008
|
+
|
1009
|
+
["bits", 1, 1,0,0, 0,0],
|
1010
|
+
|
1011
|
+
["get_bits", ["get_operand_key", 2, :re_num], 0, 5],
|
1012
|
+
|
1013
|
+
["bits", 0,1, 0, 0,1,1,1,0, 0],
|
1014
|
+
|
1015
|
+
["get_bits", size[:enc_q], 0, 1],
|
1016
|
+
["bits", 0],
|
1017
|
+
],
|
1018
|
+
bitsize: 32
|
1019
|
+
}
|
1020
|
+
end
|
1021
|
+
fp_sizes.each do |size|
|
1022
|
+
@simd_fp_instructions << {
|
1023
|
+
keyword: "fmla.#{size[:suffix]}",
|
1024
|
+
name: "Floating-point multiply-add to accumulator (vector, #{size[:suffix]})",
|
1025
|
+
description: "Multiplies the corresponding floating-point elements in the first and second source SIMD&FP registers, adds the result and the corresponding floating-point elements in the destination SIMD&FP register (accumulates), and writes the result to the destination SIMD&FP register.",
|
1026
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register (accumulator)"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 1"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register 2"}],
|
1027
|
+
mc_constructor: [
|
1028
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
1029
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
1030
|
+
|
1031
|
+
["bits", 1, 1,0,0,1,1],
|
1032
|
+
|
1033
|
+
["get_bits", ["get_operand_key", 2, :re_num], 0, 5],
|
1034
|
+
|
1035
|
+
["bits", 1],
|
1036
|
+
|
1037
|
+
["get_bits", size[:enc_size], 0, 1],
|
1038
|
+
["bits", 0, 0,1,1,1,0, 0],
|
1039
|
+
["get_bits", size[:enc_q], 0, 1],
|
1040
|
+
["bits", 0],
|
1041
|
+
],
|
1042
|
+
bitsize: 32
|
1043
|
+
}
|
1044
|
+
end
|
1045
|
+
|
1046
|
+
|
1047
|
+
ldr_sizes = [
|
1048
|
+
{suffix: "b", enc_size: 0b00, enc_opc_bit2: 0, bytesize: 1},
|
1049
|
+
{suffix: "h", enc_size: 0b01, enc_opc_bit2: 0, bytesize: 2},
|
1050
|
+
{suffix: "s", enc_size: 0b10, enc_opc_bit2: 0, bytesize: 4},
|
1051
|
+
{suffix: "d", enc_size: 0b11, enc_opc_bit2: 0, bytesize: 8},
|
1052
|
+
{suffix: "q", enc_size: 0b00, enc_opc_bit2: 1, bytesize: 16},
|
1053
|
+
]
|
1054
|
+
|
1055
|
+
|
1056
|
+
ldr_sizes.each do |size|
|
1057
|
+
@simd_fp_instructions << {
|
1058
|
+
keyword: "ldr.#{size[:suffix]}",
|
1059
|
+
name: "Load SIMD&FP Register (#{size[:suffix]})",
|
1060
|
+
description: "Loads the specified amount from memory at the address in the source general-purpose register, and writes the result to the destination SIMD&FP register.",
|
1061
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP register"}, {type: "register", restrictions: {reg_type: "gpr", reg_size: 64}, name: "Address source general-purpose register"}],
|
1062
|
+
mc_constructor: [
|
1063
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
1064
|
+
["get_bits", ["get_operand_key", 1, :reg_value], 0, 5],
|
1065
|
+
|
1066
|
+
["get_bits", 0, 0, 12], # imm12
|
1067
|
+
|
1068
|
+
["bits", 1, size[:enc_opc_bit2]],
|
1069
|
+
|
1070
|
+
["bits", 1,0, 1, 1,1,1],
|
1071
|
+
|
1072
|
+
["get_bits", size[:enc_size], 0, 2],
|
1073
|
+
],
|
1074
|
+
bitsize: 32
|
1075
|
+
}
|
1076
|
+
end
|
1077
|
+
ldr_sizes.each do |size|
|
1078
|
+
@simd_fp_instructions << {
|
1079
|
+
keyword: "ldr.unsigned.#{size[:suffix]}",
|
1080
|
+
name: "Load SIMD&FP Register (immediate, unsigned offset, #{size[:suffix]})",
|
1081
|
+
description: "Loads the specified amount from memory at the address in in the source general-purpose register, with a signed immediate offset added, and writes the result to the destination SIMD&FP register.",
|
1082
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP register"}, {type: "register", restrictions: {reg_type: "gpr", reg_size: 64}, name: "Address source general-purpose register"}, {type: "immediate", name: "Unsigned offset"}],
|
1083
|
+
mc_constructor: [
|
1084
|
+
["if_eq_else", ["modulo", ["get_operand", 2], size[:bytesize]], 0, [], ["raise_error", "ldr (immediate) Error: Immediate offset is not divisible by #{size[:bytesize].to_s}."]],
|
1085
|
+
|
1086
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
1087
|
+
["get_bits", ["get_operand_key", 1, :reg_value], 0, 5],
|
1088
|
+
|
1089
|
+
["get_bits", ["divide", ["get_operand", 2], size[:bytesize]], 0, 12], # imm12
|
1090
|
+
|
1091
|
+
["bits", 1, size[:enc_opc_bit2]],
|
1092
|
+
|
1093
|
+
["bits", 1,0, 1, 1,1,1],
|
1094
|
+
|
1095
|
+
["get_bits", size[:enc_size], 0, 2],
|
1096
|
+
],
|
1097
|
+
bitsize: 32
|
1098
|
+
}
|
1099
|
+
end
|
1100
|
+
ldr_sizes.each do |size|
|
1101
|
+
@simd_fp_instructions << {
|
1102
|
+
keyword: "ldr.post_index.#{size[:suffix]}",
|
1103
|
+
name: "Load SIMD&FP Register (immediate, signed post-index offset, #{size[:suffix]})",
|
1104
|
+
description: "Loads the specified amount from memory at the address in in the source general-purpose register, with a signed immediate offset added permanently after reading, and writes the result to the destination SIMD&FP register.",
|
1105
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP register"}, {type: "register", restrictions: {reg_type: "gpr", reg_size: 64}, name: "Address source general-purpose register"}, {type: "immediate", name: "Signed offset"}],
|
1106
|
+
mc_constructor: [
|
1107
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
1108
|
+
["get_bits", ["get_operand_key", 1, :reg_value], 0, 5],
|
1109
|
+
|
1110
|
+
["bits", 1,0],
|
1111
|
+
|
1112
|
+
["get_bits", ["get_operand", 2], 0, 9], # imm9
|
1113
|
+
|
1114
|
+
["bits", 0],
|
1115
|
+
["bits", 1, size[:enc_opc_bit2]],
|
1116
|
+
["bits", 0,0, 1, 1,1,1],
|
1117
|
+
["get_bits", size[:enc_size], 0, 2],
|
1118
|
+
],
|
1119
|
+
bitsize: 32
|
1120
|
+
}
|
1121
|
+
end
|
1122
|
+
ldr_sizes.each do |size|
|
1123
|
+
@simd_fp_instructions << {
|
1124
|
+
keyword: "ldr.pre_index.#{size[:suffix]}",
|
1125
|
+
name: "Load SIMD&FP Register (immediate, signed pre-index offset, #{size[:suffix]})",
|
1126
|
+
description: "Loads the specified amount from memory at the address in in the source general-purpose register, with a signed immediate offset added permanently before reading, and writes the result to the destination SIMD&FP register.",
|
1127
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP register"}, {type: "register", restrictions: {reg_type: "gpr", reg_size: 64}, name: "Address source general-purpose register"}, {type: "immediate", name: "Signed offset"}],
|
1128
|
+
mc_constructor: [
|
1129
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
1130
|
+
["get_bits", ["get_operand_key", 1, :reg_value], 0, 5],
|
1131
|
+
|
1132
|
+
["bits", 1,1],
|
1133
|
+
|
1134
|
+
["get_bits", ["get_operand", 2], 0, 9], # imm9
|
1135
|
+
|
1136
|
+
["bits", 0],
|
1137
|
+
["bits", 1, size[:enc_opc_bit2]],
|
1138
|
+
["bits", 0,0, 1, 1,1,1],
|
1139
|
+
["get_bits", size[:enc_size], 0, 2],
|
1140
|
+
],
|
1141
|
+
bitsize: 32
|
1142
|
+
}
|
1143
|
+
end
|
1144
|
+
|
1145
|
+
|
1146
|
+
|
1147
|
+
|
1148
|
+
|
1149
|
+
ldr_sizes.each do |size|
|
1150
|
+
@simd_fp_instructions << {
|
1151
|
+
keyword: "str.#{size[:suffix]}",
|
1152
|
+
name: "Store SIMD&FP Register (#{size[:suffix]})",
|
1153
|
+
description: "Stores a SIMD&FP register of the specified size to memory at the address in the source general-purpose register.",
|
1154
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP register"}, {type: "register", restrictions: {reg_type: "gpr", reg_size: 64}, name: "Address source general-purpose register"}],
|
1155
|
+
mc_constructor: [
|
1156
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
1157
|
+
["get_bits", ["get_operand_key", 1, :reg_value], 0, 5],
|
1158
|
+
|
1159
|
+
["get_bits", 0, 0, 12], # imm12
|
1160
|
+
|
1161
|
+
["bits", 0, size[:enc_opc_bit2]],
|
1162
|
+
|
1163
|
+
["bits", 1,0, 1, 1,1,1],
|
1164
|
+
|
1165
|
+
["get_bits", size[:enc_size], 0, 2],
|
1166
|
+
],
|
1167
|
+
bitsize: 32
|
1168
|
+
}
|
1169
|
+
end
|
1170
|
+
ldr_sizes.each do |size|
|
1171
|
+
@simd_fp_instructions << {
|
1172
|
+
keyword: "str.unsigned.#{size[:suffix]}",
|
1173
|
+
name: "Store SIMD&FP Register (immediate, unsigned offset, #{size[:suffix]})",
|
1174
|
+
description: "Stores a SIMD&FP register of the specified size to memory at the address in the source general-purpose register with an unsigned immediate offset added.",
|
1175
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP register"}, {type: "register", restrictions: {reg_type: "gpr", reg_size: 64}, name: "Address source general-purpose register"}, {type: "immediate", name: "Unsigned offset"}],
|
1176
|
+
mc_constructor: [
|
1177
|
+
["if_eq_else", ["modulo", ["get_operand", 2], size[:bytesize]], 0, [], ["raise_error", "ldr (immediate) Error: Immediate offset is not divisible by #{size[:bytesize].to_s}."]],
|
1178
|
+
|
1179
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
1180
|
+
["get_bits", ["get_operand_key", 1, :reg_value], 0, 5],
|
1181
|
+
|
1182
|
+
["get_bits", ["divide", ["get_operand", 2], size[:bytesize]], 0, 12], # imm12
|
1183
|
+
|
1184
|
+
["bits", 0, size[:enc_opc_bit2]],
|
1185
|
+
|
1186
|
+
["bits", 1,0, 1, 1,1,1],
|
1187
|
+
|
1188
|
+
["get_bits", size[:enc_size], 0, 2],
|
1189
|
+
],
|
1190
|
+
bitsize: 32
|
1191
|
+
}
|
1192
|
+
end
|
1193
|
+
ldr_sizes.each do |size|
|
1194
|
+
@simd_fp_instructions << {
|
1195
|
+
keyword: "str.post_index.#{size[:suffix]}",
|
1196
|
+
name: "Store SIMD&FP Register (immediate, signed post-index offset, #{size[:suffix]})",
|
1197
|
+
description: "Stores a SIMD&FP register of the specified size to memory at the address in the source general-purpose register with a signed immediate offset permanently added after writing.",
|
1198
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP register"}, {type: "register", restrictions: {reg_type: "gpr", reg_size: 64}, name: "Address source general-purpose register"}, {type: "immediate", name: "Signed offset"}],
|
1199
|
+
mc_constructor: [
|
1200
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
1201
|
+
["get_bits", ["get_operand_key", 1, :reg_value], 0, 5],
|
1202
|
+
|
1203
|
+
["bits", 1,0],
|
1204
|
+
|
1205
|
+
["get_bits", ["get_operand", 2], 0, 9], # imm9
|
1206
|
+
|
1207
|
+
["bits", 0],
|
1208
|
+
["bits", 0, size[:enc_opc_bit2]],
|
1209
|
+
["bits", 0,0, 1, 1,1,1],
|
1210
|
+
["get_bits", size[:enc_size], 0, 2],
|
1211
|
+
],
|
1212
|
+
bitsize: 32
|
1213
|
+
}
|
1214
|
+
end
|
1215
|
+
ldr_sizes.each do |size|
|
1216
|
+
@simd_fp_instructions << {
|
1217
|
+
keyword: "str.pre_index.#{size[:suffix]}",
|
1218
|
+
name: "Store SIMD&FP Register (immediate, signed pre-index offset, #{size[:suffix]})",
|
1219
|
+
description: "Stores a SIMD&FP register of the specified size to memory at the address in the source general-purpose register with a signed immediate offset permanently added before writing.",
|
1220
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP register"}, {type: "register", restrictions: {reg_type: "gpr", reg_size: 64}, name: "Address source general-purpose register"}, {type: "immediate", name: "Signed offset"}],
|
1221
|
+
mc_constructor: [
|
1222
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
1223
|
+
["get_bits", ["get_operand_key", 1, :reg_value], 0, 5],
|
1224
|
+
|
1225
|
+
["bits", 1,1],
|
1226
|
+
|
1227
|
+
["get_bits", ["get_operand", 2], 0, 9], # imm9
|
1228
|
+
|
1229
|
+
["bits", 0],
|
1230
|
+
["bits", 0, size[:enc_opc_bit2]],
|
1231
|
+
["bits", 0,0, 1, 1,1,1],
|
1232
|
+
["get_bits", size[:enc_size], 0, 2],
|
1233
|
+
],
|
1234
|
+
bitsize: 32
|
1235
|
+
}
|
1236
|
+
end
|
1237
|
+
|
1238
|
+
|
1239
|
+
|
1240
|
+
|
1241
|
+
|
1242
|
+
|
1243
|
+
fp_hp_sizes.each do |size|
|
1244
|
+
@simd_fp_instructions << {
|
1245
|
+
keyword: "fabs.#{size[:suffix]}",
|
1246
|
+
name: "Floating-point absolute value (vector, #{size[:suffix]})",
|
1247
|
+
description: "Calculates the absolute value of each floating-point element in the source SIMD&FP register, and writes the result to the destination register.",
|
1248
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register"}],
|
1249
|
+
mc_constructor: [
|
1250
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
1251
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
1252
|
+
|
1253
|
+
["bits", 0,1, 1,1,1,1,0, 0,0,1,1,1,1, 1, 0,1,1,1,0, 0],
|
1254
|
+
|
1255
|
+
["get_bits", size[:enc_q], 0, 1],
|
1256
|
+
["bits", 0],
|
1257
|
+
],
|
1258
|
+
bitsize: 32
|
1259
|
+
}
|
1260
|
+
end
|
1261
|
+
fp_sizes.each do |size|
|
1262
|
+
@simd_fp_instructions << {
|
1263
|
+
keyword: "fabs.#{size[:suffix]}",
|
1264
|
+
name: "Floating-point absolute value (vector, #{size[:suffix]})",
|
1265
|
+
description: "Calculates the absolute value of each floating-point element in the source SIMD&FP register, and writes the result to the destination register.",
|
1266
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register"}],
|
1267
|
+
mc_constructor: [
|
1268
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
1269
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
1270
|
+
|
1271
|
+
["bits", 0,1, 1,1,1,1,0, 0,0,0,0,1],
|
1272
|
+
|
1273
|
+
["get_bits", size[:enc_size], 0, 1],
|
1274
|
+
["bits", 1, 0,1,1,1,0, 0],
|
1275
|
+
["get_bits", size[:enc_q], 0, 1],
|
1276
|
+
["bits", 0],
|
1277
|
+
],
|
1278
|
+
bitsize: 32
|
1279
|
+
}
|
1280
|
+
end
|
1281
|
+
ftypes.each do |size|
|
1282
|
+
@simd_fp_instructions << {
|
1283
|
+
keyword: "fabs.#{size[:suffix]}",
|
1284
|
+
name: "Floating-point absolute value (scalar, #{size[:suffix]})",
|
1285
|
+
description: "Calculates the absolute value of each floating-point element in the source SIMD&FP register, and writes the result to the destination register.",
|
1286
|
+
operands: [{type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Destination SIMD&FP vector register"}, {type: "register", restrictions: {reg_type: "simd_fp_reg"}, name: "Source SIMD&FP vector register"}],
|
1287
|
+
mc_constructor: [
|
1288
|
+
["get_bits", ["get_operand_key", 0, :re_num], 0, 5],
|
1289
|
+
["get_bits", ["get_operand_key", 1, :re_num], 0, 5],
|
1290
|
+
|
1291
|
+
["bits", 0,0,0,0,1, 1,0, 0,0,0,0, 1],
|
1292
|
+
|
1293
|
+
["get_bits", size[:enc_ftype], 0, 2],
|
1294
|
+
["bits", 0,1,1,1,1, 0, 0, 0],
|
1295
|
+
],
|
1296
|
+
bitsize: 32
|
1297
|
+
}
|
1298
|
+
end
|
1299
|
+
|
1300
|
+
|
1301
|
+
|
1302
|
+
|
1303
|
+
|
1304
|
+
|
1305
|
+
|
1306
|
+
end # Kompiler::ARMv8A
|
1307
|
+
|
1308
|
+
end # Kompiler
|