kompiler 0.0.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,490 @@
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
+ class ARMv8A
7
+
8
+ def self.instructions
9
+ @@instructions
10
+ end
11
+
12
+ @@instructions = [
13
+ { keyword: "mov",
14
+ operands: [{type: "register", restrictions: {reg_size: 64}}, {type: "immediate", restrictions: {}}],
15
+ mc_constructor: [
16
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
17
+ ["get_bits", ["get_operand", 1], 0, 16],
18
+ ["bits", 0,0, 1,0,1,0,0,1, 0,1, 1]
19
+ ],
20
+ bitsize: 32
21
+ },
22
+ { keyword: "mov",
23
+ operands: [{type: "register", restrictions: {reg_size: 64}}, {type: "register", restrictions: {reg_size: 64}}],
24
+ mc_constructor: [
25
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5], # Rd
26
+ ["bits", 1,1,1,1,1], # rn
27
+ ["bits", 0,0,0,0,0,0], # imm6
28
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5], # Rm
29
+ ["bits", 0, 0,0, 0,1,0,1,0,1,0, 1]
30
+ ],
31
+ bitsize: 32
32
+ },
33
+ { keyword: "mov_sp",
34
+ operands: [{type: "register", restrictions: {reg_size: 64}}, {type: "register", restrictions: {reg_size: 64}}],
35
+ mc_constructor: [
36
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5], # Rd
37
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5], # Rn
38
+ ["get_bits", 0, 0, 12], # imm12 as ones
39
+ ["bits", 0, 0,1,0,0,0,1, 0, 0, 1]
40
+ ],
41
+ bitsize: 32
42
+ },
43
+ { keyword: "mvn", # MVN writes the bitwise opposite of the source register to a destination register
44
+ description: "MVN writes the bitwise opposite of the source register to the destination register",
45
+ operands: [{type: "register", restrictions: {reg_size: 64}, name: "Destination"}, {type: "register", restrictions: {reg_size: 64}, name: "Source"}],
46
+ mc_constructor: [
47
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5], # Rd
48
+ ["bits", 1,1,1,1,1], # Rn
49
+ ["bits", 0,0,0,0,0,0], # imm6 (shift amount) set to zero
50
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5], # Rm
51
+ ["bits", 1, 0,0, 0,1,0,1,0,1,0, 1] # N - shift type (zero / LSL) - bits
52
+ ],
53
+ bitsize: 32
54
+ },
55
+ { keyword: "mvn", # MVN writes the bitwise opposite of the source register to a destination register
56
+ description: "MVN writes the bitwise opposite of the source register to the destination register",
57
+ operands: [{type: "register", restrictions: {reg_size: 32}, name: "Destination"}, {type: "register", restrictions: {reg_size: 32}, name: "Source"}],
58
+ mc_constructor: [
59
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5], # Rd
60
+ ["bits", 1,1,1,1,1], # Rn
61
+ ["bits", 0,0,0,0,0,0], # imm6 (shift amount) set to zero
62
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5], # Rm
63
+ ["bits", 1, 0,0, 0,1,0,1,0,1,0, 0] # N - shift type (zero / LSL) - bits
64
+ ],
65
+ bitsize: 32
66
+ },
67
+ { keyword: "mov",
68
+ operands: [{type: "register", restrictions: {reg_size: 32}}, {type: "immediate", restrictions: {}}],
69
+ mc_constructor: [
70
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
71
+ ["get_bits", ["get_operand", 1], 0, 16],
72
+ ["bits", 0,0, 1,0,1,0,0,1, 0,1, 0]
73
+ ],
74
+ bitsize: 32
75
+ },
76
+ {
77
+ keyword: "add",
78
+ operands: [{type: "register", restrictions: {reg_size: 64}}, {type: "register", restrictions: {reg_size: 64}}, {type: "immediate", restrictions: {}}],
79
+ mc_constructor: [
80
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
81
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
82
+ ["get_bits", ["get_operand", 2], 0, 12],
83
+ ["bits", 0, 0,1,0,0,0,1,0,0,1]
84
+ ],
85
+ bitsize: 32
86
+ },
87
+
88
+ {
89
+ keyword: "add",
90
+ name: "ADD (registers)",
91
+ description: "Adds two source registers and writes the result to the destination register",
92
+ operands: [{type: "register", restrictions: {reg_size: 64}}, {type: "register", restrictions: {reg_size: 64}}, {type: "register", restrictions: {reg_size: 64}}],
93
+ mc_constructor: [
94
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5], # Rd
95
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5], # Rn
96
+ ["get_bits", 0, 0, 6], # imm6
97
+ ["get_bits", ["encode_gp_register", ["get_operand", 2]], 0, 5], # Rm
98
+ ["bits", 0],
99
+ ["bits", 0,0], # shift
100
+ ["bits", 1,1,0,1,0, 0, 0, 1], # sf at the end
101
+ ],
102
+ bitsize: 32
103
+ },
104
+
105
+ {
106
+ keyword: "and", # And between registers, with shift set to zero
107
+ name: "And",
108
+ description: "Computes a logical bit-wise AND operation between two registers and writes the result to the destination register.",
109
+ operands: [{type: "register", restrictions: {reg_size: 64}, name: "Destination"}, {type: "register", restrictions: {reg_size: 64}, name: "Register 1"}, {type: "register", restrictions: {reg_size: 64}, name: "Register 2"}],
110
+ mc_constructor: [
111
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
112
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
113
+ ["get_bits", 0, 0, 6], # imm6 (shift amount) set to zero
114
+ ["get_bits", ["encode_gp_register", ["get_operand", 2]], 0, 5],
115
+ ["bits", 0], # N
116
+ ["bits", 0,0], # shift type
117
+ ["bits", 0,1,0,1,0, 0,0, 1],
118
+ ],
119
+ bitsize: 32
120
+ },
121
+
122
+ {
123
+ keyword: "orr", # And between registers, with shift set to zero
124
+ name: "Or",
125
+ description: "Computes a logical bit-wise OR operation between two registers and writes the result to the destination register.",
126
+ operands: [{type: "register", restrictions: {reg_size: 64}, name: "Destination"}, {type: "register", restrictions: {reg_size: 64}, name: "Register 1"}, {type: "register", restrictions: {reg_size: 64}, name: "Register 2"}],
127
+ mc_constructor: [
128
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
129
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
130
+ ["get_bits", 0, 0, 6], # imm6 (shift amount) set to zero
131
+ ["get_bits", ["encode_gp_register", ["get_operand", 2]], 0, 5],
132
+ ["bits", 0], # N
133
+ ["bits", 0,0], # shift type
134
+ ["bits", 0,1,0,1,0, 1,0, 1],
135
+ ],
136
+ bitsize: 32
137
+ },
138
+
139
+ {
140
+ keyword: "adr",
141
+ operands: [{type: "register", restrictions: {reg_size: 64}}, {type: "label"}],
142
+ mc_constructor: [
143
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
144
+ ["get_bits", ["subtract", ["get_label_address", ["get_operand", 1]], ["get_current_address"]], 2, 19],
145
+ ["bits", 0,0,0,0,1],
146
+ ["get_bits", ["subtract", ["get_label_address", ["get_operand", 1]], ["get_current_address"]], 0, 2],
147
+ ["bits", 0],
148
+ ],
149
+ bitsize: 32
150
+ },
151
+ {
152
+ keyword: "b",
153
+ operands: [{type: "immediate"}],
154
+ mc_constructor: [["get_bits", ["get_operand", 0], 0, 26], ["bits", 1,0,1,0,0,0]],
155
+ bitsize: 32
156
+ },
157
+ {
158
+ keyword: "b",
159
+ operands: [{type: "label"}],
160
+ mc_constructor: [
161
+ ["if_eq_else", ["modulo", ["subtract", ["get_label_address", ["get_operand", 0]], ["get_current_address"]], 4], 0, [], ["raise_error", "Can't branch to the address - offset not divisible by 4 bytes."]], # Check if address is accessible
162
+ ["get_bits", ["divide", ["subtract", ["get_label_address", ["get_operand", 0]], ["get_current_address"]], 4], 0, 26],
163
+ ["bits", 1,0,1,0,0,0]
164
+ ],
165
+ bitsize: 32
166
+ },
167
+ {
168
+ keyword: "br",
169
+ operands: [{type: "register", restrictions: {reg_size: 64}}],
170
+ mc_constructor: [
171
+ ["bits", 0,0,0,0,0],
172
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
173
+ ["bits", 0, 0, 0,0,0,0, 1,1,1,1,1, 0,0, 0, 0, 1,1,0,1,0,1,1]
174
+ ],
175
+ bitsize: 32
176
+ },
177
+ {
178
+ keyword: "bl",
179
+ operands: [{type: "label"}],
180
+ mc_constructor: [
181
+ ["if_eq_else", ["modulo", ["subtract", ["get_label_address", ["get_operand", 0]], ["get_current_address"]], 4], 0, [], ["raise_error", "Can't branch to the address - offset not divisible by 4 bytes."]], # Check if address is accessible
182
+ ["get_bits", ["divide", ["subtract", ["get_label_address", ["get_operand", 0]], ["get_current_address"]], 4], 0, 26],
183
+ ["bits", 1,0,1,0,0,1]
184
+ ],
185
+ bitsize: 32
186
+ },
187
+ {
188
+ # LSL (Logical shift left) with an immediate
189
+ # immr (rotation) is just set to zeros
190
+ keyword: "lsl",
191
+ name: "LSL (immediate)",
192
+ description: "Logically shifts left the value in the source register by the amount specified by the immediate, and stores the output in the destination register",
193
+ operands: [{type: "register", restrictions: {reg_size: 64}, name: "Destination"}, {type: "register", restrictions: {reg_size: 64}, name: "Source"}, {type: "immediate", name: "Amount"}],
194
+ mc_constructor: [
195
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
196
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
197
+
198
+ ["get_bits", ["subtract", 63, ["get_operand", 2]], 0, 6],
199
+ ["get_bits", ["modulo", ["multiply", ["get_operand", 2], -1], 64], 0, 6],
200
+
201
+ ["bits", 1, 0,1,1,0,0,1, 0,1, 1],
202
+ ],
203
+ bitsize: 32
204
+ },
205
+ {
206
+ # LSL (Logical shift left) with an immediate for 32-bit registers
207
+ # immr (rotation) is just set to zeros
208
+ keyword: "lsl",
209
+ name: "LSL (immediate)",
210
+ description: "Logically shifts left the value in the source register by the amount specified by the immediate, and stores the output in the destination register",
211
+ operands: [{type: "register", restrictions: {reg_size: 32}, name: "Destination"}, {type: "register", restrictions: {reg_size: 32}, name: "Source"}, {type: "immediate", name: "Amount"}],
212
+ mc_constructor: [
213
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
214
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
215
+ ["get_bits", ["subtract", 31, ["get_operand", 2]], 0, 6],
216
+ ["get_bits", ["modulo", ["multiply", ["get_operand", 2], -1], 32], 0, 6],
217
+ ["bits", 0, 0,1,1,0,0,1, 0,1, 0],
218
+ ],
219
+ bitsize: 32
220
+ },
221
+
222
+
223
+
224
+ {
225
+ # LSL (Logical shift left) with an immediate
226
+ # immr (rotation) is just set to zeros
227
+ keyword: "lsr",
228
+ name: "LSR (immediate)",
229
+ description: "Logically shifts right the value in the source register by the amount specified by the immediate, and stores the output in the destination register",
230
+ operands: [{type: "register", restrictions: {reg_size: 64}, name: "Destination"}, {type: "register", restrictions: {reg_size: 64}, name: "Source"}, {type: "immediate", name: "Amount"}],
231
+ mc_constructor: [
232
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
233
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
234
+
235
+ ["bits", 1,1,1,1,1], # imms
236
+ ["bits", 1], # imms end (specifies size)
237
+ ["get_bits", ["get_operand", 2], 0, 6], # immr
238
+
239
+ ["bits", 1, 0,1,1,0,0,1, 0,1, 1],
240
+ ],
241
+ bitsize: 32
242
+ },
243
+ {
244
+ keyword: "lsr",
245
+ name: "LSR (immediate)",
246
+ description: "Logically shifts right the value in the source register by the amount specified by the immediate, and stores the output in the destination register",
247
+ operands: [{type: "register", restrictions: {reg_size: 32}, name: "Destination"}, {type: "register", restrictions: {reg_size: 32}, name: "Source"}, {type: "immediate", name: "Amount"}],
248
+ mc_constructor: [
249
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
250
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
251
+
252
+ ["bits", 1,1,1,1,1], # imms
253
+ ["bits", 0], # imms end (specifies size)
254
+ ["get_bits", ["get_operand", 2], 0, 6], # immr
255
+
256
+ ["bits", 0, 0,1,1,0,0,1, 0,1, 0],
257
+ ],
258
+ bitsize: 32
259
+ },
260
+
261
+
262
+
263
+
264
+ {
265
+ # LDR immediate
266
+ keyword: "ldr",
267
+ operands: [{type: "register", restrictions: {reg_size: 64}}, {type: "label"}],
268
+ mc_constructor: [
269
+ ["if_eq_else", ["modulo", ["subtract", ["get_label_address", ["get_operand", 1]], ["get_current_address"]], 4], 0, [], ["raise_error", "Can't represent address for LDR - offset not divisible by 4 bytes."]], # Check if address is accessible
270
+
271
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
272
+ ["get_bits", ["divide", ["subtract", ["get_label_address", ["get_operand", 1]], ["get_current_address"]], 4], 0, 19],
273
+
274
+ ["bits", 0,0,0,1,1,0,1,0],
275
+ ],
276
+ bitsize: 32
277
+ },
278
+ {
279
+ keyword: "ldr",
280
+ operands: [{type: "register", restrictions: {reg_size: 64}}, {type: "register", restrictions: {reg_size: 64}}],
281
+ mc_constructor: [
282
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
283
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
284
+ ["get_bits", 0, 0, 12], # Immediate offset zero
285
+ ["bits", 1,0, 1,0, 0, 1,1,1, 1,1],
286
+ ],
287
+ bitsize: 32
288
+ },
289
+ {
290
+ keyword: "ldr",
291
+ operands: [{type: "register", restrictions: {reg_size: 32}}, {type: "register", restrictions: {reg_size: 64}}],
292
+ mc_constructor: [
293
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
294
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
295
+ ["get_bits", 0, 0, 12], # Immediate offset zero
296
+ ["bits", 1,0, 1,0, 0, 1,1,1, 0,1],
297
+ ],
298
+ bitsize: 32
299
+ },
300
+ {
301
+ keyword: "strh",
302
+ operands: [{type: "register", restrictions: {reg_size: 32}}, {type: "register", restrictions: {reg_size: 64}}],
303
+ mc_constructor: [
304
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
305
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
306
+ ["get_bits", 0, 0, 12], # Immediate offset zero
307
+ ["bits", 0,0, 1,0, 0, 1,1,1, 1,0],
308
+ ],
309
+ bitsize: 32
310
+ },
311
+ {
312
+ keyword: "str",
313
+ description: "Stores the contents of a 32 bit register at the address specified by the second register",
314
+ operands: [{type: "register", restrictions: {reg_size: 32}, name: "Content"}, {type: "register", restrictions: {reg_size: 64}, name: "Address"}],
315
+ mc_constructor: [
316
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
317
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
318
+ ["get_bits", 0, 0, 12], # Immediate offset zero
319
+ ["bits", 0,0, 1,0, 0, 1,1,1, 0,1],
320
+ ],
321
+ bitsize: 32
322
+ },
323
+ {
324
+ keyword: "str",
325
+ description: "Stores the contents of a 64 bit register at the address specified by the second register",
326
+ operands: [{type: "register", restrictions: {reg_size: 64}, name: "Content"}, {type: "register", restrictions: {reg_size: 64}, name: "Address"}],
327
+ mc_constructor: [
328
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
329
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
330
+ ["get_bits", 0, 0, 12], # Immediate offset zero
331
+ ["bits", 0,0, 1,0, 0, 1,1,1, 1,1],
332
+ ],
333
+ bitsize: 32
334
+ },
335
+
336
+ {
337
+ keyword: "str_unsigned",
338
+ name: "STR (immediate), unsigned offset",
339
+ description: "Stores the contents of a 32 bit register at the address specified by the second register with an unsigned immediate offset.",
340
+ operands: [{type: "register", restrictions: {reg_size: 32}, name: "Content"}, {type: "register", restrictions: {reg_size: 64}, name: "Address"}, {type: "immediate", name: "Address Offset"}],
341
+ mc_constructor: [
342
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
343
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
344
+ ["get_bits", ["get_operand", 2], 0, 12], # Immediate offset zero
345
+ ["bits", 0,0, 1,0, 0, 1,1,1, 0,1],
346
+ ],
347
+ bitsize: 32
348
+ },
349
+
350
+ {
351
+ keyword: "str_unsigned",
352
+ name: "STR (immediate), unsigned offset",
353
+ description: "Stores the contents of a 64 bit register at the address specified by the second register with an unsigned immediate offset.",
354
+ operands: [{type: "register", restrictions: {reg_size: 64}, name: "Content"}, {type: "register", restrictions: {reg_size: 64}, name: "Address"}, {type: "immediate", name: "Address Offset"}],
355
+ mc_constructor: [
356
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
357
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
358
+ ["get_bits", ["get_operand", 2], 0, 12], # Immediate offset zero
359
+ ["bits", 0,0, 1,0, 0, 1,1,1, 1,1],
360
+ ],
361
+ bitsize: 32
362
+ },
363
+
364
+ {
365
+ keyword: "str_pre_index",
366
+ name: "STR (immediate), signed offset, pre-index",
367
+ description: "Stores the contents of a 64-bit register at the address specified by the second register with a signed immediate offset that is added before storing.",
368
+ operands: [{type: "register", restrictions: {reg_size: 64}, name: "Content"}, {type: "register", restrictions: {reg_size: 64}, name: "Address"}, {type: "immediate", name: "Address Offset"}],
369
+ mc_constructor: [
370
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
371
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
372
+ ["bits", 1, 1],
373
+ ["get_bits", ["get_operand", 2], 0, 9],
374
+ ["bits", 0, 0,0, 0,0, 0, 1,1,1, 1,1],
375
+ ],
376
+ bitsize: 32
377
+ },
378
+
379
+ {
380
+ keyword: "str_pre_index",
381
+ name: "STR (immediate), signed offset, pre-index",
382
+ description: "Stores the contents of a 32-bit register at the address specified by the second register with a signed immediate offset that is added before storing.",
383
+ operands: [{type: "register", restrictions: {reg_size: 32}, name: "Content"}, {type: "register", restrictions: {reg_size: 64}, name: "Address"}, {type: "immediate", name: "Address Offset"}],
384
+ mc_constructor: [
385
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
386
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
387
+ ["bits", 1, 1],
388
+ ["get_bits", ["get_operand", 2], 0, 9],
389
+ ["bits", 0, 0,0, 0,0, 0, 1,1,1, 0,1],
390
+ ],
391
+ bitsize: 32
392
+ },
393
+
394
+
395
+ {
396
+ keyword: "cmp",
397
+ operands: [{type: "register", restrictions: {reg_size: 64}}, {type: "immediate"}],
398
+ mc_constructor: [
399
+ ["bits", 1,1,1,1,1],
400
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
401
+ ["get_bits", ["get_operand", 1], 0, 12], # Immediate offset zero
402
+ ["bits", 0, 0,1,0,0,0,1, 1, 1, 1],
403
+ ],
404
+ bitsize: 32
405
+ },
406
+
407
+ {
408
+ keyword: "cmp",
409
+ name: "CMP (two registers)",
410
+ description: "Compares two 64-bit registers and updates condition flags based on the result.",
411
+ operands: [{type: "register", restrictions: {reg_size: 64}, name: "Register 1"}, {type: "register", restrictions: {reg_size: 64}, name: "Register 2"}],
412
+ mc_constructor: [
413
+ ["bits", 1,1,1,1,1], # Rd
414
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
415
+ ["get_bits", 0, 0, 6], # Immediate offset zero (shift amount)
416
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5], # Rm
417
+ ["bits", 0],
418
+ ["bits", 0, 0], # Shift type
419
+ ["bits", 1,1,0,1,0,1,1,1],
420
+ ],
421
+ bitsize: 32
422
+ },
423
+
424
+ {
425
+ keyword: "cmp",
426
+ name: "CMP (two registers)",
427
+ description: "Compares two 32-bit registers and updates condition flags based on the result.",
428
+ operands: [{type: "register", restrictions: {reg_size: 32}, name: "Register 1"}, {type: "register", restrictions: {reg_size: 32}, name: "Register 2"}],
429
+ mc_constructor: [
430
+ ["bits", 1,1,1,1,1], # Rd
431
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
432
+ ["get_bits", 0, 0, 6], # Immediate offset zero (shift amount)
433
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5], # Rm
434
+ ["bits", 0],
435
+ ["bits", 0, 0], # Shift type
436
+ ["bits", 1,1,0,1,0,1,1,0],
437
+ ],
438
+ bitsize: 32
439
+ },
440
+
441
+ {
442
+ keyword: "sub",
443
+ operands: [{type: "register", restrictions: {reg_size: 64}}, {type: "register", restrictions: {reg_size: 64}}, {type: "immediate"}],
444
+ mc_constructor: [
445
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
446
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
447
+ ["get_bits", ["get_operand", 2], 0, 12], # Immediate offset zero
448
+ ["bits", 0], # Shift
449
+ ["bits", 0,1,0,0,0,1,0,1,1],
450
+ ],
451
+ bitsize: 32
452
+ },
453
+
454
+
455
+
456
+ #
457
+ # B.cond instructions
458
+ #
459
+
460
+ {
461
+ keyword: "b.eq",
462
+ name: "Branch with condition",
463
+ description: "Branches to a label if the condition (equality) is met",
464
+ operands: [{type: "label"}],
465
+ mc_constructor: [
466
+ ["if_eq_else", ["modulo", ["subtract", ["get_label_address", ["get_operand", 0]], ["get_current_address"]], 4], 0, [], ["raise_error", "Can't branch to the address - offset not divisible by 4 bytes."]], # Check if address is accessible
467
+ ["bits", 0,0,0,0], # eq condition
468
+ ["bits", 0],
469
+ ["get_bits", ["divide", ["subtract", ["get_label_address", ["get_operand", 0]], ["get_current_address"]], 4], 0, 19],
470
+ ["bits", 0, 0,1,0,1,0,1,0],
471
+ ],
472
+ bitsize: 32
473
+ },
474
+ {
475
+ keyword: "b.eq",
476
+ operands: [{type: "immediate"}],
477
+ description: "Changes the PC relatively by the immediate value if the condition is met (equality)",
478
+ mc_constructor: [
479
+ ["bits", 0,0,0,0], # eq condition
480
+ ["bits", 0],
481
+ ["get_bits", ["get_operand", 0], 0, 19],
482
+ ["bits", 0, 0,1,0,1,0,1,0],
483
+ ],
484
+ bitsize: 32
485
+ },
486
+ ]
487
+
488
+ end # Kompiler::ARMv8A
489
+
490
+ end # Kompiler
@@ -0,0 +1,8 @@
1
+ # Copyright 2024 Kyrylo Shyshko
2
+ # Licensed under the Apache License, Version 2.0. See LICENSE file for details.
3
+
4
+ require 'kompiler/arch/armv8a/instructions.rb'
5
+ require 'kompiler/arch/armv8a/registers.rb'
6
+
7
+
8
+ Kompiler::Architecture.set_arch(Kompiler::ARMv8A.instructions, Kompiler::ARMv8A.registers)
@@ -0,0 +1,67 @@
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
+ class ARMv8A
7
+
8
+ def self.registers
9
+ @@registers
10
+ end
11
+
12
+ @@registers = [
13
+ {:reg_name=>"w0", :reg_value=>0, :reg_size=>32, :reg_type=>"gpr"},
14
+ {:reg_name=>"w1", :reg_value=>1, :reg_size=>32, :reg_type=>"gpr"},
15
+ {:reg_name=>"w2", :reg_value=>2, :reg_size=>32, :reg_type=>"gpr"},
16
+ {:reg_name=>"w3", :reg_value=>3, :reg_size=>32, :reg_type=>"gpr"},
17
+ {:reg_name=>"w4", :reg_value=>4, :reg_size=>32, :reg_type=>"gpr"},
18
+ {:reg_name=>"w5", :reg_value=>5, :reg_size=>32, :reg_type=>"gpr"},
19
+ {:reg_name=>"w6", :reg_value=>6, :reg_size=>32, :reg_type=>"gpr"},
20
+ {:reg_name=>"w7", :reg_value=>7, :reg_size=>32, :reg_type=>"gpr"},
21
+ {:reg_name=>"w8", :reg_value=>8, :reg_size=>32, :reg_type=>"gpr"},
22
+ {:reg_name=>"w9", :reg_value=>9, :reg_size=>32, :reg_type=>"gpr"},
23
+ {:reg_name=>"w10", :reg_value=>10, :reg_size=>32, :reg_type=>"gpr"},
24
+ {:reg_name=>"w11", :reg_value=>11, :reg_size=>32, :reg_type=>"gpr"},
25
+ {:reg_name=>"w12", :reg_value=>12, :reg_size=>32, :reg_type=>"gpr"},
26
+ {:reg_name=>"w13", :reg_value=>13, :reg_size=>32, :reg_type=>"gpr"},
27
+ {:reg_name=>"w14", :reg_value=>14, :reg_size=>32, :reg_type=>"gpr"},
28
+ {:reg_name=>"w15", :reg_value=>15, :reg_size=>32, :reg_type=>"gpr"},
29
+ {:reg_name=>"x0", :reg_value=>0, :reg_size=>64, :reg_type=>"gpr"},
30
+ {:reg_name=>"x1", :reg_value=>1, :reg_size=>64, :reg_type=>"gpr"},
31
+ {:reg_name=>"x2", :reg_value=>2, :reg_size=>64, :reg_type=>"gpr"},
32
+ {:reg_name=>"x3", :reg_value=>3, :reg_size=>64, :reg_type=>"gpr"},
33
+ {:reg_name=>"x4", :reg_value=>4, :reg_size=>64, :reg_type=>"gpr"},
34
+ {:reg_name=>"x5", :reg_value=>5, :reg_size=>64, :reg_type=>"gpr"},
35
+ {:reg_name=>"x6", :reg_value=>6, :reg_size=>64, :reg_type=>"gpr"},
36
+ {:reg_name=>"x7", :reg_value=>7, :reg_size=>64, :reg_type=>"gpr"},
37
+ {:reg_name=>"x8", :reg_value=>8, :reg_size=>64, :reg_type=>"gpr"},
38
+ {:reg_name=>"x9", :reg_value=>9, :reg_size=>64, :reg_type=>"gpr"},
39
+ {:reg_name=>"x10", :reg_value=>10, :reg_size=>64, :reg_type=>"gpr"},
40
+ {:reg_name=>"x11", :reg_value=>11, :reg_size=>64, :reg_type=>"gpr"},
41
+ {:reg_name=>"x12", :reg_value=>12, :reg_size=>64, :reg_type=>"gpr"},
42
+ {:reg_name=>"x13", :reg_value=>13, :reg_size=>64, :reg_type=>"gpr"},
43
+ {:reg_name=>"x14", :reg_value=>14, :reg_size=>64, :reg_type=>"gpr"},
44
+ {:reg_name=>"x15", :reg_value=>15, :reg_size=>64, :reg_type=>"gpr"},
45
+ {:reg_name=>"x16", :reg_value=>16, :reg_size=>64, :reg_type=>"gpr"},
46
+ {:reg_name=>"x17", :reg_value=>17, :reg_size=>64, :reg_type=>"gpr"},
47
+ {:reg_name=>"x18", :reg_value=>18, :reg_size=>64, :reg_type=>"gpr"},
48
+ {:reg_name=>"x19", :reg_value=>19, :reg_size=>64, :reg_type=>"gpr"},
49
+ {:reg_name=>"x20", :reg_value=>20, :reg_size=>64, :reg_type=>"gpr"},
50
+ {:reg_name=>"x21", :reg_value=>21, :reg_size=>64, :reg_type=>"gpr"},
51
+ {:reg_name=>"x22", :reg_value=>22, :reg_size=>64, :reg_type=>"gpr"},
52
+ {:reg_name=>"x23", :reg_value=>23, :reg_size=>64, :reg_type=>"gpr"},
53
+ {:reg_name=>"x24", :reg_value=>24, :reg_size=>64, :reg_type=>"gpr"},
54
+ {:reg_name=>"x25", :reg_value=>25, :reg_size=>64, :reg_type=>"gpr"},
55
+ {:reg_name=>"x26", :reg_value=>26, :reg_size=>64, :reg_type=>"gpr"},
56
+ {:reg_name=>"x27", :reg_value=>27, :reg_size=>64, :reg_type=>"gpr"},
57
+ {:reg_name=>"x28", :reg_value=>28, :reg_size=>64, :reg_type=>"gpr"},
58
+ {:reg_name=>"x29", :reg_value=>29, :reg_size=>64, :reg_type=>"gpr"},
59
+ {:reg_name=>"x30", :reg_value=>30, :reg_size=>64, :reg_type=>"gpr"},
60
+ {:reg_name=>"x31", :reg_value=>31, :reg_size=>64, :reg_type=>"gpr"},
61
+ {:reg_name=>"lr", :reg_value=>30, :reg_size=>64, :reg_type=>"gpr"},
62
+ {:reg_name=>"sp", :reg_value=>31, :reg_size=>64, :reg_type=>"gpr"},
63
+ ]
64
+
65
+ end # Kompiler::ARMv8A
66
+
67
+ end # Kompiler
@@ -0,0 +1,30 @@
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
+ class Architecture
7
+
8
+ @@instructions = []
9
+ @@registers = []
10
+
11
+ def self.set_arch instructions, registers
12
+ @@instructions = instructions
13
+ @@registers = registers
14
+ end
15
+
16
+ def self.load_arch(arch_name)
17
+ require "kompiler/arch/#{arch_name.downcase}/load"
18
+ end
19
+
20
+ def self.instructions
21
+ @@instructions
22
+ end
23
+
24
+ def self.registers
25
+ @@registers
26
+ end
27
+
28
+ end
29
+
30
+ end