kompiler 0.2.0.pre.1 → 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 +427 -72
- data/lib/kompiler/mc_builder.rb +1 -0
- data/lib/kompiler/parsers.rb +33 -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,80 +443,236 @@ 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
|
+
},
|
397
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
|
+
},
|
398
490
|
|
399
491
|
{
|
400
|
-
keyword: "
|
401
|
-
|
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"}],
|
402
496
|
mc_constructor: [
|
403
|
-
["bits", 1,1,1,1,1],
|
404
497
|
["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
|
405
|
-
["get_bits", ["get_operand", 1], 0,
|
406
|
-
["bits",
|
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],
|
407
502
|
],
|
408
503
|
bitsize: 32
|
409
504
|
},
|
410
505
|
|
506
|
+
|
411
507
|
{
|
412
508
|
keyword: "cmp",
|
413
|
-
name: "
|
414
|
-
description: "
|
415
|
-
operands: [{type: "register", restrictions: {
|
509
|
+
name: "Compare (immediate)",
|
510
|
+
description: "Subtracts an immediate value from a register value, and updates the condition flags based on the result.",
|
511
|
+
operands: [{type: "register", restrictions: {reg_type: "gpr"}}, {type: "immediate"}],
|
416
512
|
mc_constructor: [
|
417
|
-
["bits", 1,1,1,1,1],
|
513
|
+
["bits", 1,1,1,1,1],
|
418
514
|
["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
|
419
|
-
["get_bits",
|
420
|
-
["
|
421
|
-
["bits", 0],
|
422
|
-
["bits", 0, 0], # Shift type
|
423
|
-
["bits", 1,1,0,1,0,1,1,1],
|
515
|
+
["get_bits", ["get_operand", 1], 0, 12], # Immediate value
|
516
|
+
["bits", 0, 0,1,0,0,0,1, 1, 1],
|
517
|
+
["case", ["get_key", ["get_operand", 0], :reg_size], 64, ["bits", 1], 32, ["bits", 0], []], # sf
|
424
518
|
],
|
425
519
|
bitsize: 32
|
426
520
|
},
|
427
521
|
|
428
522
|
{
|
429
523
|
keyword: "cmp",
|
430
|
-
name: "
|
431
|
-
description: "
|
432
|
-
operands: [{type: "register", restrictions: {
|
524
|
+
name: "Compare (registers)",
|
525
|
+
description: "Subtracts the second register value from the first register value, and updates the condition flags based on the result.",
|
526
|
+
operands: [{type: "register", restrictions: {reg_type: "gpr"}, name: "Register 1"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Register 2"}],
|
433
527
|
mc_constructor: [
|
528
|
+
["if_eq_else", ["get_key", ["get_operand", 0], :reg_size], ["get_key", ["get_operand", 1], :reg_size], [], ["raise_error", "cmp Error: Register sizes are not the same"]],
|
434
529
|
["bits", 1,1,1,1,1], # Rd
|
435
|
-
["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
|
530
|
+
["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5], # Rn
|
436
531
|
["get_bits", 0, 0, 6], # Immediate offset zero (shift amount)
|
437
532
|
["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5], # Rm
|
438
533
|
["bits", 0],
|
439
534
|
["bits", 0, 0], # Shift type
|
440
|
-
["bits", 1,1,0,1,0,1,1
|
535
|
+
["bits", 1,1,0,1,0,1,1],
|
536
|
+
["case", ["get_key", ["get_operand", 0], :reg_size], 64, ["bits", 1], 32, ["bits", 0], []], # sf
|
441
537
|
],
|
442
538
|
bitsize: 32
|
443
539
|
},
|
540
|
+
|
444
541
|
|
445
542
|
{
|
446
543
|
keyword: "sub",
|
447
|
-
|
544
|
+
name: "Subtract (immediate)",
|
545
|
+
description: "Subtract an immediate value from a register value, and store the result in the destination register",
|
546
|
+
operands: [{type: "register", restrictions: {reg_type: "gpr"}, name: "Destination"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Source"}, {type: "immediate", name: "Immediate"}],
|
448
547
|
mc_constructor: [
|
548
|
+
["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"]],
|
449
549
|
["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
|
450
550
|
["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
|
451
551
|
["get_bits", ["get_operand", 2], 0, 12], # Immediate offset zero
|
452
552
|
["bits", 0], # Shift
|
453
|
-
["bits", 0,1,0,0,0,1,0,1
|
553
|
+
["bits", 0,1,0,0,0,1,0,1],
|
554
|
+
["case", ["get_key", ["get_operand", 0], :reg_size], 64, ["bits", 1], 32, ["bits", 0], []], # sf
|
555
|
+
],
|
556
|
+
bitsize: 32
|
557
|
+
},
|
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
|
454
575
|
],
|
455
576
|
bitsize: 32
|
456
577
|
},
|
457
578
|
|
458
579
|
{
|
459
580
|
keyword: "mul",
|
460
|
-
name: "
|
461
|
-
description: "Multiply the contents of two registers and store the output in the destination register.",
|
462
|
-
operands: [{type: "register", restrictions: {reg_type: "gpr"}}, {type: "register", restrictions: {reg_type: "gpr"}}, {type: "register", restrictions: {reg_type: "gpr"}}],
|
581
|
+
name: "Multiply",
|
582
|
+
description: "Multiply the contents of two registers, and store the output in the destination register.",
|
583
|
+
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"}],
|
463
584
|
mc_constructor: [
|
585
|
+
["if_eq_else", ["get_key", ["get_operand", 0], :reg_size], ["get_key", ["get_operand", 1], :reg_size], [], ["raise_error", "mul Error: Register sizes are not the same"]],
|
586
|
+
["if_eq_else", ["get_key", ["get_operand", 1], :reg_size], ["get_key", ["get_operand", 2], :reg_size], [], ["raise_error", "mul Error: Register sizes are not the same"]],
|
464
587
|
["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5], # Rd
|
465
588
|
["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5], # Rn
|
466
589
|
["bits", 1,1,1,1,1, 0], # Ra o0
|
467
590
|
["get_bits", ["encode_gp_register", ["get_operand", 2]], 0, 5], # Rm
|
468
591
|
["bits", 0,0,0, 1,1,0,1,1, 0,0],
|
469
|
-
["
|
470
|
-
|
592
|
+
["case", ["get_key", ["get_operand", 0], :reg_size], 64, ["bits", 1], 32, ["bits", 0], []], # sf
|
593
|
+
],
|
594
|
+
bitsize: 32
|
595
|
+
},
|
596
|
+
|
597
|
+
|
598
|
+
{
|
599
|
+
keyword: "madd",
|
600
|
+
name: "Multiply-Add",
|
601
|
+
description: "Multiplies two register values, adds a third register value, and writes the result to the destination register.",
|
602
|
+
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 add)"}],
|
603
|
+
mc_constructor: [
|
604
|
+
# Checks for register sizes being the same
|
605
|
+
["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"]],
|
606
|
+
["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"]],
|
607
|
+
["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"]],
|
608
|
+
|
609
|
+
["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5], # Rd
|
610
|
+
["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5], # Rn
|
611
|
+
["get_bits", ["encode_gp_register", ["get_operand", 3]], 0, 5], #Ra
|
612
|
+
["bits", 0], # o0
|
613
|
+
["get_bits", ["encode_gp_register", ["get_operand", 2]], 0, 5], # Rm
|
614
|
+
["bits", 0,0,0, 1,1,0,1,1, 0,0],
|
615
|
+
["case", ["get_key", ["get_operand", 0], :reg_size], 64, ["bits", 1], 32, ["bits", 0], []], # sf
|
616
|
+
],
|
617
|
+
bitsize: 32,
|
618
|
+
},
|
619
|
+
|
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
|
471
676
|
],
|
472
677
|
bitsize: 32
|
473
678
|
},
|
@@ -479,8 +684,8 @@ end
|
|
479
684
|
|
480
685
|
{
|
481
686
|
keyword: "b.eq",
|
482
|
-
name: "Branch
|
483
|
-
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",
|
484
689
|
operands: [{type: "label"}],
|
485
690
|
mc_constructor: [
|
486
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
|
@@ -493,8 +698,9 @@ end
|
|
493
698
|
},
|
494
699
|
{
|
495
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",
|
496
703
|
operands: [{type: "immediate"}],
|
497
|
-
description: "Changes the PC relatively by the immediate value if the condition is met (equality)",
|
498
704
|
mc_constructor: [
|
499
705
|
["bits", 0,0,0,0], # eq condition
|
500
706
|
["bits", 0],
|
@@ -503,8 +709,157 @@ end
|
|
503
709
|
],
|
504
710
|
bitsize: 32
|
505
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
|
+
|
506
861
|
]
|
507
862
|
|
508
863
|
end # Kompiler::ARMv8A
|
509
864
|
|
510
|
-
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,15 +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
|
+
elsif code[i] == "0"
|
26
|
+
str_content << "\0"
|
25
27
|
else
|
26
|
-
str_content << "\\"
|
27
28
|
str_content << code[i]
|
28
29
|
end
|
29
30
|
next_char_backslashed = false
|
30
31
|
else
|
31
|
-
if code[i] ==
|
32
|
+
if code[i] == quote
|
32
33
|
break
|
33
34
|
elsif code[i] == "\\"
|
34
35
|
next_char_backslashed = true
|
@@ -145,6 +146,29 @@ def self.check_decimal_operand(str)
|
|
145
146
|
end
|
146
147
|
|
147
148
|
|
149
|
+
def self.check_char_operand(str)
|
150
|
+
|
151
|
+
# If doesn't start with ' or doesn't end with ', return false
|
152
|
+
if (str[0] != "'") || (str[-1] != "'")
|
153
|
+
return [false, nil]
|
154
|
+
end
|
155
|
+
|
156
|
+
# Use existing logic to parse the contents
|
157
|
+
to_parse = str.dup
|
158
|
+
to_parse[0] = '"'
|
159
|
+
to_parse[-1] = '"'
|
160
|
+
content, parse_i = parse_str(to_parse)
|
161
|
+
|
162
|
+
# If more than one character, return false
|
163
|
+
if content.size != 1
|
164
|
+
return [false, nil]
|
165
|
+
end
|
166
|
+
|
167
|
+
return [true, content.encode("ascii").bytes[0]]
|
168
|
+
end
|
169
|
+
|
170
|
+
|
171
|
+
|
148
172
|
def self.check_immediate_operand(operand_str)
|
149
173
|
|
150
174
|
is_bin, bin_value = check_binary_operand(operand_str)
|
@@ -156,6 +180,9 @@ def self.check_immediate_operand(operand_str)
|
|
156
180
|
is_hex, hex_value = check_hex_operand(operand_str)
|
157
181
|
return [true, {type: "immediate", value: hex_value, def_type: "hex"}] if is_hex
|
158
182
|
|
183
|
+
is_char, char_value = check_char_operand(operand_str)
|
184
|
+
return [true, {type: "immediate", value: char_value, def_type: "char"}] if is_char
|
185
|
+
|
159
186
|
return [false, nil]
|
160
187
|
end
|
161
188
|
|
@@ -179,7 +206,6 @@ end
|
|
179
206
|
|
180
207
|
def self.parse_operand_str(operand_str)
|
181
208
|
|
182
|
-
|
183
209
|
# Check if the operand is a register
|
184
210
|
is_register, register = check_register_operand(operand_str)
|
185
211
|
return {type: "register", value: register, register: register} if is_register
|
@@ -260,9 +286,9 @@ def self.parse_instruction_line(line)
|
|
260
286
|
end
|
261
287
|
|
262
288
|
# If a string definition, parse to the end of the string
|
263
|
-
if
|
289
|
+
if ["\"", "'"].include?(line[i])
|
264
290
|
str_content, parsed_size = parse_str(line[i..])
|
265
|
-
operand_content +=
|
291
|
+
operand_content += line[i] + str_content + line[i]
|
266
292
|
i += parsed_size
|
267
293
|
next
|
268
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
|