diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.zig | 7 | ||||
-rw-r--r-- | src/mods/Parser.zig | 2 | ||||
-rw-r--r-- | src/mods/ir.zig | 279 | ||||
-rw-r--r-- | src/mods/mods.zig | 5 |
4 files changed, 288 insertions, 5 deletions
diff --git a/src/main.zig b/src/main.zig index 97aa5bf..e8ff1d1 100644 --- a/src/main.zig +++ b/src/main.zig @@ -5,9 +5,8 @@ const window = @import("rendering/window.zig"); const config = @import("config"); const Renderer = @import("rendering/renderer_vulkan.zig"); const math = @import("math.zig"); -const Parser = @import("mods/Parser.zig"); -const vm = @import("mods/vm.zig"); -const wasm = @import("mods/wasm.zig"); +const mods = @import("mods"); + const components = @import("ecs/components.zig"); const entities = @import("ecs/entities.zig"); @@ -30,7 +29,7 @@ pub fn main() !void { // const file = try std.fs.cwd().openFile("assets/core.wasm", .{}); // const all = try file.readToEndAlloc(allocator, 1_000_000); // 1 MB - // var parser = Parser{ + // var parser = mods.Parser{ // .bytes = all, // .byte_idx = 0, // .allocator = allocator, diff --git a/src/mods/Parser.zig b/src/mods/Parser.zig index 29f18d8..d9f7ccf 100644 --- a/src/mods/Parser.zig +++ b/src/mods/Parser.zig @@ -144,7 +144,7 @@ fn parseReftype(self: *Parser) !std.wasm.RefType { // NOTE: Parsing of Valtype can be improved but it makes it less close to spec so... // TODO: Do we really need Valtype? -const Valtype = union(enum) { +pub const Valtype = union(enum) { val: std.wasm.Valtype, ref: std.wasm.RefType, }; 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, + +}; + diff --git a/src/mods/mods.zig b/src/mods/mods.zig new file mode 100644 index 0000000..9d845e1 --- /dev/null +++ b/src/mods/mods.zig @@ -0,0 +1,5 @@ +pub const Parser = @import("Parser.zig"); +pub const VM = @import("vm.zig"); +// TODO: is this really needed? +pub const Wasm = @import("wasm.zig"); +pub const IR = @import("ir.zig"); |