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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 36f0387094d41fc93e8f85e56446392a1941cbcd115bf94c3ffd799c3d85cc78
4
- data.tar.gz: 63a7973c95797b77119b47f24b8aa5bda591d7d2a4e5cbd5e34485fb11aea9b7
3
+ metadata.gz: fc460a4bb7ead297f0fe530c19304038f4d3980103cde260df057c52b35cfeeb
4
+ data.tar.gz: 57ea6ace09f3b1a5c3d0914d9edbbd02a83a5002b5c55ecde398f593cdcbb211
5
5
  SHA512:
6
- metadata.gz: 761aed3357cef9084d7dc0e7d8f9a73bb6dc883c7b1fc2cb5b0ee8b6499aa3f1f972bcc48d8d8adb2a3bd7f793738b28c1a37a21c17152d958cb79e39c7f8dab
7
- data.tar.gz: dae7000f44475fdcb2c6c8e78c82f638ca09790c4442706ddeb57b5f76a41f30786bec6fd6e1620c5eba95999c283c5ed8083161d258562ba4672651a2caab54
6
+ metadata.gz: 8c78b06f86db101176939c5aad994950e60d63827fe1a1470d5fad991fb9f2f3d26efef86981039fa2c41b22f034ad2c953bead0961ea4ea411ec583d64e5a27
7
+ data.tar.gz: 4c001f5a2c64e4a26752c98a116ff85138733662fe376e4b470352731cee721688bd194760f89e949552cf59e3824ef7b2ac607f6ab696732d783dff1b779cf6
@@ -103,18 +103,21 @@ end
103
103
  },
104
104
 
105
105
  {
106
- keyword: "and", # And between registers, with shift set to zero
107
- name: "And",
108
- description: "Computes a logical bit-wise AND operation between two registers and writes the result to the destination register.",
109
- operands: [{type: "register", restrictions: {reg_size: 64}, name: "Destination"}, {type: "register", restrictions: {reg_size: 64}, name: "Register 1"}, {type: "register", restrictions: {reg_size: 64}, name: "Register 2"}],
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
- ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
112
- ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
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, 1],
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: "LSL (immediate)",
192
- description: "Logically shifts left the value in the source register by the amount specified by the immediate, and stores the output in the destination register",
193
- operands: [{type: "register", restrictions: {reg_size: 64}, name: "Destination"}, {type: "register", restrictions: {reg_size: 64}, name: "Source"}, {type: "immediate", name: "Amount"}],
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
- ["get_bits", ["subtract", 63, ["get_operand", 2]], 0, 6],
199
- ["get_bits", ["modulo", ["multiply", ["get_operand", 2], -1], 64], 0, 6],
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
- ["bits", 1, 0,1,1,0,0,1, 0,1, 1],
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: "LSL (immediate)",
210
- description: "Logically shifts left the value in the source register by the amount specified by the immediate, and stores the output in the destination register",
211
- operands: [{type: "register", restrictions: {reg_size: 32}, name: "Destination"}, {type: "register", restrictions: {reg_size: 32}, name: "Source"}, {type: "immediate", name: "Amount"}],
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
- ["get_bits", ["subtract", 31, ["get_operand", 2]], 0, 6],
216
- ["get_bits", ["modulo", ["multiply", ["get_operand", 2], -1], 32], 0, 6],
217
- ["bits", 0, 0,1,1,0,0,1, 0,1, 0],
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: "LSR (immediate)",
229
- description: "Logically shifts right the value in the source register by the amount specified by the immediate, and stores the output in the destination register",
230
- operands: [{type: "register", restrictions: {reg_size: 64}, name: "Destination"}, {type: "register", restrictions: {reg_size: 64}, name: "Source"}, {type: "immediate", name: "Amount"}],
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 (specifies size)
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
- ["bits", 1, 0,1,1,0,0,1, 0,1, 1],
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: "LSR (immediate)",
246
- description: "Logically shifts right the value in the source register by the amount specified by the immediate, and stores the output in the destination register",
247
- operands: [{type: "register", restrictions: {reg_size: 32}, name: "Destination"}, {type: "register", restrictions: {reg_size: 32}, name: "Source"}, {type: "immediate", name: "Amount"}],
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", 0, 0,1,1,0,0,1, 0,1, 0],
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: "cmp",
401
- operands: [{type: "register", restrictions: {reg_size: 64}}, {type: "immediate"}],
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, 12], # Immediate offset zero
406
- ["bits", 0, 0,1,0,0,0,1, 1, 1, 1],
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: "CMP (two registers)",
414
- description: "Compares two 64-bit registers and updates condition flags based on the result.",
415
- operands: [{type: "register", restrictions: {reg_size: 64}, name: "Register 1"}, {type: "register", restrictions: {reg_size: 64}, name: "Register 2"}],
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], # Rd
513
+ ["bits", 1,1,1,1,1],
418
514
  ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
419
- ["get_bits", 0, 0, 6], # Immediate offset zero (shift amount)
420
- ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5], # Rm
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: "CMP (two registers)",
431
- description: "Compares two 32-bit registers and updates condition flags based on the result.",
432
- operands: [{type: "register", restrictions: {reg_size: 32}, name: "Register 1"}, {type: "register", restrictions: {reg_size: 32}, name: "Register 2"}],
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,0],
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
- operands: [{type: "register", restrictions: {reg_size: 64}}, {type: "register", restrictions: {reg_size: 64}}, {type: "immediate"}],
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,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: "MUL",
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
- ["if_eq_else", ["get_key", ["get_operand", 0], :reg_size], 64, ["bits", 1], []], # SF = 1 if 64-bit
470
- ["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
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 with condition",
483
- description: "Branches to a label if the condition (equality) is met",
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
@@ -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)
@@ -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 line[i] == "\""
289
+ if ["\"", "'"].include?(line[i])
264
290
  str_content, parsed_size = parse_str(line[i..])
265
- operand_content += '"' + str_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.pre.1
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-28 00:00:00.000000000 Z
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