forked from libre-chip/cpu
implement decoding all rotate instructions
This commit is contained in:
parent
130c1b2892
commit
a42b76b468
5 changed files with 31516 additions and 764 deletions
|
|
@ -6,8 +6,8 @@ use crate::{
|
||||||
instruction::{
|
instruction::{
|
||||||
AddSubMOp, BranchMOp, CompareMOp, CompareMode, ConditionMode, LoadMOp, LoadStoreConversion,
|
AddSubMOp, BranchMOp, CompareMOp, CompareMode, ConditionMode, LoadMOp, LoadStoreConversion,
|
||||||
LoadStoreWidth, LogicalFlagsMOp, LogicalFlagsMOpImm, LogicalMOp, Lut4, MOp, MOpDestReg,
|
LoadStoreWidth, LogicalFlagsMOp, LogicalFlagsMOpImm, LogicalMOp, Lut4, MOp, MOpDestReg,
|
||||||
MOpRegNum, MoveRegMOp, OutputIntegerMode, ShiftRotateMOp, ShiftRotateMOpImm,
|
MOpRegNum, MoveRegMOp, OutputIntegerMode, ShiftRotateDestLogicOp, ShiftRotateMOp,
|
||||||
ShiftRotateMode, StoreMOp,
|
ShiftRotateMOpImm, ShiftRotateMode, StoreMOp,
|
||||||
},
|
},
|
||||||
powerisa_instructions_xml::{
|
powerisa_instructions_xml::{
|
||||||
InstructionBitFieldName, InstructionBitFieldsInner, Instructions, TextLineItem,
|
InstructionBitFieldName, InstructionBitFieldsInner, Instructions, TextLineItem,
|
||||||
|
|
@ -221,6 +221,14 @@ impl_fields! {
|
||||||
struct FieldDS(SInt<14>);
|
struct FieldDS(SInt<14>);
|
||||||
#[name = "LI"]
|
#[name = "LI"]
|
||||||
struct FieldLI(SInt<24>);
|
struct FieldLI(SInt<24>);
|
||||||
|
#[name = "MB"]
|
||||||
|
struct FieldMB(UInt<5>);
|
||||||
|
#[name = "mb"]
|
||||||
|
struct FieldMb(UInt<6>);
|
||||||
|
#[name = "ME"]
|
||||||
|
struct FieldME(UInt<5>);
|
||||||
|
#[name = "me"]
|
||||||
|
struct FieldMe(UInt<6>);
|
||||||
#[name = "SH"]
|
#[name = "SH"]
|
||||||
struct FieldSH(UInt<5>);
|
struct FieldSH(UInt<5>);
|
||||||
#[name = "sh"]
|
#[name = "sh"]
|
||||||
|
|
@ -1911,6 +1919,242 @@ impl DecodeState<'_> {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
#[hdl]
|
||||||
|
fn rotate_dest_logic_op(
|
||||||
|
&mut self,
|
||||||
|
msb0_mask_begin_: Expr<UInt<6>>,
|
||||||
|
msb0_mask_end_: Expr<UInt<6>>,
|
||||||
|
fallback_is_src2: bool,
|
||||||
|
) -> Expr<HdlOption<ShiftRotateDestLogicOp>> {
|
||||||
|
#[hdl]
|
||||||
|
let msb0_mask_begin = wire();
|
||||||
|
connect(msb0_mask_begin, msb0_mask_begin_);
|
||||||
|
#[hdl]
|
||||||
|
let msb0_mask_end = wire();
|
||||||
|
connect(msb0_mask_end, msb0_mask_end_);
|
||||||
|
#[hdl]
|
||||||
|
let rotated_output_start: UInt<6> = wire();
|
||||||
|
#[hdl]
|
||||||
|
let rotated_output_len: UInt<6> = wire();
|
||||||
|
|
||||||
|
// gives the correct value modulo 2^6 even when `msb0_mask_begin > msb0_mask_end`
|
||||||
|
connect_any(
|
||||||
|
rotated_output_len,
|
||||||
|
msb0_mask_end - msb0_mask_begin + 1_hdl_u6,
|
||||||
|
);
|
||||||
|
|
||||||
|
// account for lsb0 vs. msb0
|
||||||
|
connect(rotated_output_start, !msb0_mask_end);
|
||||||
|
|
||||||
|
#[hdl]
|
||||||
|
let rotate_dest_logic_op = wire();
|
||||||
|
|
||||||
|
#[hdl]
|
||||||
|
if rotated_output_len.cmp_eq(0_hdl_u6) {
|
||||||
|
// it's really 64, it wrapped around to 0
|
||||||
|
connect(rotate_dest_logic_op, HdlNone());
|
||||||
|
} else {
|
||||||
|
connect(
|
||||||
|
rotate_dest_logic_op,
|
||||||
|
HdlSome(
|
||||||
|
#[hdl]
|
||||||
|
ShiftRotateDestLogicOp {
|
||||||
|
rotated_output_start,
|
||||||
|
rotated_output_len,
|
||||||
|
fallback_is_src2,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
rotate_dest_logic_op
|
||||||
|
}
|
||||||
|
#[hdl]
|
||||||
|
fn rotate_helper(
|
||||||
|
&mut self,
|
||||||
|
is_32bit: bool,
|
||||||
|
msb0_mask_begin: Expr<UInt<6>>,
|
||||||
|
msb0_mask_end: Expr<UInt<6>>,
|
||||||
|
ra: FieldRA,
|
||||||
|
rs: FieldRS,
|
||||||
|
rb: FieldRB,
|
||||||
|
rc: FieldRc,
|
||||||
|
) {
|
||||||
|
// TODO: handle SO propagation
|
||||||
|
connect(
|
||||||
|
ArrayVec::len(self.output),
|
||||||
|
1usize.cast_to_static::<Length<_>>(),
|
||||||
|
);
|
||||||
|
let dest_logic_op = self.rotate_dest_logic_op(msb0_mask_begin, msb0_mask_end, false);
|
||||||
|
connect(
|
||||||
|
self.output[0],
|
||||||
|
ShiftRotateMOp::shift_rotate(
|
||||||
|
MOpDestReg::new([gpr(ra.0)], [(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc.0)]),
|
||||||
|
[gpr(rs.0).value, gpr(rs.0).value, gpr(rb.0).value],
|
||||||
|
#[hdl]
|
||||||
|
ShiftRotateMOpImm {
|
||||||
|
shift_rotate_amount: HdlNone(),
|
||||||
|
shift_rotate_right: false,
|
||||||
|
dest_logic_op,
|
||||||
|
},
|
||||||
|
OutputIntegerMode.Full64(),
|
||||||
|
if is_32bit {
|
||||||
|
ShiftRotateMode.FunnelShift2x32Bit()
|
||||||
|
} else {
|
||||||
|
ShiftRotateMode.FunnelShift2x64Bit()
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#[hdl]
|
||||||
|
fn rotate_imm_helper(
|
||||||
|
&mut self,
|
||||||
|
is_32bit: bool,
|
||||||
|
fallback_is_src2: bool,
|
||||||
|
msb0_mask_begin: Expr<UInt<6>>,
|
||||||
|
msb0_mask_end: Expr<UInt<6>>,
|
||||||
|
rotate_amount: Expr<UInt<6>>,
|
||||||
|
ra: FieldRA,
|
||||||
|
rs: FieldRS,
|
||||||
|
rc: FieldRc,
|
||||||
|
) {
|
||||||
|
// TODO: handle SO propagation
|
||||||
|
connect(
|
||||||
|
ArrayVec::len(self.output),
|
||||||
|
1usize.cast_to_static::<Length<_>>(),
|
||||||
|
);
|
||||||
|
let dest_logic_op =
|
||||||
|
self.rotate_dest_logic_op(msb0_mask_begin, msb0_mask_end, fallback_is_src2);
|
||||||
|
#[hdl]
|
||||||
|
let rotate_imm_src2 = wire();
|
||||||
|
connect(rotate_imm_src2, MOpRegNum::const_zero().value);
|
||||||
|
// if dest_logic_op is HdlNone, we don't need to read from src2
|
||||||
|
#[hdl]
|
||||||
|
if let HdlSome(dest_logic_op) = dest_logic_op {
|
||||||
|
#[hdl]
|
||||||
|
if dest_logic_op.fallback_is_src2 {
|
||||||
|
connect(rotate_imm_src2, gpr(ra.0).value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
connect(
|
||||||
|
self.output[0],
|
||||||
|
ShiftRotateMOp::shift_rotate(
|
||||||
|
MOpDestReg::new([gpr(ra.0)], [(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc.0)]),
|
||||||
|
[gpr(rs.0).value, gpr(rs.0).value, rotate_imm_src2],
|
||||||
|
#[hdl]
|
||||||
|
ShiftRotateMOpImm {
|
||||||
|
shift_rotate_amount: HdlSome(rotate_amount),
|
||||||
|
shift_rotate_right: false,
|
||||||
|
dest_logic_op,
|
||||||
|
},
|
||||||
|
OutputIntegerMode.Full64(),
|
||||||
|
if is_32bit {
|
||||||
|
ShiftRotateMode.FunnelShift2x32Bit()
|
||||||
|
} else {
|
||||||
|
ShiftRotateMode.FunnelShift2x64Bit()
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/// for `rlwinm[.]/rlwnm[.]/rlwimi[.]/rldicl[.]/rldicr[.]/rldic[.]/rldcl[.]/rldcr[.]/rldimi[.]`
|
||||||
|
#[hdl]
|
||||||
|
fn decode_rotate(&mut self) {
|
||||||
|
match self.mnemonic.trim_end_matches('.') {
|
||||||
|
"rlwinm" => self.decode_scope(
|
||||||
|
|this, (ra, rs, FieldSH(sh), FieldMB(mb), FieldME(me), rc)| {
|
||||||
|
this.rotate_imm_helper(
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
(mb + 32u8).cast_to_static::<UInt<_>>(),
|
||||||
|
(me + 32u8).cast_to_static::<UInt<_>>(),
|
||||||
|
sh.cast_to_static::<UInt<_>>(),
|
||||||
|
ra,
|
||||||
|
rs,
|
||||||
|
rc,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
"rlwnm" => self.decode_scope(|this, (ra, rs, rb, FieldMB(mb), FieldME(me), rc)| {
|
||||||
|
this.rotate_helper(
|
||||||
|
true,
|
||||||
|
(mb + 32u8).cast_to_static::<UInt<_>>(),
|
||||||
|
(me + 32u8).cast_to_static::<UInt<_>>(),
|
||||||
|
ra,
|
||||||
|
rs,
|
||||||
|
rb,
|
||||||
|
rc,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
"rlwimi" => self.decode_scope(
|
||||||
|
|this, (ra, rs, FieldSH(sh), FieldMB(mb), FieldME(me), rc)| {
|
||||||
|
this.rotate_imm_helper(
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
(mb + 32u8).cast_to_static::<UInt<_>>(),
|
||||||
|
(me + 32u8).cast_to_static::<UInt<_>>(),
|
||||||
|
sh.cast_to_static::<UInt<_>>(),
|
||||||
|
ra,
|
||||||
|
rs,
|
||||||
|
rc,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
"rldicl" => self.decode_scope(|this, (ra, rs, FieldSh(sh), FieldMb(mb), rc)| {
|
||||||
|
this.rotate_imm_helper(
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
mb.rotate_right(1),
|
||||||
|
63_hdl_u6,
|
||||||
|
sh.rotate_right(1),
|
||||||
|
ra,
|
||||||
|
rs,
|
||||||
|
rc,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
"rldicr" => self.decode_scope(|this, (ra, rs, FieldSh(sh), FieldMe(me), rc)| {
|
||||||
|
this.rotate_imm_helper(
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
0_hdl_u6,
|
||||||
|
me.rotate_right(1),
|
||||||
|
sh.rotate_right(1),
|
||||||
|
ra,
|
||||||
|
rs,
|
||||||
|
rc,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
"rldic" => self.decode_scope(|this, (ra, rs, FieldSh(sh), FieldMb(mb), rc)| {
|
||||||
|
this.rotate_imm_helper(
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
mb.rotate_right(1),
|
||||||
|
!sh.rotate_right(1),
|
||||||
|
sh.rotate_right(1),
|
||||||
|
ra,
|
||||||
|
rs,
|
||||||
|
rc,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
"rldcl" => self.decode_scope(|this, (ra, rs, rb, FieldMb(mb), rc)| {
|
||||||
|
this.rotate_helper(false, mb.rotate_right(1), 63_hdl_u6, ra, rs, rb, rc);
|
||||||
|
}),
|
||||||
|
"rldcr" => self.decode_scope(|this, (ra, rs, rb, FieldMe(me), rc)| {
|
||||||
|
this.rotate_helper(false, 0_hdl_u6, me.rotate_right(1), ra, rs, rb, rc);
|
||||||
|
}),
|
||||||
|
"rldimi" => self.decode_scope(|this, (ra, rs, FieldSh(sh), FieldMb(mb), rc)| {
|
||||||
|
this.rotate_imm_helper(
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
mb.rotate_right(1),
|
||||||
|
!sh.rotate_right(1),
|
||||||
|
sh.rotate_right(1),
|
||||||
|
ra,
|
||||||
|
rs,
|
||||||
|
rc,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
_ => unreachable!("{:?}", self.mnemonic),
|
||||||
|
}
|
||||||
|
}
|
||||||
/// for `slw[.]/srw[.]/srawi[.]/sraw[.]/sld[.]/sradi[.]/srd[.]/srad[.]`
|
/// for `slw[.]/srw[.]/srawi[.]/sraw[.]/sld[.]/sradi[.]/srd[.]/srad[.]`
|
||||||
#[hdl]
|
#[hdl]
|
||||||
fn decode_shift(&mut self) {
|
fn decode_shift(&mut self) {
|
||||||
|
|
@ -2299,9 +2543,7 @@ const DECODE_FNS: &[(&[&str], DecodeFn)] = &[
|
||||||
"rldicr", "rldicr.", "rldic", "rldic.", "rldcl", "rldcl.", "rldcr", "rldcr.", "rldimi",
|
"rldicr", "rldicr.", "rldic", "rldic.", "rldcl", "rldcl.", "rldcr", "rldcr.", "rldimi",
|
||||||
"rldimi.",
|
"rldimi.",
|
||||||
],
|
],
|
||||||
|_state| {
|
|state| DecodeState::decode_rotate(state),
|
||||||
// TODO
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
&[
|
&[
|
||||||
|
|
|
||||||
|
|
@ -1780,8 +1780,8 @@ impl HdlPartialEqImpl<Self> for ShiftRotateMode {
|
||||||
pub struct ShiftRotateDestLogicOp {
|
pub struct ShiftRotateDestLogicOp {
|
||||||
pub rotated_output_start: UInt<6>,
|
pub rotated_output_start: UInt<6>,
|
||||||
pub rotated_output_len: UInt<6>,
|
pub rotated_output_len: UInt<6>,
|
||||||
/// `false` for fallback is zeros, `true` for fallback is `src1`
|
/// `false` for fallback is zeros, `true` for fallback is `src2`
|
||||||
pub fallback_is_src1: Bool,
|
pub fallback_is_src2: Bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ShiftRotateDestLogicOp {
|
impl ShiftRotateDestLogicOp {
|
||||||
|
|
@ -1789,9 +1789,9 @@ impl ShiftRotateDestLogicOp {
|
||||||
fn operation_impl<U64, U6, U, B, S1>(
|
fn operation_impl<U64, U6, U, B, S1>(
|
||||||
rotated_output_start: U6,
|
rotated_output_start: U6,
|
||||||
rotated_output_len: U6,
|
rotated_output_len: U6,
|
||||||
fallback_is_src1: B,
|
fallback_is_src2: B,
|
||||||
rotated_output: U64,
|
rotated_output: U64,
|
||||||
src1: U64,
|
src2: U64,
|
||||||
) -> U64
|
) -> U64
|
||||||
where
|
where
|
||||||
U64: ValueType<Type = UInt<64>>
|
U64: ValueType<Type = UInt<64>>
|
||||||
|
|
@ -1812,47 +1812,47 @@ impl ShiftRotateDestLogicOp {
|
||||||
{
|
{
|
||||||
let unrotated_mask = ((1u8 << rotated_output_len) - 1u8).cast_to_static::<UInt<64>>();
|
let unrotated_mask = ((1u8 << rotated_output_len) - 1u8).cast_to_static::<UInt<64>>();
|
||||||
let mask = unrotated_mask.rotate_left(rotated_output_start);
|
let mask = unrotated_mask.rotate_left(rotated_output_start);
|
||||||
let src1_mask = fallback_is_src1
|
let src1_mask = fallback_is_src2
|
||||||
.cast_to_static::<SInt<1>>()
|
.cast_to_static::<SInt<1>>()
|
||||||
.cast_to_static::<UInt<64>>();
|
.cast_to_static::<UInt<64>>();
|
||||||
((rotated_output & mask.clone()) | (src1_mask & src1 & !mask)).cast_to_static::<UInt<64>>()
|
((rotated_output & mask.clone()) | (src1_mask & src2 & !mask)).cast_to_static::<UInt<64>>()
|
||||||
}
|
}
|
||||||
pub fn operation(
|
pub fn operation(
|
||||||
this: impl ToExpr<Type = Self>,
|
this: impl ToExpr<Type = Self>,
|
||||||
rotated_output: impl ToExpr<Type = UInt<64>>,
|
rotated_output: impl ToExpr<Type = UInt<64>>,
|
||||||
src1: impl ToExpr<Type = UInt<64>>,
|
src2: impl ToExpr<Type = UInt<64>>,
|
||||||
) -> Expr<UInt<64>> {
|
) -> Expr<UInt<64>> {
|
||||||
let this = this.to_expr();
|
let this = this.to_expr();
|
||||||
let rotated_output = rotated_output.to_expr();
|
let rotated_output = rotated_output.to_expr();
|
||||||
let src1 = src1.to_expr();
|
let src2 = src2.to_expr();
|
||||||
Self::operation_impl(
|
Self::operation_impl(
|
||||||
this.rotated_output_start,
|
this.rotated_output_start,
|
||||||
this.rotated_output_len,
|
this.rotated_output_len,
|
||||||
this.fallback_is_src1,
|
this.fallback_is_src2,
|
||||||
rotated_output,
|
rotated_output,
|
||||||
src1,
|
src2,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
#[hdl]
|
#[hdl]
|
||||||
pub fn operation_sim(
|
pub fn operation_sim(
|
||||||
this: impl ToSimValue<Type = Self>,
|
this: impl ToSimValue<Type = Self>,
|
||||||
rotated_output: impl ToSimValue<Type = UInt<64>>,
|
rotated_output: impl ToSimValue<Type = UInt<64>>,
|
||||||
src1: impl ToSimValue<Type = UInt<64>>,
|
src2: impl ToSimValue<Type = UInt<64>>,
|
||||||
) -> SimValue<UInt<64>> {
|
) -> SimValue<UInt<64>> {
|
||||||
#[hdl(sim)]
|
#[hdl(sim)]
|
||||||
let Self {
|
let Self {
|
||||||
rotated_output_start,
|
rotated_output_start,
|
||||||
rotated_output_len,
|
rotated_output_len,
|
||||||
fallback_is_src1,
|
fallback_is_src2,
|
||||||
} = this.into_sim_value();
|
} = this.into_sim_value();
|
||||||
let rotated_output = rotated_output.into_sim_value();
|
let rotated_output = rotated_output.into_sim_value();
|
||||||
let src1 = src1.into_sim_value();
|
let src2 = src2.into_sim_value();
|
||||||
Self::operation_impl(
|
Self::operation_impl(
|
||||||
rotated_output_start,
|
rotated_output_start,
|
||||||
rotated_output_len,
|
rotated_output_len,
|
||||||
fallback_is_src1,
|
fallback_is_src2,
|
||||||
rotated_output,
|
rotated_output,
|
||||||
src1,
|
src2,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -54,6 +54,17 @@ fn test_test_cases_assembly() -> std::io::Result<()> {
|
||||||
let mut lines = stdout.lines();
|
let mut lines = stdout.lines();
|
||||||
let text_line = lines.next();
|
let text_line = lines.next();
|
||||||
assert_eq!(text_line, Some("\t.text"));
|
assert_eq!(text_line, Some("\t.text"));
|
||||||
|
let mut any_error = false;
|
||||||
|
macro_rules! assert_eq_cont {
|
||||||
|
($l:expr, $r:expr, $($msg:tt)+) => {
|
||||||
|
match (&$l, &$r) {
|
||||||
|
(l, r) => if l != r {
|
||||||
|
eprintln!("assertion failed: {}\nl={l:#?}\nr={r:#?}", format_args!($($msg)+));
|
||||||
|
any_error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
for test_case @ TestCase {
|
for test_case @ TestCase {
|
||||||
mnemonic: _,
|
mnemonic: _,
|
||||||
first_input,
|
first_input,
|
||||||
|
|
@ -95,14 +106,18 @@ fn test_test_cases_assembly() -> std::io::Result<()> {
|
||||||
} else {
|
} else {
|
||||||
format!(" encoding: [0x{b0:02x},0x{b1:02x},0x{b2:02x},0x{b3:02x}]")
|
format!(" encoding: [0x{b0:02x},0x{b1:02x},0x{b2:02x},0x{b3:02x}]")
|
||||||
};
|
};
|
||||||
assert_eq!(
|
assert_eq_cont!(
|
||||||
comment, expected_comment,
|
comment,
|
||||||
|
expected_comment,
|
||||||
"test_case={test_case:?}\nline:\n{line}"
|
"test_case={test_case:?}\nline:\n{line}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
for line in lines {
|
for line in lines {
|
||||||
assert!(line.trim().is_empty(), "bad trailing output line: {line:?}");
|
assert!(line.trim().is_empty(), "bad trailing output line: {line:?}");
|
||||||
}
|
}
|
||||||
|
if any_error {
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
use crate::test_cases::{TestCase, insn_single};
|
use crate::test_cases::{TestCase, insn_single};
|
||||||
use cpu::instruction::{
|
use cpu::instruction::{
|
||||||
AddSubMOp, MOpDestReg, MOpRegNum, OutputIntegerMode, ShiftRotateMOp, ShiftRotateMOpImm,
|
MOpDestReg, MOpRegNum, OutputIntegerMode, ShiftRotateDestLogicOp, ShiftRotateMOp,
|
||||||
ShiftRotateMode,
|
ShiftRotateMOpImm, ShiftRotateMode,
|
||||||
};
|
};
|
||||||
use fayalite::prelude::*;
|
use fayalite::prelude::*;
|
||||||
|
|
||||||
|
|
@ -22,9 +22,707 @@ fn shift_imm(amount: Option<u8>, shift_right: bool) -> Expr<ShiftRotateMOpImm> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[hdl]
|
||||||
|
fn rotate_imm(
|
||||||
|
amount: Option<u8>,
|
||||||
|
rotated_output_start_and_len: Option<(u8, u8)>,
|
||||||
|
fallback_is_src2: bool,
|
||||||
|
) -> SimValue<ShiftRotateMOpImm> {
|
||||||
|
#[hdl(sim)]
|
||||||
|
ShiftRotateMOpImm {
|
||||||
|
shift_rotate_amount: if let Some(amount) = amount {
|
||||||
|
#[hdl(sim)]
|
||||||
|
HdlSome(amount.cast_to_static::<UInt<_>>())
|
||||||
|
} else {
|
||||||
|
#[hdl(sim)]
|
||||||
|
HdlNone()
|
||||||
|
},
|
||||||
|
shift_rotate_right: false,
|
||||||
|
dest_logic_op: if let Some((rotated_output_start, rotated_output_len)) =
|
||||||
|
rotated_output_start_and_len
|
||||||
|
{
|
||||||
|
#[hdl(sim)]
|
||||||
|
HdlSome(
|
||||||
|
#[hdl(sim)]
|
||||||
|
ShiftRotateDestLogicOp {
|
||||||
|
rotated_output_start: rotated_output_start.cast_to_static::<UInt<_>>(),
|
||||||
|
rotated_output_len: rotated_output_len.cast_to_static::<UInt<_>>(),
|
||||||
|
fallback_is_src2,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
#[hdl(sim)]
|
||||||
|
HdlNone()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[hdl]
|
||||||
|
fn rotate_imm_src2(imm: &SimValue<ShiftRotateMOpImm>, dest: usize) -> Expr<MOpRegNum> {
|
||||||
|
#[hdl(sim)]
|
||||||
|
match &imm.dest_logic_op {
|
||||||
|
HdlSome(dest_logic_op) => {
|
||||||
|
if *dest_logic_op.fallback_is_src2 {
|
||||||
|
MOpRegNum::power_isa_gpr_reg_imm(dest)
|
||||||
|
} else {
|
||||||
|
MOpRegNum::const_zero()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => MOpRegNum::const_zero(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// covers instructions in PowerISA v3.1C Book I 3.3.14 Fixed-Point Rotate and Shift Instructions
|
/// covers instructions in PowerISA v3.1C Book I 3.3.14 Fixed-Point Rotate and Shift Instructions
|
||||||
pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<TestCase>) {
|
pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<TestCase>) {
|
||||||
// TODO: rotate instructions
|
macro_rules! rotate_imm {
|
||||||
|
(
|
||||||
|
$mnemonic:literal $dest:literal, $src:literal, $amount:literal $(, $args:literal)*;
|
||||||
|
$encoding:literal;
|
||||||
|
$rotated_output_start_and_len:expr;
|
||||||
|
$fallback_is_src2:literal;
|
||||||
|
$shift_rotate_mode:ident;
|
||||||
|
) => {{
|
||||||
|
let imm = rotate_imm(Some($amount), $rotated_output_start_and_len, $fallback_is_src2);
|
||||||
|
let src2 = rotate_imm_src2(&imm, $dest);
|
||||||
|
retval.push(insn_single(
|
||||||
|
concat!(
|
||||||
|
$mnemonic,
|
||||||
|
" ",
|
||||||
|
stringify!($dest),
|
||||||
|
", ",
|
||||||
|
stringify!($src),
|
||||||
|
", ",
|
||||||
|
stringify!($amount),
|
||||||
|
$(", ",
|
||||||
|
stringify!($args),)*
|
||||||
|
),
|
||||||
|
$encoding,
|
||||||
|
None,
|
||||||
|
ShiftRotateMOp::shift_rotate(
|
||||||
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||||
|
[
|
||||||
|
MOpRegNum::power_isa_gpr_reg_imm($src).value,
|
||||||
|
MOpRegNum::power_isa_gpr_reg_imm($src).value,
|
||||||
|
src2.value,
|
||||||
|
],
|
||||||
|
&imm,
|
||||||
|
OutputIntegerMode.Full64(),
|
||||||
|
ShiftRotateMode.$shift_rotate_mode(),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
retval.push(insn_single(
|
||||||
|
concat!(
|
||||||
|
$mnemonic,
|
||||||
|
". ",
|
||||||
|
stringify!($dest),
|
||||||
|
", ",
|
||||||
|
stringify!($src),
|
||||||
|
", ",
|
||||||
|
stringify!($amount),
|
||||||
|
$(", ",
|
||||||
|
stringify!($args),)*
|
||||||
|
),
|
||||||
|
$encoding | 1,
|
||||||
|
None,
|
||||||
|
ShiftRotateMOp::shift_rotate(
|
||||||
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],),
|
||||||
|
[
|
||||||
|
MOpRegNum::power_isa_gpr_reg_imm($src).value,
|
||||||
|
MOpRegNum::power_isa_gpr_reg_imm($src).value,
|
||||||
|
src2.value,
|
||||||
|
],
|
||||||
|
imm,
|
||||||
|
OutputIntegerMode.Full64(),
|
||||||
|
ShiftRotateMode.$shift_rotate_mode(),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
macro_rules! rotate {
|
||||||
|
(
|
||||||
|
$mnemonic:literal $dest:literal, $src:literal, $amount:literal $(, $args:literal)*;
|
||||||
|
$encoding:literal;
|
||||||
|
$rotated_output_start_and_len:expr;
|
||||||
|
$shift_rotate_mode:ident;
|
||||||
|
) => {{
|
||||||
|
retval.push(insn_single(
|
||||||
|
concat!(
|
||||||
|
$mnemonic,
|
||||||
|
" ",
|
||||||
|
stringify!($dest),
|
||||||
|
", ",
|
||||||
|
stringify!($src),
|
||||||
|
", ",
|
||||||
|
stringify!($amount),
|
||||||
|
$(", ",
|
||||||
|
stringify!($args),)*
|
||||||
|
),
|
||||||
|
$encoding,
|
||||||
|
None,
|
||||||
|
ShiftRotateMOp::shift_rotate(
|
||||||
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||||
|
[
|
||||||
|
MOpRegNum::power_isa_gpr_reg_imm($src).value,
|
||||||
|
MOpRegNum::power_isa_gpr_reg_imm($src).value,
|
||||||
|
MOpRegNum::power_isa_gpr_reg_imm($amount).value,
|
||||||
|
],
|
||||||
|
rotate_imm(None, $rotated_output_start_and_len, false),
|
||||||
|
OutputIntegerMode.Full64(),
|
||||||
|
ShiftRotateMode.$shift_rotate_mode(),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
retval.push(insn_single(
|
||||||
|
concat!(
|
||||||
|
$mnemonic,
|
||||||
|
". ",
|
||||||
|
stringify!($dest),
|
||||||
|
", ",
|
||||||
|
stringify!($src),
|
||||||
|
", ",
|
||||||
|
stringify!($amount),
|
||||||
|
$(", ",
|
||||||
|
stringify!($args),)*
|
||||||
|
),
|
||||||
|
$encoding | 1,
|
||||||
|
None,
|
||||||
|
ShiftRotateMOp::shift_rotate(
|
||||||
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],),
|
||||||
|
[
|
||||||
|
MOpRegNum::power_isa_gpr_reg_imm($src).value,
|
||||||
|
MOpRegNum::power_isa_gpr_reg_imm($src).value,
|
||||||
|
MOpRegNum::power_isa_gpr_reg_imm($amount).value,
|
||||||
|
],
|
||||||
|
rotate_imm(None, $rotated_output_start_and_len, false),
|
||||||
|
OutputIntegerMode.Full64(),
|
||||||
|
ShiftRotateMode.$shift_rotate_mode(),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
rotate_imm! {
|
||||||
|
"rlwinm" 3, 4, 0, 0, 0;
|
||||||
|
0x54830000;
|
||||||
|
Some((31, 1));
|
||||||
|
false;
|
||||||
|
FunnelShift2x32Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rlwinm" 3, 4, 5, 0, 0;
|
||||||
|
0x54832800;
|
||||||
|
Some((31, 1));
|
||||||
|
false;
|
||||||
|
FunnelShift2x32Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rlwinm" 3, 4, 31, 0, 0;
|
||||||
|
0x5483f800;
|
||||||
|
Some((31, 1));
|
||||||
|
false;
|
||||||
|
FunnelShift2x32Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rlwinm" 3, 4, 5, 0, 16;
|
||||||
|
0x54832820;
|
||||||
|
Some((15, 17));
|
||||||
|
false;
|
||||||
|
FunnelShift2x32Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rlwinm" 3, 4, 5, 0, 31;
|
||||||
|
0x5483283e;
|
||||||
|
Some((0, 32));
|
||||||
|
false;
|
||||||
|
FunnelShift2x32Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rlwinm" 3, 4, 5, 31, 31;
|
||||||
|
0x54832ffe;
|
||||||
|
Some((0, 1));
|
||||||
|
false;
|
||||||
|
FunnelShift2x32Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rlwinm" 3, 4, 5, 31, 0;
|
||||||
|
0x54832fc0;
|
||||||
|
Some((31, 34));
|
||||||
|
false;
|
||||||
|
FunnelShift2x32Bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
rotate! {
|
||||||
|
"rlwnm" 3, 4, 5, 0, 0;
|
||||||
|
0x5c832800;
|
||||||
|
Some((31, 1));
|
||||||
|
FunnelShift2x32Bit;
|
||||||
|
}
|
||||||
|
rotate! {
|
||||||
|
"rlwnm" 3, 4, 5, 0, 16;
|
||||||
|
0x5c832820;
|
||||||
|
Some((15, 17));
|
||||||
|
FunnelShift2x32Bit;
|
||||||
|
}
|
||||||
|
rotate! {
|
||||||
|
"rlwnm" 3, 4, 5, 0, 31;
|
||||||
|
0x5c83283e;
|
||||||
|
Some((0, 32));
|
||||||
|
FunnelShift2x32Bit;
|
||||||
|
}
|
||||||
|
rotate! {
|
||||||
|
"rlwnm" 3, 4, 5, 31, 31;
|
||||||
|
0x5c832ffe;
|
||||||
|
Some((0, 1));
|
||||||
|
FunnelShift2x32Bit;
|
||||||
|
}
|
||||||
|
rotate! {
|
||||||
|
"rlwnm" 3, 4, 5, 31, 0;
|
||||||
|
0x5c832fc0;
|
||||||
|
Some((31, 34));
|
||||||
|
FunnelShift2x32Bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
rotate_imm! {
|
||||||
|
"rlwimi" 3, 4, 0, 0, 0;
|
||||||
|
0x50830000;
|
||||||
|
Some((31, 1));
|
||||||
|
true;
|
||||||
|
FunnelShift2x32Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rlwimi" 3, 4, 5, 0, 0;
|
||||||
|
0x50832800;
|
||||||
|
Some((31, 1));
|
||||||
|
true;
|
||||||
|
FunnelShift2x32Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rlwimi" 3, 4, 31, 0, 0;
|
||||||
|
0x5083f800;
|
||||||
|
Some((31, 1));
|
||||||
|
true;
|
||||||
|
FunnelShift2x32Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rlwimi" 3, 4, 5, 0, 16;
|
||||||
|
0x50832820;
|
||||||
|
Some((15, 17));
|
||||||
|
true;
|
||||||
|
FunnelShift2x32Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rlwimi" 3, 4, 5, 0, 31;
|
||||||
|
0x5083283e;
|
||||||
|
Some((0, 32));
|
||||||
|
true;
|
||||||
|
FunnelShift2x32Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rlwimi" 3, 4, 5, 31, 31;
|
||||||
|
0x50832ffe;
|
||||||
|
Some((0, 1));
|
||||||
|
true;
|
||||||
|
FunnelShift2x32Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rlwimi" 3, 4, 5, 31, 0;
|
||||||
|
0x50832fc0;
|
||||||
|
Some((31, 34));
|
||||||
|
true;
|
||||||
|
FunnelShift2x32Bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
rotate_imm! {
|
||||||
|
"rldicl" 3, 4, 0, 0;
|
||||||
|
0x78830000;
|
||||||
|
None;
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldicl" 3, 4, 5, 0;
|
||||||
|
0x78832800;
|
||||||
|
None;
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldicl" 3, 4, 16, 0;
|
||||||
|
0x78838000;
|
||||||
|
None;
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldicl" 3, 4, 31, 0;
|
||||||
|
0x7883f800;
|
||||||
|
None;
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldicl" 3, 4, 32, 0;
|
||||||
|
0x78830002;
|
||||||
|
None;
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldicl" 3, 4, 63, 0;
|
||||||
|
0x7883f802;
|
||||||
|
None;
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldicl" 3, 4, 5, 5;
|
||||||
|
0x78832940;
|
||||||
|
Some((0, 59));
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldicl" 3, 4, 5, 16;
|
||||||
|
0x78832c00;
|
||||||
|
Some((0, 48));
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldicl" 3, 4, 5, 31;
|
||||||
|
0x78832fc0;
|
||||||
|
Some((0, 33));
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldicl" 3, 4, 5, 32;
|
||||||
|
0x78832820;
|
||||||
|
Some((0, 32));
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldicl" 3, 4, 5, 63;
|
||||||
|
0x78832fe0;
|
||||||
|
Some((0, 1));
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
rotate_imm! {
|
||||||
|
"rldicr" 3, 4, 0, 63;
|
||||||
|
0x788307e4;
|
||||||
|
None;
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldicr" 3, 4, 5, 63;
|
||||||
|
0x78832fe4;
|
||||||
|
None;
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldicr" 3, 4, 16, 63;
|
||||||
|
0x788387e4;
|
||||||
|
None;
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldicr" 3, 4, 31, 63;
|
||||||
|
0x7883ffe4;
|
||||||
|
None;
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldicr" 3, 4, 32, 63;
|
||||||
|
0x788307e6;
|
||||||
|
None;
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldicr" 3, 4, 63, 63;
|
||||||
|
0x7883ffe6;
|
||||||
|
None;
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldicr" 3, 4, 5, 0;
|
||||||
|
0x78832804;
|
||||||
|
Some((63, 1));
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldicr" 3, 4, 5, 5;
|
||||||
|
0x78832944;
|
||||||
|
Some((58, 6));
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldicr" 3, 4, 5, 16;
|
||||||
|
0x78832c04;
|
||||||
|
Some((47, 17));
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldicr" 3, 4, 5, 31;
|
||||||
|
0x78832fc4;
|
||||||
|
Some((32, 32));
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldicr" 3, 4, 5, 32;
|
||||||
|
0x78832824;
|
||||||
|
Some((31, 33));
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldicr" 3, 4, 5, 63;
|
||||||
|
0x78832fe4;
|
||||||
|
None;
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
rotate_imm! {
|
||||||
|
"rldic" 3, 4, 0, 0;
|
||||||
|
0x78830008;
|
||||||
|
None;
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldic" 3, 4, 0, 16;
|
||||||
|
0x78830408;
|
||||||
|
Some((0, 48));
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldic" 3, 4, 0, 31;
|
||||||
|
0x788307c8;
|
||||||
|
Some((0, 33));
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldic" 3, 4, 0, 32;
|
||||||
|
0x78830028;
|
||||||
|
Some((0, 32));
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldic" 3, 4, 0, 63;
|
||||||
|
0x788307e8;
|
||||||
|
Some((0, 1));
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldic" 3, 4, 16, 63;
|
||||||
|
0x788387e8;
|
||||||
|
Some((16, 49));
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldic" 3, 4, 31, 63;
|
||||||
|
0x7883ffe8;
|
||||||
|
Some((31, 34));
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldic" 3, 4, 32, 63;
|
||||||
|
0x788307ea;
|
||||||
|
Some((32, 33));
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldic" 3, 4, 63, 63;
|
||||||
|
0x7883ffea;
|
||||||
|
Some((63, 2));
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldic" 3, 4, 63, 32;
|
||||||
|
0x7883f82a;
|
||||||
|
Some((63, 33));
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldic" 3, 4, 63, 0;
|
||||||
|
0x7883f80a;
|
||||||
|
Some((63, 1));
|
||||||
|
false;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
rotate! {
|
||||||
|
"rldcl" 3, 4, 5, 0;
|
||||||
|
0x78832810;
|
||||||
|
None;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate! {
|
||||||
|
"rldcl" 3, 4, 5, 5;
|
||||||
|
0x78832950;
|
||||||
|
Some((0, 59));
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate! {
|
||||||
|
"rldcl" 3, 4, 5, 16;
|
||||||
|
0x78832c10;
|
||||||
|
Some((0, 48));
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate! {
|
||||||
|
"rldcl" 3, 4, 5, 31;
|
||||||
|
0x78832fd0;
|
||||||
|
Some((0, 33));
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate! {
|
||||||
|
"rldcl" 3, 4, 5, 32;
|
||||||
|
0x78832830;
|
||||||
|
Some((0, 32));
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate! {
|
||||||
|
"rldcl" 3, 4, 5, 63;
|
||||||
|
0x78832ff0;
|
||||||
|
Some((0, 1));
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
rotate! {
|
||||||
|
"rldcr" 3, 4, 5, 0;
|
||||||
|
0x78832812;
|
||||||
|
Some((63, 1));
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate! {
|
||||||
|
"rldcr" 3, 4, 5, 5;
|
||||||
|
0x78832952;
|
||||||
|
Some((58, 6));
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate! {
|
||||||
|
"rldcr" 3, 4, 5, 16;
|
||||||
|
0x78832c12;
|
||||||
|
Some((47, 17));
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate! {
|
||||||
|
"rldcr" 3, 4, 5, 31;
|
||||||
|
0x78832fd2;
|
||||||
|
Some((32, 32));
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate! {
|
||||||
|
"rldcr" 3, 4, 5, 32;
|
||||||
|
0x78832832;
|
||||||
|
Some((31, 33));
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate! {
|
||||||
|
"rldcr" 3, 4, 5, 63;
|
||||||
|
0x78832ff2;
|
||||||
|
None;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
rotate_imm! {
|
||||||
|
"rldimi" 3, 4, 0, 0;
|
||||||
|
0x7883000c;
|
||||||
|
None;
|
||||||
|
true;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldimi" 3, 4, 0, 16;
|
||||||
|
0x7883040c;
|
||||||
|
Some((0, 48));
|
||||||
|
true;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldimi" 3, 4, 0, 31;
|
||||||
|
0x788307cc;
|
||||||
|
Some((0, 33));
|
||||||
|
true;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldimi" 3, 4, 0, 32;
|
||||||
|
0x7883002c;
|
||||||
|
Some((0, 32));
|
||||||
|
true;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldimi" 3, 4, 0, 63;
|
||||||
|
0x788307ec;
|
||||||
|
Some((0, 1));
|
||||||
|
true;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldimi" 3, 4, 16, 63;
|
||||||
|
0x788387ec;
|
||||||
|
Some((16, 49));
|
||||||
|
true;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldimi" 3, 4, 31, 63;
|
||||||
|
0x7883ffec;
|
||||||
|
Some((31, 34));
|
||||||
|
true;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldimi" 3, 4, 32, 63;
|
||||||
|
0x788307ee;
|
||||||
|
Some((32, 33));
|
||||||
|
true;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldimi" 3, 4, 63, 63;
|
||||||
|
0x7883ffee;
|
||||||
|
Some((63, 2));
|
||||||
|
true;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldimi" 3, 4, 63, 32;
|
||||||
|
0x7883f82e;
|
||||||
|
Some((63, 33));
|
||||||
|
true;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
rotate_imm! {
|
||||||
|
"rldimi" 3, 4, 63, 0;
|
||||||
|
0x7883f80e;
|
||||||
|
Some((63, 1));
|
||||||
|
true;
|
||||||
|
FunnelShift2x64Bit;
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! shift_left {
|
macro_rules! shift_left {
|
||||||
(
|
(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue