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 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