kompiler 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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