227 lines
6.5 KiB
Rust
227 lines
6.5 KiB
Rust
use crate::cdsl::formats::{FormatRegistry, InstructionFormatBuilder as Builder};
|
|
use crate::shared::{entities::EntityRefs, immediates::Immediates};
|
|
|
|
pub(crate) fn define(imm: &Immediates, entities: &EntityRefs) -> FormatRegistry {
|
|
let mut registry = FormatRegistry::new();
|
|
|
|
registry.insert(Builder::new("Unary").value());
|
|
registry.insert(Builder::new("UnaryImm").imm(&imm.imm64));
|
|
registry.insert(Builder::new("UnaryIeee32").imm(&imm.ieee32));
|
|
registry.insert(Builder::new("UnaryIeee64").imm(&imm.ieee64));
|
|
registry.insert(Builder::new("UnaryBool").imm(&imm.boolean));
|
|
registry.insert(Builder::new("UnaryConst").imm(&imm.pool_constant));
|
|
registry.insert(Builder::new("UnaryGlobalValue").imm(&entities.global_value));
|
|
|
|
registry.insert(Builder::new("Binary").value().value());
|
|
registry.insert(Builder::new("BinaryImm").value().imm(&imm.imm64));
|
|
|
|
// The select instructions are controlled by the second VALUE operand.
|
|
// The first VALUE operand is the controlling flag which has a derived type.
|
|
// The fma instruction has the same constraint on all inputs.
|
|
registry.insert(
|
|
Builder::new("Ternary")
|
|
.value()
|
|
.value()
|
|
.value()
|
|
.typevar_operand(1),
|
|
);
|
|
|
|
// Catch-all for instructions with many outputs and inputs and no immediate
|
|
// operands.
|
|
registry.insert(Builder::new("MultiAry").varargs());
|
|
|
|
registry.insert(Builder::new("NullAry"));
|
|
|
|
registry.insert(
|
|
Builder::new("InsertLane")
|
|
.value()
|
|
.imm_with_name("lane", &imm.uimm8)
|
|
.value(),
|
|
);
|
|
registry.insert(
|
|
Builder::new("ExtractLane")
|
|
.value()
|
|
.imm_with_name("lane", &imm.uimm8),
|
|
);
|
|
registry.insert(
|
|
Builder::new("Shuffle")
|
|
.value()
|
|
.value()
|
|
.imm_with_name("mask", &imm.uimm128),
|
|
);
|
|
|
|
registry.insert(Builder::new("IntCompare").imm(&imm.intcc).value().value());
|
|
registry.insert(
|
|
Builder::new("IntCompareImm")
|
|
.imm(&imm.intcc)
|
|
.value()
|
|
.imm(&imm.imm64),
|
|
);
|
|
registry.insert(Builder::new("IntCond").imm(&imm.intcc).value());
|
|
|
|
registry.insert(
|
|
Builder::new("FloatCompare")
|
|
.imm(&imm.floatcc)
|
|
.value()
|
|
.value(),
|
|
);
|
|
registry.insert(Builder::new("FloatCond").imm(&imm.floatcc).value());;
|
|
|
|
registry.insert(
|
|
Builder::new("IntSelect")
|
|
.imm(&imm.intcc)
|
|
.value()
|
|
.value()
|
|
.value(),
|
|
);
|
|
|
|
registry.insert(Builder::new("Jump").imm(&entities.ebb).varargs());
|
|
registry.insert(Builder::new("Branch").value().imm(&entities.ebb).varargs());
|
|
registry.insert(
|
|
Builder::new("BranchInt")
|
|
.imm(&imm.intcc)
|
|
.value()
|
|
.imm(&entities.ebb)
|
|
.varargs(),
|
|
);
|
|
registry.insert(
|
|
Builder::new("BranchFloat")
|
|
.imm(&imm.floatcc)
|
|
.value()
|
|
.imm(&entities.ebb)
|
|
.varargs(),
|
|
);
|
|
registry.insert(
|
|
Builder::new("BranchIcmp")
|
|
.imm(&imm.intcc)
|
|
.value()
|
|
.value()
|
|
.imm(&entities.ebb)
|
|
.varargs(),
|
|
);
|
|
registry.insert(
|
|
Builder::new("BranchTable")
|
|
.value()
|
|
.imm(&entities.ebb)
|
|
.imm(&entities.jump_table),
|
|
);
|
|
registry.insert(
|
|
Builder::new("BranchTableEntry")
|
|
.value()
|
|
.value()
|
|
.imm(&imm.uimm8)
|
|
.imm(&entities.jump_table),
|
|
);
|
|
registry.insert(Builder::new("BranchTableBase").imm(&entities.jump_table));
|
|
registry.insert(
|
|
Builder::new("IndirectJump")
|
|
.value()
|
|
.imm(&entities.jump_table),
|
|
);
|
|
|
|
registry.insert(Builder::new("Call").imm(&entities.func_ref).varargs());
|
|
registry.insert(
|
|
Builder::new("CallIndirect")
|
|
.imm(&entities.sig_ref)
|
|
.value()
|
|
.varargs(),
|
|
);
|
|
registry.insert(Builder::new("FuncAddr").imm(&entities.func_ref));
|
|
|
|
registry.insert(
|
|
Builder::new("Load")
|
|
.imm(&imm.memflags)
|
|
.value()
|
|
.imm(&imm.offset32),
|
|
);
|
|
registry.insert(
|
|
Builder::new("LoadComplex")
|
|
.imm(&imm.memflags)
|
|
.varargs()
|
|
.imm(&imm.offset32),
|
|
);
|
|
registry.insert(
|
|
Builder::new("Store")
|
|
.imm(&imm.memflags)
|
|
.value()
|
|
.value()
|
|
.imm(&imm.offset32),
|
|
);
|
|
registry.insert(
|
|
Builder::new("StoreComplex")
|
|
.imm(&imm.memflags)
|
|
.value()
|
|
.varargs()
|
|
.imm(&imm.offset32),
|
|
);
|
|
registry.insert(
|
|
Builder::new("StackLoad")
|
|
.imm(&entities.stack_slot)
|
|
.imm(&imm.offset32),
|
|
);
|
|
registry.insert(
|
|
Builder::new("StackStore")
|
|
.value()
|
|
.imm(&entities.stack_slot)
|
|
.imm(&imm.offset32),
|
|
);
|
|
|
|
// Accessing a WebAssembly heap.
|
|
registry.insert(
|
|
Builder::new("HeapAddr")
|
|
.imm(&entities.heap)
|
|
.value()
|
|
.imm(&imm.uimm32),
|
|
);
|
|
|
|
// Accessing a WebAssembly table.
|
|
registry.insert(
|
|
Builder::new("TableAddr")
|
|
.imm(&entities.table)
|
|
.value()
|
|
.imm(&imm.offset32),
|
|
);
|
|
|
|
registry.insert(
|
|
Builder::new("RegMove")
|
|
.value()
|
|
.imm_with_name("src", &imm.regunit)
|
|
.imm_with_name("dst", &imm.regunit),
|
|
);
|
|
registry.insert(
|
|
Builder::new("CopySpecial")
|
|
.imm_with_name("src", &imm.regunit)
|
|
.imm_with_name("dst", &imm.regunit),
|
|
);
|
|
registry.insert(Builder::new("CopyToSsa").imm_with_name("src", &imm.regunit));
|
|
registry.insert(
|
|
Builder::new("RegSpill")
|
|
.value()
|
|
.imm_with_name("src", &imm.regunit)
|
|
.imm_with_name("dst", &entities.stack_slot),
|
|
);
|
|
registry.insert(
|
|
Builder::new("RegFill")
|
|
.value()
|
|
.imm_with_name("src", &entities.stack_slot)
|
|
.imm_with_name("dst", &imm.regunit),
|
|
);
|
|
|
|
registry.insert(Builder::new("Trap").imm(&imm.trapcode));
|
|
registry.insert(Builder::new("CondTrap").value().imm(&imm.trapcode));
|
|
registry.insert(
|
|
Builder::new("IntCondTrap")
|
|
.imm(&imm.intcc)
|
|
.value()
|
|
.imm(&imm.trapcode),
|
|
);
|
|
registry.insert(
|
|
Builder::new("FloatCondTrap")
|
|
.imm(&imm.floatcc)
|
|
.value()
|
|
.imm(&imm.trapcode),
|
|
);
|
|
|
|
registry
|
|
}
|