kompiler 0.2.0.pre.2 → 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: 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