use std::ffi::{c_char, CString};
use cranelift::codegen::ir::{entities::JumpTable, types::*, Function, TrapCode, UserFuncName};
use cranelift::codegen::verifier::verify_function;
use cranelift::prelude::isa::CallConv;
use cranelift::prelude::settings::{self, Builder, Flags};
use cranelift::prelude::{
AbiParam, Block, FunctionBuilder, FunctionBuilderContext, Imm64, InstBuilder, Signature, Value,
Variable,
};
#[repr(C)]
pub enum CTrapCode {
StackOverflow,
HeapOutOfBounds,
HeapMisaligned,
TableOutOfBounds,
IndirectCallToNull,
BadSignature,
IntegerOverflow,
IntegerDivisionByZero,
BadConversionToInteger,
UnreachableCodeReached,
Interrupt,
User(u16),
}
#[repr(C)]
pub enum CType {
I8,
I16,
I32,
I64,
I128,
F32,
F64,
R32,
R64,
I8X8,
I16X4,
I32X2,
F32X2,
I8X16,
I16X8,
I32X4,
I64X2,
F32X4,
F64X2,
F32X8,
F64X4,
F32X16,
F64X8,
}
#[repr(transparent)]
pub struct CImm64(i64);
#[repr(transparent)]
pub struct CVariable(u32);
#[repr(transparent)]
pub struct CBlock(u32);
#[repr(transparent)]
pub struct CValue(u32);
#[repr(transparent)]
pub struct CInst(u32);
#[repr(transparent)]
pub struct CFuncRef(u32);
#[repr(transparent)]
pub struct CJumpTable(u32);
#[repr(C)]
pub enum CCallConv {
Fast,
Cold,
Tail,
SystemV,
WindowsFastcall,
AppleAarch64,
Probestack,
WasmtimeSystemV,
WasmtimeFastcall,
WasmtimeAppleAarch64,
}
macro_rules! easy_type {
($val:ident, $typ:ident, $($variant:ident,)*) => {
match $val {
$($typ::$variant => $variant,)*
}
};
}
macro_rules! union_enum {
($val:ident, $nl:ident, $nr:ident, $($variant:ident,)*) => {
match $val {
$($nl::$variant => Some($nr::$variant),)*
_ => None
}
};
}
macro_rules! easy_enum {
($val:ident, $nl:ident, $nr:ident, $($variant:ident,)*) => {
match $val {
$($nl::$variant => $nr::$variant,)*
}
};
}
#[allow(non_snake_case)]
fn convert_CType(td: CType) -> Type {
return easy_type!(
td, CType, I8, I16, I32, I64, I128, F32, F64, R32, R64, I8X8, I16X4, I32X2, F32X2, I8X16,
I16X8, I32X4, I64X2, F32X4, F64X2, F32X8, F64X4, F32X16, F64X8,
);
}
#[allow(non_snake_case)]
fn convert_CCallConv(ccd: CCallConv) -> CallConv {
return easy_enum!(
ccd,
CCallConv,
CallConv,
Fast,
Cold,
Tail,
SystemV,
WindowsFastcall,
AppleAarch64,
Probestack,
WasmtimeSystemV,
WasmtimeFastcall,
WasmtimeAppleAarch64,
);
}
#[allow(non_snake_case)]
fn convert_CTrapCode(ctc: CTrapCode) -> TrapCode {
let result = union_enum!(
ctc,
CTrapCode,
TrapCode,
StackOverflow,
HeapOutOfBounds,
HeapMisaligned,
TableOutOfBounds,
IndirectCallToNull,
BadSignature,
IntegerOverflow,
IntegerDivisionByZero,
BadConversionToInteger,
UnreachableCodeReached,
Interrupt,
);
if result.is_none() {
if let CTrapCode::User(x) = ctc {
return TrapCode::User(x);
} else {
return result.unwrap();
}
} else {
return result.unwrap();
}
}
macro_rules! namespace_new {
($namespace:ident) => {
paste::paste! {
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn [< CL_ $namespace _ new >]() -> *mut $namespace {
return Box::into_raw(Box::new($namespace::new()));
}
}
};
}
macro_rules! namespace_new_one_convert {
($namespace:ident, $one:ident) => {
paste::paste! {
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn [< CL_ $namespace _ new >](one: $one) -> *mut $namespace {
return Box::into_raw(Box::new($namespace::new([< convert_ $one >](one))));
}
}
};
}
macro_rules! empty_dispose {
($namespace:ident) => {
paste::paste! {
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn [< CL_ $namespace _dispose >](val: *mut $namespace) -> () {
if (!val.is_null()) {
unsafe { drop(Box::from_raw(val)) };
}
}
}
};
}
#[no_mangle]
pub extern "C" fn cstr_free(s: *mut c_char) {
if s.is_null() {
return;
}
unsafe { drop(CString::from_raw(s)) };
}
namespace_new!(FunctionBuilderContext);
empty_dispose!(FunctionBuilderContext);
empty_dispose!(FunctionBuilder);
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn CL_FunctionBuilder_new<'a>(
func: *mut Function,
ctx: *mut FunctionBuilderContext,
) -> *mut FunctionBuilder<'a> {
assert!(!func.is_null());
assert!(!ctx.is_null());
let ufunc = unsafe { &mut *func };
let uctx = unsafe { &mut *ctx };
return Box::into_raw(Box::new(FunctionBuilder::new(ufunc, uctx)));
}
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn CL_FunctionBuilder_create_block(builder: *mut FunctionBuilder) -> CBlock {
assert!(!builder.is_null());
let ubuilder = unsafe { &mut *builder };
return CBlock(ubuilder.create_block().as_u32());
}
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn CL_FunctionBuilder_declare_var(
builder: *mut FunctionBuilder,
variable: CVariable,
typ: CType,
) -> () {
assert!(!builder.is_null());
let ubuilder = unsafe { &mut *builder };
ubuilder.declare_var(Variable::from_u32(variable.0), convert_CType(typ));
}
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn CL_FunctionBuilder_def_var(
builder: *mut FunctionBuilder,
variable: CVariable,
val: CValue,
) -> () {
assert!(!builder.is_null());
let ubuilder = unsafe { &mut *builder };
ubuilder.def_var(Variable::from_u32(variable.0), Value::from_u32(val.0));
}
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn CL_FunctionBuilder_use_var(
builder: *mut FunctionBuilder,
variable: CVariable,
) -> CValue {
assert!(!builder.is_null());
let ubuilder = unsafe { &mut *builder };
let result = ubuilder.use_var(Variable::from_u32(variable.0));
CValue(result.as_u32())
}
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn CL_FunctionBuilder_append_block_params_for_function_params(
builder: *mut FunctionBuilder,
block: CBlock,
) -> () {
assert!(!builder.is_null());
let ubuilder = unsafe { &mut *builder };
ubuilder.append_block_params_for_function_params(Block::from_u32(block.0));
}
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn CL_FunctionBuilder_finalize(builder: *mut FunctionBuilder) -> () {
assert!(!builder.is_null());
let ubuilder = unsafe { Box::from_raw(builder) };
ubuilder.finalize();
}
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn CL_FunctionBuilder_switch_to_block(
builder: *mut FunctionBuilder,
block: CBlock,
) -> () {
assert!(!builder.is_null());
let ubuilder = unsafe { &mut *builder };
ubuilder.switch_to_block(Block::from_u32(block.0));
}
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn CL_FunctionBuilder_seal_block(
builder: *mut FunctionBuilder,
block: CBlock,
) -> () {
assert!(!builder.is_null());
let ubuilder = unsafe { &mut *builder };
ubuilder.seal_block(Block::from_u32(block.0));
}
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn CL_FunctionBuilder_block_params(
builder: *mut FunctionBuilder,
block: CBlock,
idx: usize,
) -> CValue {
assert!(!builder.is_null());
let ubuilder = unsafe { &mut *builder };
let result = ubuilder.block_params(Block::from_u32(block.0))[idx];
CValue(result.as_u32())
}
empty_dispose!(UserFuncName);
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn CL_UserFuncName_user(one: u32, two: u32) -> *mut UserFuncName {
return Box::into_raw(Box::new(UserFuncName::user(one, two)));
}
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn CL_Variable_from_u32(val: u32) -> CVariable {
return CVariable(val);
}
empty_dispose!(Function);
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn CL_Function_with_name_signature(
user: *mut UserFuncName,
sig: *mut Signature,
) -> *mut Function {
assert!(!sig.is_null());
assert!(!user.is_null());
let usig = unsafe { Box::from_raw(sig) };
let uuser = unsafe { Box::from_raw(user) };
return Box::into_raw(Box::new(Function::with_name_signature(*uuser, *usig)));
}
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn CL_Function_verify(func: *mut Function, flags: *mut Flags) -> () {
assert!(!func.is_null());
assert!(!flags.is_null());
let ufunc = unsafe { &*func };
let uflags = unsafe { &*flags };
return verify_function(ufunc, uflags).unwrap();
}
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn CL_Function_display(func: *mut Function) -> *mut c_char {
assert!(!func.is_null());
let ufunc = unsafe { &*func };
let display = ufunc.display().to_string();
return CString::new(display).unwrap().into_raw();
}
namespace_new_one_convert!(AbiParam, CType);
namespace_new_one_convert!(Signature, CCallConv);
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn CL_Signature_returns_push(sig: *mut Signature, abi: *mut AbiParam) -> () {
assert!(!abi.is_null());
assert!(!sig.is_null());
let usig = unsafe { &mut *sig };
let uabi = unsafe { Box::from_raw(abi) };
usig.returns.push(*uabi);
}
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn CL_Signature_params_push(sig: *mut Signature, abi: *mut AbiParam) -> () {
assert!(!abi.is_null());
assert!(!abi.is_null());
let usig = unsafe { &mut *sig };
let uabi = unsafe { Box::from_raw(abi) };
usig.params.push(*uabi);
}
empty_dispose!(Flags);
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn CL_Flags_new(builder: *mut Builder) -> *mut Flags {
assert!(!builder.is_null());
let ubuilder = unsafe { Box::from_raw(builder) };
return Box::into_raw(Box::new(Flags::new(*ubuilder)));
}
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn CL_Builder_builder() -> *mut Builder {
return Box::into_raw(Box::new(settings::builder()));
}
macro_rules! instr_five_value_block_svalue_block_svalue_inst {
($invoke:ident) => {
paste::paste! {
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn [< CL_FunctionBuilder_ $invoke >](builder: *mut FunctionBuilder, val: CValue, block_one_label: CBlock, block_one_args: *mut CValue, one_len: usize, block_two_label: CBlock, block_two_args: *mut CValue, two_len: usize) -> CInst {
assert!(!builder.is_null());
let first = unsafe { core::slice::from_raw_parts(block_one_args, one_len)};
let second = unsafe { core::slice::from_raw_parts(block_two_args, two_len)};
let converts_one: Vec<Value> = first.into_iter().map(|x| {return Value::from_u32(x.0); }).collect();
let converts_two: Vec<Value> = second.into_iter().map(|x| {return Value::from_u32(x.0); }).collect();
let ubuilder = unsafe { &mut *builder };
let cval = Value::from_u32(val.0);
let result = ubuilder
.ins()
.$invoke(cval, Block::from_u32(block_one_label.0), converts_one.as_slice(), Block::from_u32(block_two_label.0), converts_two.as_slice());
CInst(result.as_u32())
}
}
};
}
macro_rules! instr_two_block_svalue_inst {
($invoke:ident) => {
paste::paste! {
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn [< CL_FunctionBuilder_ $invoke >](builder: *mut FunctionBuilder, block_call_label: CBlock, block_call_args: *mut CValue, len: usize) -> CInst {
assert!(!builder.is_null());
let rvals = unsafe { core::slice::from_raw_parts(block_call_args, len)};
let converts: Vec<Value> = rvals.into_iter().map(|x| {return Value::from_u32(x.0); }).collect();
let ubuilder = unsafe { &mut *builder };
let result = ubuilder
.ins()
.$invoke(Block::from_u32(block_call_label.0), converts.as_slice());
CInst(result.as_u32())
}
}
};
}
macro_rules! instr_three_value_value_value_value {
($invoke:ident) => {
paste::paste! {
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn [< CL_FunctionBuilder_ $invoke >](builder: *mut FunctionBuilder, c: CValue, left: CValue, right: CValue) -> CValue {
assert!(!builder.is_null());
let ubuilder = unsafe { &mut *builder };
let result = ubuilder
.ins()
.$invoke(Value::from_u32(c.0), Value::from_u32(left.0), Value::from_u32(right.0));
CValue(result.as_u32())
}
}
};
}
macro_rules! instr_two_value_value_value {
($invoke:ident) => {
paste::paste! {
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn [< CL_FunctionBuilder_ $invoke >](builder: *mut FunctionBuilder, left: CValue, right: CValue) -> CValue {
assert!(!builder.is_null());
let ubuilder = unsafe { &mut *builder };
let result = ubuilder
.ins()
.$invoke(Value::from_u32(left.0), Value::from_u32(right.0));
CValue(result.as_u32())
}
}
};
}
macro_rules! instr_one_value_inst {
($invoke:ident) => {
paste::paste! {
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn [< CL_FunctionBuilder_ $invoke >](builder: *mut FunctionBuilder, one: CValue) -> CInst {
assert!(!builder.is_null());
let ubuilder = unsafe { &mut *builder };
let result = ubuilder
.ins()
.$invoke(Value::from_u32(one.0));
CInst(result.as_u32())
}
}
};
}
macro_rules! instr_one_value_value {
($invoke:ident) => {
paste::paste! {
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn [< CL_FunctionBuilder_ $invoke >](builder: *mut FunctionBuilder, one: CValue) -> CValue {
assert!(!builder.is_null());
let ubuilder = unsafe { &mut *builder };
let result = ubuilder
.ins()
.$invoke(Value::from_u32(one.0));
CValue(result.as_u32())
}
}
};
}
macro_rules! instr_two_value_imm_value {
($invoke:ident) => {
paste::paste! {
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn [< CL_FunctionBuilder_ $invoke >](builder: *mut FunctionBuilder, one: CValue, imm: CImm64) -> CValue {
assert!(!builder.is_null());
let ubuilder = unsafe { &mut *builder };
let result = ubuilder
.ins()
.$invoke(Value::from_u32(one.0), Imm64::new(imm.0));
CValue(result.as_u32())
}
}
};
}
macro_rules! instr_one_type_value {
($invoke:ident) => {
paste::paste! {
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn [< CL_FunctionBuilder_ $invoke >](builder: *mut FunctionBuilder, one: CType) -> CValue {
assert!(!builder.is_null());
let ubuilder = unsafe { &mut *builder };
let result = ubuilder
.ins()
.$invoke(convert_CType(one));
CValue(result.as_u32())
}
}
};
}
macro_rules! instr_two_type_value_value {
($invoke:ident) => {
paste::paste! {
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn [< CL_FunctionBuilder_ $invoke >](builder: *mut FunctionBuilder, one: CType, val: CValue) -> CValue {
assert!(!builder.is_null());
let ubuilder = unsafe { &mut *builder };
let result = ubuilder
.ins()
.$invoke(convert_CType(one), Value::from_u32(val.0));
CValue(result.as_u32())
}
}
};
}
macro_rules! instr_two_type_imm_value {
($invoke:ident) => {
paste::paste! {
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn [< CL_FunctionBuilder_ $invoke >](builder: *mut FunctionBuilder, one: CType, imm: CImm64) -> CValue {
assert!(!builder.is_null());
let ubuilder = unsafe { &mut *builder };
let result = ubuilder
.ins()
.$invoke(convert_CType(one), Imm64::new(imm.0));
CValue(result.as_u32())
}
}
};
}
macro_rules! instr_two_value_jt_inst {
($invoke:ident) => {
paste::paste! {
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn [< CL_FunctionBuilder_ $invoke >](builder: *mut FunctionBuilder, val: CValue, jt: CJumpTable) -> CInst {
assert!(!builder.is_null());
let ubuilder = unsafe { &mut *builder };
let result = ubuilder
.ins()
.$invoke(Value::from_u32(val.0), JumpTable::from_u32(jt.0));
CInst(result.as_u32())
}
}
};
}
macro_rules! instr_one_svalue_inst {
($invoke:ident) => {
paste::paste! {
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn [< CL_FunctionBuilder_ $invoke >](builder: *mut FunctionBuilder, rvals_raw: *mut CValue, len: usize) -> CInst {
assert!(!builder.is_null());
assert!(!rvals_raw.is_null());
let rvals = unsafe { core::slice::from_raw_parts(rvals_raw, len)};
let ubuilder = unsafe { &mut *builder };
let converts: Vec<Value> = rvals.into_iter().map(|x| {return Value::from_u32(x.0); }).collect();
let result = ubuilder
.ins()
.$invoke(converts.as_slice());
CInst(result.as_u32())
}
}
};
}
macro_rules! instr_two_value_code_inst {
($invoke:ident) => {
paste::paste! {
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn [< CL_FunctionBuilder_ $invoke >](builder: *mut FunctionBuilder, val: CValue, code: CTrapCode) -> CInst {
assert!(!builder.is_null());
let ubuilder = unsafe { &mut *builder };
let result = ubuilder
.ins()
.$invoke(Value::from_u32(val.0),convert_CTrapCode(code));
CInst(result.as_u32())
}
}
};
}
macro_rules! instr_one_code_inst {
($invoke:ident) => {
paste::paste! {
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn [< CL_FunctionBuilder_ $invoke >](builder: *mut FunctionBuilder, code: CTrapCode) -> CInst {
assert!(!builder.is_null());
let ubuilder = unsafe { &mut *builder };
let result = ubuilder
.ins()
.$invoke(convert_CTrapCode(code));
CInst(result.as_u32())
}
}
};
}
macro_rules! instr_zero_inst {
($invoke:ident) => {
paste::paste! {
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn [< CL_FunctionBuilder_ $invoke >](builder: *mut FunctionBuilder) -> CInst {
assert!(!builder.is_null());
let ubuilder = unsafe { &mut *builder };
let result = ubuilder
.ins()
.$invoke();
CInst(result.as_u32())
}
}
};
}
instr_zero_inst!(debugtrap);
instr_zero_inst!(fence);
instr_zero_inst!(nop);
instr_one_code_inst!(trap);
instr_one_code_inst!(resumable_trap);
instr_two_value_code_inst!(trapz);
instr_two_value_code_inst!(trapnz);
instr_one_svalue_inst!(return_);
instr_two_type_imm_value!(iconst);
instr_two_type_value_value!(scalar_to_vector);
instr_two_type_value_value!(bmask);
instr_two_type_value_value!(ireduce);
instr_two_type_value_value!(uextend);
instr_two_type_value_value!(sextend);
instr_two_type_value_value!(fpromote);
instr_two_type_value_value!(fdemote);
instr_two_type_value_value!(fcvt_to_uint);
instr_two_type_value_value!(fcvt_to_sint);
instr_two_type_value_value!(fcvt_to_sint_sat);
instr_two_type_value_value!(x86_cvtt2dq);
instr_two_type_value_value!(fcvt_from_uint);
instr_two_type_value_value!(fcvt_from_sint);
instr_two_type_value_value!(fcvt_low_from_sint);
instr_one_type_value!(get_stack_pointer);
instr_one_type_value!(get_return_address);
instr_one_type_value!(null);
instr_two_value_imm_value!(iadd_imm);
instr_two_value_imm_value!(imul_imm);
instr_two_value_imm_value!(udiv_imm);
instr_two_value_imm_value!(sdiv_imm);
instr_two_value_imm_value!(urem_imm);
instr_two_value_imm_value!(srem_imm);
instr_two_value_imm_value!(irsub_imm);
instr_two_value_imm_value!(band_imm);
instr_two_value_imm_value!(bor_imm);
instr_two_value_imm_value!(bxor_imm);
instr_two_value_imm_value!(rotl_imm);
instr_two_value_imm_value!(rotr_imm);
instr_two_value_imm_value!(ishl_imm);
instr_two_value_imm_value!(ushr_imm);
instr_two_value_imm_value!(sshr_imm);
instr_two_value_jt_inst!(br_table);
instr_two_block_svalue_inst!(jump);
instr_three_value_value_value_value!(select);
instr_three_value_value_value_value!(select_spectre_guard);
instr_three_value_value_value_value!(bitselect);
instr_three_value_value_value_value!(x86_blendv);
instr_three_value_value_value_value!(iadd_cin);
instr_three_value_value_value_value!(isub_bin);
instr_three_value_value_value_value!(fma);
instr_two_value_value_value!(iadd);
instr_two_value_value_value!(uadd_sat);
instr_two_value_value_value!(sadd_sat);
instr_two_value_value_value!(isub);
instr_two_value_value_value!(udiv);
instr_two_value_value_value!(sdiv);
instr_two_value_value_value!(urem);
instr_two_value_value_value!(srem);
instr_two_value_value_value!(usub_sat);
instr_two_value_value_value!(ssub_sat);
instr_two_value_value_value!(imul);
instr_two_value_value_value!(umulhi);
instr_two_value_value_value!(smulhi);
instr_two_value_value_value!(sqmul_round_sat);
instr_two_value_value_value!(x86_pmulhrsw);
instr_two_value_value_value!(smin);
instr_two_value_value_value!(umin);
instr_two_value_value_value!(smax);
instr_two_value_value_value!(umax);
instr_two_value_value_value!(avg_round);
instr_two_value_value_value!(swizzle);
instr_two_value_value_value!(x86_pshufb);
instr_two_value_value_value!(band);
instr_two_value_value_value!(bor);
instr_two_value_value_value!(bxor);
instr_two_value_value_value!(band_not);
instr_two_value_value_value!(bor_not);
instr_two_value_value_value!(bxor_not);
instr_two_value_value_value!(rotl);
instr_two_value_value_value!(rotr);
instr_two_value_value_value!(ishl);
instr_two_value_value_value!(ushr);
instr_two_value_value_value!(sshr);
instr_two_value_value_value!(fadd);
instr_two_value_value_value!(fsub);
instr_two_value_value_value!(fmul);
instr_two_value_value_value!(fdiv);
instr_two_value_value_value!(fcopysign);
instr_two_value_value_value!(fmin);
instr_two_value_value_value!(fmin_pseudo);
instr_two_value_value_value!(fmax);
instr_two_value_value_value!(fmax_pseudo);
instr_two_value_value_value!(snarrow);
instr_two_value_value_value!(unarrow);
instr_two_value_value_value!(uunarrow);
instr_two_value_value_value!(iadd_pairwise);
instr_two_value_value_value!(x86_pmaddubsw);
instr_two_value_value_value!(iconcat);
instr_one_value_value!(ineg);
instr_one_value_value!(iabs);
instr_one_value_value!(vany_true);
instr_one_value_value!(vall_true);
instr_one_value_value!(bnot);
instr_one_value_value!(bitrev);
instr_one_value_value!(clz);
instr_one_value_value!(cls);
instr_one_value_value!(ctz);
instr_one_value_value!(bswap);
instr_one_value_value!(popcnt);
instr_one_value_value!(sqrt);
instr_one_value_value!(fneg);
instr_one_value_value!(fabs);
instr_one_value_value!(ceil);
instr_one_value_value!(floor);
instr_one_value_value!(trunc);
instr_one_value_value!(nearest);
instr_one_value_value!(is_null);
instr_one_value_value!(is_invalid);
instr_one_value_value!(swiden_low);
instr_one_value_value!(uwiden_low);
instr_one_value_value!(swiden_high);
instr_one_value_value!(uwiden_high);
instr_one_value_value!(fvdemote);
instr_one_value_value!(fvpromote_low);
instr_one_value_inst!(set_pinned_reg);
instr_five_value_block_svalue_block_svalue_inst!(brif);