kompiler 0.2.0.pre.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 69b1e8272e45a6c9ce0b8bb60dbfb89b0d65d0f8f615cbd744726857ecf1d94f
4
- data.tar.gz: eba0c518a787b345d191a2cf41e76ecb52ca25dac10f14f17b72d5cbbcb2f201
3
+ metadata.gz: fc460a4bb7ead297f0fe530c19304038f4d3980103cde260df057c52b35cfeeb
4
+ data.tar.gz: 57ea6ace09f3b1a5c3d0914d9edbbd02a83a5002b5c55ecde398f593cdcbb211
5
5
  SHA512:
6
- metadata.gz: a325a47eff59b3766cead44c9e81063773af594e224d96aa667b7015a7a469d10be65e0ecdb68b36db88645472ae320309e92872ba568c3ed32f8da4525b113e
7
- data.tar.gz: 31881ac3bba3ac3e3afa0a1c87366ea1680c32189d07cbdcd62e7eee33b19712fb85c0198b91b2315377e1f16ad0a973c95083810ef0a125c4a385ea84774101
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,8 +443,67 @@ end
394
443
  ],
395
444
  bitsize: 32
396
445
  },
446
+
447
+
448
+ {
449
+ keyword: "strb",
450
+ name: "Store byte",
451
+ description: "Stores the least significant byte of a 32-bit general purpose register at the address specified by the second register.",
452
+ operands: [{type: "register", restrictions: {reg_type: "gpr", reg_size: 32}, name: "Content"}, {type: "register", restrictions: {reg_type: "gpr", reg_size: 64}, name: "Address"}],
453
+ mc_constructor: [
454
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
455
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
456
+ ["get_bits", 0, 0, 12],
457
+ ["bits", 0,0, 1,0, 0, 1,1,1, 0,0],
458
+ ],
459
+ bitsize: 32
460
+ },
461
+
462
+ {
463
+ keyword: "strb_unsigned",
464
+ name: "Store byte (immediate), unsigned offset",
465
+ description: "Stores the least significant byte of a 32-bit general purpose register at the address specified by the second register with an unsigned immediate offset.",
466
+ operands: [{type: "register", restrictions: {reg_type: "gpr", reg_size: 32}, name: "Content"}, {type: "register", restrictions: {reg_type: "gpr", reg_size: 64}, name: "Address"}, {type: "immediate", name: "Address Offset"}],
467
+ mc_constructor: [
468
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
469
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
470
+ ["get_bits", ["get_operand", 2], 0, 12],
471
+ ["bits", 0,0, 1,0, 0, 1,1,1, 0,0],
472
+ ],
473
+ bitsize: 32
474
+ },
475
+
476
+ {
477
+ keyword: "strb_post_index",
478
+ name: "Store byte (immediate), signed post-index offset",
479
+ description: "Stores the least significant byte of a 32-bit general purpose register at the address specified by the second register with an immediate offset added after writing.",
480
+ operands: [{type: "register", restrictions: {reg_type: "gpr", reg_size: 32}, name: "Content"}, {type: "register", restrictions: {reg_type: "gpr", reg_size: 64}, name: "Address"}, {type: "immediate", name: "Address Offset"}],
481
+ mc_constructor: [
482
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
483
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
484
+ ["bits", 1,0],
485
+ ["get_bits", ["get_operand", 2], 0, 9],
486
+ ["bits", 0, 0,0, 0,0, 0, 1,1,1, 0,0],
487
+ ],
488
+ bitsize: 32
489
+ },
397
490
 
491
+ {
492
+ keyword: "strb_pre_index",
493
+ name: "Store byte (immediate), signed pre-index offset",
494
+ description: "Stores the least significant byte of a 32-bit general purpose register at the address specified by the second register with an immediate offset added before writing.",
495
+ operands: [{type: "register", restrictions: {reg_type: "gpr", reg_size: 32}, name: "Content"}, {type: "register", restrictions: {reg_type: "gpr", reg_size: 64}, name: "Address"}, {type: "immediate", name: "Address Offset"}],
496
+ mc_constructor: [
497
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5],
498
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5],
499
+ ["bits", 1,1],
500
+ ["get_bits", ["get_operand", 2], 0, 9],
501
+ ["bits", 0, 0,0, 0,0, 0, 1,1,1, 0,0],
502
+ ],
503
+ bitsize: 32
504
+ },
398
505
 
506
+
399
507
  {
400
508
  keyword: "cmp",
401
509
  name: "Compare (immediate)",
@@ -448,6 +556,26 @@ end
448
556
  bitsize: 32
449
557
  },
450
558
 
559
+ {
560
+ keyword: "sub",
561
+ name: "Subtract (register)",
562
+ description: "Subtract the second register value from the first register value, and store the result in the destination register",
563
+ operands: [{type: "register", restrictions: {reg_type: "gpr"}, name: "Destination"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Register 1 (Source)"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Register 2 (To subtract)"}],
564
+ mc_constructor: [
565
+ # Check for size
566
+ ["if_eq_else", ["get_key", ["get_operand", 0], :reg_size], ["get_key", ["get_operand", 1], :reg_size], [], ["raise_error", "sub Error: Register sizes are not the same"]],
567
+ ["if_eq_else", ["get_key", ["get_operand", 1], :reg_size], ["get_key", ["get_operand", 2], :reg_size], [], ["raise_error", "sub Error: Register sizes are not the same"]],
568
+
569
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5], # Rd
570
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5], # Rn
571
+ ["get_bits", 0, 0, 6], # shift amount zero
572
+ ["get_bits", ["encode_gp_register", ["get_operand", 2]], 0, 5], # Rm
573
+ ["bits", 0, 0,0, 1,1,0,1,0, 0, 1],
574
+ ["case", ["get_key", ["get_operand", 0], :reg_size], 64, ["bits", 1], 32, ["bits", 0], []], # sf
575
+ ],
576
+ bitsize: 32
577
+ },
578
+
451
579
  {
452
580
  keyword: "mul",
453
581
  name: "Multiply",
@@ -461,8 +589,7 @@ end
461
589
  ["bits", 1,1,1,1,1, 0], # Ra o0
462
590
  ["get_bits", ["encode_gp_register", ["get_operand", 2]], 0, 5], # Rm
463
591
  ["bits", 0,0,0, 1,1,0,1,1, 0,0],
464
- ["if_eq_else", ["get_key", ["get_operand", 0], :reg_size], 64, ["bits", 1], []], # SF = 1 if 64-bit
465
- ["if_eq_else", ["get_key", ["get_operand", 0], :reg_size], 32, ["bits", 0], []], # SF = 0 if 32-bit
592
+ ["case", ["get_key", ["get_operand", 0], :reg_size], 64, ["bits", 1], 32, ["bits", 0], []], # sf
466
593
  ],
467
594
  bitsize: 32
468
595
  },
@@ -491,14 +618,74 @@ end
491
618
  },
492
619
 
493
620
 
621
+ {
622
+ keyword: "msub",
623
+ name: "Multiply-Subtract",
624
+ description: "Multiplies two register values, subtracts the product from a third register value, and writes the result to the destination register.",
625
+ operands: [{type: "register", restrictions: {reg_type: "gpr"}, name: "Destination"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Register 1 (to multiply)"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Register 2 (to multiply)"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Register 3 (To subtract from)"}],
626
+ mc_constructor: [
627
+ # Checks for register sizes being the same
628
+ ["if_eq_else", ["get_key", ["get_operand", 0], :reg_size], ["get_key", ["get_operand", 1], :reg_size], [], ["raise_error", "madd Error: Register sizes are not the same"]],
629
+ ["if_eq_else", ["get_key", ["get_operand", 1], :reg_size], ["get_key", ["get_operand", 2], :reg_size], [], ["raise_error", "madd Error: Register sizes are not the same"]],
630
+ ["if_eq_else", ["get_key", ["get_operand", 2], :reg_size], ["get_key", ["get_operand", 3], :reg_size], [], ["raise_error", "madd Error: Register sizes are not the same"]],
631
+
632
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5], # Rd
633
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5], # Rn
634
+ ["get_bits", ["encode_gp_register", ["get_operand", 3]], 0, 5], #Ra
635
+ ["bits", 1], # o0
636
+ ["get_bits", ["encode_gp_register", ["get_operand", 2]], 0, 5], # Rm
637
+ ["bits", 0,0,0, 1,1,0,1,1, 0,0],
638
+ ["case", ["get_key", ["get_operand", 0], :reg_size], 64, ["bits", 1], 32, ["bits", 0], []], # sf
639
+ ],
640
+ bitsize: 32,
641
+ },
642
+
643
+
644
+ {
645
+ keyword: "udiv",
646
+ name: "Unsigned Divide",
647
+ description: "Divides an unsigned integer register value by another unsigned integer register value, and writes the result to the destination register.",
648
+ operands: [{type: "register", restrictions: {reg_type: "gpr"}, name: "Destination"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Register 1"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Register 2"}],
649
+ mc_constructor: [
650
+ ["if_eq_else", ["get_key", ["get_operand", 0], :reg_size], ["get_key", ["get_operand", 1], :reg_size], [], ["raise_error", "udiv Error: Register sizes are not the same"]],
651
+ ["if_eq_else", ["get_key", ["get_operand", 1], :reg_size], ["get_key", ["get_operand", 2], :reg_size], [], ["raise_error", "udiv Error: Register sizes are not the same"]],
652
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5], # Rd
653
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5], # Rn
654
+ ["bits", 0, 1,0,0,0,0],
655
+ ["get_bits", ["encode_gp_register", ["get_operand", 2]], 0, 5], # Rm
656
+ ["bits", 0,1,1,0,1,0,1,1, 0, 0],
657
+ ["case", ["get_key", ["get_operand", 0], :reg_size], 64, ["bits", 1], 32, ["bits", 0], []], # sf
658
+ ],
659
+ bitsize: 32
660
+ },
661
+
662
+ {
663
+ keyword: "sdiv",
664
+ name: "Signed Divide",
665
+ description: "Divides a signed integer register value by another signed integer register value, and writes the result to the destination register.",
666
+ operands: [{type: "register", restrictions: {reg_type: "gpr"}, name: "Destination"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Register 1"}, {type: "register", restrictions: {reg_type: "gpr"}, name: "Register 2"}],
667
+ mc_constructor: [
668
+ ["if_eq_else", ["get_key", ["get_operand", 0], :reg_size], ["get_key", ["get_operand", 1], :reg_size], [], ["raise_error", "udiv Error: Register sizes are not the same"]],
669
+ ["if_eq_else", ["get_key", ["get_operand", 1], :reg_size], ["get_key", ["get_operand", 2], :reg_size], [], ["raise_error", "udiv Error: Register sizes are not the same"]],
670
+ ["get_bits", ["encode_gp_register", ["get_operand", 0]], 0, 5], # Rd
671
+ ["get_bits", ["encode_gp_register", ["get_operand", 1]], 0, 5], # Rn
672
+ ["bits", 1, 1,0,0,0,0],
673
+ ["get_bits", ["encode_gp_register", ["get_operand", 2]], 0, 5], # Rm
674
+ ["bits", 0,1,1,0,1,0,1,1, 0, 0],
675
+ ["case", ["get_key", ["get_operand", 0], :reg_size], 64, ["bits", 1], 32, ["bits", 0], []], # sf
676
+ ],
677
+ bitsize: 32
678
+ },
679
+
680
+
494
681
  #
495
682
  # B.cond instructions
496
683
  #
497
684
 
498
685
  {
499
686
  keyword: "b.eq",
500
- name: "Branch with condition",
501
- 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",
502
689
  operands: [{type: "label"}],
503
690
  mc_constructor: [
504
691
  ["if_eq_else", ["modulo", ["subtract", ["get_label_address", ["get_operand", 0]], ["get_current_address"]], 4], 0, [], ["raise_error", "Can't branch to the address - offset not divisible by 4 bytes."]], # Check if address is accessible
@@ -511,8 +698,9 @@ end
511
698
  },
512
699
  {
513
700
  keyword: "b.eq",
701
+ name: "Branch if equal (immediate)",
702
+ description: "Changes the PC relatively by the immediate value if the condition is met",
514
703
  operands: [{type: "immediate"}],
515
- description: "Changes the PC relatively by the immediate value if the condition is met (equality)",
516
704
  mc_constructor: [
517
705
  ["bits", 0,0,0,0], # eq condition
518
706
  ["bits", 0],
@@ -521,8 +709,157 @@ end
521
709
  ],
522
710
  bitsize: 32
523
711
  },
712
+
713
+
714
+ {
715
+ keyword: "b.ne",
716
+ name: "Branch if not equal (label)",
717
+ description: "Branches to a label if the condition is met",
718
+ operands: [{type: "label"}],
719
+ mc_constructor: [
720
+ ["if_eq_else", ["modulo", ["subtract", ["get_label_address", ["get_operand", 0]], ["get_current_address"]], 4], 0, [], ["raise_error", "Can't branch to the address - offset not divisible by 4 bytes."]], # Check if address is accessible
721
+ ["bits", 1,0,0,0], # condition
722
+ ["bits", 0],
723
+ ["get_bits", ["divide", ["subtract", ["get_label_address", ["get_operand", 0]], ["get_current_address"]], 4], 0, 19],
724
+ ["bits", 0, 0,1,0,1,0,1,0],
725
+ ],
726
+ bitsize: 32
727
+ },
728
+ {
729
+ keyword: "b.ne",
730
+ name: "Branch if not equal (immediate)",
731
+ description: "Changes the PC relatively by the immediate value if the condition is met",
732
+ operands: [{type: "immediate"}],
733
+ mc_constructor: [
734
+ ["bits", 1,0,0,0], # condition
735
+ ["bits", 0],
736
+ ["get_bits", ["get_operand", 0], 0, 19],
737
+ ["bits", 0, 0,1,0,1,0,1,0],
738
+ ],
739
+ bitsize: 32
740
+ },
741
+
742
+
743
+ {
744
+ keyword: "b.ge",
745
+ name: "Branch if greater or equal (label)",
746
+ description: "Branches to a label if the condition is met",
747
+ operands: [{type: "label"}],
748
+ mc_constructor: [
749
+ ["if_eq_else", ["modulo", ["subtract", ["get_label_address", ["get_operand", 0]], ["get_current_address"]], 4], 0, [], ["raise_error", "Can't branch to the address - offset not divisible by 4 bytes."]], # Check if address is accessible
750
+ ["bits", 0,1,0,1], # condition
751
+ ["bits", 0],
752
+ ["get_bits", ["divide", ["subtract", ["get_label_address", ["get_operand", 0]], ["get_current_address"]], 4], 0, 19],
753
+ ["bits", 0, 0,1,0,1,0,1,0],
754
+ ],
755
+ bitsize: 32
756
+ },
757
+ {
758
+ keyword: "b.ge",
759
+ name: "Branch if greater or equal (immediate)",
760
+ description: "Changes the PC relatively by the immediate value if the condition is met",
761
+ operands: [{type: "immediate"}],
762
+ mc_constructor: [
763
+ ["bits", 0,1,0,1], # condition
764
+ ["bits", 0],
765
+ ["get_bits", ["get_operand", 0], 0, 19],
766
+ ["bits", 0, 0,1,0,1,0,1,0],
767
+ ],
768
+ bitsize: 32
769
+ },
770
+
771
+
772
+
773
+ {
774
+ keyword: "b.lt",
775
+ name: "Branch if less than (label)",
776
+ description: "Branches to a label if the condition is met",
777
+ operands: [{type: "label"}],
778
+ mc_constructor: [
779
+ ["if_eq_else", ["modulo", ["subtract", ["get_label_address", ["get_operand", 0]], ["get_current_address"]], 4], 0, [], ["raise_error", "Can't branch to the address - offset not divisible by 4 bytes."]], # Check if address is accessible
780
+ ["bits", 1,1,0,1], # condition
781
+ ["bits", 0],
782
+ ["get_bits", ["divide", ["subtract", ["get_label_address", ["get_operand", 0]], ["get_current_address"]], 4], 0, 19],
783
+ ["bits", 0, 0,1,0,1,0,1,0],
784
+ ],
785
+ bitsize: 32
786
+ },
787
+ {
788
+ keyword: "b.lt",
789
+ name: "Branch if less than (immediate)",
790
+ description: "Changes the PC relatively by the immediate value if the condition is met",
791
+ operands: [{type: "immediate"}],
792
+ mc_constructor: [
793
+ ["bits", 1,1,0,1], # condition
794
+ ["bits", 0],
795
+ ["get_bits", ["get_operand", 0], 0, 19],
796
+ ["bits", 0, 0,1,0,1,0,1,0],
797
+ ],
798
+ bitsize: 32
799
+ },
800
+
801
+
802
+
803
+
804
+ {
805
+ keyword: "b.gt",
806
+ name: "Branch if greater than (label)",
807
+ description: "Branches to a label if the condition is met",
808
+ operands: [{type: "label"}],
809
+ mc_constructor: [
810
+ ["if_eq_else", ["modulo", ["subtract", ["get_label_address", ["get_operand", 0]], ["get_current_address"]], 4], 0, [], ["raise_error", "Can't branch to the address - offset not divisible by 4 bytes."]], # Check if address is accessible
811
+ ["bits", 0,0,1,1], # condition
812
+ ["bits", 0],
813
+ ["get_bits", ["divide", ["subtract", ["get_label_address", ["get_operand", 0]], ["get_current_address"]], 4], 0, 19],
814
+ ["bits", 0, 0,1,0,1,0,1,0],
815
+ ],
816
+ bitsize: 32
817
+ },
818
+ {
819
+ keyword: "b.gt",
820
+ name: "Branch if greater than (immediate)",
821
+ description: "Changes the PC relatively by the immediate value if the condition is met",
822
+ operands: [{type: "immediate"}],
823
+ mc_constructor: [
824
+ ["bits", 0,0,1,1], # condition
825
+ ["bits", 0],
826
+ ["get_bits", ["get_operand", 0], 0, 19],
827
+ ["bits", 0, 0,1,0,1,0,1,0],
828
+ ],
829
+ bitsize: 32
830
+ },
831
+
832
+
833
+ {
834
+ keyword: "b.le",
835
+ name: "Branch if less or equal (label)",
836
+ description: "Branches to a label if the condition is met",
837
+ operands: [{type: "label"}],
838
+ mc_constructor: [
839
+ ["if_eq_else", ["modulo", ["subtract", ["get_label_address", ["get_operand", 0]], ["get_current_address"]], 4], 0, [], ["raise_error", "Can't branch to the address - offset not divisible by 4 bytes."]], # Check if address is accessible
840
+ ["bits", 1,0,1,1], # condition
841
+ ["bits", 0],
842
+ ["get_bits", ["divide", ["subtract", ["get_label_address", ["get_operand", 0]], ["get_current_address"]], 4], 0, 19],
843
+ ["bits", 0, 0,1,0,1,0,1,0],
844
+ ],
845
+ bitsize: 32
846
+ },
847
+ {
848
+ keyword: "b.le",
849
+ name: "Branch if less or equal (immediate)",
850
+ description: "Changes the PC relatively by the immediate value if the condition is met",
851
+ operands: [{type: "immediate"}],
852
+ mc_constructor: [
853
+ ["bits", 1,0,1,1], # condition
854
+ ["bits", 0],
855
+ ["get_bits", ["get_operand", 0], 0, 19],
856
+ ["bits", 0, 0,1,0,1,0,1,0],
857
+ ],
858
+ bitsize: 32
859
+ },
860
+
524
861
  ]
525
862
 
526
863
  end # Kompiler::ARMv8A
527
864
 
528
- end # Kompiler
865
+ end # Kompiler
@@ -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,17 +22,14 @@ def self.parse_str(code)
20
22
  str_content << "\n"
21
23
  elsif code[i] == "r"
22
24
  str_content << "\r"
23
- elsif code[i] == "\\"
24
- str_content << "\\"
25
25
  elsif code[i] == "0"
26
26
  str_content << "\0"
27
27
  else
28
- str_content << "\\"
29
28
  str_content << code[i]
30
29
  end
31
30
  next_char_backslashed = false
32
31
  else
33
- if code[i] == "\""
32
+ if code[i] == quote
34
33
  break
35
34
  elsif code[i] == "\\"
36
35
  next_char_backslashed = true
@@ -207,7 +206,6 @@ end
207
206
 
208
207
  def self.parse_operand_str(operand_str)
209
208
 
210
-
211
209
  # Check if the operand is a register
212
210
  is_register, register = check_register_operand(operand_str)
213
211
  return {type: "register", value: register, register: register} if is_register
@@ -288,9 +286,9 @@ def self.parse_instruction_line(line)
288
286
  end
289
287
 
290
288
  # If a string definition, parse to the end of the string
291
- if line[i] == "\""
289
+ if ["\"", "'"].include?(line[i])
292
290
  str_content, parsed_size = parse_str(line[i..])
293
- operand_content += '"' + str_content + '"'
291
+ operand_content += line[i] + str_content + line[i]
294
292
  i += parsed_size
295
293
  next
296
294
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kompiler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0.pre.2
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