x64: Migrate get_pinned_reg, set_pinned_reg, vconst, and raw_bitcast to ISLE (#4763)

https://github.com/bytecodealliance/wasmtime/pull/4763
This commit is contained in:
Trevor Elliott
2022-08-23 16:32:00 -07:00
committed by GitHub
parent cb918e8a24
commit 4bdfa76370
8 changed files with 100 additions and 90 deletions

View File

@@ -1196,6 +1196,10 @@
(decl temp_writable_xmm () WritableXmm)
(extern constructor temp_writable_xmm temp_writable_xmm)
;; Fetch the special pinned register.
(decl pinned_writable_gpr () WritableGpr)
(extern constructor pinned_writable_gpr pinned_writable_gpr)
;; Construct a new `XmmMem` from the given `RegMem`.
;;
;; Asserts that the `RegMem`'s register, if any, is an XMM register.
@@ -3606,6 +3610,17 @@
(_ Unit (emit_div_or_rem kind ty dst a b)))
dst))
;;;; Pinned Register ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(decl read_pinned_gpr () Gpr)
(rule (read_pinned_gpr)
(pinned_writable_gpr))
(decl write_pinned_gpr (Gpr) SideEffectNoResult)
(rule (write_pinned_gpr val)
(let ((dst WritableGpr (pinned_writable_gpr)))
(SideEffectNoResult.Inst (gen_move $I64 dst val))))
;;;; Automatic conversions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(convert Gpr InstOutput output_gpr)

View File

@@ -3485,3 +3485,28 @@
(let ((res ValueRegs (mul_hi $I64 $true a b))
(hi Gpr (value_regs_get_gpr res 1)))
hi))
;; Rules for `get_pinned_reg` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (get_pinned_reg))
(read_pinned_gpr))
;; Rules for `set_pinned_reg` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (set_pinned_reg a @ (value_type ty)))
(side_effect (write_pinned_gpr a)))
;; Rules for `vconst` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type ty (vconst const)))
;; TODO use Inst::gen_constant() instead.
(x64_xmm_load_const ty (const_to_vconst const)))
;; Rules for `raw_bitcast` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; A raw_bitcast is just a mechanism for correcting the type of V128 values (see
;; https://github.com/bytecodealliance/wasmtime/issues/1147). As such, this IR
;; instruction should emit no machine code but a move is necessary to give the
;; register allocator a definition for the output virtual register.
(rule (lower (raw_bitcast val))
(put_in_regs val))

View File

@@ -580,55 +580,17 @@ fn lower_insn_to_regs(
| Opcode::Sdiv
| Opcode::Srem
| Opcode::Umulhi
| Opcode::Smulhi => {
| Opcode::Smulhi
| Opcode::GetPinnedReg
| Opcode::SetPinnedReg
| Opcode::Vconst
| Opcode::RawBitcast
| Opcode::Insertlane => {
implemented_in_isle(ctx);
}
Opcode::DynamicStackAddr => unimplemented!("DynamicStackAddr"),
Opcode::GetPinnedReg => {
let dst = get_output_reg(ctx, outputs[0]).only_reg().unwrap();
ctx.emit(Inst::gen_move(dst, regs::pinned_reg(), types::I64));
}
Opcode::SetPinnedReg => {
let src = put_input_in_reg(ctx, inputs[0]);
ctx.emit(Inst::gen_move(
Writable::from_reg(regs::pinned_reg()),
src,
types::I64,
));
}
Opcode::Vconst => {
let used_constant = if let &InstructionData::UnaryConst {
constant_handle, ..
} = ctx.data(insn)
{
ctx.use_constant(VCodeConstantData::Pool(
constant_handle,
ctx.get_constant_data(constant_handle).clone(),
))
} else {
unreachable!("vconst should always have unary_const format")
};
// TODO use Inst::gen_constant() instead.
let dst = get_output_reg(ctx, outputs[0]).only_reg().unwrap();
let ty = ty.unwrap();
ctx.emit(Inst::xmm_load_const(used_constant, dst, ty));
}
Opcode::RawBitcast => {
// A raw_bitcast is just a mechanism for correcting the type of V128 values (see
// https://github.com/bytecodealliance/wasmtime/issues/1147). As such, this IR
// instruction should emit no machine code but a move is necessary to give the register
// allocator a definition for the output virtual register.
let src = put_input_in_reg(ctx, inputs[0]);
let dst = get_output_reg(ctx, outputs[0]).only_reg().unwrap();
let ty = ty.unwrap();
ctx.emit(Inst::gen_move(dst, src, ty));
}
Opcode::Shuffle => {
let ty = ty.unwrap();
let dst = get_output_reg(ctx, outputs[0]).only_reg().unwrap();
@@ -756,14 +718,6 @@ fn lower_insn_to_regs(
));
}
Opcode::Insertlane => {
unreachable!(
"implemented in ISLE: inst = `{}`, type = `{:?}`",
ctx.dfg().display_inst(insn),
ty
);
}
Opcode::Extractlane => {
// The instruction format maps to variables like: %dst = extractlane %src, %lane
let ty = ty.unwrap();

View File

@@ -849,6 +849,11 @@ impl Context for IsleContext<'_, '_, MInst, Flags, IsaFlags, 6> {
.use_constant(VCodeConstantData::WellKnown(&UMAX_MASK))
}
#[inline]
fn pinned_writable_gpr(&mut self) -> WritableGpr {
Writable::from_reg(Gpr::new(regs::pinned_reg()).unwrap())
}
fn emit_div_or_rem(
&mut self,
kind: &DivOrRemKind,

View File

@@ -774,6 +774,14 @@ macro_rules! isle_prelude_methods {
self.lower_ctx.use_constant(data)
}
#[inline]
fn const_to_vconst(&mut self, constant: Constant) -> VCodeConstant {
self.lower_ctx.use_constant(VCodeConstantData::Pool(
constant,
self.lower_ctx.get_constant_data(constant).clone(),
))
}
fn range(&mut self, start: usize, end: usize) -> Range {
(start, end)
}

View File

@@ -559,6 +559,10 @@
(decl emit_u64_le_const (u64) VCodeConstant)
(extern constructor emit_u64_le_const emit_u64_le_const)
;; Fetch the VCodeConstant associated with a Constant.
(decl const_to_vconst (Constant) VCodeConstant)
(extern constructor const_to_vconst const_to_vconst)
;;;; Helpers for Side-Effectful Instructions Without Results ;;;;;;;;;;;;;;;;;;;
(type SideEffectNoResult (enum
@@ -804,7 +808,6 @@
(decl u64_from_constant (u64) Constant)
(extern extractor u64_from_constant u64_from_constant)
;;;; Helpers for tail recursion loops ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; A range of integers to loop through.