Compare commits

..

No commits in common. "more-alu-branch" and "master" have entirely different histories.

12 changed files with 14728 additions and 469730 deletions

View file

@ -1953,18 +1953,10 @@ impl DecodeState<'_> {
ShiftRotateMOpImm {
shift_rotate_amount: HdlNone(),
shift_rotate_right: false,
shift_amount_overflow_behavior: if is_32bit {
ShiftAmountOverflowBehavior.WrapToUInt5()
} else {
ShiftAmountOverflowBehavior.WrapToUInt6()
},
shift_amount_overflow_behavior: ShiftAmountOverflowBehavior.WrapToWidth(),
dest_logic_op,
},
if is_32bit {
OutputIntegerMode.DupLow32()
} else {
OutputIntegerMode.Full64()
},
OutputIntegerMode.Full64(),
if is_32bit {
ShiftRotateMode.FunnelShift2x32Bit()
} else {
@ -2012,14 +2004,10 @@ impl DecodeState<'_> {
ShiftRotateMOpImm {
shift_rotate_amount: HdlSome(rotate_amount),
shift_rotate_right: false,
shift_amount_overflow_behavior: ShiftAmountOverflowBehavior.WrapToUInt6(),
shift_amount_overflow_behavior: ShiftAmountOverflowBehavior.WrapToWidth(),
dest_logic_op,
},
if is_32bit {
OutputIntegerMode.DupLow32()
} else {
OutputIntegerMode.Full64()
},
OutputIntegerMode.Full64(),
if is_32bit {
ShiftRotateMode.FunnelShift2x32Bit()
} else {
@ -2168,7 +2156,7 @@ impl DecodeState<'_> {
shift_rotate_amount: HdlSome(sh.cast_to_static::<UInt<_>>()),
shift_rotate_right: true,
shift_amount_overflow_behavior: ShiftAmountOverflowBehavior
.WrapToUInt6(),
.WrapToWidth(),
dest_logic_op: HdlNone(),
},
OutputIntegerMode.Full64(),
@ -2198,7 +2186,7 @@ impl DecodeState<'_> {
shift_rotate_amount: HdlSome(sh.rotate_right(1)),
shift_rotate_right: true,
shift_amount_overflow_behavior: ShiftAmountOverflowBehavior
.WrapToUInt6(),
.WrapToWidth(),
dest_logic_op: HdlNone(),
},
OutputIntegerMode.Full64(),
@ -2240,19 +2228,8 @@ impl DecodeState<'_> {
ShiftRotateMOpImm {
shift_rotate_amount: HdlNone(),
shift_rotate_right: is_right_shift,
shift_amount_overflow_behavior: if is_signed && is_right_shift {
if is_32bit {
ShiftAmountOverflowBehavior.WrapToUInt6()
} else {
ShiftAmountOverflowBehavior.WrapToUInt7()
}
} else {
if is_32bit {
ShiftAmountOverflowBehavior.WrapToUInt6ZeroIfGE32()
} else {
ShiftAmountOverflowBehavior.WrapToUInt7ZeroIfGE64()
}
},
shift_amount_overflow_behavior: ShiftAmountOverflowBehavior
.WrapToTwiceWidth(),
dest_logic_op: HdlNone(),
},
OutputIntegerMode.Full64(),
@ -2289,7 +2266,7 @@ impl DecodeState<'_> {
shift_rotate_amount: HdlSome(sh.rotate_right(1)),
shift_rotate_right: false,
shift_amount_overflow_behavior: ShiftAmountOverflowBehavior
.WrapToUInt6(),
.WrapToWidth(),
dest_logic_op: HdlNone(),
},
OutputIntegerMode.Full64(),

View file

@ -2157,21 +2157,21 @@ impl<DestReg: Type, SrcReg: Type> LogicalMOp<DestReg, SrcReg, ConstUsize<1>> {
#[hdl(cmp_eq)]
pub enum ShiftRotateMode {
/// like `llvm.fsh[lr].i8(src0, src1, shift_rotate_amount)` then zero-extended to 64-bits
/// like `llvm.fsh[lr].i8(src0, src1, shift_rotate_amount.unwrap_or(src2))`
FunnelShift2x8Bit,
/// like `llvm.fsh[lr].i16(src0, src1, shift_rotate_amount)` then zero-extended to 64-bits
/// like `llvm.fsh[lr].i16(src0, src1, shift_rotate_amount.unwrap_or(src2))`
FunnelShift2x16Bit,
/// like `llvm.fsh[lr].i32(src0, src1, shift_rotate_amount)` then zero-extended to 64-bits
/// like `llvm.fsh[lr].i32(src0, src1, shift_rotate_amount.unwrap_or(src2))`
FunnelShift2x32Bit,
/// like `llvm.fsh[lr].i64(src0, src1, shift_rotate_amount)`
/// like `llvm.fsh[lr].i64(src0, src1, shift_rotate_amount.unwrap_or(src2))`
FunnelShift2x64Bit,
/// `shift(src0 as i8 as i64, shift_rotate_amount)`
/// `shift(src0 as i8 as i64, shift_rotate_amount.unwrap_or(src2))`
SignExt8To64BitThenShift,
/// `shift(src0 as i16 as i64, shift_rotate_amount)`
/// `shift(src0 as i16 as i64, shift_rotate_amount.unwrap_or(src2))`
SignExt16To64BitThenShift,
/// `shift(src0 as i32 as i64, shift_rotate_amount)`
/// `shift(src0 as i32 as i64, shift_rotate_amount.unwrap_or(src2))`
SignExt32To64BitThenShift,
/// `shift(src0 as i64, shift_rotate_amount)`
/// `shift(src0 as i64, shift_rotate_amount.unwrap_or(src2))`
ShiftSigned64,
}
@ -2275,22 +2275,10 @@ impl ShiftRotateDestLogicOp {
#[hdl(cmp_eq)]
pub enum ShiftAmountOverflowBehavior {
/// the shift amount is wrapped to fit in [`UInt<3>`], this is the same as `shift_rotate_amount % 8`
WrapToUInt3,
/// the shift amount is wrapped to fit in [`UInt<4>`], this is the same as `shift_rotate_amount % 0x10`
WrapToUInt4,
/// the shift amount is wrapped to fit in [`UInt<5>`], this is the same as `shift_rotate_amount % 0x20`
WrapToUInt5,
/// the shift amount is wrapped to fit in [`UInt<6>`], this is the same as `shift_rotate_amount % 0x40`
WrapToUInt6,
/// the shift amount is wrapped to fit in [`UInt<7>`], this is the same as `shift_rotate_amount % 0x80`
WrapToUInt7,
/// the shift amount is wrapped to fit in [`UInt<8>`], this is the same as `shift_rotate_amount % 0x100`
WrapToUInt8,
/// the shift amount is wrapped to fit in [`UInt<6>`] but the shifted output is zero if the wrapped shift amount is `>= 32`
WrapToUInt6ZeroIfGE32,
/// the shift amount is wrapped to fit in [`UInt<7>`] but the shifted output is zero if the wrapped shift amount is `>= 64`
WrapToUInt7ZeroIfGE64,
/// wrap shift amount to width specified by [`ShiftRotateMode`]
WrapToWidth,
/// wrap shift amount to twice the width specified by [`ShiftRotateMode`]
WrapToTwiceWidth,
}
/// immediate values for [`ShiftRotateMOp`].
@ -2361,31 +2349,6 @@ common_mop_struct! {
})]
#[mapped(<NewDestReg, NewSrcReg> ShiftRotateMOp<NewDestReg, NewSrcReg>)]
#[hdl(cmp_eq, custom_debug(sim))]
/// Shift/Rotate.
///
/// Operation:
/// * If [`imm.shift_rotate_amount`] is `HdlSome(v)`, then:
/// * `shift_rotate_amount` is set to `v`.
/// * `shifted_output_is_zero` is set to `false`.
/// * Otherwise:
/// * `shift_rotate_amount` and `shifted_output_is_zero` are set to the result
/// of processing `src2` according to [`imm.shift_amount_overflow_behavior`].
/// * `shifted` is set to the result of shifting/rotating `src0` and `src1` by
/// `shift_rotate_amount` according to [`mode`] and [`imm.shift_rotate_right`].
/// * If `shifted_output_is_zero`, then `shifted` is set to `0`.
/// * `extended` is set to the result of processing `shifted` according to
/// [`alu_common.output_integer_mode`].
/// * If [`imm.dest_logic_op`] is `HdlSome(o)`, then:
/// * `output` is set to the result of processing `extended` according
/// to `o` (see [`ShiftRotateDestLogicOp::operation`]).
/// * Otherwise:
/// * `output` is set to `extended`.
///
/// [`imm.shift_rotate_amount`]: ShiftRotateMOpImm::shift_rotate_amount
/// [`imm.shift_amount_overflow_behavior`]: ShiftRotateMOpImm::shift_amount_overflow_behavior
/// [`mode`]: Self::mode
/// [`imm.shift_rotate_right`]: ShiftRotateMOpImm::shift_rotate_right
/// [`imm.dest_logic_op`]: ShiftRotateMOpImm::dest_logic_op
pub struct ShiftRotateMOp<DestReg: Type, SrcReg: Type> {
#[common]
pub alu_common: AluCommonMOp<DestReg, SrcReg, ConstUsize<3>, ShiftRotateMOpImm>,

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -719,7 +719,7 @@ impl InsnsBuilder {
ShiftRotateMOpImm {
shift_rotate_amount: HdlSome(shift.cast_to_static::<UInt<_>>()),
shift_rotate_right: false,
shift_amount_overflow_behavior: ShiftAmountOverflowBehavior.WrapToUInt6(),
shift_amount_overflow_behavior: ShiftAmountOverflowBehavior.WrapToWidth(),
dest_logic_op: if rotated_output_len == 0 {
// rotated_output_len wrapped around to 64
HdlNone()
@ -735,7 +735,7 @@ impl InsnsBuilder {
)
},
},
OutputIntegerMode.DupLow32(),
OutputIntegerMode.Full64(),
ShiftRotateMode.FunnelShift2x32Bit(),
)],
));
@ -1642,7 +1642,7 @@ macro_rules! impl_funnel_shift {
}
fn funnel_shr(high: Self, low: Self, shift: u32) -> Self {
if shift == 0 {
low
high
} else {
(high << ($ty::BITS - shift)) | (low >> shift)
}
@ -1838,103 +1838,157 @@ trait MockExecutionStateTrait: Default {
shift_amount_overflow_behavior,
dest_logic_op,
} = imm;
let (shift_rotate_amount, shifted_output_is_zero) = #[hdl(sim)]
let shift_rotate_amount = #[hdl(sim)]
match shift_rotate_amount {
HdlSome(shift_rotate_amount) => (
shift_rotate_amount.cast_to_static::<UInt<64>>().as_int(),
false,
),
HdlNone => {
let do_overflow_behavior = |width: usize, zero_if_ge_half| {
let shift_rotate_amount = src_values[2].inner().int_fp.as_int() % (1 << width);
(
shift_rotate_amount,
zero_if_ge_half && shift_rotate_amount >= 1 << (width - 1),
)
};
#[hdl(sim)]
match shift_amount_overflow_behavior {
ShiftAmountOverflowBehavior::WrapToUInt3 => do_overflow_behavior(3, false),
ShiftAmountOverflowBehavior::WrapToUInt4 => do_overflow_behavior(4, false),
ShiftAmountOverflowBehavior::WrapToUInt5 => do_overflow_behavior(5, false),
ShiftAmountOverflowBehavior::WrapToUInt6 => do_overflow_behavior(6, false),
ShiftAmountOverflowBehavior::WrapToUInt7 => do_overflow_behavior(7, false),
ShiftAmountOverflowBehavior::WrapToUInt8 => do_overflow_behavior(8, false),
ShiftAmountOverflowBehavior::WrapToUInt6ZeroIfGE32 => {
do_overflow_behavior(6, true)
}
ShiftAmountOverflowBehavior::WrapToUInt7ZeroIfGE64 => {
do_overflow_behavior(7, true)
}
}
HdlSome(shift_rotate_amount) => {
shift_rotate_amount.cast_to_static::<UInt<64>>().as_int()
}
HdlNone => src_values[2].inner().int_fp.as_int(),
};
let funnel_shift = |width: u32| -> u64 {
let Ok(shift_rotate_amount) = shift_rotate_amount.try_into() else {
return 0;
};
let mask = (1 << width) - 1;
let high = src_values[0].inner().int_fp.as_int() & mask;
let low = src_values[1].inner().int_fp.as_int() & mask;
let input = ((high as u128) << width) | low as u128;
if **shift_rotate_right {
input.unbounded_shr(shift_rotate_amount) as u64 & mask
} else {
(input.unbounded_shl(shift_rotate_amount) >> width) as u64 & mask
}
};
let sign_ext_shift = |width: u32| -> u64 {
let mut input = src_values[0].inner().int_fp.as_int() as i64;
input <<= 64 - width;
input >>= 64 - width;
let Ok(shift_rotate_amount) = shift_rotate_amount.try_into() else {
return 0;
};
if **shift_rotate_right {
input.unbounded_shr(shift_rotate_amount) as u64
} else {
input.unbounded_shl(shift_rotate_amount) as u64
}
};
let mut shifted = #[hdl(sim)]
let shifted_rotated = #[hdl(sim)]
match mode {
ShiftRotateMode::FunnelShift2x8Bit => funnel_shift(8),
ShiftRotateMode::FunnelShift2x16Bit => funnel_shift(16),
ShiftRotateMode::FunnelShift2x32Bit => funnel_shift(32),
ShiftRotateMode::FunnelShift2x64Bit => funnel_shift(64),
ShiftRotateMode::SignExt8To64BitThenShift => sign_ext_shift(8),
ShiftRotateMode::SignExt16To64BitThenShift => sign_ext_shift(16),
ShiftRotateMode::SignExt32To64BitThenShift => sign_ext_shift(32),
ShiftRotateMode::ShiftSigned64 => sign_ext_shift(64),
ShiftRotateMode::FunnelShift2x8Bit => {
if shift_rotate_amount >= 8 {
todo!("large shift_rotate_amount={shift_rotate_amount}");
}
if **shift_rotate_right {
FunnelShift::funnel_shr(
src_values[0].inner().int_fp.as_int() as u8,
src_values[1].inner().int_fp.as_int() as u8,
shift_rotate_amount as _,
) as u64
} else {
FunnelShift::funnel_shl(
src_values[0].inner().int_fp.as_int() as u8,
src_values[1].inner().int_fp.as_int() as u8,
shift_rotate_amount as _,
) as u64
}
}
ShiftRotateMode::FunnelShift2x16Bit => {
if shift_rotate_amount >= 16 {
todo!("large shift_rotate_amount={shift_rotate_amount}");
}
if **shift_rotate_right {
FunnelShift::funnel_shr(
src_values[0].inner().int_fp.as_int() as u16,
src_values[1].inner().int_fp.as_int() as u16,
shift_rotate_amount as _,
) as u64
} else {
FunnelShift::funnel_shl(
src_values[0].inner().int_fp.as_int() as u16,
src_values[1].inner().int_fp.as_int() as u16,
shift_rotate_amount as _,
) as u64
}
}
ShiftRotateMode::FunnelShift2x32Bit => {
if shift_rotate_amount >= 32 {
todo!("large shift_rotate_amount={shift_rotate_amount}");
}
if **shift_rotate_right {
FunnelShift::funnel_shr(
src_values[0].inner().int_fp.as_int() as u32,
src_values[1].inner().int_fp.as_int() as u32,
shift_rotate_amount as _,
) as u64
} else {
FunnelShift::funnel_shl(
src_values[0].inner().int_fp.as_int() as u32,
src_values[1].inner().int_fp.as_int() as u32,
shift_rotate_amount as _,
) as u64
}
}
ShiftRotateMode::FunnelShift2x64Bit => {
if shift_rotate_amount >= 64 {
todo!("large shift_rotate_amount={shift_rotate_amount}");
}
if **shift_rotate_right {
FunnelShift::funnel_shr(
src_values[0].inner().int_fp.as_int(),
src_values[1].inner().int_fp.as_int(),
shift_rotate_amount as _,
)
} else {
FunnelShift::funnel_shl(
src_values[0].inner().int_fp.as_int(),
src_values[1].inner().int_fp.as_int(),
shift_rotate_amount as _,
)
}
}
ShiftRotateMode::SignExt8To64BitThenShift => {
if shift_rotate_amount >= 64 {
todo!("large shift_rotate_amount={shift_rotate_amount}");
}
let input = src_values[0].inner().int_fp.as_int() as i8 as i64;
if **shift_rotate_right {
(input >> shift_rotate_amount) as u64
} else {
(input << shift_rotate_amount) as u64
}
}
ShiftRotateMode::SignExt16To64BitThenShift => {
if shift_rotate_amount >= 64 {
todo!("large shift_rotate_amount={shift_rotate_amount}");
}
let input = src_values[0].inner().int_fp.as_int() as i16 as i64;
if **shift_rotate_right {
(input >> shift_rotate_amount) as u64
} else {
(input << shift_rotate_amount) as u64
}
}
ShiftRotateMode::SignExt32To64BitThenShift => {
if shift_rotate_amount >= 64 {
todo!("large shift_rotate_amount={shift_rotate_amount}");
}
let input = src_values[0].inner().int_fp.as_int() as i32 as i64;
if **shift_rotate_right {
(input >> shift_rotate_amount) as u64
} else {
(input << shift_rotate_amount) as u64
}
}
ShiftRotateMode::ShiftSigned64 => {
if shift_rotate_amount >= 64 {
todo!("large shift_rotate_amount={shift_rotate_amount}");
}
let input = src_values[0].inner().int_fp.as_int() as i64;
if **shift_rotate_right {
(input >> shift_rotate_amount) as u64
} else {
(input << shift_rotate_amount) as u64
}
}
};
if shifted_output_is_zero {
shifted = 0
};
let extended = #[hdl(sim)]
match output_integer_mode {
OutputIntegerMode::Full64 => shifted,
OutputIntegerMode::DupLow32 => (shifted & 0xFFFFFFFF) | (shifted << 32),
OutputIntegerMode::ZeroExt32 => shifted as u32 as u64,
OutputIntegerMode::SignExt32 => shifted as i32 as u64,
OutputIntegerMode::ZeroExt16 => shifted as u16 as u64,
OutputIntegerMode::SignExt16 => shifted as i16 as u64,
OutputIntegerMode::ZeroExt8 => shifted as u8 as u64,
OutputIntegerMode::SignExt8 => shifted as i8 as u64,
};
let output = #[hdl(sim)]
let masked = #[hdl(sim)]
if let HdlSome(dest_logic_op) = dest_logic_op {
ShiftRotateDestLogicOp::operation_sim(
dest_logic_op,
extended,
shifted_rotated,
&src_values[2].inner().int_fp,
)
.as_int()
} else {
extended
shifted_rotated
};
let int_fp = #[hdl(sim)]
match output_integer_mode {
OutputIntegerMode::Full64 => masked,
OutputIntegerMode::DupLow32 => (masked & 0xFFFFFFFF) | (masked << 32),
OutputIntegerMode::ZeroExt32 => masked as u32 as u64,
OutputIntegerMode::SignExt32 => masked as i32 as u64,
OutputIntegerMode::ZeroExt16 => masked as u16 as u64,
OutputIntegerMode::SignExt16 => masked as i16 as u64,
OutputIntegerMode::ZeroExt8 => masked as u8 as u64,
OutputIntegerMode::SignExt8 => masked as i8 as u64,
};
let retval = #[hdl(sim)]
PRegValue {
int_fp: output,
int_fp,
flags: PRegFlags::zeroed_sim(), // TODO: compute flags
};
retval.into_trace_as_string()
@ -4216,43 +4270,6 @@ fn test_rename_execute_retire_fibonacci_combinatorial() {
assert!(sim.read_bool(sim.io().all_outputs_written));
}
#[hdl]
#[test]
fn test_rename_execute_retire_fibonacci_real() {
let _n = SourceLocation::normalize_files_for_tests();
let mut config = CpuConfig::new(
vec![
UnitConfig::new(UnitKind::AluBranch),
UnitConfig::new(UnitKind::AluBranch),
UnitConfig::new(UnitKind::AluBranch),
UnitConfig::new(UnitKind::LoadStore),
UnitConfig::new(UnitKind::TransformedMove),
],
NonZeroUsize::new(20).unwrap(),
);
config.fetch_width = NonZeroUsize::new(3).unwrap();
let m = rename_execute_retire_test_harness::<FibonacciInsns>(
PhantomConst::new_sized(config),
AluBranchKind::Real,
);
let mut sim = Simulation::new(m);
let _checked_vcd_output = checked_vcd_output!(
&mut sim,
"tests/expected/rename_execute_retire_fibonacci_real.vcd",
);
sim.write_clock(sim.io().cd.clk, false);
sim.write_reset(sim.io().cd.rst, true);
for cycle in 0..200 {
sim.advance_time(SimDuration::from_nanos(500));
println!("clock tick: {cycle}");
sim.write_clock(sim.io().cd.clk, true);
sim.advance_time(SimDuration::from_nanos(500));
sim.write_clock(sim.io().cd.clk, false);
sim.write_reset(sim.io().cd.rst, false);
}
assert!(sim.read_bool(sim.io().all_outputs_written));
}
struct SlowLoopInsns;
impl SlowLoopInsns {
@ -4372,46 +4389,6 @@ fn test_rename_execute_retire_slow_loop() {
assert!(sim.read_bool(sim.io().started_any_l2_reg_file_ops));
}
#[hdl]
#[test]
fn test_rename_execute_retire_slow_loop_real() {
let _n = SourceLocation::normalize_files_for_tests();
let mut config = CpuConfig::new(
vec![
UnitConfig::new(UnitKind::AluBranch),
UnitConfig::new(UnitKind::AluBranch),
UnitConfig::new(UnitKind::AluBranch),
UnitConfig::new(UnitKind::AluBranch),
UnitConfig::new(UnitKind::LoadStore),
UnitConfig::new(UnitKind::TransformedMove),
],
NonZeroUsize::new(20).unwrap(),
);
config.fetch_width = NonZeroUsize::new(4).unwrap();
let m = rename_execute_retire_test_harness::<SlowLoopInsns>(
PhantomConst::new_sized(config),
AluBranchKind::Real,
);
let mut sim = Simulation::new(m);
let _checked_vcd_output = checked_vcd_output!(
&mut sim,
"tests/expected/rename_execute_retire_slow_loop_real.vcd",
);
sim.write_clock(sim.io().cd.clk, false);
sim.write_reset(sim.io().cd.rst, true);
for cycle in 0..350 {
sim.advance_time(SimDuration::from_nanos(500));
println!("clock tick: {cycle}");
sim.write_clock(sim.io().cd.clk, true);
sim.advance_time(SimDuration::from_nanos(500));
sim.write_clock(sim.io().cd.clk, false);
sim.write_reset(sim.io().cd.rst, false);
}
assert!(sim.read_bool(sim.io().all_outputs_written));
// make sure we're actually testing L2 reg file ops
assert!(sim.read_bool(sim.io().started_any_l2_reg_file_ops));
}
/// equivalent of Unix's `head -n1`
struct HeadN1Insns;
@ -4531,42 +4508,6 @@ fn test_rename_execute_retire_head_n1() {
assert!(sim.read_bool(sim.io().all_outputs_written));
}
#[hdl]
#[test]
fn test_rename_execute_retire_head_n1_real() {
let _n = SourceLocation::normalize_files_for_tests();
let mut config = CpuConfig::new(
vec![
UnitConfig::new(UnitKind::AluBranch),
UnitConfig::new(UnitKind::AluBranch),
UnitConfig::new(UnitKind::LoadStore),
UnitConfig::new(UnitKind::TransformedMove),
],
NonZeroUsize::new(20).unwrap(),
);
config.fetch_width = NonZeroUsize::new(2).unwrap();
let m = rename_execute_retire_test_harness::<HeadN1Insns>(
PhantomConst::new_sized(config),
AluBranchKind::Real,
);
let mut sim = Simulation::new(m);
let _checked_vcd_output = checked_vcd_output!(
&mut sim,
"tests/expected/rename_execute_retire_head_n1_real.vcd",
);
sim.write_clock(sim.io().cd.clk, false);
sim.write_reset(sim.io().cd.rst, true);
for cycle in 0..300 {
sim.advance_time(SimDuration::from_nanos(500));
println!("clock tick: {cycle}");
sim.write_clock(sim.io().cd.clk, true);
sim.advance_time(SimDuration::from_nanos(500));
sim.write_clock(sim.io().cd.clk, false);
sim.write_reset(sim.io().cd.rst, false);
}
assert!(sim.read_bool(sim.io().all_outputs_written));
}
struct SaveRestoreGprsInsns;
impl SaveRestoreGprsInsns {
@ -4668,7 +4609,7 @@ fn test_rename_execute_retire_save_restore_gprs() {
#[hdl]
#[test]
fn test_rename_execute_retire_save_restore_gprs_real() {
fn test_rename_execute_retire_real_alu_branch() {
let _n = SourceLocation::normalize_files_for_tests();
let mut config = CpuConfig::new(
vec![
@ -4687,7 +4628,7 @@ fn test_rename_execute_retire_save_restore_gprs_real() {
let mut sim = Simulation::new(m);
let _checked_vcd_output = checked_vcd_output!(
&mut sim,
"tests/expected/rename_execute_retire_save_restore_gprs_real.vcd",
"tests/expected/rename_execute_retire_real_alu_branch.vcd",
);
sim.write_clock(sim.io().cd.clk, false);
sim.write_reset(sim.io().cd.rst, true);

File diff suppressed because it is too large Load diff

View file

@ -3,10 +3,9 @@
use crate::test_cases::TestCase;
use cpu::{
checked_vcd_output, decoder::simple_power_isa::decode_one_insn, instruction::MOp,
util::array_vec::ArrayVec,
decoder::simple_power_isa::decode_one_insn, instruction::MOp, util::array_vec::ArrayVec,
};
use fayalite::prelude::*;
use fayalite::{prelude::*, sim::vcd::VcdWriterDecls, util::RcWriter};
use std::{fmt::Write as _, io::Write, process::Command};
mod test_cases;
@ -128,10 +127,22 @@ fn test_decode_insn() {
let _n = SourceLocation::normalize_files_for_tests();
let m = decode_one_insn();
let mut sim = Simulation::new(m);
let _checked_vcd_output = checked_vcd_output!(
&mut sim,
"tests/simple_power_isa_decoder/expected/decode_one_insn.vcd",
);
let writer = RcWriter::default();
sim.add_trace_writer(VcdWriterDecls::new(writer.clone()));
struct DumpVcdOnDrop {
writer: Option<RcWriter>,
}
impl Drop for DumpVcdOnDrop {
fn drop(&mut self) {
if let Some(mut writer) = self.writer.take() {
let vcd = String::from_utf8(writer.take()).unwrap();
println!("####### VCD:\n{vcd}\n#######");
}
}
}
let mut writer = DumpVcdOnDrop {
writer: Some(writer),
};
for test_case @ TestCase {
mnemonic: _,
first_input,
@ -174,6 +185,11 @@ fn test_decode_insn() {
"test_case={test_case:#?}\noutput={output}\nexpected={expected}"
);
}
let vcd = String::from_utf8(writer.writer.take().unwrap().take()).unwrap();
println!("####### VCD:\n{vcd}\n#######");
if vcd != include_str!("expected/decode_one_insn.vcd") {
panic!();
}
}
#[hdl]

View file

@ -9,11 +9,7 @@ use cpu::instruction::{
use fayalite::prelude::*;
#[hdl]
fn shift_imm(
amount: Option<u8>,
shift_right: bool,
overflow_behavior: Expr<ShiftAmountOverflowBehavior>,
) -> Expr<ShiftRotateMOpImm> {
fn shift_imm(amount: Option<u8>, shift_right: bool) -> Expr<ShiftRotateMOpImm> {
#[hdl]
ShiftRotateMOpImm {
shift_rotate_amount: if let Some(amount) = amount {
@ -22,7 +18,11 @@ fn shift_imm(
HdlNone()
},
shift_rotate_right: shift_right,
shift_amount_overflow_behavior: overflow_behavior,
shift_amount_overflow_behavior: if amount.is_some() {
ShiftAmountOverflowBehavior.WrapToWidth()
} else {
ShiftAmountOverflowBehavior.WrapToTwiceWidth()
},
dest_logic_op: HdlNone(),
}
}
@ -30,7 +30,6 @@ fn shift_imm(
#[hdl]
fn rotate_imm(
amount: Option<u8>,
overflow_behavior: Expr<ShiftAmountOverflowBehavior>,
rotated_output_start_and_len: Option<(u8, u8)>,
fallback_is_src2: bool,
) -> SimValue<ShiftRotateMOpImm> {
@ -38,7 +37,7 @@ fn rotate_imm(
ShiftRotateMOpImm {
shift_rotate_amount: amount.map(|amount| amount.cast_to_static::<UInt<_>>()),
shift_rotate_right: false,
shift_amount_overflow_behavior: overflow_behavior,
shift_amount_overflow_behavior: ShiftAmountOverflowBehavior.WrapToWidth(),
dest_logic_op: if let Some((rotated_output_start, rotated_output_len)) =
rotated_output_start_and_len
{
@ -81,15 +80,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
$encoding:literal;
$rotated_output_start_and_len:expr;
$fallback_is_src2:literal;
$output_integer_mode:ident;
$shift_rotate_mode:ident;
) => {{
let imm = rotate_imm(
Some($amount),
ShiftAmountOverflowBehavior.WrapToUInt6(),
$rotated_output_start_and_len,
$fallback_is_src2,
);
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!(
@ -113,7 +106,7 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
src2,
],
&imm,
OutputIntegerMode.$output_integer_mode(),
OutputIntegerMode.Full64(),
ShiftRotateMode.$shift_rotate_mode(),
),
));
@ -139,7 +132,7 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
src2,
],
imm,
OutputIntegerMode.$output_integer_mode(),
OutputIntegerMode.Full64(),
ShiftRotateMode.$shift_rotate_mode(),
),
));
@ -149,9 +142,7 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
(
$mnemonic:literal $dest:literal, $src:literal, $amount:literal $(, $args:literal)*;
$encoding:literal;
$overflow_behavior:ident;
$rotated_output_start_and_len:expr;
$output_integer_mode:ident;
$shift_rotate_mode:ident;
) => {{
retval.push(insn_single(
@ -175,13 +166,8 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
MOpRegNum::power_isa_gpr_reg_imm($src),
MOpRegNum::power_isa_gpr_reg_imm($amount),
],
rotate_imm(
None,
ShiftAmountOverflowBehavior.$overflow_behavior(),
$rotated_output_start_and_len,
false,
),
OutputIntegerMode.$output_integer_mode(),
rotate_imm(None, $rotated_output_start_and_len, false),
OutputIntegerMode.Full64(),
ShiftRotateMode.$shift_rotate_mode(),
),
));
@ -206,13 +192,8 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
MOpRegNum::power_isa_gpr_reg_imm($src),
MOpRegNum::power_isa_gpr_reg_imm($amount),
],
rotate_imm(
None,
ShiftAmountOverflowBehavior.$overflow_behavior(),
$rotated_output_start_and_len,
false,
),
OutputIntegerMode.$output_integer_mode(),
rotate_imm(None, $rotated_output_start_and_len, false),
OutputIntegerMode.Full64(),
ShiftRotateMode.$shift_rotate_mode(),
),
));
@ -224,7 +205,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x54830000;
Some((31, 1));
false;
DupLow32;
FunnelShift2x32Bit;
}
rotate_imm! {
@ -232,7 +212,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x54832800;
Some((31, 1));
false;
DupLow32;
FunnelShift2x32Bit;
}
rotate_imm! {
@ -240,7 +219,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x5483f800;
Some((31, 1));
false;
DupLow32;
FunnelShift2x32Bit;
}
rotate_imm! {
@ -248,7 +226,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x54832820;
Some((15, 17));
false;
DupLow32;
FunnelShift2x32Bit;
}
rotate_imm! {
@ -256,7 +233,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x5483283e;
Some((0, 32));
false;
DupLow32;
FunnelShift2x32Bit;
}
rotate_imm! {
@ -264,7 +240,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x54832ffe;
Some((0, 1));
false;
DupLow32;
FunnelShift2x32Bit;
}
rotate_imm! {
@ -272,48 +247,37 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x54832fc0;
Some((31, 34));
false;
DupLow32;
FunnelShift2x32Bit;
}
rotate! {
"rlwnm" 3, 4, 5, 0, 0;
0x5c832800;
WrapToUInt5;
Some((31, 1));
DupLow32;
FunnelShift2x32Bit;
}
rotate! {
"rlwnm" 3, 4, 5, 0, 16;
0x5c832820;
WrapToUInt5;
Some((15, 17));
DupLow32;
FunnelShift2x32Bit;
}
rotate! {
"rlwnm" 3, 4, 5, 0, 31;
0x5c83283e;
WrapToUInt5;
Some((0, 32));
DupLow32;
FunnelShift2x32Bit;
}
rotate! {
"rlwnm" 3, 4, 5, 31, 31;
0x5c832ffe;
WrapToUInt5;
Some((0, 1));
DupLow32;
FunnelShift2x32Bit;
}
rotate! {
"rlwnm" 3, 4, 5, 31, 0;
0x5c832fc0;
WrapToUInt5;
Some((31, 34));
DupLow32;
FunnelShift2x32Bit;
}
@ -322,7 +286,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x50830000;
Some((31, 1));
true;
DupLow32;
FunnelShift2x32Bit;
}
rotate_imm! {
@ -330,7 +293,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x50832800;
Some((31, 1));
true;
DupLow32;
FunnelShift2x32Bit;
}
rotate_imm! {
@ -338,7 +300,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x5083f800;
Some((31, 1));
true;
DupLow32;
FunnelShift2x32Bit;
}
rotate_imm! {
@ -346,7 +307,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x50832820;
Some((15, 17));
true;
DupLow32;
FunnelShift2x32Bit;
}
rotate_imm! {
@ -354,7 +314,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x5083283e;
Some((0, 32));
true;
DupLow32;
FunnelShift2x32Bit;
}
rotate_imm! {
@ -362,7 +321,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x50832ffe;
Some((0, 1));
true;
DupLow32;
FunnelShift2x32Bit;
}
rotate_imm! {
@ -370,7 +328,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x50832fc0;
Some((31, 34));
true;
DupLow32;
FunnelShift2x32Bit;
}
@ -379,7 +336,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x78830000;
None;
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -387,7 +343,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x78832800;
None;
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -395,7 +350,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x78838000;
None;
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -403,7 +357,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x7883f800;
None;
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -411,7 +364,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x78830002;
None;
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -419,7 +371,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x7883f802;
None;
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -427,7 +378,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x78832940;
Some((0, 59));
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -435,7 +385,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x78832c00;
Some((0, 48));
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -443,7 +392,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x78832fc0;
Some((0, 33));
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -451,7 +399,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x78832820;
Some((0, 32));
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -459,7 +406,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x78832fe0;
Some((0, 1));
false;
Full64;
FunnelShift2x64Bit;
}
@ -468,7 +414,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x788307e4;
None;
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -476,7 +421,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x78832fe4;
None;
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -484,7 +428,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x788387e4;
None;
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -492,7 +435,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x7883ffe4;
None;
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -500,7 +442,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x788307e6;
None;
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -508,7 +449,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x7883ffe6;
None;
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -516,7 +456,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x78832804;
Some((63, 1));
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -524,7 +463,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x78832944;
Some((58, 6));
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -532,7 +470,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x78832c04;
Some((47, 17));
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -540,7 +477,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x78832fc4;
Some((32, 32));
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -548,7 +484,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x78832824;
Some((31, 33));
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -556,7 +491,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x78832fe4;
None;
false;
Full64;
FunnelShift2x64Bit;
}
@ -565,7 +499,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x78830008;
None;
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -573,7 +506,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x78830408;
Some((0, 48));
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -581,7 +513,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x788307c8;
Some((0, 33));
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -589,7 +520,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x78830028;
Some((0, 32));
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -597,7 +527,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x788307e8;
Some((0, 1));
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -605,7 +534,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x788387e8;
Some((16, 49));
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -613,7 +541,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x7883ffe8;
Some((31, 34));
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -621,7 +548,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x788307ea;
Some((32, 33));
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -629,7 +555,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x7883ffea;
Some((63, 2));
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -637,7 +562,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x7883f82a;
Some((63, 33));
false;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -645,105 +569,80 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x7883f80a;
Some((63, 1));
false;
Full64;
FunnelShift2x64Bit;
}
rotate! {
"rldcl" 3, 4, 5, 0;
0x78832810;
WrapToUInt6;
None;
Full64;
FunnelShift2x64Bit;
}
rotate! {
"rldcl" 3, 4, 5, 5;
0x78832950;
WrapToUInt6;
Some((0, 59));
Full64;
FunnelShift2x64Bit;
}
rotate! {
"rldcl" 3, 4, 5, 16;
0x78832c10;
WrapToUInt6;
Some((0, 48));
Full64;
FunnelShift2x64Bit;
}
rotate! {
"rldcl" 3, 4, 5, 31;
0x78832fd0;
WrapToUInt6;
Some((0, 33));
Full64;
FunnelShift2x64Bit;
}
rotate! {
"rldcl" 3, 4, 5, 32;
0x78832830;
WrapToUInt6;
Some((0, 32));
Full64;
FunnelShift2x64Bit;
}
rotate! {
"rldcl" 3, 4, 5, 63;
0x78832ff0;
WrapToUInt6;
Some((0, 1));
Full64;
FunnelShift2x64Bit;
}
rotate! {
"rldcr" 3, 4, 5, 0;
0x78832812;
WrapToUInt6;
Some((63, 1));
Full64;
FunnelShift2x64Bit;
}
rotate! {
"rldcr" 3, 4, 5, 5;
0x78832952;
WrapToUInt6;
Some((58, 6));
Full64;
FunnelShift2x64Bit;
}
rotate! {
"rldcr" 3, 4, 5, 16;
0x78832c12;
WrapToUInt6;
Some((47, 17));
Full64;
FunnelShift2x64Bit;
}
rotate! {
"rldcr" 3, 4, 5, 31;
0x78832fd2;
WrapToUInt6;
Some((32, 32));
Full64;
FunnelShift2x64Bit;
}
rotate! {
"rldcr" 3, 4, 5, 32;
0x78832832;
WrapToUInt6;
Some((31, 33));
Full64;
FunnelShift2x64Bit;
}
rotate! {
"rldcr" 3, 4, 5, 63;
0x78832ff2;
WrapToUInt6;
None;
Full64;
FunnelShift2x64Bit;
}
@ -752,7 +651,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x7883000c;
None;
true;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -760,7 +658,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x7883040c;
Some((0, 48));
true;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -768,7 +665,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x788307cc;
Some((0, 33));
true;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -776,7 +672,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x7883002c;
Some((0, 32));
true;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -784,7 +679,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x788307ec;
Some((0, 1));
true;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -792,7 +686,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x788387ec;
Some((16, 49));
true;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -800,7 +693,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x7883ffec;
Some((31, 34));
true;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -808,7 +700,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x788307ee;
Some((32, 33));
true;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -816,7 +707,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x7883ffee;
Some((63, 2));
true;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -824,7 +714,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x7883f82e;
Some((63, 33));
true;
Full64;
FunnelShift2x64Bit;
}
rotate_imm! {
@ -832,7 +721,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
0x7883f80e;
Some((63, 1));
true;
Full64;
FunnelShift2x64Bit;
}
@ -840,7 +728,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
(
$mnemonic:literal $dest:literal, $src:literal, $amount:literal;
$encoding:literal;
$overflow_behavior:ident;
$shift_rotate_mode:ident;
) => {{
retval.push(insn_single(
@ -862,11 +749,7 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
MOpRegNum::const_zero(),
MOpRegNum::power_isa_gpr_reg_imm($amount),
],
shift_imm(
None,
false,
ShiftAmountOverflowBehavior.$overflow_behavior(),
),
shift_imm(None, false),
OutputIntegerMode.Full64(),
ShiftRotateMode.$shift_rotate_mode(),
),
@ -893,11 +776,7 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
MOpRegNum::const_zero(),
MOpRegNum::power_isa_gpr_reg_imm($amount),
],
shift_imm(
None,
false,
ShiftAmountOverflowBehavior.$overflow_behavior(),
),
shift_imm(None, false),
OutputIntegerMode.Full64(),
ShiftRotateMode.$shift_rotate_mode(),
),
@ -908,7 +787,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
(
$mnemonic:literal $dest:literal, $src:literal, $amount:literal;
$encoding:literal;
$overflow_behavior:ident;
$shift_rotate_mode:ident;
) => {{
retval.push(insn_single(
@ -930,7 +808,7 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
MOpRegNum::power_isa_gpr_reg_imm($src),
MOpRegNum::power_isa_gpr_reg_imm($amount),
],
shift_imm(None, true, ShiftAmountOverflowBehavior.$overflow_behavior()),
shift_imm(None, true),
OutputIntegerMode.Full64(),
ShiftRotateMode.$shift_rotate_mode(),
),
@ -957,7 +835,7 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
MOpRegNum::power_isa_gpr_reg_imm($src),
MOpRegNum::power_isa_gpr_reg_imm($amount),
],
shift_imm(None, true, ShiftAmountOverflowBehavior.$overflow_behavior()),
shift_imm(None, true),
OutputIntegerMode.Full64(),
ShiftRotateMode.$shift_rotate_mode(),
),
@ -968,7 +846,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
(
$mnemonic:literal $dest:literal, $src:literal, $amount:literal;
$encoding:literal;
$overflow_behavior:ident;
$shift_rotate_mode:ident;
) => {{
retval.push(insn_single(
@ -996,7 +873,7 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
MOpRegNum::const_zero(),
MOpRegNum::power_isa_gpr_reg_imm($amount),
],
shift_imm(None, true, ShiftAmountOverflowBehavior.$overflow_behavior()),
shift_imm(None, true),
OutputIntegerMode.Full64(),
ShiftRotateMode.$shift_rotate_mode(),
),
@ -1026,7 +903,7 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
MOpRegNum::const_zero(),
MOpRegNum::power_isa_gpr_reg_imm($amount),
],
shift_imm(None, true, ShiftAmountOverflowBehavior.$overflow_behavior()),
shift_imm(None, true),
OutputIntegerMode.Full64(),
ShiftRotateMode.$shift_rotate_mode(),
),
@ -1064,11 +941,7 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
MOpRegNum::const_zero(),
MOpRegNum::const_zero(),
],
shift_imm(
Some($amount),
true,
ShiftAmountOverflowBehavior.WrapToUInt6(),
),
shift_imm(Some($amount), true),
OutputIntegerMode.Full64(),
ShiftRotateMode.$shift_rotate_mode(),
),
@ -1098,11 +971,7 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
MOpRegNum::const_zero(),
MOpRegNum::const_zero(),
],
shift_imm(
Some($amount),
true,
ShiftAmountOverflowBehavior.WrapToUInt6(),
),
shift_imm(Some($amount), true),
OutputIntegerMode.Full64(),
ShiftRotateMode.$shift_rotate_mode(),
),
@ -1112,13 +981,11 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
shift_left! {
"slw" 3, 4, 5;
0x7c832830;
WrapToUInt6ZeroIfGE32;
FunnelShift2x32Bit;
}
shift_right_unsigned! {
"srw" 3, 4, 5;
0x7c832c30;
WrapToUInt6ZeroIfGE32;
FunnelShift2x32Bit;
}
shift_right_signed_imm! {
@ -1144,19 +1011,16 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
shift_right_signed! {
"sraw" 3, 4, 5;
0x7c832e30;
WrapToUInt6;
SignExt32To64BitThenShift;
}
shift_left! {
"sld" 3, 4, 5;
0x7c832836;
WrapToUInt7ZeroIfGE64;
FunnelShift2x64Bit;
}
shift_right_unsigned! {
"srd" 3, 4, 5;
0x7c832c36;
WrapToUInt7ZeroIfGE64;
FunnelShift2x64Bit;
}
shift_right_signed_imm! {
@ -1192,7 +1056,6 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
shift_right_signed! {
"srad" 3, 4, 5;
0x7c832e34;
WrapToUInt7;
ShiftSigned64;
}
macro_rules! extswsli {
@ -1219,11 +1082,7 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
MOpRegNum::const_zero(),
MOpRegNum::const_zero(),
],
shift_imm(
Some($amount),
false,
ShiftAmountOverflowBehavior.WrapToUInt6(),
),
shift_imm(Some($amount), false),
OutputIntegerMode.Full64(),
ShiftRotateMode.SignExt32To64BitThenShift(),
),
@ -1250,11 +1109,7 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
MOpRegNum::const_zero(),
MOpRegNum::const_zero(),
],
shift_imm(
Some($amount),
false,
ShiftAmountOverflowBehavior.WrapToUInt6(),
),
shift_imm(Some($amount), false),
OutputIntegerMode.Full64(),
ShiftRotateMode.SignExt32To64BitThenShift(),
),