remove expect from pop func and add return value other wasm opcode functions
This commit is contained in:
@@ -721,8 +721,8 @@ macro_rules! int_div {
|
|||||||
// TODO: Fast div using mul for constant divisor? It looks like LLVM doesn't do that for us when
|
// TODO: Fast div using mul for constant divisor? It looks like LLVM doesn't do that for us when
|
||||||
// emitting Wasm.
|
// emitting Wasm.
|
||||||
pub fn $div_u(&mut self) -> Result<(), Error>{
|
pub fn $div_u(&mut self) -> Result<(), Error>{
|
||||||
let divisor = self.pop();
|
let divisor = self.pop()?;
|
||||||
let dividend = self.pop();
|
let dividend = self.pop()?;
|
||||||
|
|
||||||
if let (Some(dividend), Some(divisor)) = (dividend.$imm_fn(), divisor.$imm_fn()) {
|
if let (Some(dividend), Some(divisor)) = (dividend.$imm_fn(), divisor.$imm_fn()) {
|
||||||
if divisor == 0 {
|
if divisor == 0 {
|
||||||
@@ -766,8 +766,8 @@ macro_rules! int_div {
|
|||||||
// TODO: Fast div using mul for constant divisor? It looks like LLVM doesn't do that for us when
|
// TODO: Fast div using mul for constant divisor? It looks like LLVM doesn't do that for us when
|
||||||
// emitting Wasm.
|
// emitting Wasm.
|
||||||
pub fn $div_s(&mut self) -> Result<(), Error>{
|
pub fn $div_s(&mut self) -> Result<(), Error>{
|
||||||
let divisor = self.pop();
|
let divisor = self.pop()?;
|
||||||
let dividend = self.pop();
|
let dividend = self.pop()?;
|
||||||
|
|
||||||
if let (Some(dividend), Some(divisor)) = (dividend.$imm_fn(), divisor.$imm_fn()) {
|
if let (Some(dividend), Some(divisor)) = (dividend.$imm_fn(), divisor.$imm_fn()) {
|
||||||
if divisor == 0 {
|
if divisor == 0 {
|
||||||
@@ -809,8 +809,8 @@ macro_rules! int_div {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn $rem_u(&mut self) -> Result<(), Error>{
|
pub fn $rem_u(&mut self) -> Result<(), Error>{
|
||||||
let divisor = self.pop();
|
let divisor = self.pop()?;
|
||||||
let dividend = self.pop();
|
let dividend = self.pop()?;
|
||||||
|
|
||||||
if let (Some(dividend), Some(divisor)) = (dividend.$imm_fn(), divisor.$imm_fn()) {
|
if let (Some(dividend), Some(divisor)) = (dividend.$imm_fn(), divisor.$imm_fn()) {
|
||||||
if divisor == 0 {
|
if divisor == 0 {
|
||||||
@@ -851,8 +851,8 @@ macro_rules! int_div {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn $rem_s(&mut self) -> Result<(), Error>{
|
pub fn $rem_s(&mut self) -> Result<(), Error>{
|
||||||
let mut divisor = self.pop();
|
let mut divisor = self.pop()?;
|
||||||
let dividend = self.pop();
|
let dividend = self.pop()?;
|
||||||
|
|
||||||
if let (Some(dividend), Some(divisor)) = (dividend.$imm_fn(), divisor.$imm_fn()) {
|
if let (Some(dividend), Some(divisor)) = (dividend.$imm_fn(), divisor.$imm_fn()) {
|
||||||
if divisor == 0 {
|
if divisor == 0 {
|
||||||
@@ -968,7 +968,7 @@ macro_rules! int_div {
|
|||||||
macro_rules! unop {
|
macro_rules! unop {
|
||||||
($name:ident, $instr:ident, $reg_ty:tt, $typ:ty, $const_fallback:expr) => {
|
($name:ident, $instr:ident, $reg_ty:tt, $typ:ty, $const_fallback:expr) => {
|
||||||
pub fn $name(&mut self) -> Result<(), Error>{
|
pub fn $name(&mut self) -> Result<(), Error>{
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
let out_val = match val {
|
let out_val = match val {
|
||||||
ValueLocation::Immediate(imm) =>
|
ValueLocation::Immediate(imm) =>
|
||||||
@@ -1014,7 +1014,7 @@ macro_rules! conversion {
|
|||||||
$const_fallback:expr
|
$const_fallback:expr
|
||||||
) => {
|
) => {
|
||||||
pub fn $name(&mut self) -> Result<(), Error>{
|
pub fn $name(&mut self) -> Result<(), Error>{
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
let out_val = match val {
|
let out_val = match val {
|
||||||
ValueLocation::Immediate(imm) =>
|
ValueLocation::Immediate(imm) =>
|
||||||
@@ -1054,8 +1054,8 @@ macro_rules! conversion {
|
|||||||
macro_rules! shift {
|
macro_rules! shift {
|
||||||
($name:ident, $reg_ty:tt, $instr:ident, $const_fallback:expr, $ty:expr) => {
|
($name:ident, $reg_ty:tt, $instr:ident, $const_fallback:expr, $ty:expr) => {
|
||||||
pub fn $name(&mut self) -> Result<(), Error>{
|
pub fn $name(&mut self) -> Result<(), Error>{
|
||||||
let mut count = self.pop();
|
let mut count = self.pop()?;
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
if let Some(imm) = count.immediate() {
|
if let Some(imm) = count.immediate() {
|
||||||
if let Some(imm) = imm.as_int() {
|
if let Some(imm) = imm.as_int() {
|
||||||
@@ -1146,8 +1146,8 @@ macro_rules! shift {
|
|||||||
macro_rules! cmp_i32 {
|
macro_rules! cmp_i32 {
|
||||||
($name:ident, $flags:expr, $reverse_flags:expr, $const_fallback:expr) => {
|
($name:ident, $flags:expr, $reverse_flags:expr, $const_fallback:expr) => {
|
||||||
pub fn $name(&mut self) -> Result<(), Error>{
|
pub fn $name(&mut self) -> Result<(), Error>{
|
||||||
let mut right = self.pop();
|
let mut right = self.pop()?;
|
||||||
let mut left = self.pop();
|
let mut left = self.pop()?;
|
||||||
|
|
||||||
let out = if let Some(i) = left.imm_i32() {
|
let out = if let Some(i) = left.imm_i32() {
|
||||||
match right {
|
match right {
|
||||||
@@ -1214,8 +1214,8 @@ macro_rules! cmp_i32 {
|
|||||||
macro_rules! cmp_i64 {
|
macro_rules! cmp_i64 {
|
||||||
($name:ident, $flags:expr, $reverse_flags:expr, $const_fallback:expr) => {
|
($name:ident, $flags:expr, $reverse_flags:expr, $const_fallback:expr) => {
|
||||||
pub fn $name(&mut self) -> Result<(), Error> {
|
pub fn $name(&mut self) -> Result<(), Error> {
|
||||||
let mut right = self.pop();
|
let mut right = self.pop()?;
|
||||||
let mut left = self.pop();
|
let mut left = self.pop()?;
|
||||||
|
|
||||||
let out = if let Some(i) = left.imm_i64() {
|
let out = if let Some(i) = left.imm_i64() {
|
||||||
match right {
|
match right {
|
||||||
@@ -1316,8 +1316,8 @@ macro_rules! cmp_f32 {
|
|||||||
macro_rules! eq_float {
|
macro_rules! eq_float {
|
||||||
($name:ident, $instr:ident, $imm_fn:ident, $const_fallback:expr) => {
|
($name:ident, $instr:ident, $imm_fn:ident, $const_fallback:expr) => {
|
||||||
pub fn $name(&mut self) -> Result<(), Error>{
|
pub fn $name(&mut self) -> Result<(), Error>{
|
||||||
let right = self.pop();
|
let right = self.pop()?;
|
||||||
let left = self.pop();
|
let left = self.pop()?;
|
||||||
|
|
||||||
if let Some(right) = right.immediate() {
|
if let Some(right) = right.immediate() {
|
||||||
if let Some(left) = left.immediate() {
|
if let Some(left) = left.immediate() {
|
||||||
@@ -1367,8 +1367,8 @@ macro_rules! minmax_float {
|
|||||||
$const_fallback:expr
|
$const_fallback:expr
|
||||||
) => {
|
) => {
|
||||||
pub fn $name(&mut self) -> Result<(), Error>{
|
pub fn $name(&mut self) -> Result<(), Error>{
|
||||||
let right = self.pop();
|
let right = self.pop()?;
|
||||||
let left = self.pop();
|
let left = self.pop()?;
|
||||||
|
|
||||||
if let Some(right) = right.immediate() {
|
if let Some(right) = right.immediate() {
|
||||||
if let Some(left) = left.immediate() {
|
if let Some(left) = left.immediate() {
|
||||||
@@ -1462,8 +1462,8 @@ macro_rules! cmp_float {
|
|||||||
}};
|
}};
|
||||||
($cmp_instr:ident, $ty:ty, $imm_fn:ident, $name:ident, $reverse_name:ident, $instr:ident, $const_fallback:expr) => {
|
($cmp_instr:ident, $ty:ty, $imm_fn:ident, $name:ident, $reverse_name:ident, $instr:ident, $const_fallback:expr) => {
|
||||||
pub fn $name(&mut self) -> Result<(), Error> {
|
pub fn $name(&mut self) -> Result<(), Error> {
|
||||||
let mut right = self.pop();
|
let mut right = self.pop()?;
|
||||||
let mut left = self.pop();
|
let mut left = self.pop()?;
|
||||||
|
|
||||||
let out = cmp_float!(@helper
|
let out = cmp_float!(@helper
|
||||||
$cmp_instr,
|
$cmp_instr,
|
||||||
@@ -1484,8 +1484,8 @@ macro_rules! cmp_float {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn $reverse_name(&mut self) -> Result<(), Error> {
|
pub fn $reverse_name(&mut self) -> Result<(), Error> {
|
||||||
let mut right = self.pop();
|
let mut right = self.pop()?;
|
||||||
let mut left = self.pop();
|
let mut left = self.pop()?;
|
||||||
|
|
||||||
let out = cmp_float!(@helper
|
let out = cmp_float!(@helper
|
||||||
$cmp_instr,
|
$cmp_instr,
|
||||||
@@ -1673,8 +1673,8 @@ macro_rules! binop {
|
|||||||
};
|
};
|
||||||
($name:ident, $instr:ident, $const_fallback:expr, $reg_ty:tt, $reg_fn:ident, $ty:expr, $imm_fn:ident, $direct_imm:expr, $map_op:expr) => {
|
($name:ident, $instr:ident, $const_fallback:expr, $reg_ty:tt, $reg_fn:ident, $ty:expr, $imm_fn:ident, $direct_imm:expr, $map_op:expr) => {
|
||||||
pub fn $name(&mut self) -> Result<(), Error> {
|
pub fn $name(&mut self) -> Result<(), Error> {
|
||||||
let right = self.pop();
|
let right = self.pop()?;
|
||||||
let left = self.pop();
|
let left = self.pop()?;
|
||||||
|
|
||||||
if let Some(i1) = left.$imm_fn() {
|
if let Some(i1) = left.$imm_fn() {
|
||||||
if let Some(i0) = right.$imm_fn() {
|
if let Some(i0) = right.$imm_fn() {
|
||||||
@@ -1811,7 +1811,7 @@ macro_rules! load {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
let base = self.pop();
|
let base = self.pop()?;
|
||||||
|
|
||||||
let temp = self.take_reg($rtype).unwrap();
|
let temp = self.take_reg($rtype).unwrap();
|
||||||
|
|
||||||
@@ -1988,8 +1988,8 @@ macro_rules! store {
|
|||||||
|
|
||||||
assert_le!(offset, i32::max_value() as u32);
|
assert_le!(offset, i32::max_value() as u32);
|
||||||
|
|
||||||
let mut src = self.pop();
|
let mut src = self.pop()?;
|
||||||
let base = self.pop();
|
let base = self.pop()?;
|
||||||
|
|
||||||
// `store_from_reg` frees `src`
|
// `store_from_reg` frees `src`
|
||||||
// TODO: Would it be better to free it outside `store_from_reg`?
|
// TODO: Would it be better to free it outside `store_from_reg`?
|
||||||
@@ -2203,7 +2203,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
// result in different code. It would also allow us to generate better
|
// result in different code. It would also allow us to generate better
|
||||||
// code for `neq` and `gt_u` with const 0 operand
|
// code for `neq` and `gt_u` with const 0 operand
|
||||||
pub fn i32_eqz(&mut self) -> Result<(), Error> {
|
pub fn i32_eqz(&mut self) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
if let ValueLocation::Immediate(Value::I32(i)) = val {
|
if let ValueLocation::Immediate(Value::I32(i)) = val {
|
||||||
self.push(ValueLocation::Immediate(
|
self.push(ValueLocation::Immediate(
|
||||||
@@ -2233,7 +2233,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn i64_eqz(&mut self) -> Result<(), Error> {
|
pub fn i64_eqz(&mut self) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
if let ValueLocation::Immediate(Value::I64(i)) = val {
|
if let ValueLocation::Immediate(Value::I64(i)) = val {
|
||||||
self.push(ValueLocation::Immediate(
|
self.push(ValueLocation::Immediate(
|
||||||
@@ -2304,7 +2304,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
target: impl Into<BrTarget<Label>>,
|
target: impl Into<BrTarget<Label>>,
|
||||||
pass_args: impl FnOnce(&mut Self) -> Result<(), Error>,
|
pass_args: impl FnOnce(&mut Self) -> Result<(), Error>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
let label = target
|
let label = target
|
||||||
.into()
|
.into()
|
||||||
.label()
|
.label()
|
||||||
@@ -2338,7 +2338,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
target: impl Into<BrTarget<Label>>,
|
target: impl Into<BrTarget<Label>>,
|
||||||
pass_args: impl FnOnce(&mut Self) -> Result<(), Error>,
|
pass_args: impl FnOnce(&mut Self) -> Result<(), Error>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
let label = target
|
let label = target
|
||||||
.into()
|
.into()
|
||||||
.label()
|
.label()
|
||||||
@@ -2389,7 +2389,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
let mut targets = targets.into_iter();
|
let mut targets = targets.into_iter();
|
||||||
let count = targets.len();
|
let count = targets.len();
|
||||||
|
|
||||||
let mut selector = self.pop();
|
let mut selector = self.pop()?;
|
||||||
|
|
||||||
pass_args(self)?;
|
pass_args(self)?;
|
||||||
|
|
||||||
@@ -2571,7 +2571,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
out_args.reverse();
|
out_args.reverse();
|
||||||
|
|
||||||
while out_args.len() < params as usize {
|
while out_args.len() < params as usize {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
// TODO: We can use stack slots for values already on the stack but we
|
// TODO: We can use stack slots for values already on the stack but we
|
||||||
// don't refcount stack slots right now
|
// don't refcount stack slots right now
|
||||||
@@ -2596,7 +2596,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
|
|
||||||
// TODO: We can make this more efficient now that `pop` isn't so complicated
|
// TODO: We can make this more efficient now that `pop` isn't so complicated
|
||||||
for _ in 0..count {
|
for _ in 0..count {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
// TODO: We can use stack slots for values already on the stack but we
|
// TODO: We can use stack slots for values already on the stack but we
|
||||||
// don't refcount stack slots right now
|
// don't refcount stack slots right now
|
||||||
let loc = self.into_temp_loc(None, &mut val)?;
|
let loc = self.into_temp_loc(None, &mut val)?;
|
||||||
@@ -2653,7 +2653,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_global(&mut self, global_idx: u32) -> Result<(), Error> {
|
pub fn set_global(&mut self, global_idx: u32) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
let (reg, offset) = self
|
let (reg, offset) = self
|
||||||
.module_context
|
.module_context
|
||||||
.defined_global_index(global_idx)
|
.defined_global_index(global_idx)
|
||||||
@@ -3028,19 +3028,25 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
self.block_state.stack.push(value);
|
self.block_state.stack.push(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pop(&mut self) -> ValueLocation {
|
fn pop(&mut self) -> Result<ValueLocation, Error> {
|
||||||
self.block_state.stack.pop().expect("Stack is empty")
|
match self.block_state.stack.pop() {
|
||||||
|
Some(v) => Ok(v),
|
||||||
|
None => return Err(Error::Microwasm(
|
||||||
|
"Stack is empty - pop impossible".to_string(),
|
||||||
|
)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn drop(&mut self, range: RangeInclusive<u32>) -> Result<(), Error> {
|
pub fn drop(&mut self, range: RangeInclusive<u32>) -> Result<(), Error> {
|
||||||
let mut repush = Vec::with_capacity(*range.start() as _);
|
let mut repush = Vec::with_capacity(*range.start() as _);
|
||||||
|
|
||||||
for _ in 0..*range.start() {
|
for _ in 0..*range.start() {
|
||||||
repush.push(self.pop());
|
let v = self.pop()?;
|
||||||
|
repush.push(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
for _ in range {
|
for _ in range {
|
||||||
let val = self.pop();
|
let val = self.pop()?;
|
||||||
self.free_value(val)?;
|
self.free_value(val)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3051,7 +3057,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn pop_into(&mut self, dst: CCLoc) -> Result<(), Error> {
|
fn pop_into(&mut self, dst: CCLoc) -> Result<(), Error> {
|
||||||
let val = self.pop();
|
let val = self.pop()?;
|
||||||
self.copy_value(val, dst)?;
|
self.copy_value(val, dst)?;
|
||||||
self.free_value(val)?;
|
self.free_value(val)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -3149,8 +3155,8 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn f32_neg(&mut self) {
|
pub fn f32_neg(&mut self) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
let out = if let Some(i) = val.imm_f32() {
|
let out = if let Some(i) = val.imm_f32() {
|
||||||
ValueLocation::Immediate(
|
ValueLocation::Immediate(
|
||||||
@@ -3168,10 +3174,11 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
self.push(out);
|
self.push(out);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn f64_neg(&mut self) {
|
pub fn f64_neg(&mut self) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
let out = if let Some(i) = val.imm_f64() {
|
let out = if let Some(i) = val.imm_f64() {
|
||||||
ValueLocation::Immediate(
|
ValueLocation::Immediate(
|
||||||
@@ -3189,10 +3196,11 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
self.push(out);
|
self.push(out);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn f32_abs(&mut self) {
|
pub fn f32_abs(&mut self) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
let out = if let Some(i) = val.imm_f32() {
|
let out = if let Some(i) = val.imm_f32() {
|
||||||
ValueLocation::Immediate(
|
ValueLocation::Immediate(
|
||||||
@@ -3210,10 +3218,11 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
self.push(out);
|
self.push(out);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn f64_abs(&mut self) {
|
pub fn f64_abs(&mut self) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
let out = if let Some(i) = val.imm_f64() {
|
let out = if let Some(i) = val.imm_f64() {
|
||||||
ValueLocation::Immediate(
|
ValueLocation::Immediate(
|
||||||
@@ -3231,10 +3240,11 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
self.push(out);
|
self.push(out);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn f32_sqrt(&mut self) {
|
pub fn f32_sqrt(&mut self) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
let out = if let Some(i) = val.imm_f32() {
|
let out = if let Some(i) = val.imm_f32() {
|
||||||
ValueLocation::Immediate(
|
ValueLocation::Immediate(
|
||||||
@@ -3251,10 +3261,11 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
self.push(out);
|
self.push(out);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn f64_sqrt(&mut self) {
|
pub fn f64_sqrt(&mut self) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
let out = if let Some(i) = val.imm_f64() {
|
let out = if let Some(i) = val.imm_f64() {
|
||||||
ValueLocation::Immediate(
|
ValueLocation::Immediate(
|
||||||
@@ -3271,11 +3282,12 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
self.push(out);
|
self.push(out);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn f32_copysign(&mut self) -> Result<(), Error> {
|
pub fn f32_copysign(&mut self) -> Result<(), Error> {
|
||||||
let mut right = self.pop();
|
let mut right = self.pop()?;
|
||||||
let mut left = self.pop();
|
let mut left = self.pop()?;
|
||||||
|
|
||||||
let out = if let (Some(left), Some(right)) = (left.imm_f32(), right.imm_f32()) {
|
let out = if let (Some(left), Some(right)) = (left.imm_f32(), right.imm_f32()) {
|
||||||
ValueLocation::Immediate(
|
ValueLocation::Immediate(
|
||||||
@@ -3306,8 +3318,8 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn f64_copysign(&mut self) -> Result<(), Error> {
|
pub fn f64_copysign(&mut self) -> Result<(), Error> {
|
||||||
let mut right = self.pop();
|
let mut right = self.pop()?;
|
||||||
let mut left = self.pop();
|
let mut left = self.pop()?;
|
||||||
|
|
||||||
let out = if let (Some(left), Some(right)) = (left.imm_f64(), right.imm_f64()) {
|
let out = if let (Some(left), Some(right)) = (left.imm_f64(), right.imm_f64()) {
|
||||||
ValueLocation::Immediate(
|
ValueLocation::Immediate(
|
||||||
@@ -3338,7 +3350,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn i32_clz(&mut self) -> Result<(), Error> {
|
pub fn i32_clz(&mut self) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
let out_val = match val {
|
let out_val = match val {
|
||||||
ValueLocation::Immediate(imm) => {
|
ValueLocation::Immediate(imm) => {
|
||||||
@@ -3395,7 +3407,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn i64_clz(&mut self) -> Result<(), Error> {
|
pub fn i64_clz(&mut self) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
let out_val = match val {
|
let out_val = match val {
|
||||||
ValueLocation::Immediate(imm) => {
|
ValueLocation::Immediate(imm) => {
|
||||||
@@ -3452,7 +3464,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn i32_ctz(&mut self) -> Result<(), Error> {
|
pub fn i32_ctz(&mut self) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
let out_val = match val {
|
let out_val = match val {
|
||||||
ValueLocation::Immediate(imm) => {
|
ValueLocation::Immediate(imm) => {
|
||||||
@@ -3505,7 +3517,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn i64_ctz(&mut self) -> Result<(), Error> {
|
pub fn i64_ctz(&mut self) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
let out_val = match val {
|
let out_val = match val {
|
||||||
ValueLocation::Immediate(imm) => {
|
ValueLocation::Immediate(imm) => {
|
||||||
@@ -3551,7 +3563,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn i32_extend_u(&mut self) -> Result<(), Error> {
|
pub fn i32_extend_u(&mut self) -> Result<(), Error> {
|
||||||
let val = self.pop();
|
let val = self.pop()?;
|
||||||
|
|
||||||
let out = if let ValueLocation::Immediate(imm) = val {
|
let out = if let ValueLocation::Immediate(imm) = val {
|
||||||
ValueLocation::Immediate((imm.as_i32().unwrap() as u32 as u64).into())
|
ValueLocation::Immediate((imm.as_i32().unwrap() as u32 as u64).into())
|
||||||
@@ -3593,7 +3605,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn i32_extend_s(&mut self) -> Result<(), Error> {
|
pub fn i32_extend_s(&mut self) -> Result<(), Error> {
|
||||||
let val = self.pop();
|
let val = self.pop()?;
|
||||||
|
|
||||||
self.free_value(val)?;
|
self.free_value(val)?;
|
||||||
let new_reg = self.take_reg(I64).unwrap();
|
let new_reg = self.take_reg(I64).unwrap();
|
||||||
@@ -3661,7 +3673,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
|a: Ieee64| Ieee32::from_bits((f64::from_bits(a.to_bits()) as f32).to_bits())
|
|a: Ieee64| Ieee32::from_bits((f64::from_bits(a.to_bits()) as f32).to_bits())
|
||||||
);
|
);
|
||||||
pub fn i32_truncate_f32_s(&mut self) -> Result<(), Error> {
|
pub fn i32_truncate_f32_s(&mut self) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
let out_val = match val {
|
let out_val = match val {
|
||||||
ValueLocation::Immediate(imm) => ValueLocation::Immediate(
|
ValueLocation::Immediate(imm) => ValueLocation::Immediate(
|
||||||
@@ -3700,7 +3712,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn i32_truncate_f32_u(&mut self) -> Result<(), Error> {
|
pub fn i32_truncate_f32_u(&mut self) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
let out_val = match val {
|
let out_val = match val {
|
||||||
ValueLocation::Immediate(imm) => ValueLocation::Immediate(
|
ValueLocation::Immediate(imm) => ValueLocation::Immediate(
|
||||||
@@ -3742,7 +3754,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn i32_truncate_f64_s(&mut self) -> Result<(), Error> {
|
pub fn i32_truncate_f64_s(&mut self) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
let out_val = match val {
|
let out_val = match val {
|
||||||
ValueLocation::Immediate(imm) => ValueLocation::Immediate(
|
ValueLocation::Immediate(imm) => ValueLocation::Immediate(
|
||||||
@@ -3782,7 +3794,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn i32_truncate_f64_u(&mut self) -> Result<(), Error> {
|
pub fn i32_truncate_f64_u(&mut self) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
let out_val = match val {
|
let out_val = match val {
|
||||||
ValueLocation::Immediate(imm) => ValueLocation::Immediate(
|
ValueLocation::Immediate(imm) => ValueLocation::Immediate(
|
||||||
@@ -3874,7 +3886,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
pub fn i64_truncate_f32_s(&mut self) -> Result<(), Error> {
|
pub fn i64_truncate_f32_s(&mut self) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
let out_val = match val {
|
let out_val = match val {
|
||||||
ValueLocation::Immediate(imm) => ValueLocation::Immediate(
|
ValueLocation::Immediate(imm) => ValueLocation::Immediate(
|
||||||
@@ -3913,7 +3925,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn i64_truncate_f64_s(&mut self) -> Result<(), Error> {
|
pub fn i64_truncate_f64_s(&mut self) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
let out_val = match val {
|
let out_val = match val {
|
||||||
ValueLocation::Immediate(imm) => ValueLocation::Immediate(
|
ValueLocation::Immediate(imm) => ValueLocation::Immediate(
|
||||||
@@ -3953,7 +3965,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn i64_truncate_f32_u(&mut self) -> Result<(), Error> {
|
pub fn i64_truncate_f32_u(&mut self) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
let out_val = match val {
|
let out_val = match val {
|
||||||
ValueLocation::Immediate(imm) => ValueLocation::Immediate(
|
ValueLocation::Immediate(imm) => ValueLocation::Immediate(
|
||||||
@@ -3995,7 +4007,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn i64_truncate_f64_u(&mut self) -> Result<(), Error> {
|
pub fn i64_truncate_f64_u(&mut self) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
let out_val = match val {
|
let out_val = match val {
|
||||||
ValueLocation::Immediate(imm) => ValueLocation::Immediate(
|
ValueLocation::Immediate(imm) => ValueLocation::Immediate(
|
||||||
@@ -4038,7 +4050,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn f32_convert_from_i32_u(&mut self) -> Result<(), Error> {
|
pub fn f32_convert_from_i32_u(&mut self) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
let out_val = match val {
|
let out_val = match val {
|
||||||
ValueLocation::Immediate(imm) => ValueLocation::Immediate(
|
ValueLocation::Immediate(imm) => ValueLocation::Immediate(
|
||||||
@@ -4065,7 +4077,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn f64_convert_from_i32_u(&mut self) -> Result<(), Error> {
|
pub fn f64_convert_from_i32_u(&mut self) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
let out_val = match val {
|
let out_val = match val {
|
||||||
ValueLocation::Immediate(imm) => ValueLocation::Immediate(
|
ValueLocation::Immediate(imm) => ValueLocation::Immediate(
|
||||||
@@ -4091,7 +4103,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn f32_convert_from_i64_u(&mut self) -> Result<(), Error> {
|
pub fn f32_convert_from_i64_u(&mut self) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
let out_val = match val {
|
let out_val = match val {
|
||||||
ValueLocation::Immediate(imm) => ValueLocation::Immediate(
|
ValueLocation::Immediate(imm) => ValueLocation::Immediate(
|
||||||
@@ -4130,7 +4142,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn f64_convert_from_i64_u(&mut self) -> Result<(), Error> {
|
pub fn f64_convert_from_i64_u(&mut self) -> Result<(), Error> {
|
||||||
let mut val = self.pop();
|
let mut val = self.pop()?;
|
||||||
|
|
||||||
let out_val = match val {
|
let out_val = match val {
|
||||||
ValueLocation::Immediate(imm) => ValueLocation::Immediate(
|
ValueLocation::Immediate(imm) => ValueLocation::Immediate(
|
||||||
@@ -4170,7 +4182,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn i32_wrap_from_i64(&mut self) -> Result<(), Error> {
|
pub fn i32_wrap_from_i64(&mut self) -> Result<(), Error> {
|
||||||
let val = self.pop();
|
let val = self.pop()?;
|
||||||
|
|
||||||
let out = match val {
|
let out = match val {
|
||||||
ValueLocation::Immediate(imm) => {
|
ValueLocation::Immediate(imm) => {
|
||||||
@@ -4184,7 +4196,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn i32_reinterpret_from_f32(&mut self) -> Result<(), Error> {
|
pub fn i32_reinterpret_from_f32(&mut self) -> Result<(), Error> {
|
||||||
let val = self.pop();
|
let val = self.pop()?;
|
||||||
|
|
||||||
let out = match val {
|
let out = match val {
|
||||||
ValueLocation::Immediate(imm) => {
|
ValueLocation::Immediate(imm) => {
|
||||||
@@ -4198,7 +4210,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn i64_reinterpret_from_f64(&mut self) -> Result<(), Error> {
|
pub fn i64_reinterpret_from_f64(&mut self) -> Result<(), Error> {
|
||||||
let val = self.pop();
|
let val = self.pop()?;
|
||||||
|
|
||||||
let out = match val {
|
let out = match val {
|
||||||
ValueLocation::Immediate(imm) => {
|
ValueLocation::Immediate(imm) => {
|
||||||
@@ -4212,7 +4224,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn f32_reinterpret_from_i32(&mut self) -> Result<(), Error> {
|
pub fn f32_reinterpret_from_i32(&mut self) -> Result<(), Error> {
|
||||||
let val = self.pop();
|
let val = self.pop()?;
|
||||||
|
|
||||||
let out = match val {
|
let out = match val {
|
||||||
ValueLocation::Immediate(imm) => {
|
ValueLocation::Immediate(imm) => {
|
||||||
@@ -4226,7 +4238,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn f64_reinterpret_from_i64(&mut self) -> Result<(), Error> {
|
pub fn f64_reinterpret_from_i64(&mut self) -> Result<(), Error> {
|
||||||
let val = self.pop();
|
let val = self.pop()?;
|
||||||
|
|
||||||
let out = match val {
|
let out = match val {
|
||||||
ValueLocation::Immediate(imm) => {
|
ValueLocation::Immediate(imm) => {
|
||||||
@@ -4705,8 +4717,8 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
// `i32_mul` needs to be separate because the immediate form of the instruction
|
// `i32_mul` needs to be separate because the immediate form of the instruction
|
||||||
// has a different syntax to the immediate form of the other instructions.
|
// has a different syntax to the immediate form of the other instructions.
|
||||||
pub fn i32_mul(&mut self) -> Result<(), Error> {
|
pub fn i32_mul(&mut self) -> Result<(), Error> {
|
||||||
let right = self.pop();
|
let right = self.pop()?;
|
||||||
let left = self.pop();
|
let left = self.pop()?;
|
||||||
|
|
||||||
if let Some(right) = right.immediate() {
|
if let Some(right) = right.immediate() {
|
||||||
if let Some(left) = left.immediate() {
|
if let Some(left) = left.immediate() {
|
||||||
@@ -4765,8 +4777,8 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
// `i64_mul` needs to be separate because the immediate form of the instruction
|
// `i64_mul` needs to be separate because the immediate form of the instruction
|
||||||
// has a different syntax to the immediate form of the other instructions.
|
// has a different syntax to the immediate form of the other instructions.
|
||||||
pub fn i64_mul(&mut self) -> Result<(), Error> {
|
pub fn i64_mul(&mut self) -> Result<(), Error> {
|
||||||
let right = self.pop();
|
let right = self.pop()?;
|
||||||
let left = self.pop();
|
let left = self.pop()?;
|
||||||
|
|
||||||
if let Some(right) = right.immediate() {
|
if let Some(right) = right.immediate() {
|
||||||
if let Some(left) = left.immediate() {
|
if let Some(left) = left.immediate() {
|
||||||
@@ -4949,9 +4961,9 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn select(&mut self) -> Result<(), Error> {
|
pub fn select(&mut self) -> Result<(), Error> {
|
||||||
let mut cond = self.pop();
|
let mut cond = self.pop()?;
|
||||||
let mut else_ = self.pop();
|
let mut else_ = self.pop()?;
|
||||||
let mut then = self.pop();
|
let mut then = self.pop()?;
|
||||||
|
|
||||||
if let ValueLocation::Immediate(i) = cond {
|
if let ValueLocation::Immediate(i) = cond {
|
||||||
if i.as_i32().unwrap() == 0 {
|
if i.as_i32().unwrap() == 0 {
|
||||||
@@ -5226,7 +5238,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
let mut pending = Vec::<(ValueLocation, CCLoc)>::with_capacity(out_locs.len());
|
let mut pending = Vec::<(ValueLocation, CCLoc)>::with_capacity(out_locs.len());
|
||||||
|
|
||||||
for &loc in out_locs.iter().rev() {
|
for &loc in out_locs.iter().rev() {
|
||||||
let val = self.pop();
|
let val = self.pop()?;
|
||||||
|
|
||||||
pending.push((val, loc));
|
pending.push((val, loc));
|
||||||
}
|
}
|
||||||
@@ -5302,7 +5314,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut callee = self.pop();
|
let mut callee = self.pop()?;
|
||||||
let callee_reg = self.into_temp_reg(I32, &mut callee).unwrap();
|
let callee_reg = self.into_temp_reg(I32, &mut callee).unwrap();
|
||||||
|
|
||||||
for &loc in &locs {
|
for &loc in &locs {
|
||||||
|
|||||||
@@ -631,9 +631,9 @@ where
|
|||||||
Operator::Min(Size::_32) => ctx.f32_min()?,
|
Operator::Min(Size::_32) => ctx.f32_min()?,
|
||||||
Operator::Max(Size::_32) => ctx.f32_max()?,
|
Operator::Max(Size::_32) => ctx.f32_max()?,
|
||||||
Operator::Copysign(Size::_32) => ctx.f32_copysign()?,
|
Operator::Copysign(Size::_32) => ctx.f32_copysign()?,
|
||||||
Operator::Sqrt(Size::_32) => ctx.f32_sqrt(),
|
Operator::Sqrt(Size::_32) => ctx.f32_sqrt()?,
|
||||||
Operator::Neg(Size::_32) => ctx.f32_neg(),
|
Operator::Neg(Size::_32) => ctx.f32_neg()?,
|
||||||
Operator::Abs(Size::_32) => ctx.f32_abs(),
|
Operator::Abs(Size::_32) => ctx.f32_abs()?,
|
||||||
Operator::Floor(Size::_32) => ctx.f32_floor()?,
|
Operator::Floor(Size::_32) => ctx.f32_floor()?,
|
||||||
Operator::Ceil(Size::_32) => ctx.f32_ceil()?,
|
Operator::Ceil(Size::_32) => ctx.f32_ceil()?,
|
||||||
Operator::Nearest(Size::_32) => ctx.f32_nearest()?,
|
Operator::Nearest(Size::_32) => ctx.f32_nearest()?,
|
||||||
@@ -651,9 +651,9 @@ where
|
|||||||
Operator::Min(Size::_64) => ctx.f64_min()?,
|
Operator::Min(Size::_64) => ctx.f64_min()?,
|
||||||
Operator::Max(Size::_64) => ctx.f64_max()?,
|
Operator::Max(Size::_64) => ctx.f64_max()?,
|
||||||
Operator::Copysign(Size::_64) => ctx.f64_copysign()?,
|
Operator::Copysign(Size::_64) => ctx.f64_copysign()?,
|
||||||
Operator::Sqrt(Size::_64) => ctx.f64_sqrt(),
|
Operator::Sqrt(Size::_64) => ctx.f64_sqrt()?,
|
||||||
Operator::Neg(Size::_64) => ctx.f64_neg(),
|
Operator::Neg(Size::_64) => ctx.f64_neg()?,
|
||||||
Operator::Abs(Size::_64) => ctx.f64_abs(),
|
Operator::Abs(Size::_64) => ctx.f64_abs()?,
|
||||||
Operator::Floor(Size::_64) => ctx.f64_floor()?,
|
Operator::Floor(Size::_64) => ctx.f64_floor()?,
|
||||||
Operator::Ceil(Size::_64) => ctx.f64_ceil()?,
|
Operator::Ceil(Size::_64) => ctx.f64_ceil()?,
|
||||||
Operator::Nearest(Size::_64) => ctx.f64_nearest()?,
|
Operator::Nearest(Size::_64) => ctx.f64_nearest()?,
|
||||||
|
|||||||
Reference in New Issue
Block a user