Convert fma, valltrue & vanytrue to ISLE (AArch64) (#4608)

* Convert `fma`, `valltrue` & `vanytrue` to ISLE (AArch64)

Ported the existing implementations of the following opcodes to ISLE on
AArch64:
- `fma`
  - Introduced missing support for `fma` on vector values, as per the
    docs.
- `valltrue`
- `vanytrue`

Also fixed `fcmp` on scalar values in the interpreter, and enabled
interpreter tests in `simd-fma.clif`.

This introduces the `FMLA` machine instruction.

Copyright (c) 2022 Arm Limited

* Add comments for `Fmla` and `Bsl`

Copyright (c) 2022 Arm Limited
This commit is contained in:
Damian Heaton
2022-08-05 17:47:56 +01:00
committed by GitHub
parent 1ed7b43e62
commit eb332b8369
19 changed files with 608 additions and 206 deletions

View File

@@ -715,10 +715,25 @@ where
};
assign(count)
}
Opcode::Fcmp => assign(Value::bool(
fcmp(inst.fp_cond_code().unwrap(), &arg(0)?, &arg(1)?)?,
ctrl_ty.as_bool(),
)?),
Opcode::Fcmp => {
let arg0 = extractlanes(&arg(0)?, ctrl_ty)?;
let arg1 = extractlanes(&arg(1)?, ctrl_ty)?;
assign(vectorizelanes(
&(arg0
.into_iter()
.zip(arg1.into_iter())
.map(|(x, y)| {
V::bool(
fcmp(inst.fp_cond_code().unwrap(), &x, &y).unwrap(),
ctrl_ty.lane_type().as_bool(),
)
})
.collect::<ValueResult<SimdVec<V>>>()?),
ctrl_ty,
)?)
}
Opcode::Ffcmp => {
let arg0 = arg(0)?;
let arg1 = arg(1)?;
@@ -750,7 +765,21 @@ where
Opcode::Fmul => binary(Value::mul, arg(0)?, arg(1)?)?,
Opcode::Fdiv => binary(Value::div, arg(0)?, arg(1)?)?,
Opcode::Sqrt => assign(Value::sqrt(arg(0)?)?),
Opcode::Fma => assign(Value::fma(arg(0)?, arg(1)?, arg(2)?)?),
Opcode::Fma => {
let arg0 = extractlanes(&arg(0)?, ctrl_ty)?;
let arg1 = extractlanes(&arg(1)?, ctrl_ty)?;
let arg2 = extractlanes(&arg(2)?, ctrl_ty)?;
assign(vectorizelanes(
&(arg0
.into_iter()
.zip(arg1.into_iter())
.zip(arg2.into_iter())
.map(|((x, y), z)| Value::fma(x, y, z))
.collect::<ValueResult<SimdVec<V>>>()?),
ctrl_ty,
)?)
}
Opcode::Fneg => assign(Value::neg(arg(0)?)?),
Opcode::Fabs => assign(Value::abs(arg(0)?)?),
Opcode::Fcopysign => binary(Value::copysign, arg(0)?, arg(1)?)?,
@@ -1205,8 +1234,8 @@ where
let iterations = match lane_type {
types::I8 | types::B1 | types::B8 => 1,
types::I16 | types::B16 => 2,
types::I32 | types::B32 => 4,
types::I64 | types::B64 => 8,
types::I32 | types::B32 | types::F32 => 4,
types::I64 | types::B64 | types::F64 => 8,
_ => unimplemented!("vectors with lanes wider than 64-bits are currently unsupported."),
};
@@ -1219,6 +1248,8 @@ where
let lane_val: V = if lane_type.is_bool() {
Value::bool(lane != 0, lane_type)?
} else if lane_type.is_float() {
Value::float(lane as u64, lane_type)?
} else {
Value::int(lane, lane_type)?
};
@@ -1242,8 +1273,8 @@ where
let iterations = match lane_type {
types::I8 | types::B1 | types::B8 => 1,
types::I16 | types::B16 => 2,
types::I32 | types::B32 => 4,
types::I64 | types::B64 => 8,
types::I32 | types::B32 | types::F32 => 4,
types::I64 | types::B64 | types::F64 => 8,
_ => unimplemented!("vectors with lanes wider than 64-bits are currently unsupported."),
};
let mut result: [u8; 16] = [0; 16];