mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 00:24:34 +00:00
wasm_interp: implement remaining i32 ops
This commit is contained in:
parent
ae2e561945
commit
f7dcd8f421
1 changed files with 170 additions and 38 deletions
|
@ -646,22 +646,72 @@ impl<'a> ExecutionState<'a> {
|
||||||
self.value_stack.push(Value::F64(value));
|
self.value_stack.push(Value::F64(value));
|
||||||
self.program_counter += 8;
|
self.program_counter += 8;
|
||||||
}
|
}
|
||||||
I32EQZ => todo!("{:?} @ {:#x}", op_code, file_offset),
|
I32EQZ => {
|
||||||
I32EQ => todo!("{:?} @ {:#x}", op_code, file_offset),
|
let arg = self.value_stack.pop_i32();
|
||||||
I32NE => todo!("{:?} @ {:#x}", op_code, file_offset),
|
let result: bool = arg == 0;
|
||||||
I32LTS => {
|
|
||||||
let second = self.value_stack.pop_i32();
|
|
||||||
let first = self.value_stack.pop_i32();
|
|
||||||
let result: bool = first < second;
|
|
||||||
self.value_stack.push(Value::I32(result as i32));
|
self.value_stack.push(Value::I32(result as i32));
|
||||||
}
|
}
|
||||||
I32LTU => todo!("{:?} @ {:#x}", op_code, file_offset),
|
I32EQ => {
|
||||||
I32GTS => todo!("{:?} @ {:#x}", op_code, file_offset),
|
let arg2 = self.value_stack.pop_i32();
|
||||||
I32GTU => todo!("{:?} @ {:#x}", op_code, file_offset),
|
let arg1 = self.value_stack.pop_i32();
|
||||||
I32LES => todo!("{:?} @ {:#x}", op_code, file_offset),
|
let result: bool = arg1 == arg2;
|
||||||
I32LEU => todo!("{:?} @ {:#x}", op_code, file_offset),
|
self.value_stack.push(Value::I32(result as i32));
|
||||||
I32GES => todo!("{:?} @ {:#x}", op_code, file_offset),
|
}
|
||||||
I32GEU => todo!("{:?} @ {:#x}", op_code, file_offset),
|
I32NE => {
|
||||||
|
let arg2 = self.value_stack.pop_i32();
|
||||||
|
let arg1 = self.value_stack.pop_i32();
|
||||||
|
let result: bool = arg1 != arg2;
|
||||||
|
self.value_stack.push(Value::I32(result as i32));
|
||||||
|
}
|
||||||
|
I32LTS => {
|
||||||
|
let arg2 = self.value_stack.pop_i32();
|
||||||
|
let arg1 = self.value_stack.pop_i32();
|
||||||
|
let result: bool = arg1 < arg2;
|
||||||
|
self.value_stack.push(Value::I32(result as i32));
|
||||||
|
}
|
||||||
|
I32LTU => {
|
||||||
|
let arg2 = self.value_stack.pop_u32();
|
||||||
|
let arg1 = self.value_stack.pop_u32();
|
||||||
|
let result: bool = arg1 < arg2;
|
||||||
|
self.value_stack.push(Value::I32(result as i32));
|
||||||
|
}
|
||||||
|
I32GTS => {
|
||||||
|
let arg2 = self.value_stack.pop_i32();
|
||||||
|
let arg1 = self.value_stack.pop_i32();
|
||||||
|
let result: bool = arg1 > arg2;
|
||||||
|
self.value_stack.push(Value::I32(result as i32));
|
||||||
|
}
|
||||||
|
I32GTU => {
|
||||||
|
let arg2 = self.value_stack.pop_u32();
|
||||||
|
let arg1 = self.value_stack.pop_u32();
|
||||||
|
let result: bool = arg1 > arg2;
|
||||||
|
self.value_stack.push(Value::I32(result as i32));
|
||||||
|
}
|
||||||
|
I32LES => {
|
||||||
|
let arg2 = self.value_stack.pop_i32();
|
||||||
|
let arg1 = self.value_stack.pop_i32();
|
||||||
|
let result: bool = arg1 <= arg2;
|
||||||
|
self.value_stack.push(Value::I32(result as i32));
|
||||||
|
}
|
||||||
|
I32LEU => {
|
||||||
|
let arg2 = self.value_stack.pop_u32();
|
||||||
|
let arg1 = self.value_stack.pop_u32();
|
||||||
|
let result: bool = arg1 <= arg2;
|
||||||
|
self.value_stack.push(Value::I32(result as i32));
|
||||||
|
}
|
||||||
|
I32GES => {
|
||||||
|
let arg2 = self.value_stack.pop_i32();
|
||||||
|
let arg1 = self.value_stack.pop_i32();
|
||||||
|
let result: bool = arg1 >= arg2;
|
||||||
|
self.value_stack.push(Value::I32(result as i32));
|
||||||
|
}
|
||||||
|
I32GEU => {
|
||||||
|
let arg2 = self.value_stack.pop_u32();
|
||||||
|
let arg1 = self.value_stack.pop_u32();
|
||||||
|
let result: bool = arg1 >= arg2;
|
||||||
|
self.value_stack.push(Value::I32(result as i32));
|
||||||
|
}
|
||||||
|
|
||||||
I64EQZ => todo!("{:?} @ {:#x}", op_code, file_offset),
|
I64EQZ => todo!("{:?} @ {:#x}", op_code, file_offset),
|
||||||
I64EQ => todo!("{:?} @ {:#x}", op_code, file_offset),
|
I64EQ => todo!("{:?} @ {:#x}", op_code, file_offset),
|
||||||
I64NE => todo!("{:?} @ {:#x}", op_code, file_offset),
|
I64NE => todo!("{:?} @ {:#x}", op_code, file_offset),
|
||||||
|
@ -688,36 +738,116 @@ impl<'a> ExecutionState<'a> {
|
||||||
F64LE => todo!("{:?} @ {:#x}", op_code, file_offset),
|
F64LE => todo!("{:?} @ {:#x}", op_code, file_offset),
|
||||||
F64GE => todo!("{:?} @ {:#x}", op_code, file_offset),
|
F64GE => todo!("{:?} @ {:#x}", op_code, file_offset),
|
||||||
|
|
||||||
I32CLZ => todo!("{:?} @ {:#x}", op_code, file_offset),
|
I32CLZ => {
|
||||||
I32CTZ => todo!("{:?} @ {:#x}", op_code, file_offset),
|
let arg = self.value_stack.pop_u32();
|
||||||
I32POPCNT => todo!("{:?} @ {:#x}", op_code, file_offset),
|
self.value_stack
|
||||||
|
.push(Value::I32(arg.leading_zeros() as i32));
|
||||||
|
}
|
||||||
|
I32CTZ => {
|
||||||
|
let arg = self.value_stack.pop_u32();
|
||||||
|
self.value_stack
|
||||||
|
.push(Value::I32(arg.trailing_zeros() as i32));
|
||||||
|
}
|
||||||
|
I32POPCNT => {
|
||||||
|
let arg = self.value_stack.pop_u32();
|
||||||
|
self.value_stack.push(Value::I32(arg.count_ones() as i32));
|
||||||
|
}
|
||||||
I32ADD => {
|
I32ADD => {
|
||||||
let x = self.value_stack.pop_i32();
|
let arg2 = self.value_stack.pop_i32();
|
||||||
let y = self.value_stack.pop_i32();
|
let arg1 = self.value_stack.pop_i32();
|
||||||
self.value_stack.push(Value::I32(y + x));
|
self.value_stack.push(Value::I32(arg1 + arg2));
|
||||||
}
|
}
|
||||||
I32SUB => {
|
I32SUB => {
|
||||||
let x = self.value_stack.pop_i32();
|
let arg2 = self.value_stack.pop_i32();
|
||||||
let y = self.value_stack.pop_i32();
|
let arg1 = self.value_stack.pop_i32();
|
||||||
self.value_stack.push(Value::I32(y - x));
|
self.value_stack.push(Value::I32(arg1 - arg2));
|
||||||
}
|
}
|
||||||
I32MUL => {
|
I32MUL => {
|
||||||
let x = self.value_stack.pop_i32();
|
let arg2 = self.value_stack.pop_i32();
|
||||||
let y = self.value_stack.pop_i32();
|
let arg1 = self.value_stack.pop_i32();
|
||||||
self.value_stack.push(Value::I32(y * x));
|
self.value_stack.push(Value::I32(arg1 * arg2));
|
||||||
|
}
|
||||||
|
I32DIVS => {
|
||||||
|
let arg2 = self.value_stack.pop_i32();
|
||||||
|
let arg1 = self.value_stack.pop_i32();
|
||||||
|
self.value_stack.push(Value::I32(arg1 / arg2));
|
||||||
|
}
|
||||||
|
I32DIVU => {
|
||||||
|
let arg2 = self.value_stack.pop_u32();
|
||||||
|
let arg1 = self.value_stack.pop_u32();
|
||||||
|
let result: u32 = arg1 / arg2;
|
||||||
|
self.value_stack
|
||||||
|
.push(Value::I32(i32::from_ne_bytes(result.to_ne_bytes())));
|
||||||
|
}
|
||||||
|
I32REMS => {
|
||||||
|
let arg2 = self.value_stack.pop_i32();
|
||||||
|
let arg1 = self.value_stack.pop_i32();
|
||||||
|
self.value_stack.push(Value::I32(arg1 % arg2));
|
||||||
|
}
|
||||||
|
I32REMU => {
|
||||||
|
let arg2 = self.value_stack.pop_u32();
|
||||||
|
let arg1 = self.value_stack.pop_u32();
|
||||||
|
let result: u32 = arg1 % arg2;
|
||||||
|
self.value_stack
|
||||||
|
.push(Value::I32(i32::from_ne_bytes(result.to_ne_bytes())));
|
||||||
|
}
|
||||||
|
I32AND => {
|
||||||
|
let arg2 = self.value_stack.pop_u32();
|
||||||
|
let arg1 = self.value_stack.pop_u32();
|
||||||
|
let result: u32 = arg1 & arg2;
|
||||||
|
self.value_stack
|
||||||
|
.push(Value::I32(i32::from_ne_bytes(result.to_ne_bytes())));
|
||||||
|
}
|
||||||
|
I32OR => {
|
||||||
|
let arg2 = self.value_stack.pop_u32();
|
||||||
|
let arg1 = self.value_stack.pop_u32();
|
||||||
|
let result: u32 = arg1 | arg2;
|
||||||
|
self.value_stack
|
||||||
|
.push(Value::I32(i32::from_ne_bytes(result.to_ne_bytes())));
|
||||||
|
}
|
||||||
|
I32XOR => {
|
||||||
|
let arg2 = self.value_stack.pop_u32();
|
||||||
|
let arg1 = self.value_stack.pop_u32();
|
||||||
|
let result: u32 = arg1 ^ arg2;
|
||||||
|
self.value_stack
|
||||||
|
.push(Value::I32(i32::from_ne_bytes(result.to_ne_bytes())));
|
||||||
|
}
|
||||||
|
I32SHL => {
|
||||||
|
let arg2 = self.value_stack.pop_u32();
|
||||||
|
let arg1 = self.value_stack.pop_u32();
|
||||||
|
let k = arg2 % 32;
|
||||||
|
let result: u32 = arg1 << k;
|
||||||
|
self.value_stack
|
||||||
|
.push(Value::I32(i32::from_ne_bytes(result.to_ne_bytes())));
|
||||||
|
}
|
||||||
|
I32SHRS => {
|
||||||
|
let arg2 = self.value_stack.pop_i32();
|
||||||
|
let arg1 = self.value_stack.pop_i32();
|
||||||
|
let k = arg2 % 32;
|
||||||
|
self.value_stack.push(Value::I32(arg1 >> k));
|
||||||
|
}
|
||||||
|
I32SHRU => {
|
||||||
|
let arg2 = self.value_stack.pop_u32();
|
||||||
|
let arg1 = self.value_stack.pop_u32();
|
||||||
|
let k = arg2 % 32;
|
||||||
|
let result: u32 = arg1 >> k;
|
||||||
|
self.value_stack
|
||||||
|
.push(Value::I32(i32::from_ne_bytes(result.to_ne_bytes())));
|
||||||
|
}
|
||||||
|
I32ROTL => {
|
||||||
|
let arg2 = self.value_stack.pop_u32();
|
||||||
|
let arg1 = self.value_stack.pop_u32();
|
||||||
|
let result: u32 = arg1.rotate_left(arg2);
|
||||||
|
self.value_stack
|
||||||
|
.push(Value::I32(i32::from_ne_bytes(result.to_ne_bytes())));
|
||||||
|
}
|
||||||
|
I32ROTR => {
|
||||||
|
let arg2 = self.value_stack.pop_u32();
|
||||||
|
let arg1 = self.value_stack.pop_u32();
|
||||||
|
let result: u32 = arg1.rotate_right(arg2);
|
||||||
|
self.value_stack
|
||||||
|
.push(Value::I32(i32::from_ne_bytes(result.to_ne_bytes())));
|
||||||
}
|
}
|
||||||
I32DIVS => todo!("{:?} @ {:#x}", op_code, file_offset),
|
|
||||||
I32DIVU => todo!("{:?} @ {:#x}", op_code, file_offset),
|
|
||||||
I32REMS => todo!("{:?} @ {:#x}", op_code, file_offset),
|
|
||||||
I32REMU => todo!("{:?} @ {:#x}", op_code, file_offset),
|
|
||||||
I32AND => todo!("{:?} @ {:#x}", op_code, file_offset),
|
|
||||||
I32OR => todo!("{:?} @ {:#x}", op_code, file_offset),
|
|
||||||
I32XOR => todo!("{:?} @ {:#x}", op_code, file_offset),
|
|
||||||
I32SHL => todo!("{:?} @ {:#x}", op_code, file_offset),
|
|
||||||
I32SHRS => todo!("{:?} @ {:#x}", op_code, file_offset),
|
|
||||||
I32SHRU => todo!("{:?} @ {:#x}", op_code, file_offset),
|
|
||||||
I32ROTL => todo!("{:?} @ {:#x}", op_code, file_offset),
|
|
||||||
I32ROTR => todo!("{:?} @ {:#x}", op_code, file_offset),
|
|
||||||
|
|
||||||
I64CLZ => todo!("{:?} @ {:#x}", op_code, file_offset),
|
I64CLZ => todo!("{:?} @ {:#x}", op_code, file_offset),
|
||||||
I64CTZ => todo!("{:?} @ {:#x}", op_code, file_offset),
|
I64CTZ => todo!("{:?} @ {:#x}", op_code, file_offset),
|
||||||
|
@ -737,6 +867,7 @@ impl<'a> ExecutionState<'a> {
|
||||||
I64SHRU => todo!("{:?} @ {:#x}", op_code, file_offset),
|
I64SHRU => todo!("{:?} @ {:#x}", op_code, file_offset),
|
||||||
I64ROTL => todo!("{:?} @ {:#x}", op_code, file_offset),
|
I64ROTL => todo!("{:?} @ {:#x}", op_code, file_offset),
|
||||||
I64ROTR => todo!("{:?} @ {:#x}", op_code, file_offset),
|
I64ROTR => todo!("{:?} @ {:#x}", op_code, file_offset),
|
||||||
|
|
||||||
F32ABS => todo!("{:?} @ {:#x}", op_code, file_offset),
|
F32ABS => todo!("{:?} @ {:#x}", op_code, file_offset),
|
||||||
F32NEG => todo!("{:?} @ {:#x}", op_code, file_offset),
|
F32NEG => todo!("{:?} @ {:#x}", op_code, file_offset),
|
||||||
F32CEIL => todo!("{:?} @ {:#x}", op_code, file_offset),
|
F32CEIL => todo!("{:?} @ {:#x}", op_code, file_offset),
|
||||||
|
@ -751,6 +882,7 @@ impl<'a> ExecutionState<'a> {
|
||||||
F32MIN => todo!("{:?} @ {:#x}", op_code, file_offset),
|
F32MIN => todo!("{:?} @ {:#x}", op_code, file_offset),
|
||||||
F32MAX => todo!("{:?} @ {:#x}", op_code, file_offset),
|
F32MAX => todo!("{:?} @ {:#x}", op_code, file_offset),
|
||||||
F32COPYSIGN => todo!("{:?} @ {:#x}", op_code, file_offset),
|
F32COPYSIGN => todo!("{:?} @ {:#x}", op_code, file_offset),
|
||||||
|
|
||||||
F64ABS => todo!("{:?} @ {:#x}", op_code, file_offset),
|
F64ABS => todo!("{:?} @ {:#x}", op_code, file_offset),
|
||||||
F64NEG => todo!("{:?} @ {:#x}", op_code, file_offset),
|
F64NEG => todo!("{:?} @ {:#x}", op_code, file_offset),
|
||||||
F64CEIL => todo!("{:?} @ {:#x}", op_code, file_offset),
|
F64CEIL => todo!("{:?} @ {:#x}", op_code, file_offset),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue