use crate::Result;
use crate::operand_stack::OperandStack;
use cranelift::codegen::ir::Value;
use cranelift::frontend::FunctionBuilder;
use cranelift::prelude::types;
fn is_category_1(function_builder: &mut FunctionBuilder, value: Value) -> bool {
let value_type = function_builder.func.dfg.value_type(value);
value_type != types::I64 && value_type != types::F64
}
pub(crate) fn pop(stack: &mut OperandStack) -> Result<()> {
let _ = stack.pop()?;
Ok(())
}
pub(crate) fn pop2(function_builder: &mut FunctionBuilder, stack: &mut OperandStack) -> Result<()> {
let value = stack.pop()?;
if is_category_1(function_builder, value) {
let _ = stack.pop()?;
}
Ok(())
}
pub(crate) fn dup(stack: &mut OperandStack) -> Result<()> {
let value = stack.pop()?;
stack.push(value)?;
stack.push(value)?;
Ok(())
}
pub(crate) fn dup_x1(stack: &mut OperandStack) -> Result<()> {
let value1 = stack.pop()?;
let value2 = stack.pop()?;
stack.push(value1)?;
stack.push(value2)?;
stack.push(value1)?;
Ok(())
}
pub(crate) fn dup_x2(
function_builder: &mut FunctionBuilder,
stack: &mut OperandStack,
) -> Result<()> {
let value1 = stack.pop()?;
let value2 = stack.pop()?;
if is_category_1(function_builder, value2) {
let value3 = stack.pop()?;
stack.push(value1)?;
stack.push(value3)?;
stack.push(value2)?;
stack.push(value1)?;
} else {
stack.push(value1)?;
stack.push(value2)?;
stack.push(value1)?;
}
Ok(())
}
pub(crate) fn dup2(function_builder: &mut FunctionBuilder, stack: &mut OperandStack) -> Result<()> {
let value1 = stack.pop()?;
if is_category_1(function_builder, value1) {
let value2 = stack.pop()?;
stack.push(value2)?;
stack.push(value1)?;
stack.push(value2)?;
stack.push(value1)?;
} else {
stack.push(value1)?;
stack.push(value1)?;
}
Ok(())
}
pub(crate) fn dup2_x1(
function_builder: &mut FunctionBuilder,
stack: &mut OperandStack,
) -> Result<()> {
let value1 = stack.pop()?;
let value2 = stack.pop()?;
if is_category_1(function_builder, value1) {
let value3 = stack.pop()?;
stack.push(value2)?;
stack.push(value1)?;
stack.push(value3)?;
stack.push(value2)?;
stack.push(value1)?;
} else {
stack.push(value1)?;
stack.push(value2)?;
stack.push(value1)?;
}
Ok(())
}
pub(crate) fn dup2_x2(
function_builder: &mut FunctionBuilder,
stack: &mut OperandStack,
) -> Result<()> {
let value1 = stack.pop()?;
let value2 = stack.pop()?;
if is_category_1(function_builder, value1) {
let value3 = stack.pop()?;
if is_category_1(function_builder, value3) {
let value4 = stack.pop()?;
stack.push(value2)?;
stack.push(value1)?;
stack.push(value4)?;
} else {
stack.push(value1)?;
}
stack.push(value3)?;
stack.push(value2)?;
stack.push(value1)?;
} else {
if is_category_1(function_builder, value2) {
let value3 = stack.pop()?;
stack.push(value1)?;
stack.push(value3)?;
} else {
stack.push(value1)?;
}
stack.push(value2)?;
stack.push(value1)?;
}
Ok(())
}
pub(crate) fn swap(stack: &mut OperandStack) -> Result<()> {
let value1 = stack.pop()?;
let value2 = stack.pop()?;
stack.push(value1)?;
stack.push(value2)?;
Ok(())
}