kompiler 0.2.0.pre.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|