Port vconst to ISLE (AArch64) (#4750)

* Port `vconst` to ISLE (AArch64)

Ported the existing implementation of `vconst` to ISLE for AArch64, and
added support for 64-bit vector constants.

Also introduced 64-bit `vconst` support to the interpreter.

Copyright (c) 2022 Arm Limited

* Replace if-chains with match statements

Copyright (c) 2022 Arm Limited
This commit is contained in:
Damian Heaton
2022-08-23 17:40:11 +01:00
committed by GitHub
parent 418dbc15bd
commit da1fb305a3
10 changed files with 97 additions and 21 deletions

View File

@@ -2435,6 +2435,11 @@
(if-let addr_reg (amode_is_reg addr))
addr_reg)
;; Lower a constant f64.
(decl constant_f64 (u64) Reg)
;; TODO: Port lower_constant_f64() to ISLE.
(extern constructor constant_f64 constant_f64)
;; Lower a constant f128.
(decl constant_f128 (u128) Reg)
;; TODO: Port lower_constant_f128() to ISLE.

View File

@@ -1628,6 +1628,15 @@
(rule (lower (resumable_trap trap_code))
(side_effect (udf trap_code)))
;;;; Rules for `vconst` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type (ty_vec128 _) (vconst (u128_from_constant x))))
(constant_f128 x))
(rule (lower (has_type ty (vconst (u64_from_constant x))))
(if (ty_vec64 ty))
(constant_f64 x))
;;;; Rules for `splat` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type ty (splat x @ (value_type in_ty))))

View File

@@ -8,7 +8,6 @@
//! - Floating-point immediates (FIMM instruction).
use super::lower_inst;
use crate::data_value::DataValue;
use crate::ir::condcodes::{FloatCC, IntCC};
use crate::ir::types::*;
use crate::ir::Inst as IRInst;
@@ -94,13 +93,6 @@ pub(crate) fn input_to_shiftimm(
input_to_const(ctx, input).and_then(ShiftOpShiftImm::maybe_from_shift)
}
pub(crate) fn const_param_to_u128(ctx: &mut Lower<Inst>, inst: IRInst) -> Option<u128> {
match ctx.get_immediate(inst) {
Some(DataValue::V128(bytes)) => Some(u128::from_le_bytes(bytes)),
_ => None,
}
}
/// How to handle narrow values loaded into registers; see note on `narrow_mode`
/// parameter to `put_input_in_*` below.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]

View File

@@ -5,9 +5,9 @@ pub mod generated_code;
// Types that the generated ISLE code uses via `use super::*`.
use super::{
insn_inputs, lower_constant_f128, writable_zero_reg, zero_reg, AMode, ASIMDFPModImm,
ASIMDMovModImm, BranchTarget, CallIndInfo, CallInfo, Cond, CondBrKind, ExtendOp, FPUOpRI,
FloatCC, Imm12, ImmLogic, ImmShift, Inst as MInst, IntCC, JTSequenceInfo, MachLabel,
insn_inputs, lower_constant_f128, lower_constant_f64, writable_zero_reg, zero_reg, AMode,
ASIMDFPModImm, ASIMDMovModImm, BranchTarget, CallIndInfo, CallInfo, Cond, CondBrKind, ExtendOp,
FPUOpRI, FloatCC, Imm12, ImmLogic, ImmShift, Inst as MInst, IntCC, JTSequenceInfo, MachLabel,
MoveWideConst, MoveWideOp, NarrowValueMode, Opcode, OperandSize, PairAMode, Reg, ScalarSize,
ShiftOpAndAmt, UImm5, VecMisc2, VectorSize, NZCV,
};
@@ -484,6 +484,14 @@ impl generated_code::Context for IsleContext<'_, '_, MInst, Flags, IsaFlags, 6>
address.is_reg()
}
fn constant_f64(&mut self, value: u64) -> Reg {
let rd = self.temp_writable_reg(I8X16);
lower_constant_f64(self.lower_ctx, rd, f64::from_bits(value));
rd.to_reg()
}
fn constant_f128(&mut self, value: u128) -> Reg {
let rd = self.temp_writable_reg(I8X16);

View File

@@ -644,11 +644,7 @@ pub(crate) fn lower_insn_to_regs(
panic!("Branch opcode reached non-branch lowering logic!");
}
Opcode::Vconst => {
let value = const_param_to_u128(ctx, insn).expect("Invalid immediate bytes");
let rd = get_output_reg(ctx, outputs[0]).only_reg().unwrap();
lower_constant_f128(ctx, rd, value);
}
Opcode::Vconst => implemented_in_isle(ctx),
Opcode::RawBitcast => {
let rm = put_input_in_reg(ctx, inputs[0], NarrowValueMode::None);