kompiler 0.2.0.pre.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/kompiler/architectures/armv8a/instructions.rb +385 -48
- data/lib/kompiler/mc_builder.rb +1 -0
- data/lib/kompiler/parsers.rb +5 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fc460a4bb7ead297f0fe530c19304038f4d3980103cde260df057c52b35cfeeb
|
4
|
+
data.tar.gz: 57ea6ace09f3b1a5c3d0914d9edbbd02a83a5002b5c55ecde398f593cdcbb211
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c78b06f86db101176939c5aad994950e60d63827fe1a1470d5fad991fb9f2f3d26efef86981039fa2c41b22f034ad2c953bead0961ea4ea411ec583d64e5a27
|
7
|
+
data.tar.gz: 4c001f5a2c64e4a26752c98a116ff85138733662fe376e4b470352731cee721688bd194760f89e949552cf59e3824ef7b2ac607f6ab696732d783dff1b779cf6
|
@@ -103,18 +103,21 @@ end
|
|
103
103
|
},
|
104
104
|
|
105
105
|
{
|
106
|
-
keyword: "and",
|
107
|
-
name: "And",
|
108
|
-
description: "
|
109
|
-
operands: [{type: "register", restrictions: {
|
106
|
+
keyword: "and",
|
107
|
+
name: "And (register)",
|
108
|
+
description: "Performs a bitwise AND of two register values and writes the result to the destination register.",
|
109
|
+
operands: [{type: "register", restrictions: {reg_type: "gpr"}, name: "Destination"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Register 1"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Register 2"}],
|
110
110
|
mc_constructor: [
|
111
|
-
["
|
112
|
-
["
|
111
|
+
["if_eq_else", ["get_key", ["get_operand", 0], :reg_size], ["get_key", ["get_operand", 1], :reg_size], [], ["raise_error", "and Error: Register sizes are not the same"]],
|
112
|
+
["if_eq_else", ["get_key", ["get_operand", 1], :reg_size], ["get_key", ["get_operand", 2], :reg_size], [], ["raise_error", "and Error: Register sizes are not the same"]],
|
113
|
+
["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5], # Rd
|
114
|
+
["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5], # Rn
|
113
115
|
["get_bits", 0, 0, 6], # imm6 (shift amount) set to zero
|
114
116
|
["get_bits", ["encode_gp_register", ["get_operand", 2]], 0, 5],
|
115
117
|
["bits", 0], # N
|
116
118
|
["bits", 0,0], # shift type
|
117
|
-
["bits", 0,1,0,1,0, 0,0
|
119
|
+
["bits", 0,1,0,1,0, 0,0],
|
120
|
+
["case", ["get_key", ["get_operand", 0], :reg_size], 64, ["bits", 1], 32, ["bits", 0], []], # sf
|
118
121
|
],
|
119
122
|
bitsize: 32
|
120
123
|
},
|
@@ -185,82 +188,101 @@ end
|
|
185
188
|
bitsize: 32
|
186
189
|
},
|
187
190
|
{
|
188
|
-
# LSL (Logical shift left) with an immediate
|
189
|
-
# immr (rotation) is just set to zeros
|
190
191
|
keyword: "lsl",
|
191
|
-
name: "
|
192
|
-
description: "Logically shifts left the value in the source register by the amount specified by the immediate, and
|
193
|
-
operands: [{type: "register", restrictions: {
|
192
|
+
name: "Logical shift left (immediate)",
|
193
|
+
description: "Logically shifts left the value in the source register by the amount specified by the immediate, and writes the result to the destination register",
|
194
|
+
operands: [{type: "register", restrictions: {reg_type: "gpr"}, name: "Destination"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Source"}, {type: "immediate", name: "Shift amount"}],
|
194
195
|
mc_constructor: [
|
196
|
+
["if_eq_else", ["get_key", ["get_operand", 0], :reg_size], ["get_key", ["get_operand", 1], :reg_size], [], ["raise_error", "lsl Error: Register sizes are not the same"]],
|
195
197
|
["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
|
196
198
|
["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
|
197
199
|
|
198
|
-
["
|
199
|
-
|
200
|
+
["case", ["get_key", ["get_operand", 0], :reg_size],
|
201
|
+
64, ["concat", ["get_bits", ["subtract", 63, ["get_operand", 2]], 0, 6],
|
202
|
+
["get_bits", ["modulo", ["multiply", ["get_operand", 2], -1], 64], 0, 6],],
|
203
|
+
32, ["concat", ["get_bits", ["subtract", 31, ["get_operand", 2]], 0, 6],
|
204
|
+
["get_bits", ["modulo", ["multiply", ["get_operand", 2], -1], 32], 0, 6]],
|
205
|
+
[]
|
206
|
+
],
|
200
207
|
|
201
|
-
["
|
208
|
+
["case", ["get_key", ["get_operand", 0], :reg_size], 64, ["bits", 1], 32, ["bits", 0], []], # N
|
209
|
+
["bits", 0,1,1,0,0,1, 0,1],
|
210
|
+
["case", ["get_key", ["get_operand", 0], :reg_size], 64, ["bits", 1], 32, ["bits", 0], []], # sf
|
202
211
|
],
|
203
212
|
bitsize: 32
|
204
213
|
},
|
214
|
+
|
205
215
|
{
|
206
|
-
# LSL (Logical shift left) with an immediate for 32-bit registers
|
207
|
-
# immr (rotation) is just set to zeros
|
208
216
|
keyword: "lsl",
|
209
|
-
name: "
|
210
|
-
description: "Logically shifts left the value in the source register by the amount specified by
|
211
|
-
operands: [{type: "register", restrictions: {
|
217
|
+
name: "Logical shift left (register)",
|
218
|
+
description: "Logically shifts left the value in the source register by the amount specified by a variable number of bits, shifting in zeros, and writes the result to the destination register. The shift amount is equal to a modulo operation between the second register value and register size (either 64 or 32).",
|
219
|
+
operands: [{type: "register", restrictions: {reg_type: "gpr"}, name: "Destination"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Source"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Shift amount"}],
|
212
220
|
mc_constructor: [
|
221
|
+
["if_eq_else", ["get_key", ["get_operand", 0], :reg_size], ["get_key", ["get_operand", 1], :reg_size], [], ["raise_error", "lsl Error: Register sizes are not the same"]],
|
222
|
+
["if_eq_else", ["get_key", ["get_operand", 1], :reg_size], ["get_key", ["get_operand", 2], :reg_size], [], ["raise_error", "lsl Error: Register sizes are not the same"]],
|
223
|
+
|
213
224
|
["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
|
214
225
|
["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
|
215
|
-
|
216
|
-
["
|
217
|
-
|
226
|
+
|
227
|
+
["bits", 0,0, 0,1,0,0],
|
228
|
+
|
229
|
+
["get_bits", ["encode_gp_register", ["get_operand", 2]], 0, 5],
|
230
|
+
|
231
|
+
["bits", 0,1,1,0,1,0,1,1, 0, 0],
|
232
|
+
["case", ["get_key", ["get_operand", 0], :reg_size], 64, ["bits", 1], 32, ["bits", 0], []], # sf
|
218
233
|
],
|
219
234
|
bitsize: 32
|
220
235
|
},
|
221
236
|
|
222
|
-
|
223
|
-
|
224
237
|
{
|
225
|
-
# LSL (Logical shift left) with an immediate
|
226
|
-
# immr (rotation) is just set to zeros
|
227
238
|
keyword: "lsr",
|
228
|
-
name: "
|
229
|
-
description: "Logically shifts right the value in the source register by the amount specified by the immediate, and
|
230
|
-
operands: [{type: "register", restrictions: {
|
239
|
+
name: "Logical shift right (immediate)",
|
240
|
+
description: "Logically shifts right the value in the source register by the amount specified by the immediate, and writes the result to the destination register",
|
241
|
+
operands: [{type: "register", restrictions: {reg_type: "gpr"}, name: "Destination"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Source"}, {type: "immediate", name: "Shift amount"}],
|
231
242
|
mc_constructor: [
|
243
|
+
["if_eq_else", ["get_key", ["get_operand", 0], :reg_size], ["get_key", ["get_operand", 1], :reg_size], [], ["raise_error", "lsr Error: Register sizes are not the same"]],
|
232
244
|
["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
|
233
245
|
["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
|
234
|
-
|
246
|
+
|
235
247
|
["bits", 1,1,1,1,1], # imms
|
236
|
-
["bits", 1], # imms end
|
248
|
+
["case", ["get_key", ["get_operand", 0], :reg_size], 64, ["bits", 1], 32, ["bits", 0], []], # imms end
|
249
|
+
|
237
250
|
["get_bits", ["get_operand", 2], 0, 6], # immr
|
238
251
|
|
239
|
-
["
|
252
|
+
["case", ["get_key", ["get_operand", 0], :reg_size], 64, ["bits", 1], 32, ["bits", 0], []], # N
|
253
|
+
|
254
|
+
["bits", 0,1,1,0,0,1, 0,1],
|
255
|
+
|
256
|
+
["case", ["get_key", ["get_operand", 0], :reg_size], 64, ["bits", 1], 32, ["bits", 0], []], # sf
|
240
257
|
],
|
241
258
|
bitsize: 32
|
242
259
|
},
|
260
|
+
|
261
|
+
|
243
262
|
{
|
244
263
|
keyword: "lsr",
|
245
|
-
name: "
|
246
|
-
description: "Logically shifts right the value in the source register by the amount specified by
|
247
|
-
operands: [{type: "register", restrictions: {
|
264
|
+
name: "Logical shift right (register)",
|
265
|
+
description: "Logically shifts right the value in the source register by the amount specified by a variable number of bits, shifting in zeros, and writes the result to the destination register. The shift amount is equal to a modulo operation between the second register value and register size (either 64 or 32).",
|
266
|
+
operands: [{type: "register", restrictions: {reg_type: "gpr"}, name: "Destination"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Source"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Shift amount"}],
|
248
267
|
mc_constructor: [
|
268
|
+
["if_eq_else", ["get_key", ["get_operand", 0], :reg_size], ["get_key", ["get_operand", 1], :reg_size], [], ["raise_error", "lsl Error: Register sizes are not the same"]],
|
269
|
+
["if_eq_else", ["get_key", ["get_operand", 1], :reg_size], ["get_key", ["get_operand", 2], :reg_size], [], ["raise_error", "lsl Error: Register sizes are not the same"]],
|
270
|
+
|
249
271
|
["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
|
250
272
|
["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
273
|
|
256
|
-
["bits",
|
274
|
+
["bits", 1,0, 0,1,0,0],
|
275
|
+
|
276
|
+
["get_bits", ["encode_gp_register", ["get_operand", 2]], 0, 5],
|
277
|
+
|
278
|
+
["bits", 0,1,1,0,1,0,1,1, 0, 0],
|
279
|
+
["case", ["get_key", ["get_operand", 0], :reg_size], 64, ["bits", 1], 32, ["bits", 0], []], # sf
|
257
280
|
],
|
258
281
|
bitsize: 32
|
259
282
|
},
|
260
283
|
|
261
284
|
|
262
285
|
|
263
|
-
|
264
286
|
{
|
265
287
|
# LDR immediate
|
266
288
|
keyword: "ldr",
|
@@ -292,6 +314,33 @@ end
|
|
292
314
|
bitsize: 32
|
293
315
|
},
|
294
316
|
|
317
|
+
{
|
318
|
+
keyword: "ldr_unsigned",
|
319
|
+
name: "Load Register (immediate), unsigned offset",
|
320
|
+
description: "Loads 4 or 8 bytes from memory at the address in the second register with an unsigned immediate offset, and writes it to the destination register",
|
321
|
+
operands: [{type: "register", restrictions: {reg_type: "gpr"}, name: "Destination"}, {type: "register", restrictions: {reg_type: "gpr", reg_size: 64}, name: "Source address"}, {type: "immediate", name: "Offset"}],
|
322
|
+
mc_constructor: [
|
323
|
+
["case", ["get_key", ["get_operand", 0], :reg_size],
|
324
|
+
64, ["if_eq_else", ["modulo", ["get_operand", 2], 8], 0, [], ["raise_error", "ldr_unsigned Error: Unsigned offset must be divisible by 8 for 64-bit registers."]],
|
325
|
+
32, ["if_eq_else", ["modulo", ["get_operand", 2], 4], 0, [], ["raise_error", "ldr_unsigned Error: Unsigned offset must be divisible by 4 for 32-bit registers."]],
|
326
|
+
[]
|
327
|
+
],
|
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",
|
331
|
+
["case", ["get_key", ["get_operand", 0], :reg_size],
|
332
|
+
64, ["divide", ["get_operand", 2], 8],
|
333
|
+
32, ["divide", ["get_operand", 2], 4],
|
334
|
+
["get_operand", 2]
|
335
|
+
],
|
336
|
+
0, 12],
|
337
|
+
["bits", 1,0, 1,0, 0, 1,1,1],
|
338
|
+
["case", ["get_key", ["get_operand", 0], :reg_size], 64, ["bits", 1], 32, ["bits", 0], []],
|
339
|
+
["bits", 1],
|
340
|
+
],
|
341
|
+
bitsize: 32
|
342
|
+
},
|
343
|
+
|
295
344
|
{
|
296
345
|
keyword: "ldrb",
|
297
346
|
name: "Load Register Byte",
|
@@ -394,8 +443,67 @@ end
|
|
394
443
|
],
|
395
444
|
bitsize: 32
|
396
445
|
},
|
446
|
+
|
447
|
+
|
448
|
+
{
|
449
|
+
keyword: "strb",
|
450
|
+
name: "Store byte",
|
451
|
+
description: "Stores the least significant byte of a 32-bit general purpose register at the address specified by the second register.",
|
452
|
+
operands: [{type: "register", restrictions: {reg_type: "gpr", reg_size: 32}, name: "Content"}, {type: "register", restrictions: {reg_type: "gpr", reg_size: 64}, name: "Address"}],
|
453
|
+
mc_constructor: [
|
454
|
+
["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
|
455
|
+
["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
|
456
|
+
["get_bits", 0, 0, 12],
|
457
|
+
["bits", 0,0, 1,0, 0, 1,1,1, 0,0],
|
458
|
+
],
|
459
|
+
bitsize: 32
|
460
|
+
},
|
461
|
+
|
462
|
+
{
|
463
|
+
keyword: "strb_unsigned",
|
464
|
+
name: "Store byte (immediate), unsigned offset",
|
465
|
+
description: "Stores the least significant byte of a 32-bit general purpose register at the address specified by the second register with an unsigned immediate offset.",
|
466
|
+
operands: [{type: "register", restrictions: {reg_type: "gpr", reg_size: 32}, name: "Content"}, {type: "register", restrictions: {reg_type: "gpr", reg_size: 64}, name: "Address"}, {type: "immediate", name: "Address Offset"}],
|
467
|
+
mc_constructor: [
|
468
|
+
["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
|
469
|
+
["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
|
470
|
+
["get_bits", ["get_operand", 2], 0, 12],
|
471
|
+
["bits", 0,0, 1,0, 0, 1,1,1, 0,0],
|
472
|
+
],
|
473
|
+
bitsize: 32
|
474
|
+
},
|
475
|
+
|
476
|
+
{
|
477
|
+
keyword: "strb_post_index",
|
478
|
+
name: "Store byte (immediate), signed post-index offset",
|
479
|
+
description: "Stores the least significant byte of a 32-bit general purpose register at the address specified by the second register with an immediate offset added after writing.",
|
480
|
+
operands: [{type: "register", restrictions: {reg_type: "gpr", reg_size: 32}, name: "Content"}, {type: "register", restrictions: {reg_type: "gpr", reg_size: 64}, name: "Address"}, {type: "immediate", name: "Address Offset"}],
|
481
|
+
mc_constructor: [
|
482
|
+
["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
|
483
|
+
["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
|
484
|
+
["bits", 1,0],
|
485
|
+
["get_bits", ["get_operand", 2], 0, 9],
|
486
|
+
["bits", 0, 0,0, 0,0, 0, 1,1,1, 0,0],
|
487
|
+
],
|
488
|
+
bitsize: 32
|
489
|
+
},
|
397
490
|
|
491
|
+
{
|
492
|
+
keyword: "strb_pre_index",
|
493
|
+
name: "Store byte (immediate), signed pre-index offset",
|
494
|
+
description: "Stores the least significant byte of a 32-bit general purpose register at the address specified by the second register with an immediate offset added before writing.",
|
495
|
+
operands: [{type: "register", restrictions: {reg_type: "gpr", reg_size: 32}, name: "Content"}, {type: "register", restrictions: {reg_type: "gpr", reg_size: 64}, name: "Address"}, {type: "immediate", name: "Address Offset"}],
|
496
|
+
mc_constructor: [
|
497
|
+
["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
|
498
|
+
["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
|
499
|
+
["bits", 1,1],
|
500
|
+
["get_bits", ["get_operand", 2], 0, 9],
|
501
|
+
["bits", 0, 0,0, 0,0, 0, 1,1,1, 0,0],
|
502
|
+
],
|
503
|
+
bitsize: 32
|
504
|
+
},
|
398
505
|
|
506
|
+
|
399
507
|
{
|
400
508
|
keyword: "cmp",
|
401
509
|
name: "Compare (immediate)",
|
@@ -448,6 +556,26 @@ end
|
|
448
556
|
bitsize: 32
|
449
557
|
},
|
450
558
|
|
559
|
+
{
|
560
|
+
keyword: "sub",
|
561
|
+
name: "Subtract (register)",
|
562
|
+
description: "Subtract the second register value from the first register value, and store the result in the destination register",
|
563
|
+
operands: [{type: "register", restrictions: {reg_type: "gpr"}, name: "Destination"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Register 1 (Source)"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Register 2 (To subtract)"}],
|
564
|
+
mc_constructor: [
|
565
|
+
# Check for size
|
566
|
+
["if_eq_else", ["get_key", ["get_operand", 0], :reg_size], ["get_key", ["get_operand", 1], :reg_size], [], ["raise_error", "sub Error: Register sizes are not the same"]],
|
567
|
+
["if_eq_else", ["get_key", ["get_operand", 1], :reg_size], ["get_key", ["get_operand", 2], :reg_size], [], ["raise_error", "sub Error: Register sizes are not the same"]],
|
568
|
+
|
569
|
+
["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5], # Rd
|
570
|
+
["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5], # Rn
|
571
|
+
["get_bits", 0, 0, 6], # shift amount zero
|
572
|
+
["get_bits", ["encode_gp_register", ["get_operand", 2]], 0, 5], # Rm
|
573
|
+
["bits", 0, 0,0, 1,1,0,1,0, 0, 1],
|
574
|
+
["case", ["get_key", ["get_operand", 0], :reg_size], 64, ["bits", 1], 32, ["bits", 0], []], # sf
|
575
|
+
],
|
576
|
+
bitsize: 32
|
577
|
+
},
|
578
|
+
|
451
579
|
{
|
452
580
|
keyword: "mul",
|
453
581
|
name: "Multiply",
|
@@ -461,8 +589,7 @@ end
|
|
461
589
|
["bits", 1,1,1,1,1, 0], # Ra o0
|
462
590
|
["get_bits", ["encode_gp_register", ["get_operand", 2]], 0, 5], # Rm
|
463
591
|
["bits", 0,0,0, 1,1,0,1,1, 0,0],
|
464
|
-
["
|
465
|
-
["if_eq_else", ["get_key", ["get_operand", 0], :reg_size], 32, ["bits", 0], []], # SF = 0 if 32-bit
|
592
|
+
["case", ["get_key", ["get_operand", 0], :reg_size], 64, ["bits", 1], 32, ["bits", 0], []], # sf
|
466
593
|
],
|
467
594
|
bitsize: 32
|
468
595
|
},
|
@@ -491,14 +618,74 @@ end
|
|
491
618
|
},
|
492
619
|
|
493
620
|
|
621
|
+
{
|
622
|
+
keyword: "msub",
|
623
|
+
name: "Multiply-Subtract",
|
624
|
+
description: "Multiplies two register values, subtracts the product from a third register value, and writes the result to the destination register.",
|
625
|
+
operands: [{type: "register", restrictions: {reg_type: "gpr"}, name: "Destination"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Register 1 (to multiply)"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Register 2 (to multiply)"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Register 3 (To subtract from)"}],
|
626
|
+
mc_constructor: [
|
627
|
+
# Checks for register sizes being the same
|
628
|
+
["if_eq_else", ["get_key", ["get_operand", 0], :reg_size], ["get_key", ["get_operand", 1], :reg_size], [], ["raise_error", "madd Error: Register sizes are not the same"]],
|
629
|
+
["if_eq_else", ["get_key", ["get_operand", 1], :reg_size], ["get_key", ["get_operand", 2], :reg_size], [], ["raise_error", "madd Error: Register sizes are not the same"]],
|
630
|
+
["if_eq_else", ["get_key", ["get_operand", 2], :reg_size], ["get_key", ["get_operand", 3], :reg_size], [], ["raise_error", "madd Error: Register sizes are not the same"]],
|
631
|
+
|
632
|
+
["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5], # Rd
|
633
|
+
["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5], # Rn
|
634
|
+
["get_bits", ["encode_gp_register", ["get_operand", 3]], 0, 5], #Ra
|
635
|
+
["bits", 1], # o0
|
636
|
+
["get_bits", ["encode_gp_register", ["get_operand", 2]], 0, 5], # Rm
|
637
|
+
["bits", 0,0,0, 1,1,0,1,1, 0,0],
|
638
|
+
["case", ["get_key", ["get_operand", 0], :reg_size], 64, ["bits", 1], 32, ["bits", 0], []], # sf
|
639
|
+
],
|
640
|
+
bitsize: 32,
|
641
|
+
},
|
642
|
+
|
643
|
+
|
644
|
+
{
|
645
|
+
keyword: "udiv",
|
646
|
+
name: "Unsigned Divide",
|
647
|
+
description: "Divides an unsigned integer register value by another unsigned integer register value, and writes the result to the destination register.",
|
648
|
+
operands: [{type: "register", restrictions: {reg_type: "gpr"}, name: "Destination"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Register 1"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Register 2"}],
|
649
|
+
mc_constructor: [
|
650
|
+
["if_eq_else", ["get_key", ["get_operand", 0], :reg_size], ["get_key", ["get_operand", 1], :reg_size], [], ["raise_error", "udiv Error: Register sizes are not the same"]],
|
651
|
+
["if_eq_else", ["get_key", ["get_operand", 1], :reg_size], ["get_key", ["get_operand", 2], :reg_size], [], ["raise_error", "udiv Error: Register sizes are not the same"]],
|
652
|
+
["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5], # Rd
|
653
|
+
["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5], # Rn
|
654
|
+
["bits", 0, 1,0,0,0,0],
|
655
|
+
["get_bits", ["encode_gp_register", ["get_operand", 2]], 0, 5], # Rm
|
656
|
+
["bits", 0,1,1,0,1,0,1,1, 0, 0],
|
657
|
+
["case", ["get_key", ["get_operand", 0], :reg_size], 64, ["bits", 1], 32, ["bits", 0], []], # sf
|
658
|
+
],
|
659
|
+
bitsize: 32
|
660
|
+
},
|
661
|
+
|
662
|
+
{
|
663
|
+
keyword: "sdiv",
|
664
|
+
name: "Signed Divide",
|
665
|
+
description: "Divides a signed integer register value by another signed integer register value, and writes the result to the destination register.",
|
666
|
+
operands: [{type: "register", restrictions: {reg_type: "gpr"}, name: "Destination"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Register 1"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Register 2"}],
|
667
|
+
mc_constructor: [
|
668
|
+
["if_eq_else", ["get_key", ["get_operand", 0], :reg_size], ["get_key", ["get_operand", 1], :reg_size], [], ["raise_error", "udiv Error: Register sizes are not the same"]],
|
669
|
+
["if_eq_else", ["get_key", ["get_operand", 1], :reg_size], ["get_key", ["get_operand", 2], :reg_size], [], ["raise_error", "udiv Error: Register sizes are not the same"]],
|
670
|
+
["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5], # Rd
|
671
|
+
["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5], # Rn
|
672
|
+
["bits", 1, 1,0,0,0,0],
|
673
|
+
["get_bits", ["encode_gp_register", ["get_operand", 2]], 0, 5], # Rm
|
674
|
+
["bits", 0,1,1,0,1,0,1,1, 0, 0],
|
675
|
+
["case", ["get_key", ["get_operand", 0], :reg_size], 64, ["bits", 1], 32, ["bits", 0], []], # sf
|
676
|
+
],
|
677
|
+
bitsize: 32
|
678
|
+
},
|
679
|
+
|
680
|
+
|
494
681
|
#
|
495
682
|
# B.cond instructions
|
496
683
|
#
|
497
684
|
|
498
685
|
{
|
499
686
|
keyword: "b.eq",
|
500
|
-
name: "Branch
|
501
|
-
description: "Branches to a label if the condition
|
687
|
+
name: "Branch if equal (label)",
|
688
|
+
description: "Branches to a label if the condition is met",
|
502
689
|
operands: [{type: "label"}],
|
503
690
|
mc_constructor: [
|
504
691
|
["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
|
@@ -511,8 +698,9 @@ end
|
|
511
698
|
},
|
512
699
|
{
|
513
700
|
keyword: "b.eq",
|
701
|
+
name: "Branch if equal (immediate)",
|
702
|
+
description: "Changes the PC relatively by the immediate value if the condition is met",
|
514
703
|
operands: [{type: "immediate"}],
|
515
|
-
description: "Changes the PC relatively by the immediate value if the condition is met (equality)",
|
516
704
|
mc_constructor: [
|
517
705
|
["bits", 0,0,0,0], # eq condition
|
518
706
|
["bits", 0],
|
@@ -521,8 +709,157 @@ end
|
|
521
709
|
],
|
522
710
|
bitsize: 32
|
523
711
|
},
|
712
|
+
|
713
|
+
|
714
|
+
{
|
715
|
+
keyword: "b.ne",
|
716
|
+
name: "Branch if not equal (label)",
|
717
|
+
description: "Branches to a label if the condition is met",
|
718
|
+
operands: [{type: "label"}],
|
719
|
+
mc_constructor: [
|
720
|
+
["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
|
721
|
+
["bits", 1,0,0,0], # condition
|
722
|
+
["bits", 0],
|
723
|
+
["get_bits", ["divide", ["subtract", ["get_label_address", ["get_operand", 0]], ["get_current_address"]], 4], 0, 19],
|
724
|
+
["bits", 0, 0,1,0,1,0,1,0],
|
725
|
+
],
|
726
|
+
bitsize: 32
|
727
|
+
},
|
728
|
+
{
|
729
|
+
keyword: "b.ne",
|
730
|
+
name: "Branch if not equal (immediate)",
|
731
|
+
description: "Changes the PC relatively by the immediate value if the condition is met",
|
732
|
+
operands: [{type: "immediate"}],
|
733
|
+
mc_constructor: [
|
734
|
+
["bits", 1,0,0,0], # condition
|
735
|
+
["bits", 0],
|
736
|
+
["get_bits", ["get_operand", 0], 0, 19],
|
737
|
+
["bits", 0, 0,1,0,1,0,1,0],
|
738
|
+
],
|
739
|
+
bitsize: 32
|
740
|
+
},
|
741
|
+
|
742
|
+
|
743
|
+
{
|
744
|
+
keyword: "b.ge",
|
745
|
+
name: "Branch if greater or equal (label)",
|
746
|
+
description: "Branches to a label if the condition is met",
|
747
|
+
operands: [{type: "label"}],
|
748
|
+
mc_constructor: [
|
749
|
+
["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
|
750
|
+
["bits", 0,1,0,1], # condition
|
751
|
+
["bits", 0],
|
752
|
+
["get_bits", ["divide", ["subtract", ["get_label_address", ["get_operand", 0]], ["get_current_address"]], 4], 0, 19],
|
753
|
+
["bits", 0, 0,1,0,1,0,1,0],
|
754
|
+
],
|
755
|
+
bitsize: 32
|
756
|
+
},
|
757
|
+
{
|
758
|
+
keyword: "b.ge",
|
759
|
+
name: "Branch if greater or equal (immediate)",
|
760
|
+
description: "Changes the PC relatively by the immediate value if the condition is met",
|
761
|
+
operands: [{type: "immediate"}],
|
762
|
+
mc_constructor: [
|
763
|
+
["bits", 0,1,0,1], # condition
|
764
|
+
["bits", 0],
|
765
|
+
["get_bits", ["get_operand", 0], 0, 19],
|
766
|
+
["bits", 0, 0,1,0,1,0,1,0],
|
767
|
+
],
|
768
|
+
bitsize: 32
|
769
|
+
},
|
770
|
+
|
771
|
+
|
772
|
+
|
773
|
+
{
|
774
|
+
keyword: "b.lt",
|
775
|
+
name: "Branch if less than (label)",
|
776
|
+
description: "Branches to a label if the condition is met",
|
777
|
+
operands: [{type: "label"}],
|
778
|
+
mc_constructor: [
|
779
|
+
["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
|
780
|
+
["bits", 1,1,0,1], # condition
|
781
|
+
["bits", 0],
|
782
|
+
["get_bits", ["divide", ["subtract", ["get_label_address", ["get_operand", 0]], ["get_current_address"]], 4], 0, 19],
|
783
|
+
["bits", 0, 0,1,0,1,0,1,0],
|
784
|
+
],
|
785
|
+
bitsize: 32
|
786
|
+
},
|
787
|
+
{
|
788
|
+
keyword: "b.lt",
|
789
|
+
name: "Branch if less than (immediate)",
|
790
|
+
description: "Changes the PC relatively by the immediate value if the condition is met",
|
791
|
+
operands: [{type: "immediate"}],
|
792
|
+
mc_constructor: [
|
793
|
+
["bits", 1,1,0,1], # condition
|
794
|
+
["bits", 0],
|
795
|
+
["get_bits", ["get_operand", 0], 0, 19],
|
796
|
+
["bits", 0, 0,1,0,1,0,1,0],
|
797
|
+
],
|
798
|
+
bitsize: 32
|
799
|
+
},
|
800
|
+
|
801
|
+
|
802
|
+
|
803
|
+
|
804
|
+
{
|
805
|
+
keyword: "b.gt",
|
806
|
+
name: "Branch if greater than (label)",
|
807
|
+
description: "Branches to a label if the condition is met",
|
808
|
+
operands: [{type: "label"}],
|
809
|
+
mc_constructor: [
|
810
|
+
["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
|
811
|
+
["bits", 0,0,1,1], # condition
|
812
|
+
["bits", 0],
|
813
|
+
["get_bits", ["divide", ["subtract", ["get_label_address", ["get_operand", 0]], ["get_current_address"]], 4], 0, 19],
|
814
|
+
["bits", 0, 0,1,0,1,0,1,0],
|
815
|
+
],
|
816
|
+
bitsize: 32
|
817
|
+
},
|
818
|
+
{
|
819
|
+
keyword: "b.gt",
|
820
|
+
name: "Branch if greater than (immediate)",
|
821
|
+
description: "Changes the PC relatively by the immediate value if the condition is met",
|
822
|
+
operands: [{type: "immediate"}],
|
823
|
+
mc_constructor: [
|
824
|
+
["bits", 0,0,1,1], # condition
|
825
|
+
["bits", 0],
|
826
|
+
["get_bits", ["get_operand", 0], 0, 19],
|
827
|
+
["bits", 0, 0,1,0,1,0,1,0],
|
828
|
+
],
|
829
|
+
bitsize: 32
|
830
|
+
},
|
831
|
+
|
832
|
+
|
833
|
+
{
|
834
|
+
keyword: "b.le",
|
835
|
+
name: "Branch if less or equal (label)",
|
836
|
+
description: "Branches to a label if the condition is met",
|
837
|
+
operands: [{type: "label"}],
|
838
|
+
mc_constructor: [
|
839
|
+
["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
|
840
|
+
["bits", 1,0,1,1], # condition
|
841
|
+
["bits", 0],
|
842
|
+
["get_bits", ["divide", ["subtract", ["get_label_address", ["get_operand", 0]], ["get_current_address"]], 4], 0, 19],
|
843
|
+
["bits", 0, 0,1,0,1,0,1,0],
|
844
|
+
],
|
845
|
+
bitsize: 32
|
846
|
+
},
|
847
|
+
{
|
848
|
+
keyword: "b.le",
|
849
|
+
name: "Branch if less or equal (immediate)",
|
850
|
+
description: "Changes the PC relatively by the immediate value if the condition is met",
|
851
|
+
operands: [{type: "immediate"}],
|
852
|
+
mc_constructor: [
|
853
|
+
["bits", 1,0,1,1], # condition
|
854
|
+
["bits", 0],
|
855
|
+
["get_bits", ["get_operand", 0], 0, 19],
|
856
|
+
["bits", 0, 0,1,0,1,0,1,0],
|
857
|
+
],
|
858
|
+
bitsize: 32
|
859
|
+
},
|
860
|
+
|
524
861
|
]
|
525
862
|
|
526
863
|
end # Kompiler::ARMv8A
|
527
864
|
|
528
|
-
end # Kompiler
|
865
|
+
end # Kompiler
|
data/lib/kompiler/mc_builder.rb
CHANGED
@@ -40,6 +40,7 @@ MC_AST_NODES = [
|
|
40
40
|
end},
|
41
41
|
{name: "raise_error", n_args: 1, func: lambda {|args, state| raise args[0] } },
|
42
42
|
{name: "get_key", n_args: 2, func: lambda {|args, state| args[0][args[1]] }},
|
43
|
+
{name: "concat", n_args: "any", func: lambda {|args, state| args.flatten}},
|
43
44
|
]
|
44
45
|
|
45
46
|
def self.is_ast_node(val)
|
data/lib/kompiler/parsers.rb
CHANGED
@@ -9,6 +9,8 @@ def self.parse_str(code)
|
|
9
9
|
|
10
10
|
# Skip the "
|
11
11
|
i = 1
|
12
|
+
|
13
|
+
quote = code[0]
|
12
14
|
|
13
15
|
next_char_backslashed = false
|
14
16
|
|
@@ -20,17 +22,14 @@ def self.parse_str(code)
|
|
20
22
|
str_content << "\n"
|
21
23
|
elsif code[i] == "r"
|
22
24
|
str_content << "\r"
|
23
|
-
elsif code[i] == "\\"
|
24
|
-
str_content << "\\"
|
25
25
|
elsif code[i] == "0"
|
26
26
|
str_content << "\0"
|
27
27
|
else
|
28
|
-
str_content << "\\"
|
29
28
|
str_content << code[i]
|
30
29
|
end
|
31
30
|
next_char_backslashed = false
|
32
31
|
else
|
33
|
-
if code[i] ==
|
32
|
+
if code[i] == quote
|
34
33
|
break
|
35
34
|
elsif code[i] == "\\"
|
36
35
|
next_char_backslashed = true
|
@@ -207,7 +206,6 @@ end
|
|
207
206
|
|
208
207
|
def self.parse_operand_str(operand_str)
|
209
208
|
|
210
|
-
|
211
209
|
# Check if the operand is a register
|
212
210
|
is_register, register = check_register_operand(operand_str)
|
213
211
|
return {type: "register", value: register, register: register} if is_register
|
@@ -288,9 +286,9 @@ def self.parse_instruction_line(line)
|
|
288
286
|
end
|
289
287
|
|
290
288
|
# If a string definition, parse to the end of the string
|
291
|
-
if
|
289
|
+
if ["\"", "'"].include?(line[i])
|
292
290
|
str_content, parsed_size = parse_str(line[i..])
|
293
|
-
operand_content +=
|
291
|
+
operand_content += line[i] + str_content + line[i]
|
294
292
|
i += parsed_size
|
295
293
|
next
|
296
294
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kompiler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.0
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kyryl Shyshko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-12-04 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: 'Kompiler is a low-level, modular and extendable compiler for any architecture.
|
14
14
|
By default Kompiler supports ARMv8-a, but other architecture extensions can be downloaded
|