kompiler 0.3.0.pre.3 → 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.
@@ -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