diff --git a/compiler/gen_wasm/src/function_builder.rs b/compiler/gen_wasm/src/function_builder.rs index 4efcde3c04..2219ce8585 100644 --- a/compiler/gen_wasm/src/function_builder.rs +++ b/compiler/gen_wasm/src/function_builder.rs @@ -14,14 +14,14 @@ const DEBUG_LOG: bool = false; #[repr(u8)] #[derive(PartialEq, Eq, Clone, Copy)] -enum ValueType { +pub enum ValueType { I32 = 0x7f, I64 = 0x7e, F32 = 0x7d, F64 = 0x7c, } -enum BlockType { +pub enum BlockType { NoResult, Value(ValueType), } @@ -36,52 +36,32 @@ impl BlockType { } #[repr(u8)] -enum Align { +pub enum Align { Bytes1 = 0, Bytes2 = 1, Bytes4 = 2, Bytes8 = 3, + Bytes16 = 4, + Bytes32 = 5, + Bytes64 = 6, + // ... we can add more if we need them ... } -// macro_rules! instruction_method { -// ($method_name: ident, $pops: expr, $push: expr, $opcode: expr) => { -// pub fn $name(&mut self) { -// self.inst($pops, $push, $opcode); -// } -// }; -// } +macro_rules! instruction_method { + ($method_name: ident, $pops: expr, $push: expr, $opcode: expr) => { + pub fn $method_name(&mut self) { + self.inst($pops, $push, $opcode); + } + }; +} -// macro_rules! binop_method { -// ($method_name: ident, $opcode: expr) => { -// pub fn $name(&mut self) { -// self.inst(2, true, $opcode); -// } -// }; -// } - -// macro_rules! unop_method { -// ($method_name: ident, $opcode: expr) => { -// pub fn $name(&mut self) { -// self.inst(1, true, $opcode); -// } -// }; -// } - -// macro_rules! mem_method { -// ($method_name: ident, $pops: expr, $push: expr, $opcode: expr) => { -// pub fn $name(&mut self) { -// self.inst($pops, $push, $opcode); -// } -// }; -// } - -// macro_rules! instruction_method { -// ($method_name: ident, $pops: expr, $push: expr, $opcode: expr) => { -// pub fn $name(&mut self) { -// self.inst($pops, $push, $opcode); -// } -// }; -// } +macro_rules! instruction_method_mem { + ($method_name: ident, $pops: expr, $push: expr, $opcode: expr) => { + pub fn $method_name(&mut self, align: Align, offset: u32) { + self.inst_mem($pops, $push, $opcode, align, offset); + } + }; +} #[derive(Debug)] pub struct FunctionBuilder<'a> { @@ -205,7 +185,7 @@ impl<'a> FunctionBuilder<'a> { } /// Finalize a function body - pub fn finalize(&mut self, final_code: &mut std::vec::Vec) { + pub fn finalize(&mut self, _final_code: &mut std::vec::Vec) { // sort insertions // encode local declarations // encode stack frame push @@ -214,7 +194,7 @@ impl<'a> FunctionBuilder<'a> { // encode inner length } - pub fn serialize(&self, writer: W) { + pub fn serialize(&self, _writer: W) { // write inner length // write locals // write stack frame push @@ -247,197 +227,224 @@ impl<'a> FunctionBuilder<'a> { } fn inst(&mut self, pops: usize, push: bool, opcode: u8) { - panic!("TODO"); + let new_len = self.vm_stack.len() - pops as usize; + self.vm_stack.truncate(new_len); + if push { + self.vm_stack.push(Symbol::WASM_ANONYMOUS_STACK_VALUE); + } + self.code.push(opcode); } fn inst_imm8(&mut self, pops: usize, push: bool, opcode: u8, immediate: u8) { - panic!("TODO"); + self.inst(pops, push, opcode); + self.code.push(immediate); } fn inst_imm32(&mut self, pops: usize, push: bool, opcode: u8, immediate: u32) { - panic!("TODO"); + self.inst(pops, push, opcode); + let mut value = immediate; + while value >= 0x80 { + self.code.push(0x80 | ((value & 0x7f) as u8)); + value >>= 7; + } + self.code.push(value as u8); } fn inst_imm64(&mut self, pops: usize, push: bool, opcode: u8, immediate: u64) { - panic!("TODO"); + self.inst(pops, push, opcode); + let mut value = immediate; + while value >= 0x80 { + self.code.push(0x80 | ((value & 0x7f) as u8)); + value >>= 7; + } + self.code.push(value as u8); } fn inst_mem(&mut self, pops: usize, push: bool, opcode: u8, align: Align, offset: u32) { - panic!("TODO"); + self.inst(pops, push, opcode); + self.code.push(align as u8); + let mut value = offset; + while value >= 0x80 { + self.code.push(0x80 | ((value & 0x7f) as u8)); + value >>= 7; + } + self.code.push(value as u8); } - pub fn unreachable(&mut self) { - self.inst(0, false, UNREACHABLE); - } - // pub fn nop(&mut self) { self.inst(0, false, NOP); } + // Instruction methods + // One method for each Wasm instruction, ordered as in the spec and in parity-wasm + // macros are just to improve readability for the most common cases + // Patterns that don't repeat very much don't have macros + instruction_method!(unreachable_, 0, false, UNREACHABLE); + instruction_method!(nop, 0, false, NOP); // pub fn block(ty: BlockType) { self.inst_imm8(0, false, BLOCK, ty as u8); } // pub fn loop_(ty: BlockType) { self.inst_imm8(0, false, LOOP, ty as u8); } // pub fn if_(ty: BlockType) { self.inst_imm8(1, false, IF, ty as u8); } - // pub fn else_(&mut self) { self.inst(0, false, ELSE); } - // pub fn end(&mut self) { self.inst(0, false, END); } - // pub fn br(levels: u32) { self.inst_imm32(0, false, BR, levels); } - // pub fn br_if(levels: u32) { self.inst_imm32(1, false, BRIF, levels); } - // // br_table: not implemented - // pub fn return_(&mut self) { self.inst(0, false, RETURN); } - // // call: see above - // // call_indirect: not implemented - // pub fn drop(&mut self) { self.inst(1, false, DROP); } - // pub fn select(&mut self) { self.inst(3, true, SELECT); } - // pub fn get_local(&mut self, id: LocalId) { self.inst_imm32(0, true, GETLOCAL, id.0); } - // pub fn set_local(&mut self, id: LocalId) { self.inst_imm32(1, false, SETLOCAL, id.0); } - // pub fn tee_local(&mut self, id: LocalId) { self.inst_imm32(1, true, TEELOCAL, id.0); } - // pub fn get_global(&mut self, id: u32) { self.inst_imm32(0, true, GETGLOBAL, id); } - // pub fn set_global(&mut self, id: u32) { self.inst_imm32(1, false, SETGLOBAL, id); } - // pub fn i32_load(&mut self, align: Align, offset: u32) { self.inst_mem(1, true, I32LOAD, align, offset); } - // pub fn i64_load(&mut self, align: Align, offset: u32) { self.inst_mem(1, true, I64LOAD, align, offset); } - // pub fn f32_load(&mut self, align: Align, offset: u32) { self.inst_mem(1, true, F32LOAD, align, offset); } - // pub fn f64_load(&mut self, align: Align, offset: u32) { self.inst_mem(1, true, F64LOAD, align, offset); } - // pub fn i32_load8_s(&mut self, align: Align, offset: u32) { self.inst_mem(1, true, I32LOAD8S, align, offset); } - // pub fn i32_load8_u(&mut self, align: Align, offset: u32) { self.inst_mem(1, true, I32LOAD8U, align, offset); } - // pub fn i32_load16_s(&mut self, align: Align, offset: u32) { self.inst_mem(1, true, I32LOAD16S, align, offset); } - // pub fn i32_load16_u(&mut self, align: Align, offset: u32) { self.inst_mem(1, true, I32LOAD16U, align, offset); } - // pub fn i64_load8_s(&mut self, align: Align, offset: u32) { self.inst_mem(1, true, I64LOAD8S, align, offset); } - // pub fn i64_load8_u(&mut self, align: Align, offset: u32) { self.inst_mem(1, true, I64LOAD8U, align, offset); } - // pub fn i64_load16_s(&mut self, align: Align, offset: u32) { self.inst_mem(1, true, I64LOAD16S, align, offset); } - // pub fn i64_load16_u(&mut self, align: Align, offset: u32) { self.inst_mem(1, true, I64LOAD16U, align, offset); } - // pub fn i64_load32_s(&mut self, align: Align, offset: u32) { self.inst_mem(1, true, I64LOAD32S, align, offset); } - // pub fn i64_load32_u(&mut self, align: Align, offset: u32) { self.inst_mem(1, true, I64LOAD32U, align, offset); } - // pub fn i32_store(&mut self, align: Align, offset: u32) { self.inst_mem(2, false, I32STORE, align, offset); } - // pub fn i64_store(&mut self, align: Align, offset: u32) { self.inst_mem(2, false, I64STORE, align, offset); } - // pub fn f32_store(&mut self, align: Align, offset: u32) { self.inst_mem(2, false, F32STORE, align, offset); } - // pub fn f64_store(&mut self, align: Align, offset: u32) { self.inst_mem(2, false, F64STORE, align, offset); } - // pub fn i32_store8(&mut self, align: Align, offset: u32) { self.inst_mem(2, false, I32STORE8, align, offset); } - // pub fn i32_store16(&mut self, align: Align, offset: u32) { self.inst_mem(2, false, I32STORE16, align, offset); } - // pub fn i64_store8(&mut self, align: Align, offset: u32) { self.inst_mem(2, false, I64STORE8, align, offset); } - // pub fn i64_store16(&mut self, align: Align, offset: u32) { self.inst_mem(2, false, I64STORE16, align, offset); } - // pub fn i64_store32(&mut self, align: Align, offset: u32) { self.inst_mem(2, false, I64STORE32, align, offset); } - // pub fn memory_size(&mut self) { self.inst_imm8(0, true, CURRENTMEMORY, 0); } - // pub fn memory_grow(&mut self) { self.inst_imm8(1, true, GROWMEMORY, 0); } - // pub fn i32_const(&mut self, x: i32) { self.inst_imm32(0, true, I32CONST, x as u32); } - // pub fn i64_const(&mut self, x: i64) { self.inst_imm64(0, true, I64CONST, x as u64); } - // pub fn f32_const(&mut self, x: f32) { self.inst_imm32(0, true, F32CONST, x.to_bits()); } - // pub fn f64_const(&mut self, x: f64) { self.inst_imm64(0, true, F64CONST, x.to_bits()); } - // pub fn i32_eqz(&mut self) { self.inst(1, true, I32EQZ); } - // pub fn i32_eq(&mut self) { self.inst(2, true, I32EQ); } - // pub fn i32_ne(&mut self) { self.inst(2, true, I32NE); } - // pub fn i32_lt_s(&mut self) { self.inst(2, true, I32LTS); } - // pub fn i32_lt_u(&mut self) { self.inst(2, true, I32LTU); } - // pub fn i32_gt_s(&mut self) { self.inst(2, true, I32GTS); } - // pub fn i32_gt_u(&mut self) { self.inst(2, true, I32GTU); } - // pub fn i32_le_s(&mut self) { self.inst(2, true, I32LES); } - // pub fn i32_le_u(&mut self) { self.inst(2, true, I32LEU); } - // pub fn i32_ge_s(&mut self) { self.inst(2, true, I32GES); } - // pub fn i32_ge_u(&mut self) { self.inst(2, true, I32GEU); } - // pub fn i64_eqz(&mut self) { self.inst(1, true, I64EQZ); } - // pub fn i64_eq(&mut self) { self.inst(2, true, I64EQ); } - // pub fn i64_ne(&mut self) { self.inst(2, true, I64NE); } - // pub fn i64_lt_s(&mut self) { self.inst(2, true, I64LTS); } - // pub fn i64_lt_u(&mut self) { self.inst(2, true, I64LTU); } - // pub fn i64_gt_s(&mut self) { self.inst(2, true, I64GTS); } - // pub fn i64_gt_u(&mut self) { self.inst(2, true, I64GTU); } - // pub fn i64_le_s(&mut self) { self.inst(2, true, I64LES); } - // pub fn i64_le_u(&mut self) { self.inst(2, true, I64LEU); } - // pub fn i64_ge_s(&mut self) { self.inst(2, true, I64GES); } - // pub fn i64_ge_u(&mut self) { self.inst(2, true, I64GEU); } - // pub fn f32_eq(&mut self) { self.inst(2, true, F32EQ); } - // pub fn f32_ne(&mut self) { self.inst(2, true, F32NE); } - // pub fn f32_lt(&mut self) { self.inst(2, true, F32LT); } - // pub fn f32_gt(&mut self) { self.inst(2, true, F32GT); } - // pub fn f32_le(&mut self) { self.inst(2, true, F32LE); } - // pub fn f32_ge(&mut self) { self.inst(2, true, F32GE); } - // pub fn f64_eq(&mut self) { self.inst(2, true, F64EQ); } - // pub fn f64_ne(&mut self) { self.inst(2, true, F64NE); } - // pub fn f64_lt(&mut self) { self.inst(2, true, F64LT); } - // pub fn f64_gt(&mut self) { self.inst(2, true, F64GT); } - // pub fn f64_le(&mut self) { self.inst(2, true, F64LE); } - // pub fn f64_ge(&mut self) { self.inst(2, true, F64GE); } - // pub fn i32_clz(&mut self) { self.inst(1, true, I32CLZ); } - // pub fn i32_ctz(&mut self) { self.inst(1, true, I32CTZ); } - // pub fn i32_popcnt(&mut self) { self.inst(1, true, I32POPCNT); } - // pub fn i32_add(&mut self) { self.inst(2, true, I32ADD); } - // pub fn i32_sub(&mut self) { self.inst(2, true, I32SUB); } - // pub fn i32_mul(&mut self) { self.inst(2, true, I32MUL); } - // pub fn i32_div_s(&mut self) { self.inst(2, true, I32DIVS); } - // pub fn i32_div_u(&mut self) { self.inst(2, true, I32DIVU); } - // pub fn i32_rem_s(&mut self) { self.inst(2, true, I32REMS); } - // pub fn i32_rem_u(&mut self) { self.inst(2, true, I32REMU); } - // pub fn i32_and(&mut self) { self.inst(2, true, I32AND); } - // pub fn i32_or(&mut self) { self.inst(2, true, I32OR); } - // pub fn i32_xor(&mut self) { self.inst(2, true, I32XOR); } - // pub fn i32_shl(&mut self) { self.inst(2, true, I32SHL); } - // pub fn i32_shr_s(&mut self) { self.inst(2, true, I32SHRS); } - // pub fn i32_shr_u(&mut self) { self.inst(2, true, I32SHRU); } - // pub fn i32_rotl(&mut self) { self.inst(2, true, I32ROTL); } - // pub fn i32_rotr(&mut self) { self.inst(2, true, I32ROTR); } - // pub fn i64_clz(&mut self) { self.inst(1, true, I64CLZ); } - // pub fn i64_ctz(&mut self) { self.inst(1, true, I64CTZ); } - // pub fn i64_popcnt(&mut self) { self.inst(1, true, I64POPCNT); } - // pub fn i64_add(&mut self) { self.inst(2, true, I64ADD); } - // pub fn i64_sub(&mut self) { self.inst(2, true, I64SUB); } - // pub fn i64_mul(&mut self) { self.inst(2, true, I64MUL); } - // pub fn i64_div_s(&mut self) { self.inst(2, true, I64DIVS); } - // pub fn i64_div_u(&mut self) { self.inst(2, true, I64DIVU); } - // pub fn i64_rem_s(&mut self) { self.inst(2, true, I64REMS); } - // pub fn i64_rem_u(&mut self) { self.inst(2, true, I64REMU); } - // pub fn i64_and(&mut self) { self.inst(2, true, I64AND); } - // pub fn i64_or(&mut self) { self.inst(2, true, I64OR); } - // pub fn i64_xor(&mut self) { self.inst(2, true, I64XOR); } - // pub fn i64_shl(&mut self) { self.inst(2, true, I64SHL); } - // pub fn i64_shr_s(&mut self) { self.inst(2, true, I64SHRS); } - // pub fn i64_shr_u(&mut self) { self.inst(2, true, I64SHRU); } - // pub fn i64_rotl(&mut self) { self.inst(2, true, I64ROTL); } - // pub fn i64_rotr(&mut self) { self.inst(2, true, I64ROTR); } - // pub fn f32_abs(&mut self) { self.inst(1, true, F32ABS); } - // pub fn f32_neg(&mut self) { self.inst(1, true, F32NEG); } - // pub fn f32_ceil(&mut self) { self.inst(1, true, F32CEIL); } - // pub fn f32_floor(&mut self) { self.inst(1, true, F32FLOOR); } - // pub fn f32_trunc(&mut self) { self.inst(1, true, F32TRUNC); } - // pub fn f32_nearest(&mut self) { self.inst(1, true, F32NEAREST); } - // pub fn f32_sqrt(&mut self) { self.inst(1, true, F32SQRT); } - // pub fn f32_add(&mut self) { self.inst(2, true, F32ADD); } - // pub fn f32_sub(&mut self) { self.inst(2, true, F32SUB); } - // pub fn f32_mul(&mut self) { self.inst(2, true, F32MUL); } - // pub fn f32_div(&mut self) { self.inst(2, true, F32DIV); } - // pub fn f32_min(&mut self) { self.inst(2, true, F32MIN); } - // pub fn f32_max(&mut self) { self.inst(2, true, F32MAX); } - // pub fn f32_copysign(&mut self) { self.inst(2, true, F32COPYSIGN); } - // pub fn f64_abs(&mut self) { self.inst(1, true, F64ABS); } - // pub fn f64_neg(&mut self) { self.inst(1, true, F64NEG); } - // pub fn f64_ceil(&mut self) { self.inst(1, true, F64CEIL); } - // pub fn f64_floor(&mut self) { self.inst(1, true, F64FLOOR); } - // pub fn f64_trunc(&mut self) { self.inst(1, true, F64TRUNC); } - // pub fn f64_nearest(&mut self) { self.inst(1, true, F64NEAREST); } - // pub fn f64_sqrt(&mut self) { self.inst(1, true, F64SQRT); } - // pub fn f64_add(&mut self) { self.inst(2, true, F64ADD); } - // pub fn f64_sub(&mut self) { self.inst(2, true, F64SUB); } - // pub fn f64_mul(&mut self) { self.inst(2, true, F64MUL); } - // pub fn f64_div(&mut self) { self.inst(2, true, F64DIV); } - // pub fn f64_min(&mut self) { self.inst(2, true, F64MIN); } - // pub fn f64_max(&mut self) { self.inst(2, true, F64MAX); } - // pub fn f64_copysign(&mut self) { self.inst(2, true, F64COPYSIGN); } - // pub fn i32_wrap_i64(&mut self) { self.inst(1, true, I32WRAPI64); } - // pub fn i32_trunc_s_f32(&mut self) { self.inst(1, true, I32TRUNCSF32); } - // pub fn i32_trunc_u_f32(&mut self) { self.inst(1, true, I32TRUNCUF32); } - // pub fn i32_trunc_s_f64(&mut self) { self.inst(1, true, I32TRUNCSF64); } - // pub fn i32_trunc_u_f64(&mut self) { self.inst(1, true, I32TRUNCUF64); } - // pub fn i64_extend_s_i32(&mut self) { self.inst(1, true, I64EXTENDSI32); } - // pub fn i64_extend_u_i32(&mut self) { self.inst(1, true, I64EXTENDUI32); } - // pub fn i64_trunc_s_f32(&mut self) { self.inst(1, true, I64TRUNCSF32); } - // pub fn i64_trunc_u_f32(&mut self) { self.inst(1, true, I64TRUNCUF32); } - // pub fn i64_trunc_s_f64(&mut self) { self.inst(1, true, I64TRUNCSF64); } - // pub fn i64_trunc_u_f64(&mut self) { self.inst(1, true, I64TRUNCUF64); } - // pub fn f32_convert_s_i32(&mut self) { self.inst(1, true, F32CONVERTSI32); } - // pub fn f32_convert_u_i32(&mut self) { self.inst(1, true, F32CONVERTUI32); } - // pub fn f32_convert_s_i64(&mut self) { self.inst(1, true, F32CONVERTSI64); } - // pub fn f32_convert_u_i64(&mut self) { self.inst(1, true, F32CONVERTUI64); } - // pub fn f32_demote_f64(&mut self) { self.inst(1, true, F32DEMOTEF64); } - // pub fn f64_convert_s_i32(&mut self) { self.inst(1, true, F64CONVERTSI32); } - // pub fn f64_convert_u_i32(&mut self) { self.inst(1, true, F64CONVERTUI32); } - // pub fn f64_convert_s_i64(&mut self) { self.inst(1, true, F64CONVERTSI64); } - // pub fn f64_convert_u_i64(&mut self) { self.inst(1, true, F64CONVERTUI64); } - // pub fn f64_promote_f32(&mut self) { self.inst(1, true, F64PROMOTEF32); } - // pub fn i32_reinterpret_f32(&mut self) { self.inst(1, true, I32REINTERPRETF32); } - // pub fn i64_reinterpret_f64(&mut self) { self.inst(1, true, I64REINTERPRETF64); } - // pub fn f32_reinterpret_i32(&mut self) { self.inst(1, true, F32REINTERPRETI32); } - // pub fn f64_reinterpret_i64(&mut self) { self.inst(1, true, F64REINTERPRETI64); } + instruction_method!(else_, 0, false, ELSE); + instruction_method!(end, 0, false, END); + // instruction_method!(br(levels: u32) { self.inst_imm32(0, false, BR, levels); + // instruction_method!(br_if(levels: u32) { self.inst_imm32(1, false, BRIF, levels); + // br_table: not implemented + instruction_method!(return_, 0, false, RETURN); + // call: see above + // call_indirect: not implemented + instruction_method!(drop, 1, false, DROP); + instruction_method!(select, 3, true, SELECT); + // instruction_method!(get_local(&mut self, id: LocalId) { self.inst_imm32(0, true, GETLOCAL, id.0); + // instruction_method!(set_local(&mut self, id: LocalId) { self.inst_imm32(1, false, SETLOCAL, id.0); + // instruction_method!(tee_local(&mut self, id: LocalId) { self.inst_imm32(1, true, TEELOCAL, id.0); + // instruction_method!(get_global(&mut self, id: u32) { self.inst_imm32(0, true, GETGLOBAL, id); + // instruction_method!(set_global(&mut self, id: u32) { self.inst_imm32(1, false, SETGLOBAL, id); + instruction_method_mem!(i32_load, 1, true, I32LOAD); + instruction_method_mem!(i64_load, 1, true, I64LOAD); + instruction_method_mem!(f32_load, 1, true, F32LOAD); + instruction_method_mem!(f64_load, 1, true, F64LOAD); + instruction_method_mem!(i32_load8_s, 1, true, I32LOAD8S); + instruction_method_mem!(i32_load8_u, 1, true, I32LOAD8U); + instruction_method_mem!(i32_load16_s, 1, true, I32LOAD16S); + instruction_method_mem!(i32_load16_u, 1, true, I32LOAD16U); + instruction_method_mem!(i64_load8_s, 1, true, I64LOAD8S); + instruction_method_mem!(i64_load8_u, 1, true, I64LOAD8U); + instruction_method_mem!(i64_load16_s, 1, true, I64LOAD16S); + instruction_method_mem!(i64_load16_u, 1, true, I64LOAD16U); + instruction_method_mem!(i64_load32_s, 1, true, I64LOAD32S); + instruction_method_mem!(i64_load32_u, 1, true, I64LOAD32U); + instruction_method_mem!(i32_store, 2, false, I32STORE); + instruction_method_mem!(i64_store, 2, false, I64STORE); + instruction_method_mem!(f32_store, 2, false, F32STORE); + instruction_method_mem!(f64_store, 2, false, F64STORE); + instruction_method_mem!(i32_store8, 2, false, I32STORE8); + instruction_method_mem!(i32_store16, 2, false, I32STORE16); + instruction_method_mem!(i64_store8, 2, false, I64STORE8); + instruction_method_mem!(i64_store16, 2, false, I64STORE16); + instruction_method_mem!(i64_store32, 2, false, I64STORE32); + // instruction_method!(memory_size(&mut self) { self.inst_imm8(0, true, CURRENTMEMORY, 0); + // instruction_method!(memory_grow(&mut self) { self.inst_imm8(1, true, GROWMEMORY, 0); + // instruction_method!(i32_const(&mut self, x: i32) { self.inst_imm32(0, true, I32CONST, x as u32); + // instruction_method!(i64_const(&mut self, x: i64) { self.inst_imm64(0, true, I64CONST, x as u64); + // instruction_method!(f32_const(&mut self, x: f32) { self.inst_imm32(0, true, F32CONST, x.to_bits()); + // instruction_method!(f64_const(&mut self, x: f64) { self.inst_imm64(0, true, F64CONST, x.to_bits()); + instruction_method!(i32_eqz, 1, true, I32EQZ); + instruction_method!(i32_eq, 2, true, I32EQ); + instruction_method!(i32_ne, 2, true, I32NE); + instruction_method!(i32_lt_s, 2, true, I32LTS); + instruction_method!(i32_lt_u, 2, true, I32LTU); + instruction_method!(i32_gt_s, 2, true, I32GTS); + instruction_method!(i32_gt_u, 2, true, I32GTU); + instruction_method!(i32_le_s, 2, true, I32LES); + instruction_method!(i32_le_u, 2, true, I32LEU); + instruction_method!(i32_ge_s, 2, true, I32GES); + instruction_method!(i32_ge_u, 2, true, I32GEU); + instruction_method!(i64_eqz, 1, true, I64EQZ); + instruction_method!(i64_eq, 2, true, I64EQ); + instruction_method!(i64_ne, 2, true, I64NE); + instruction_method!(i64_lt_s, 2, true, I64LTS); + instruction_method!(i64_lt_u, 2, true, I64LTU); + instruction_method!(i64_gt_s, 2, true, I64GTS); + instruction_method!(i64_gt_u, 2, true, I64GTU); + instruction_method!(i64_le_s, 2, true, I64LES); + instruction_method!(i64_le_u, 2, true, I64LEU); + instruction_method!(i64_ge_s, 2, true, I64GES); + instruction_method!(i64_ge_u, 2, true, I64GEU); + instruction_method!(f32_eq, 2, true, F32EQ); + instruction_method!(f32_ne, 2, true, F32NE); + instruction_method!(f32_lt, 2, true, F32LT); + instruction_method!(f32_gt, 2, true, F32GT); + instruction_method!(f32_le, 2, true, F32LE); + instruction_method!(f32_ge, 2, true, F32GE); + instruction_method!(f64_eq, 2, true, F64EQ); + instruction_method!(f64_ne, 2, true, F64NE); + instruction_method!(f64_lt, 2, true, F64LT); + instruction_method!(f64_gt, 2, true, F64GT); + instruction_method!(f64_le, 2, true, F64LE); + instruction_method!(f64_ge, 2, true, F64GE); + instruction_method!(i32_clz, 1, true, I32CLZ); + instruction_method!(i32_ctz, 1, true, I32CTZ); + instruction_method!(i32_popcnt, 1, true, I32POPCNT); + instruction_method!(i32_add, 2, true, I32ADD); + instruction_method!(i32_sub, 2, true, I32SUB); + instruction_method!(i32_mul, 2, true, I32MUL); + instruction_method!(i32_div_s, 2, true, I32DIVS); + instruction_method!(i32_div_u, 2, true, I32DIVU); + instruction_method!(i32_rem_s, 2, true, I32REMS); + instruction_method!(i32_rem_u, 2, true, I32REMU); + instruction_method!(i32_and, 2, true, I32AND); + instruction_method!(i32_or, 2, true, I32OR); + instruction_method!(i32_xor, 2, true, I32XOR); + instruction_method!(i32_shl, 2, true, I32SHL); + instruction_method!(i32_shr_s, 2, true, I32SHRS); + instruction_method!(i32_shr_u, 2, true, I32SHRU); + instruction_method!(i32_rotl, 2, true, I32ROTL); + instruction_method!(i32_rotr, 2, true, I32ROTR); + instruction_method!(i64_clz, 1, true, I64CLZ); + instruction_method!(i64_ctz, 1, true, I64CTZ); + instruction_method!(i64_popcnt, 1, true, I64POPCNT); + instruction_method!(i64_add, 2, true, I64ADD); + instruction_method!(i64_sub, 2, true, I64SUB); + instruction_method!(i64_mul, 2, true, I64MUL); + instruction_method!(i64_div_s, 2, true, I64DIVS); + instruction_method!(i64_div_u, 2, true, I64DIVU); + instruction_method!(i64_rem_s, 2, true, I64REMS); + instruction_method!(i64_rem_u, 2, true, I64REMU); + instruction_method!(i64_and, 2, true, I64AND); + instruction_method!(i64_or, 2, true, I64OR); + instruction_method!(i64_xor, 2, true, I64XOR); + instruction_method!(i64_shl, 2, true, I64SHL); + instruction_method!(i64_shr_s, 2, true, I64SHRS); + instruction_method!(i64_shr_u, 2, true, I64SHRU); + instruction_method!(i64_rotl, 2, true, I64ROTL); + instruction_method!(i64_rotr, 2, true, I64ROTR); + instruction_method!(f32_abs, 1, true, F32ABS); + instruction_method!(f32_neg, 1, true, F32NEG); + instruction_method!(f32_ceil, 1, true, F32CEIL); + instruction_method!(f32_floor, 1, true, F32FLOOR); + instruction_method!(f32_trunc, 1, true, F32TRUNC); + instruction_method!(f32_nearest, 1, true, F32NEAREST); + instruction_method!(f32_sqrt, 1, true, F32SQRT); + instruction_method!(f32_add, 2, true, F32ADD); + instruction_method!(f32_sub, 2, true, F32SUB); + instruction_method!(f32_mul, 2, true, F32MUL); + instruction_method!(f32_div, 2, true, F32DIV); + instruction_method!(f32_min, 2, true, F32MIN); + instruction_method!(f32_max, 2, true, F32MAX); + instruction_method!(f32_copysign, 2, true, F32COPYSIGN); + instruction_method!(f64_abs, 1, true, F64ABS); + instruction_method!(f64_neg, 1, true, F64NEG); + instruction_method!(f64_ceil, 1, true, F64CEIL); + instruction_method!(f64_floor, 1, true, F64FLOOR); + instruction_method!(f64_trunc, 1, true, F64TRUNC); + instruction_method!(f64_nearest, 1, true, F64NEAREST); + instruction_method!(f64_sqrt, 1, true, F64SQRT); + instruction_method!(f64_add, 2, true, F64ADD); + instruction_method!(f64_sub, 2, true, F64SUB); + instruction_method!(f64_mul, 2, true, F64MUL); + instruction_method!(f64_div, 2, true, F64DIV); + instruction_method!(f64_min, 2, true, F64MIN); + instruction_method!(f64_max, 2, true, F64MAX); + instruction_method!(f64_copysign, 2, true, F64COPYSIGN); + instruction_method!(i32_wrap_i64, 1, true, I32WRAPI64); + instruction_method!(i32_trunc_s_f32, 1, true, I32TRUNCSF32); + instruction_method!(i32_trunc_u_f32, 1, true, I32TRUNCUF32); + instruction_method!(i32_trunc_s_f64, 1, true, I32TRUNCSF64); + instruction_method!(i32_trunc_u_f64, 1, true, I32TRUNCUF64); + instruction_method!(i64_extend_s_i32, 1, true, I64EXTENDSI32); + instruction_method!(i64_extend_u_i32, 1, true, I64EXTENDUI32); + instruction_method!(i64_trunc_s_f32, 1, true, I64TRUNCSF32); + instruction_method!(i64_trunc_u_f32, 1, true, I64TRUNCUF32); + instruction_method!(i64_trunc_s_f64, 1, true, I64TRUNCSF64); + instruction_method!(i64_trunc_u_f64, 1, true, I64TRUNCUF64); + instruction_method!(f32_convert_s_i32, 1, true, F32CONVERTSI32); + instruction_method!(f32_convert_u_i32, 1, true, F32CONVERTUI32); + instruction_method!(f32_convert_s_i64, 1, true, F32CONVERTSI64); + instruction_method!(f32_convert_u_i64, 1, true, F32CONVERTUI64); + instruction_method!(f32_demote_f64, 1, true, F32DEMOTEF64); + instruction_method!(f64_convert_s_i32, 1, true, F64CONVERTSI32); + instruction_method!(f64_convert_u_i32, 1, true, F64CONVERTUI32); + instruction_method!(f64_convert_s_i64, 1, true, F64CONVERTSI64); + instruction_method!(f64_convert_u_i64, 1, true, F64CONVERTUI64); + instruction_method!(f64_promote_f32, 1, true, F64PROMOTEF32); + instruction_method!(i32_reinterpret_f32, 1, true, I32REINTERPRETF32); + instruction_method!(i64_reinterpret_f64, 1, true, I64REINTERPRETF64); + instruction_method!(f32_reinterpret_i32, 1, true, F32REINTERPRETI32); + instruction_method!(f64_reinterpret_i64, 1, true, F64REINTERPRETI64); } diff --git a/compiler/gen_wasm/src/lib.rs b/compiler/gen_wasm/src/lib.rs index e11d2f4b30..72b23d0565 100644 --- a/compiler/gen_wasm/src/lib.rs +++ b/compiler/gen_wasm/src/lib.rs @@ -1,11 +1,15 @@ mod backend; mod code_builder; pub mod from_wasm32_memory; -mod function_builder; mod layout; -mod opcodes; mod storage; +#[allow(dead_code)] +mod function_builder; + +#[allow(dead_code)] +mod opcodes; + use bumpalo::collections::Vec; use bumpalo::Bump; use parity_wasm::builder;