summaryrefslogtreecommitdiff
path: root/src/mods/ir.zig
diff options
context:
space:
mode:
authorErnesto Lanchares <elancha98@proton.me>2025-03-23 18:20:38 +0000
committerLorenzo Torres <torres@sideros.org>2025-03-23 19:32:10 +0100
commit874134f3ff726d969fd901fee18c1aceb415c03b (patch)
tree5cd25aba47d6dc91737a2794622fe8dc21a8b9f6 /src/mods/ir.zig
parentb7854d7325dfe35ca41e56dcccfb8fb7b7d0aa22 (diff)
PROPOSAL: IR
This is a proposal of a custom IR to run wasm. At the moment only `ir.zig` has some parts related to this IR. The idea of the IR is to be a subset of the one defined in wasm. There are some gaps (mostly in wasm instructions that have opcode 0xFC) but in wasm they don't use all of the opcodes for some reason so maybe we could try to utilize them and be a superset of wasm.
Diffstat (limited to 'src/mods/ir.zig')
-rw-r--r--src/mods/ir.zig279
1 files changed, 279 insertions, 0 deletions
diff --git a/src/mods/ir.zig b/src/mods/ir.zig
new file mode 100644
index 0000000..ecb8d31
--- /dev/null
+++ b/src/mods/ir.zig
@@ -0,0 +1,279 @@
+const std = @import("std");
+const Parser = @import("Parser.zig");
+
+const Allocator = std.mem.Allocator;
+
+const DIndex = packed struct {
+ first: u32,
+ second: u32,
+};
+comptime {
+ // TODO: is this too big? we could do with 32 bits and a bit more indirection
+ std.debug.assert(@sizeOf(Index) == 8);
+}
+/// packed union has no tag
+const Index = packed union {
+ u32: u32,
+ i32: i32,
+ u64: u64,
+ i64: i64,
+ f32: f32,
+ f64: f64,
+ di: DIndex,
+};
+
+
+opcodes: []Opcode,
+/// Indices means something different depending on the Opcode.
+/// Read the docs of each opcode to know what the index means.
+indices: []Index,
+
+select_valtypes: []Parser.Valtype,
+
+/// Opcodes
+pub const Opcode = enum(u8) {
+ // CONTROL INSTRUCTIONS
+ // The rest of instructions should be implemented in terms of these ones
+ @"unreachable" = 0x00,
+ nop = 0x01,
+ /// Index: `u64`. Meaning: the next instruction pointer
+ br = 0x0C,
+ /// Index: `u64`. Meaning: the next instruction pointer
+ br_if = 0x0D,
+ /// TODO: this instruction (could be also implemented in terms of br and br_if)
+ br_table = 0x0E,
+ @"return" = 0x0F,
+ /// Index: `u64`. Meaning: The function index to call
+ call = 0x10,
+ /// TODO: index (is it enough with using a double index here? if we consider it enough then the other indices should use u32)
+ call_indirect = 0x11,
+
+ // REFERENCE INSTRUCTIONS
+ // This should be resolved at parse time and therefore not part of IR
+
+ // PARAMETRIC INSTRUCTIONS
+ // Select with no valtypes should be resolved at parse time
+ drop = 0x1A,
+ /// Index: `DIndex`. Meaning:
+ /// `first` is the index into `select_valtypes` array and
+ /// `second` is the number of valtypes
+ select = 0x1C,
+
+ // VARIABLE INSTRUCTIONS
+ /// Index: `u32`. Meaing: index into local variables
+ localget = 0x20,
+ /// Index: `u32`. Meaing: index into local variables
+ localset = 0x21,
+ /// Index: `u32`. Meaing: index into local variables
+ localtee = 0x22,
+ /// Index: `u32`. Meaing: index into global variables
+ globalget = 0x23,
+ /// Index: `u32`. Meaing: index into global variables
+ globalset = 0x24,
+
+ // TABLE INSTRUCTIONS
+ /// Index: `u32`. Meaning: index into table index
+ tableget = 0x25,
+ /// Index: `u32`. Meaning: index into table index
+ tableset = 0x26,
+ /// TODO: table operation. Value in wasm: 0xFC. Note wher is 0x27?
+ tableop = 0xF0,
+
+ // MEMORY INSTRUCTIONS
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i32load = 0x28,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i64load = 0x29,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ f32load = 0x2A,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ f64load = 0x2B,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i32load8_s = 0x2C,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i32load8_u = 0x2D,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i32load16_s = 0x2E,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i32load16_u = 0x2F,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i64load8_s = 0x30,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i64load8_u = 0x31,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i64load16_s = 0x32,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i64load16_u = 0x33,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i64load32_s = 0x34,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i64load32_u = 0x35,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i32store = 0x36,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i64store = 0x37,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ f32store = 0x38,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ f64store = 0x39,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i32store8 = 0x3A,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i32store16 = 0x3B,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i64store8 = 0x3C,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i64store16 = 0x3D,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i64store32 = 0x3E,
+ memorysize = 0x3F,
+ memorygrow = 0x40,
+ /// TODO: memory operation. Value in wasm: 0xFC
+ memoryop = 0xF1,
+
+ // NUMERIC INSTRUCTION
+ /// Index: `i32`. Meaning: constant
+ i32const = 0x41,
+ /// Index: `i64`. Meaning: constant
+ i64const = 0x42,
+ /// Index: `f32`. Meaning: constant
+ f32const = 0x43,
+ /// Index: `f64`. Meaning: constant
+ f64const = 0x44,
+ i32eqz = 0x45,
+ i32eq = 0x46,
+ i32ne = 0x47,
+ i32lt_s = 0x48,
+ i32lt_u = 0x49,
+ i32gt_s = 0x4A,
+ i32gt_u = 0x4B,
+ i32le_s = 0x4C,
+ i32le_u = 0x4D,
+ i32ge_s = 0x4E,
+ i32ge_u = 0x4F,
+ i64eqz = 0x50,
+ i64eq = 0x51,
+ i64ne = 0x52,
+ i64lt_s = 0x53,
+ i64lt_u = 0x54,
+ i64gt_s = 0x55,
+ i64gt_u = 0x56,
+ i64le_s = 0x57,
+ i64le_u = 0x58,
+ i64ge_s = 0x59,
+ i64ge_u = 0x5A,
+ f32eq = 0x5B,
+ f32ne = 0x5C,
+ f32lt = 0x5D,
+ f32gt = 0x5E,
+ f32le = 0x5F,
+ f32ge = 0x60,
+ f64eq = 0x61,
+ f64ne = 0x62,
+ f64lt = 0x63,
+ f64gt = 0x64,
+ f64le = 0x65,
+ f64ge = 0x66,
+ i32clz = 0x67,
+ i32ctz = 0x68,
+ i32popcnt = 0x69,
+ i32add = 0x6A,
+ i32sub = 0x6B,
+ i32mul = 0x6C,
+ i32div_s = 0x6D,
+ i32div_u = 0x6E,
+ i32rem_s = 0x6F,
+ i32rem_u = 0x70,
+ i32and = 0x71,
+ i32or = 0x72,
+ i32xor = 0x73,
+ i32shl = 0x74,
+ i32shr_s = 0x75,
+ i32shr_u = 0x76,
+ i32rotl = 0x77,
+ i32rotr = 0x78,
+ i64clz = 0x79,
+ i64ctz = 0x7A,
+ i64popcnt = 0x7B,
+ i64add = 0x7C,
+ i64sub = 0x7D,
+ i64mul = 0x7E,
+ i64div_s = 0x7F,
+ i64div_u = 0x80,
+ i64rem_s = 0x81,
+ i64rem_u = 0x82,
+ i64and = 0x83,
+ i64or = 0x84,
+ i64xor = 0x85,
+ i64shl = 0x86,
+ i64shr_s = 0x87,
+ i64shr_u = 0x88,
+ i64rotl = 0x89,
+ i64rotr = 0x8A,
+ f32abs = 0x8B,
+ f32neg = 0x8C,
+ f32ceil = 0x8D,
+ f32floor = 0x8E,
+ f32trunc = 0x8F,
+ f32nearest = 0x90,
+ f32sqrt = 0x91,
+ f32add = 0x92,
+ f32sub = 0x93,
+ f32mul = 0x94,
+ f32div = 0x95,
+ f32min = 0x96,
+ f32max = 0x97,
+ f32copysign = 0x98,
+ f64abs = 0x99,
+ f64neg = 0x9A,
+ f64ceil = 0x9B,
+ f64floor = 0x9C,
+ f64trunc = 0x9D,
+ f64nearest = 0x9E,
+ f64sqrt = 0x9F,
+ f64add = 0xA0,
+ f64sub = 0xA1,
+ f64mul = 0xA2,
+ f64div = 0xA3,
+ f64min = 0xA4,
+ f64max = 0xA5,
+ f64copysign = 0xA6,
+ i32wrap_i64 = 0xA7,
+ i32trunc_f32_s = 0xA8,
+ i32trunc_f32_u = 0xA9,
+ i32trunc_f64_s = 0xAA,
+ i32trunc_f64_u = 0xAB,
+ i64extend_i32_s = 0xAC,
+ i64extend_i32_u = 0xAD,
+ i64trunc_f32_s = 0xAE,
+ i64trunc_f32_u = 0xAF,
+ i64trunc_f64_s = 0xB0,
+ i64trunc_f64_u = 0xB1,
+ f32convert_i32_s = 0xB2,
+ f32convert_i32_u = 0xB3,
+ f32convert_i64_s = 0xB4,
+ f32convert_i64_u = 0xB5,
+ f32demote_f64 = 0xB6,
+ f64convert_i32_s = 0xB7,
+ f64convert_i32_u = 0xB8,
+ f64convert_i64_s = 0xB9,
+ f64convert_i64_u = 0xBA,
+ f64promote_f32 = 0xBB,
+ i32reinterpret_f32 = 0xBC,
+ i64reinterpret_f64 = 0xBD,
+ f32reinterpret_i32 = 0xBE,
+ f64reinterpret_i64 = 0xBF,
+ i32extend8_s = 0xC0,
+ i32extend16_s = 0xC1,
+ i64extend8_s = 0xC2,
+ i64extend16_s = 0xC3,
+ i64extend32_s = 0xC4,
+ /// TODO: saturation truncation instructions. Value in wasm: 0xFC
+ sattrunc = 0xF2,
+
+ // VECTOR INSTRUCTIONS
+ /// TODO: vector instructions. Value in wasm: 0xFC. Note: there are opcodes available lol
+ vecinst = 0xF3,
+
+};
+