forked from libre-chip/cpu
Compare commits
No commits in common. "241255e12cb85d8ae7ffc4a929d2b6b9ac5b00ed" and "93e948115d3f51a9f801a3f6d1f8f787789f4d30" have entirely different histories.
241255e12c
...
93e948115d
15 changed files with 89668 additions and 4451 deletions
8
Cargo.lock
generated
8
Cargo.lock
generated
|
|
@ -388,7 +388,7 @@ checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
|
|||
[[package]]
|
||||
name = "fayalite"
|
||||
version = "0.3.0"
|
||||
source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#31353862ceba3d255fd6712813a457688b269358"
|
||||
source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#cf3e6cfc6bc33eebf2d2862c7a1948b9cf40ecac"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bitvec",
|
||||
|
|
@ -417,7 +417,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "fayalite-proc-macros"
|
||||
version = "0.3.0"
|
||||
source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#31353862ceba3d255fd6712813a457688b269358"
|
||||
source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#cf3e6cfc6bc33eebf2d2862c7a1948b9cf40ecac"
|
||||
dependencies = [
|
||||
"fayalite-proc-macros-impl",
|
||||
]
|
||||
|
|
@ -425,7 +425,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "fayalite-proc-macros-impl"
|
||||
version = "0.3.0"
|
||||
source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#31353862ceba3d255fd6712813a457688b269358"
|
||||
source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#cf3e6cfc6bc33eebf2d2862c7a1948b9cf40ecac"
|
||||
dependencies = [
|
||||
"base16ct 0.2.0",
|
||||
"num-bigint",
|
||||
|
|
@ -440,7 +440,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "fayalite-visit-gen"
|
||||
version = "0.3.0"
|
||||
source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#31353862ceba3d255fd6712813a457688b269358"
|
||||
source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#cf3e6cfc6bc33eebf2d2862c7a1948b9cf40ecac"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"prettyplease",
|
||||
|
|
|
|||
|
|
@ -142,8 +142,7 @@ struct DecodeState<'a> {
|
|||
output: Expr<ArrayVec<TraceAsString<MOp>, ConstUsize<3>>>,
|
||||
is_illegal: Expr<Bool>,
|
||||
first_input: Expr<UInt<32>>,
|
||||
has_second_input: Expr<Bool>,
|
||||
second_input_value: Expr<UInt<32>>,
|
||||
second_input: Expr<HdlOption<UInt<32>>>,
|
||||
second_input_used: Expr<Bool>,
|
||||
field_wires: &'a mut HashMap<String, HashMap<Expr<UInt>, Expr<UInt>>>,
|
||||
}
|
||||
|
|
@ -430,9 +429,10 @@ impl DecodeState<'_> {
|
|||
Entry::Occupied(entry) => *entry.get(),
|
||||
}
|
||||
}
|
||||
#[hdl]
|
||||
fn decode_word(
|
||||
&mut self,
|
||||
matches: &mut Option<Expr<Bool>>,
|
||||
matches: &mut Expr<Bool>,
|
||||
fields: &mut BTreeMap<&'static str, Expr<UInt>>,
|
||||
word: Expr<UInt<32>>,
|
||||
fields_inner: &'static InstructionBitFieldsInner,
|
||||
|
|
@ -525,10 +525,7 @@ impl DecodeState<'_> {
|
|||
}
|
||||
} else {
|
||||
let value: u32 = name.parse().expect("bit field name must have at least one letter, be all `/`, or be a valid decimal number");
|
||||
*matches = match *matches {
|
||||
Some(matches) => Some(matches & field.cmp_eq(value)),
|
||||
None => Some(field.cmp_eq(value)),
|
||||
};
|
||||
*matches = *matches & field.cmp_eq(value);
|
||||
if orig_name.contains(char::is_alphabetic) {
|
||||
if fields
|
||||
.insert(orig_name, value.cast_to(field.ty()).to_expr())
|
||||
|
|
@ -540,19 +537,20 @@ impl DecodeState<'_> {
|
|||
}
|
||||
}
|
||||
}
|
||||
#[hdl]
|
||||
#[track_caller]
|
||||
fn decode_scope<FS: FieldSet, F: FnOnce(&mut Self, FS)>(&mut self, f: F) {
|
||||
let mut fields = BTreeMap::new();
|
||||
let mut matches = true.to_expr();
|
||||
let mut f = Some(f);
|
||||
#[hdl]
|
||||
#[track_caller]
|
||||
fn run<'a, FS: FieldSet, F: FnOnce(&mut DecodeState<'a>, FS)>(
|
||||
this: &mut DecodeState<'a>,
|
||||
matches: Option<Expr<Bool>>,
|
||||
matches: Expr<Bool>,
|
||||
fields: &mut BTreeMap<&str, Expr<UInt>>,
|
||||
f: &mut Option<F>,
|
||||
) {
|
||||
let matches = matches.expect("matches is known to be Some");
|
||||
#[hdl]
|
||||
if matches {
|
||||
connect(
|
||||
|
|
@ -564,22 +562,23 @@ impl DecodeState<'_> {
|
|||
}
|
||||
}
|
||||
if let Some(prefix) = self.header.bit_fields().prefix() {
|
||||
let mut matches = Some(self.has_second_input);
|
||||
self.decode_word(
|
||||
&mut matches,
|
||||
&mut fields,
|
||||
self.first_input,
|
||||
prefix.fields_inner(),
|
||||
);
|
||||
self.decode_word(
|
||||
&mut matches,
|
||||
&mut fields,
|
||||
self.second_input_value,
|
||||
self.header.bit_fields().fields_inner(),
|
||||
);
|
||||
run(self, matches, &mut fields, &mut f);
|
||||
#[hdl]
|
||||
if let HdlSome(suffix_word) = self.second_input {
|
||||
self.decode_word(
|
||||
&mut matches,
|
||||
&mut fields,
|
||||
self.first_input,
|
||||
prefix.fields_inner(),
|
||||
);
|
||||
self.decode_word(
|
||||
&mut matches,
|
||||
&mut fields,
|
||||
suffix_word,
|
||||
self.header.bit_fields().fields_inner(),
|
||||
);
|
||||
run(self, matches, &mut fields, &mut f);
|
||||
}
|
||||
} else {
|
||||
let mut matches = None;
|
||||
self.decode_word(
|
||||
&mut matches,
|
||||
&mut fields,
|
||||
|
|
@ -637,7 +636,7 @@ impl DecodeState<'_> {
|
|||
let no_cr_bit = bo[4]; // BO_0 in specification
|
||||
let (cr_field, condition_mode) = cr_bit_cond(bi);
|
||||
#[hdl]
|
||||
let branch_mop: TraceAsString<MOp> = wire();
|
||||
let branch_mop = wire();
|
||||
#[hdl]
|
||||
let branch_lr_dest_reg = wire();
|
||||
connect(branch_lr_dest_reg, MOpRegNum::const_zero());
|
||||
|
|
@ -658,7 +657,7 @@ impl DecodeState<'_> {
|
|||
#[hdl]
|
||||
if no_ctr & no_cr_bit {
|
||||
connect(
|
||||
*branch_mop,
|
||||
branch_mop,
|
||||
BranchMOp::branch_i(
|
||||
dest,
|
||||
[MOpRegNum::const_zero(), src1],
|
||||
|
|
@ -670,7 +669,7 @@ impl DecodeState<'_> {
|
|||
);
|
||||
} else if no_cr_bit {
|
||||
connect(
|
||||
*branch_mop,
|
||||
branch_mop,
|
||||
BranchMOp::branch_ctr(
|
||||
dest,
|
||||
[MOpRegNum::const_zero(), src1, branch_ctr_reg],
|
||||
|
|
@ -683,7 +682,7 @@ impl DecodeState<'_> {
|
|||
);
|
||||
} else {
|
||||
connect(
|
||||
*branch_mop,
|
||||
branch_mop,
|
||||
BranchMOp::branch_cond_ctr(
|
||||
dest,
|
||||
[cr_field, src1, branch_ctr_reg],
|
||||
|
|
@ -703,7 +702,7 @@ impl DecodeState<'_> {
|
|||
ArrayVec::len(this.output),
|
||||
1usize.cast_to_static::<Length<_>>(),
|
||||
);
|
||||
connect(this.output[0], branch_mop);
|
||||
connect(*this.output[0], branch_mop);
|
||||
connect(branch_ctr_reg, MOpRegNum::const_zero());
|
||||
} else {
|
||||
connect(
|
||||
|
|
@ -723,7 +722,7 @@ impl DecodeState<'_> {
|
|||
false,
|
||||
),
|
||||
);
|
||||
connect(this.output[1], branch_mop);
|
||||
connect(*this.output[1], branch_mop);
|
||||
connect(branch_ctr_reg, MOpRegNum::power_isa_ctr_reg());
|
||||
}
|
||||
};
|
||||
|
|
@ -2762,20 +2761,6 @@ pub fn decode_one_insn() {
|
|||
connect(second_input_used, false);
|
||||
connect(is_illegal, true);
|
||||
|
||||
#[hdl]
|
||||
let has_second_input = wire();
|
||||
#[hdl]
|
||||
let second_input_value = wire();
|
||||
|
||||
#[hdl]
|
||||
if let HdlSome(second_input) = second_input {
|
||||
connect(has_second_input, true);
|
||||
connect(second_input_value, second_input);
|
||||
} else {
|
||||
connect(has_second_input, false);
|
||||
connect(second_input_value, 0u32);
|
||||
}
|
||||
|
||||
let mut decode_fns = BTreeMap::new();
|
||||
for &(mnemonics, decode_fn) in DECODE_FNS {
|
||||
for &mnemonic in mnemonics {
|
||||
|
|
@ -2825,8 +2810,7 @@ pub fn decode_one_insn() {
|
|||
output,
|
||||
is_illegal,
|
||||
first_input,
|
||||
has_second_input,
|
||||
second_input_value,
|
||||
second_input,
|
||||
second_input_used,
|
||||
field_wires: &mut field_wires,
|
||||
});
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -149,7 +149,7 @@ fn test_decode_insn() {
|
|||
#[derive(Debug)]
|
||||
#[expect(dead_code, reason = "used only for Debug formatting")]
|
||||
struct FormattedOutput<'a> {
|
||||
insns: &'a [SimValue<TraceAsString<MOp>>],
|
||||
insns: &'a [SimValue<MOp>],
|
||||
second_input_used: bool,
|
||||
is_illegal: bool,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,23 +16,14 @@ mod fixed_point_store;
|
|||
mod move_to_from_system_register;
|
||||
mod prefixed_no_operation;
|
||||
|
||||
#[hdl(get(|_| 3))]
|
||||
pub type TestCaseOutputLen<C: PhantomConstGet<()>> = DynSize;
|
||||
|
||||
pub struct TestCase {
|
||||
pub mnemonic: &'static str,
|
||||
pub first_input: u32,
|
||||
pub second_input: Option<u32>,
|
||||
pub output: SimValue<ArrayVec<TraceAsString<MOp>, TestCaseOutputLen<PhantomConst<()>>>>,
|
||||
pub output: SimValue<ArrayVec<MOp, ConstUsize<3>>>,
|
||||
pub loc: &'static std::panic::Location<'static>,
|
||||
}
|
||||
|
||||
impl TestCase {
|
||||
pub fn output_ty() -> ArrayVec<TraceAsString<MOp>, TestCaseOutputLen<PhantomConst<()>>> {
|
||||
ArrayVec[TraceAsString[MOp]][TestCaseOutputLen[PhantomConst::default()]]
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for TestCase {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let Self {
|
||||
|
|
@ -58,91 +49,90 @@ impl fmt::Debug for TestCase {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(never)] // prevent stack overflow
|
||||
#[track_caller]
|
||||
fn insn_empty(mnemonic: &'static str, first_input: u32, second_input: Option<u32>) -> TestCase {
|
||||
let zero_mop = UInt::new_dyn(MOp.canonical().bit_width())
|
||||
.zero()
|
||||
.cast_bits_to(MOp)
|
||||
.into_trace_as_string();
|
||||
.cast_bits_to(MOp);
|
||||
TestCase {
|
||||
mnemonic,
|
||||
first_input,
|
||||
second_input,
|
||||
output: TestCase::output_ty().new_sim(zero_mop),
|
||||
output: ArrayVec::new_sim(ArrayVec[MOp][ConstUsize], &zero_mop),
|
||||
loc: std::panic::Location::caller(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)] // prevent stack overflow
|
||||
#[track_caller]
|
||||
fn insn_single<T: ToSimValue<Type = MOp>>(
|
||||
fn insn_single(
|
||||
mnemonic: &'static str,
|
||||
first_input: u32,
|
||||
second_input: Option<u32>,
|
||||
// use a closure to avoid having too many variables in one function causing a stack overflow
|
||||
output: impl FnOnce() -> T,
|
||||
output: impl ToSimValue<Type = MOp>,
|
||||
) -> TestCase {
|
||||
let mut retval = insn_empty(mnemonic, first_input, second_input);
|
||||
ArrayVec::try_push_sim(
|
||||
&mut retval.output,
|
||||
output().into_sim_value().into_trace_as_string(),
|
||||
)
|
||||
.expect("known to have space");
|
||||
retval
|
||||
let zero_mop = UInt::new_dyn(MOp.canonical().bit_width())
|
||||
.zero()
|
||||
.cast_bits_to(MOp);
|
||||
let mut single_storage = ArrayVec::new_sim(ArrayVec[MOp][ConstUsize], &zero_mop);
|
||||
ArrayVec::try_push_sim(&mut single_storage, zero_mop).expect("known to have space");
|
||||
ArrayVec::elements_sim_mut(&mut single_storage)[0] = output.to_sim_value();
|
||||
TestCase {
|
||||
mnemonic,
|
||||
first_input,
|
||||
second_input,
|
||||
output: single_storage,
|
||||
loc: std::panic::Location::caller(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)] // prevent stack overflow
|
||||
#[track_caller]
|
||||
fn insn_double<T: ToSimValue<Type = MOp>>(
|
||||
fn insn_double(
|
||||
mnemonic: &'static str,
|
||||
first_input: u32,
|
||||
second_input: Option<u32>,
|
||||
// use a closure to avoid having too many variables in one function causing a stack overflow
|
||||
insns: impl FnOnce() -> [T; 2],
|
||||
insns: [impl ToSimValue<Type = MOp>; 2],
|
||||
) -> TestCase {
|
||||
let mut retval = insn_empty(mnemonic, first_input, second_input);
|
||||
let [insn0, insn1] = insns();
|
||||
ArrayVec::try_push_sim(
|
||||
&mut retval.output,
|
||||
insn0.into_sim_value().into_trace_as_string(),
|
||||
)
|
||||
.expect("known to have space");
|
||||
ArrayVec::try_push_sim(
|
||||
&mut retval.output,
|
||||
insn1.into_sim_value().into_trace_as_string(),
|
||||
)
|
||||
.expect("known to have space");
|
||||
retval
|
||||
let zero_mop = UInt::new_dyn(MOp.canonical().bit_width())
|
||||
.zero()
|
||||
.cast_bits_to(MOp);
|
||||
let mut single_storage = ArrayVec::new_sim(ArrayVec[MOp][ConstUsize], &zero_mop);
|
||||
ArrayVec::try_push_sim(&mut single_storage, &zero_mop).expect("known to have space");
|
||||
ArrayVec::try_push_sim(&mut single_storage, zero_mop).expect("known to have space");
|
||||
ArrayVec::elements_sim_mut(&mut single_storage)[0] = insns[0].to_sim_value();
|
||||
ArrayVec::elements_sim_mut(&mut single_storage)[1] = insns[1].to_sim_value();
|
||||
TestCase {
|
||||
mnemonic,
|
||||
first_input,
|
||||
second_input,
|
||||
output: single_storage,
|
||||
loc: std::panic::Location::caller(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)] // prevent stack overflow
|
||||
#[track_caller]
|
||||
fn insn_triple<T: ToSimValue<Type = MOp>>(
|
||||
fn insn_triple(
|
||||
mnemonic: &'static str,
|
||||
first_input: u32,
|
||||
second_input: Option<u32>,
|
||||
// use a closure to avoid having too many variables in one function causing a stack overflow
|
||||
insns: impl FnOnce() -> [T; 3],
|
||||
insns: [impl ToSimValue<Type = MOp>; 3],
|
||||
) -> TestCase {
|
||||
let mut retval = insn_empty(mnemonic, first_input, second_input);
|
||||
let [insn0, insn1, insn2] = insns();
|
||||
ArrayVec::try_push_sim(
|
||||
&mut retval.output,
|
||||
insn0.into_sim_value().into_trace_as_string(),
|
||||
)
|
||||
.expect("known to have space");
|
||||
ArrayVec::try_push_sim(
|
||||
&mut retval.output,
|
||||
insn1.into_sim_value().into_trace_as_string(),
|
||||
)
|
||||
.expect("known to have space");
|
||||
ArrayVec::try_push_sim(
|
||||
&mut retval.output,
|
||||
insn2.into_sim_value().into_trace_as_string(),
|
||||
)
|
||||
.expect("known to have space");
|
||||
retval
|
||||
let zero_mop = UInt::new_dyn(MOp.canonical().bit_width())
|
||||
.zero()
|
||||
.cast_bits_to(MOp);
|
||||
let mut single_storage = ArrayVec::new_sim(ArrayVec[MOp][ConstUsize], &zero_mop);
|
||||
ArrayVec::try_push_sim(&mut single_storage, &zero_mop).expect("known to have space");
|
||||
ArrayVec::try_push_sim(&mut single_storage, &zero_mop).expect("known to have space");
|
||||
ArrayVec::try_push_sim(&mut single_storage, zero_mop).expect("known to have space");
|
||||
ArrayVec::elements_sim_mut(&mut single_storage)[0] = insns[0].to_sim_value();
|
||||
ArrayVec::elements_sim_mut(&mut single_storage)[1] = insns[1].to_sim_value();
|
||||
ArrayVec::elements_sim_mut(&mut single_storage)[2] = insns[2].to_sim_value();
|
||||
TestCase {
|
||||
mnemonic,
|
||||
first_input,
|
||||
second_input,
|
||||
output: single_storage,
|
||||
loc: std::panic::Location::caller(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn test_cases() -> Vec<TestCase> {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,10 @@ use fayalite::prelude::*;
|
|||
|
||||
/// covers instructions in PowerISA v3.1C Book I 2.4 Branch Instructions
|
||||
pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
||||
retval.push(insn_single("b 0x345678", 0x48345678, None, || {
|
||||
retval.push(insn_single(
|
||||
"b 0x345678",
|
||||
0x48345678,
|
||||
None,
|
||||
BranchMOp::branch_i(
|
||||
MOpDestReg::new_sim(&[], &[]),
|
||||
[MOpRegNum::const_zero(); 2],
|
||||
|
|
@ -17,9 +20,12 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
|||
true,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
}));
|
||||
retval.push(insn_single("ba 0x345678", 0x4834567a, None, || {
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"ba 0x345678",
|
||||
0x4834567a,
|
||||
None,
|
||||
BranchMOp::branch_i(
|
||||
MOpDestReg::new_sim(&[], &[]),
|
||||
[MOpRegNum::const_zero(); 2],
|
||||
|
|
@ -27,9 +33,12 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
|||
false,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
}));
|
||||
retval.push(insn_single("bl 0x345678", 0x48345679, None, || {
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"bl 0x345678",
|
||||
0x48345679,
|
||||
None,
|
||||
BranchMOp::branch_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_LR_REG_NUM], &[]),
|
||||
[MOpRegNum::const_zero(); 2],
|
||||
|
|
@ -37,9 +46,12 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
|||
true,
|
||||
true,
|
||||
false,
|
||||
)
|
||||
}));
|
||||
retval.push(insn_single("bla 0x345678", 0x4834567b, None, || {
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"bla 0x345678",
|
||||
0x4834567b,
|
||||
None,
|
||||
BranchMOp::branch_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_LR_REG_NUM], &[]),
|
||||
[MOpRegNum::const_zero(); 2],
|
||||
|
|
@ -47,15 +59,18 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
|||
false,
|
||||
true,
|
||||
false,
|
||||
)
|
||||
}));
|
||||
fn insn_dec_ctr_and<T: ToSimValue<Type = MOp>>(
|
||||
),
|
||||
));
|
||||
fn insn_dec_ctr_and(
|
||||
mnemonic: &'static str,
|
||||
first_input: u32,
|
||||
second_input: Option<u32>,
|
||||
second_insn: impl FnOnce() -> T,
|
||||
second_insn: impl ToSimValue<Type = MOp>,
|
||||
) -> TestCase {
|
||||
insn_double(mnemonic, first_input, second_input, || {
|
||||
insn_double(
|
||||
mnemonic,
|
||||
first_input,
|
||||
second_input,
|
||||
[
|
||||
AddSubMOp::add_sub_i::<MOp>(
|
||||
MOpDestReg::new([MOpRegNum::power_isa_ctr_reg()], []),
|
||||
|
|
@ -68,9 +83,9 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
|||
false,
|
||||
)
|
||||
.into_sim_value(),
|
||||
second_insn().into_sim_value(),
|
||||
]
|
||||
})
|
||||
second_insn.into_sim_value(),
|
||||
],
|
||||
)
|
||||
}
|
||||
macro_rules! insn_branch_conds {
|
||||
(
|
||||
|
|
@ -122,146 +137,12 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
|||
concat!($mnemonic, " 0, 0, ", $asm_last_arg),
|
||||
$encoding,
|
||||
None,
|
||||
|| {
|
||||
BranchMOp::branch_cond_ctr(
|
||||
$dest,
|
||||
[
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
$src1,
|
||||
MOpRegNum::power_isa_ctr_reg(),
|
||||
],
|
||||
$imm.cast_to_static::<SInt<_>>(),
|
||||
true,
|
||||
ConditionMode.SLt(),
|
||||
true,
|
||||
$pc_relative,
|
||||
$lk,
|
||||
$is_ret,
|
||||
)
|
||||
},
|
||||
));
|
||||
retval.push(insn_dec_ctr_and(
|
||||
concat!($mnemonic, " 0, 1, ", $asm_last_arg),
|
||||
$encoding | 0x010000,
|
||||
None,
|
||||
|| {
|
||||
BranchMOp::branch_cond_ctr(
|
||||
$dest,
|
||||
[
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
$src1,
|
||||
MOpRegNum::power_isa_ctr_reg(),
|
||||
],
|
||||
$imm.cast_to_static::<SInt<_>>(),
|
||||
true,
|
||||
ConditionMode.SGt(),
|
||||
true,
|
||||
$pc_relative,
|
||||
$lk,
|
||||
$is_ret,
|
||||
)
|
||||
},
|
||||
));
|
||||
retval.push(insn_dec_ctr_and(
|
||||
concat!($mnemonic, " 0, 2, ", $asm_last_arg),
|
||||
$encoding | 0x020000,
|
||||
None,
|
||||
|| {
|
||||
BranchMOp::branch_cond_ctr(
|
||||
$dest,
|
||||
[
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
$src1,
|
||||
MOpRegNum::power_isa_ctr_reg(),
|
||||
],
|
||||
$imm.cast_to_static::<SInt<_>>(),
|
||||
true,
|
||||
ConditionMode.Eq(),
|
||||
true,
|
||||
$pc_relative,
|
||||
$lk,
|
||||
$is_ret,
|
||||
)
|
||||
},
|
||||
));
|
||||
retval.push(insn_dec_ctr_and(
|
||||
concat!($mnemonic, " 0, 3, ", $asm_last_arg),
|
||||
$encoding | 0x030000,
|
||||
None,
|
||||
|| {
|
||||
BranchMOp::branch_cond_ctr(
|
||||
$dest,
|
||||
[
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
$src1,
|
||||
MOpRegNum::power_isa_ctr_reg(),
|
||||
],
|
||||
$imm.cast_to_static::<SInt<_>>(),
|
||||
true,
|
||||
ConditionMode.Overflow(),
|
||||
true,
|
||||
$pc_relative,
|
||||
$lk,
|
||||
$is_ret,
|
||||
)
|
||||
},
|
||||
));
|
||||
retval.push(insn_dec_ctr_and(
|
||||
concat!($mnemonic, " 0, 9, ", $asm_last_arg),
|
||||
$encoding | 0x090000,
|
||||
None,
|
||||
|| {
|
||||
BranchMOp::branch_cond_ctr(
|
||||
$dest,
|
||||
[
|
||||
MOpRegNum::power_isa_cr_reg_imm(2),
|
||||
$src1,
|
||||
MOpRegNum::power_isa_ctr_reg(),
|
||||
],
|
||||
$imm.cast_to_static::<SInt<_>>(),
|
||||
true,
|
||||
ConditionMode.SGt(),
|
||||
true,
|
||||
$pc_relative,
|
||||
$lk,
|
||||
$is_ret,
|
||||
)
|
||||
},
|
||||
));
|
||||
retval.push(insn_dec_ctr_and(
|
||||
concat!($mnemonic, " 2, 0, ", $asm_last_arg),
|
||||
$encoding | (2 << 21),
|
||||
None,
|
||||
|| {
|
||||
BranchMOp::branch_cond_ctr(
|
||||
$dest,
|
||||
[
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
$src1,
|
||||
MOpRegNum::power_isa_ctr_reg(),
|
||||
],
|
||||
$imm.cast_to_static::<SInt<_>>(),
|
||||
true,
|
||||
ConditionMode.SLt(),
|
||||
false,
|
||||
$pc_relative,
|
||||
$lk,
|
||||
$is_ret,
|
||||
)
|
||||
},
|
||||
));
|
||||
}
|
||||
retval.push(insn_single(
|
||||
concat!($mnemonic, " 4, 0, ", $asm_last_arg),
|
||||
$encoding | (4 << 21),
|
||||
None,
|
||||
|| {
|
||||
BranchMOp::branch_cond_ctr(
|
||||
$dest,
|
||||
[
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
$src1,
|
||||
MOpRegNum::const_zero(),
|
||||
MOpRegNum::power_isa_ctr_reg(),
|
||||
],
|
||||
$imm.cast_to_static::<SInt<_>>(),
|
||||
true,
|
||||
|
|
@ -270,66 +151,140 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
|||
$pc_relative,
|
||||
$lk,
|
||||
$is_ret,
|
||||
)
|
||||
},
|
||||
),
|
||||
));
|
||||
retval.push(insn_dec_ctr_and(
|
||||
concat!($mnemonic, " 0, 1, ", $asm_last_arg),
|
||||
$encoding | 0x010000,
|
||||
None,
|
||||
BranchMOp::branch_cond_ctr(
|
||||
$dest,
|
||||
[
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
$src1,
|
||||
MOpRegNum::power_isa_ctr_reg(),
|
||||
],
|
||||
$imm.cast_to_static::<SInt<_>>(),
|
||||
true,
|
||||
ConditionMode.SGt(),
|
||||
true,
|
||||
$pc_relative,
|
||||
$lk,
|
||||
$is_ret,
|
||||
),
|
||||
));
|
||||
retval.push(insn_dec_ctr_and(
|
||||
concat!($mnemonic, " 0, 2, ", $asm_last_arg),
|
||||
$encoding | 0x020000,
|
||||
None,
|
||||
BranchMOp::branch_cond_ctr(
|
||||
$dest,
|
||||
[
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
$src1,
|
||||
MOpRegNum::power_isa_ctr_reg(),
|
||||
],
|
||||
$imm.cast_to_static::<SInt<_>>(),
|
||||
true,
|
||||
ConditionMode.Eq(),
|
||||
true,
|
||||
$pc_relative,
|
||||
$lk,
|
||||
$is_ret,
|
||||
),
|
||||
));
|
||||
retval.push(insn_dec_ctr_and(
|
||||
concat!($mnemonic, " 0, 3, ", $asm_last_arg),
|
||||
$encoding | 0x030000,
|
||||
None,
|
||||
BranchMOp::branch_cond_ctr(
|
||||
$dest,
|
||||
[
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
$src1,
|
||||
MOpRegNum::power_isa_ctr_reg(),
|
||||
],
|
||||
$imm.cast_to_static::<SInt<_>>(),
|
||||
true,
|
||||
ConditionMode.Overflow(),
|
||||
true,
|
||||
$pc_relative,
|
||||
$lk,
|
||||
$is_ret,
|
||||
),
|
||||
));
|
||||
retval.push(insn_dec_ctr_and(
|
||||
concat!($mnemonic, " 0, 9, ", $asm_last_arg),
|
||||
$encoding | 0x090000,
|
||||
None,
|
||||
BranchMOp::branch_cond_ctr(
|
||||
$dest,
|
||||
[
|
||||
MOpRegNum::power_isa_cr_reg_imm(2),
|
||||
$src1,
|
||||
MOpRegNum::power_isa_ctr_reg(),
|
||||
],
|
||||
$imm.cast_to_static::<SInt<_>>(),
|
||||
true,
|
||||
ConditionMode.SGt(),
|
||||
true,
|
||||
$pc_relative,
|
||||
$lk,
|
||||
$is_ret,
|
||||
),
|
||||
));
|
||||
retval.push(insn_dec_ctr_and(
|
||||
concat!($mnemonic, " 2, 0, ", $asm_last_arg),
|
||||
$encoding | (2 << 21),
|
||||
None,
|
||||
BranchMOp::branch_cond_ctr(
|
||||
$dest,
|
||||
[
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
$src1,
|
||||
MOpRegNum::power_isa_ctr_reg(),
|
||||
],
|
||||
$imm.cast_to_static::<SInt<_>>(),
|
||||
true,
|
||||
ConditionMode.SLt(),
|
||||
false,
|
||||
$pc_relative,
|
||||
$lk,
|
||||
$is_ret,
|
||||
),
|
||||
));
|
||||
}
|
||||
retval.push(insn_single(
|
||||
concat!($mnemonic, " 4, 0, ", $asm_last_arg),
|
||||
$encoding | (4 << 21),
|
||||
None,
|
||||
BranchMOp::branch_cond_ctr(
|
||||
$dest,
|
||||
[
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
$src1,
|
||||
MOpRegNum::const_zero(),
|
||||
],
|
||||
$imm.cast_to_static::<SInt<_>>(),
|
||||
true,
|
||||
ConditionMode.SLt(),
|
||||
true,
|
||||
$pc_relative,
|
||||
$lk,
|
||||
$is_ret,
|
||||
),
|
||||
));
|
||||
if !$mnemonic.starts_with("bcctr") {
|
||||
retval.push(insn_dec_ctr_and(
|
||||
concat!($mnemonic, " 8, 0, ", $asm_last_arg),
|
||||
$encoding | (8 << 21),
|
||||
None,
|
||||
|| {
|
||||
BranchMOp::branch_cond_ctr(
|
||||
$dest,
|
||||
[
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
$src1,
|
||||
MOpRegNum::power_isa_ctr_reg(),
|
||||
],
|
||||
$imm.cast_to_static::<SInt<_>>(),
|
||||
false,
|
||||
ConditionMode.SLt(),
|
||||
true,
|
||||
$pc_relative,
|
||||
$lk,
|
||||
$is_ret,
|
||||
)
|
||||
},
|
||||
));
|
||||
retval.push(insn_dec_ctr_and(
|
||||
concat!($mnemonic, " 10, 0, ", $asm_last_arg),
|
||||
$encoding | (10 << 21),
|
||||
None,
|
||||
|| {
|
||||
BranchMOp::branch_cond_ctr(
|
||||
$dest,
|
||||
[
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
$src1,
|
||||
MOpRegNum::power_isa_ctr_reg(),
|
||||
],
|
||||
$imm.cast_to_static::<SInt<_>>(),
|
||||
false,
|
||||
ConditionMode.SLt(),
|
||||
false,
|
||||
$pc_relative,
|
||||
$lk,
|
||||
$is_ret,
|
||||
)
|
||||
},
|
||||
));
|
||||
}
|
||||
retval.push(insn_single(
|
||||
concat!($mnemonic, " 12, 0, ", $asm_last_arg),
|
||||
$encoding | (12 << 21),
|
||||
None,
|
||||
|| {
|
||||
BranchMOp::branch_cond_ctr(
|
||||
$dest,
|
||||
[
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
$src1,
|
||||
MOpRegNum::const_zero(),
|
||||
MOpRegNum::power_isa_ctr_reg(),
|
||||
],
|
||||
$imm.cast_to_static::<SInt<_>>(),
|
||||
false,
|
||||
|
|
@ -338,65 +293,99 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
|||
$pc_relative,
|
||||
$lk,
|
||||
$is_ret,
|
||||
)
|
||||
},
|
||||
),
|
||||
));
|
||||
retval.push(insn_dec_ctr_and(
|
||||
concat!($mnemonic, " 10, 0, ", $asm_last_arg),
|
||||
$encoding | (10 << 21),
|
||||
None,
|
||||
BranchMOp::branch_cond_ctr(
|
||||
$dest,
|
||||
[
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
$src1,
|
||||
MOpRegNum::power_isa_ctr_reg(),
|
||||
],
|
||||
$imm.cast_to_static::<SInt<_>>(),
|
||||
false,
|
||||
ConditionMode.SLt(),
|
||||
false,
|
||||
$pc_relative,
|
||||
$lk,
|
||||
$is_ret,
|
||||
),
|
||||
));
|
||||
}
|
||||
retval.push(insn_single(
|
||||
concat!($mnemonic, " 12, 0, ", $asm_last_arg),
|
||||
$encoding | (12 << 21),
|
||||
None,
|
||||
BranchMOp::branch_cond_ctr(
|
||||
$dest,
|
||||
[
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
$src1,
|
||||
MOpRegNum::const_zero(),
|
||||
],
|
||||
$imm.cast_to_static::<SInt<_>>(),
|
||||
false,
|
||||
ConditionMode.SLt(),
|
||||
true,
|
||||
$pc_relative,
|
||||
$lk,
|
||||
$is_ret,
|
||||
),
|
||||
));
|
||||
if !$mnemonic.starts_with("bcctr") {
|
||||
retval.push(insn_dec_ctr_and(
|
||||
concat!($mnemonic, " 16, 0, ", $asm_last_arg),
|
||||
$encoding | (16 << 21),
|
||||
None,
|
||||
|| {
|
||||
BranchMOp::branch_ctr(
|
||||
$dest,
|
||||
[
|
||||
MOpRegNum::const_zero(),
|
||||
$src1,
|
||||
MOpRegNum::power_isa_ctr_reg(),
|
||||
],
|
||||
$imm.cast_to_static::<SInt<_>>(),
|
||||
true,
|
||||
$pc_relative,
|
||||
$lk,
|
||||
$is_ret,
|
||||
)
|
||||
},
|
||||
BranchMOp::branch_ctr(
|
||||
$dest,
|
||||
[
|
||||
MOpRegNum::const_zero(),
|
||||
$src1,
|
||||
MOpRegNum::power_isa_ctr_reg(),
|
||||
],
|
||||
$imm.cast_to_static::<SInt<_>>(),
|
||||
true,
|
||||
$pc_relative,
|
||||
$lk,
|
||||
$is_ret,
|
||||
),
|
||||
));
|
||||
retval.push(insn_dec_ctr_and(
|
||||
concat!($mnemonic, " 18, 0, ", $asm_last_arg),
|
||||
$encoding | (18 << 21),
|
||||
None,
|
||||
|| {
|
||||
BranchMOp::branch_ctr(
|
||||
$dest,
|
||||
[
|
||||
MOpRegNum::const_zero(),
|
||||
$src1,
|
||||
MOpRegNum::power_isa_ctr_reg(),
|
||||
],
|
||||
$imm.cast_to_static::<SInt<_>>(),
|
||||
false,
|
||||
$pc_relative,
|
||||
$lk,
|
||||
$is_ret,
|
||||
)
|
||||
},
|
||||
BranchMOp::branch_ctr(
|
||||
$dest,
|
||||
[
|
||||
MOpRegNum::const_zero(),
|
||||
$src1,
|
||||
MOpRegNum::power_isa_ctr_reg(),
|
||||
],
|
||||
$imm.cast_to_static::<SInt<_>>(),
|
||||
false,
|
||||
$pc_relative,
|
||||
$lk,
|
||||
$is_ret,
|
||||
),
|
||||
));
|
||||
}
|
||||
retval.push(insn_single(
|
||||
concat!($mnemonic, " 20, 0, ", $asm_last_arg),
|
||||
$encoding | (20 << 21),
|
||||
None,
|
||||
|| {
|
||||
BranchMOp::branch_i(
|
||||
$dest,
|
||||
[MOpRegNum::const_zero(), $src1],
|
||||
$imm.cast_to_static::<SInt<_>>(),
|
||||
$pc_relative,
|
||||
$lk,
|
||||
$is_ret,
|
||||
)
|
||||
},
|
||||
BranchMOp::branch_i(
|
||||
$dest,
|
||||
[MOpRegNum::const_zero(), $src1],
|
||||
$imm.cast_to_static::<SInt<_>>(),
|
||||
$pc_relative,
|
||||
$lk,
|
||||
$is_ret,
|
||||
),
|
||||
));
|
||||
};
|
||||
}
|
||||
|
|
@ -446,20 +435,18 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
|||
".long 0x4e400461 # bctarl 18, 0, 0",
|
||||
0x4e400461,
|
||||
None,
|
||||
|| {
|
||||
BranchMOp::branch_ctr(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_LR_REG_NUM], &[]),
|
||||
[
|
||||
MOpRegNum::const_zero(),
|
||||
MOpRegNum::power_isa_tar_reg(),
|
||||
MOpRegNum::power_isa_ctr_reg(),
|
||||
],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
)
|
||||
},
|
||||
BranchMOp::branch_ctr(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_LR_REG_NUM], &[]),
|
||||
[
|
||||
MOpRegNum::const_zero(),
|
||||
MOpRegNum::power_isa_tar_reg(),
|
||||
MOpRegNum::power_isa_ctr_reg(),
|
||||
],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
),
|
||||
));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,70 +20,58 @@ pub fn test_cases_book_i_2_5_condition_register(retval: &mut Vec<TestCase>) {
|
|||
concat!($mnemonic, " 4*cr3+so, 4*cr1+gt, 4*cr5+lt"),
|
||||
$encoding | 0x01e5a000,
|
||||
None,
|
||||
|| {
|
||||
LogicalFlagsMOp::logical_flags(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_cr_reg_imm(1),
|
||||
MOpRegNum::power_isa_cr_reg_imm(5),
|
||||
MOpRegNum::power_isa_cr_reg_imm(3),
|
||||
],
|
||||
LogicalFlagsMOpImm::from_swizzle_fn::<PRegFlagsPowerISA>(
|
||||
|src0, src1, src2| {
|
||||
let mut dest = src2.map(|v| Some(v.into()));
|
||||
dest.so = Some((src0.cr_gt, src1.cr_lt).into());
|
||||
dest
|
||||
},
|
||||
),
|
||||
$lut,
|
||||
)
|
||||
},
|
||||
LogicalFlagsMOp::logical_flags(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_cr_reg_imm(1),
|
||||
MOpRegNum::power_isa_cr_reg_imm(5),
|
||||
MOpRegNum::power_isa_cr_reg_imm(3),
|
||||
],
|
||||
LogicalFlagsMOpImm::from_swizzle_fn::<PRegFlagsPowerISA>(|src0, src1, src2| {
|
||||
let mut dest = src2.map(|v| Some(v.into()));
|
||||
dest.so = Some((src0.cr_gt, src1.cr_lt).into());
|
||||
dest
|
||||
}),
|
||||
$lut,
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
concat!($mnemonic, " lt, gt, eq"),
|
||||
$encoding | 0x00011000,
|
||||
None,
|
||||
|| {
|
||||
LogicalFlagsMOp::logical_flags(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(0)], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
],
|
||||
LogicalFlagsMOpImm::from_swizzle_fn::<PRegFlagsPowerISA>(
|
||||
|src0, src1, src2| {
|
||||
let mut dest = src2.map(|v| Some(v.into()));
|
||||
dest.cr_lt = Some((src0.cr_gt, src1.cr_eq).into());
|
||||
dest
|
||||
},
|
||||
),
|
||||
$lut,
|
||||
)
|
||||
},
|
||||
LogicalFlagsMOp::logical_flags(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(0)], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
],
|
||||
LogicalFlagsMOpImm::from_swizzle_fn::<PRegFlagsPowerISA>(|src0, src1, src2| {
|
||||
let mut dest = src2.map(|v| Some(v.into()));
|
||||
dest.cr_lt = Some((src0.cr_gt, src1.cr_eq).into());
|
||||
dest
|
||||
}),
|
||||
$lut,
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
concat!($mnemonic, " gt, gt, eq"),
|
||||
$encoding | 0x00211000,
|
||||
None,
|
||||
|| {
|
||||
LogicalFlagsMOp::logical_flags(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(0)], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
],
|
||||
LogicalFlagsMOpImm::from_swizzle_fn::<PRegFlagsPowerISA>(
|
||||
|src0, src1, src2| {
|
||||
let mut dest = src2.map(|v| Some(v.into()));
|
||||
dest.cr_gt = Some((src0.cr_gt, src1.cr_eq).into());
|
||||
dest
|
||||
},
|
||||
),
|
||||
$lut,
|
||||
)
|
||||
},
|
||||
LogicalFlagsMOp::logical_flags(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(0)], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||
],
|
||||
LogicalFlagsMOpImm::from_swizzle_fn::<PRegFlagsPowerISA>(|src0, src1, src2| {
|
||||
let mut dest = src2.map(|v| Some(v.into()));
|
||||
dest.cr_gt = Some((src0.cr_gt, src1.cr_eq).into());
|
||||
dest
|
||||
}),
|
||||
$lut,
|
||||
),
|
||||
));
|
||||
}};
|
||||
}
|
||||
|
|
@ -101,13 +89,11 @@ pub fn test_cases_book_i_2_5_condition_register(retval: &mut Vec<TestCase>) {
|
|||
concat!("mcrf ", $dest, ", ", $src),
|
||||
$encoding,
|
||||
None,
|
||||
|| {
|
||||
MoveRegMOp::move_reg(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num($dest)], &[]),
|
||||
[MOpRegNum::power_isa_cr_reg_imm($src)],
|
||||
0i8.cast_to_static::<SInt<_>>(),
|
||||
)
|
||||
},
|
||||
MoveRegMOp::move_reg(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num($dest)], &[]),
|
||||
[MOpRegNum::power_isa_cr_reg_imm($src)],
|
||||
0i8.cast_to_static::<SInt<_>>(),
|
||||
),
|
||||
));
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,10 @@ use fayalite::prelude::*;
|
|||
|
||||
/// covers instructions in PowerISA v3.1C Book I 3.3.9 Fixed-Point Arithmetic Instructions
|
||||
pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>) {
|
||||
retval.push(insn_single("addi 3, 4, 0x1234", 0x38641234, None, || {
|
||||
retval.push(insn_single(
|
||||
"addi 3, 4, 0x1234",
|
||||
0x38641234,
|
||||
None,
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||
[MOpRegNum::power_isa_gpr_reg_imm(4), MOpRegNum::const_zero()],
|
||||
|
|
@ -17,43 +20,42 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
|||
false,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
}));
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"paddi 3, 4, 0x123456789, 0",
|
||||
0x06012345,
|
||||
Some(0x38646789),
|
||||
|| {
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||
[MOpRegNum::power_isa_gpr_reg_imm(4), MOpRegNum::const_zero()],
|
||||
0x123456789i64.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
},
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||
[MOpRegNum::power_isa_gpr_reg_imm(4), MOpRegNum::const_zero()],
|
||||
0x123456789i64.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"paddi 3, 0, 0x123456789, 1",
|
||||
0x06112345,
|
||||
Some(0x38606789),
|
||||
|| {
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||
[MOpRegNum::const_zero(), MOpRegNum::const_zero()],
|
||||
0x123456789i64.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
)
|
||||
},
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||
[MOpRegNum::const_zero(), MOpRegNum::const_zero()],
|
||||
0x123456789i64.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
),
|
||||
));
|
||||
retval.push(insn_single("addis 3, 4, 0x1234", 0x3C641234, None, || {
|
||||
retval.push(insn_single(
|
||||
"addis 3, 4, 0x1234",
|
||||
0x3C641234,
|
||||
None,
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||
[MOpRegNum::power_isa_gpr_reg_imm(4), MOpRegNum::const_zero()],
|
||||
|
|
@ -63,9 +65,12 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
|||
false,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
}));
|
||||
retval.push(insn_single("addpcis 3, 0x1234", 0x4c7a1204, None, || {
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"addpcis 3, 0x1234",
|
||||
0x4c7a1204,
|
||||
None,
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||
[MOpRegNum::const_zero(); _],
|
||||
|
|
@ -75,9 +80,12 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
|||
false,
|
||||
false,
|
||||
true,
|
||||
)
|
||||
}));
|
||||
retval.push(insn_single("add. 3, 4, 5", 0x7c642a15, None, || {
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"add. 3, 4, 5",
|
||||
0x7c642a15,
|
||||
None,
|
||||
AddSubMOp::add_sub(
|
||||
MOpDestReg::new_sim(
|
||||
&[MOpRegNum::power_isa_gpr_reg_num(3)],
|
||||
|
|
@ -94,9 +102,12 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
|||
false,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
}));
|
||||
retval.push(insn_single("addic. 3, 4, 0x1234", 0x34641234, None, || {
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"addic. 3, 4, 0x1234",
|
||||
0x34641234,
|
||||
None,
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(
|
||||
&[
|
||||
|
|
@ -112,9 +123,12 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
|||
false,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
}));
|
||||
retval.push(insn_single("subf. 3, 4, 5", 0x7c642851, None, || {
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"subf. 3, 4, 5",
|
||||
0x7c642851,
|
||||
None,
|
||||
AddSubMOp::add_sub(
|
||||
MOpDestReg::new_sim(
|
||||
&[MOpRegNum::power_isa_gpr_reg_num(3)],
|
||||
|
|
@ -131,9 +145,12 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
|||
false,
|
||||
true,
|
||||
false,
|
||||
)
|
||||
}));
|
||||
retval.push(insn_single("subfic 3, 4, 0x1234", 0x20641234, None, || {
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"subfic 3, 4, 0x1234",
|
||||
0x20641234,
|
||||
None,
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(
|
||||
&[
|
||||
|
|
@ -149,9 +166,12 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
|||
false,
|
||||
true,
|
||||
false,
|
||||
)
|
||||
}));
|
||||
retval.push(insn_single("addc. 3, 4, 5", 0x7c642815, None, || {
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"addc. 3, 4, 5",
|
||||
0x7c642815,
|
||||
None,
|
||||
AddSubMOp::add_sub(
|
||||
MOpDestReg::new_sim(
|
||||
&[
|
||||
|
|
@ -171,9 +191,12 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
|||
false,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
}));
|
||||
retval.push(insn_single("subfc. 3, 4, 5", 0x7c642811, None, || {
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"subfc. 3, 4, 5",
|
||||
0x7c642811,
|
||||
None,
|
||||
AddSubMOp::add_sub(
|
||||
MOpDestReg::new_sim(
|
||||
&[
|
||||
|
|
@ -193,9 +216,12 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
|||
false,
|
||||
true,
|
||||
false,
|
||||
)
|
||||
}));
|
||||
retval.push(insn_single("adde. 3, 4, 5", 0x7c642915, None, || {
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"adde. 3, 4, 5",
|
||||
0x7c642915,
|
||||
None,
|
||||
AddSubMOp::add_sub(
|
||||
MOpDestReg::new_sim(
|
||||
&[
|
||||
|
|
@ -215,9 +241,12 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
|||
true,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
}));
|
||||
retval.push(insn_single("subfe. 3, 4, 5", 0x7c642911, None, || {
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"subfe. 3, 4, 5",
|
||||
0x7c642911,
|
||||
None,
|
||||
AddSubMOp::add_sub(
|
||||
MOpDestReg::new_sim(
|
||||
&[
|
||||
|
|
@ -237,9 +266,12 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
|||
true,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
}));
|
||||
retval.push(insn_single("addme. 3, 4", 0x7c6401d5, None, || {
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"addme. 3, 4",
|
||||
0x7c6401d5,
|
||||
None,
|
||||
AddSubMOp::add_sub(
|
||||
MOpDestReg::new_sim(
|
||||
&[
|
||||
|
|
@ -259,9 +291,12 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
|||
true,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
}));
|
||||
retval.push(insn_single("subfme. 3, 4", 0x7c6401d1, None, || {
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"subfme. 3, 4",
|
||||
0x7c6401d1,
|
||||
None,
|
||||
AddSubMOp::add_sub(
|
||||
MOpDestReg::new_sim(
|
||||
&[
|
||||
|
|
@ -281,9 +316,12 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
|||
true,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
}));
|
||||
retval.push(insn_single("addze. 3, 4", 0x7c640195, None, || {
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"addze. 3, 4",
|
||||
0x7c640195,
|
||||
None,
|
||||
AddSubMOp::add_sub(
|
||||
MOpDestReg::new_sim(
|
||||
&[
|
||||
|
|
@ -303,9 +341,12 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
|||
true,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
}));
|
||||
retval.push(insn_single("subfze. 3, 4", 0x7c640191, None, || {
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"subfze. 3, 4",
|
||||
0x7c640191,
|
||||
None,
|
||||
AddSubMOp::add_sub(
|
||||
MOpDestReg::new_sim(
|
||||
&[
|
||||
|
|
@ -325,9 +366,12 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
|||
true,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
}));
|
||||
retval.push(insn_single("neg. 3, 4", 0x7c6400d1, None, || {
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"neg. 3, 4",
|
||||
0x7c6400d1,
|
||||
None,
|
||||
AddSubMOp::add_sub(
|
||||
MOpDestReg::new_sim(
|
||||
&[MOpRegNum::power_isa_gpr_reg_num(3)],
|
||||
|
|
@ -344,6 +388,6 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
|||
false,
|
||||
true,
|
||||
false,
|
||||
)
|
||||
}));
|
||||
),
|
||||
));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,29 +11,28 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
|
|||
"cmpi 3, 0, 4, 0x1234",
|
||||
0x2d841234,
|
||||
None,
|
||||
|| {
|
||||
CompareMOp::compare_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||
[MOpRegNum::power_isa_gpr_reg_imm(4)],
|
||||
0x1234.cast_to_static::<SInt<_>>(),
|
||||
CompareMode.S32(),
|
||||
)
|
||||
},
|
||||
CompareMOp::compare_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||
[MOpRegNum::power_isa_gpr_reg_imm(4)],
|
||||
0x1234.cast_to_static::<SInt<_>>(),
|
||||
CompareMode.S32(),
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"cmpi 3, 1, 4, -0x7655",
|
||||
0x2da489ab,
|
||||
None,
|
||||
|| {
|
||||
CompareMOp::compare_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||
[MOpRegNum::power_isa_gpr_reg_imm(4)],
|
||||
(0x89abu16 as i16).cast_to_static::<SInt<_>>(),
|
||||
CompareMode.S64(),
|
||||
)
|
||||
},
|
||||
CompareMOp::compare_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||
[MOpRegNum::power_isa_gpr_reg_imm(4)],
|
||||
(0x89abu16 as i16).cast_to_static::<SInt<_>>(),
|
||||
CompareMode.S64(),
|
||||
),
|
||||
));
|
||||
retval.push(insn_single("cmp 3, 0, 4, 5", 0x7d842800, None, || {
|
||||
retval.push(insn_single(
|
||||
"cmp 3, 0, 4, 5",
|
||||
0x7d842800,
|
||||
None,
|
||||
CompareMOp::compare(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||
[
|
||||
|
|
@ -41,9 +40,12 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
|
|||
MOpRegNum::power_isa_gpr_reg_imm(5),
|
||||
],
|
||||
CompareMode.S32(),
|
||||
)
|
||||
}));
|
||||
retval.push(insn_single("cmp 3, 1, 4, 5", 0x7da42800, None, || {
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"cmp 3, 1, 4, 5",
|
||||
0x7da42800,
|
||||
None,
|
||||
CompareMOp::compare(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||
[
|
||||
|
|
@ -51,35 +53,34 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
|
|||
MOpRegNum::power_isa_gpr_reg_imm(5),
|
||||
],
|
||||
CompareMode.S64(),
|
||||
)
|
||||
}));
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"cmpli 3, 0, 4, 0x1234",
|
||||
0x29841234,
|
||||
None,
|
||||
|| {
|
||||
CompareMOp::compare_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||
[MOpRegNum::power_isa_gpr_reg_imm(4)],
|
||||
0x1234.cast_to_static::<SInt<_>>(),
|
||||
CompareMode.U32(),
|
||||
)
|
||||
},
|
||||
CompareMOp::compare_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||
[MOpRegNum::power_isa_gpr_reg_imm(4)],
|
||||
0x1234.cast_to_static::<SInt<_>>(),
|
||||
CompareMode.U32(),
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"cmpli 3, 1, 4, 0x89ab",
|
||||
0x29a489ab,
|
||||
None,
|
||||
|| {
|
||||
CompareMOp::compare_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||
[MOpRegNum::power_isa_gpr_reg_imm(4)],
|
||||
0x89ab.cast_to_static::<SInt<_>>(),
|
||||
CompareMode.U64(),
|
||||
)
|
||||
},
|
||||
CompareMOp::compare_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||
[MOpRegNum::power_isa_gpr_reg_imm(4)],
|
||||
0x89ab.cast_to_static::<SInt<_>>(),
|
||||
CompareMode.U64(),
|
||||
),
|
||||
));
|
||||
retval.push(insn_single("cmpl 3, 0, 4, 5", 0x7d842840, None, || {
|
||||
retval.push(insn_single(
|
||||
"cmpl 3, 0, 4, 5",
|
||||
0x7d842840,
|
||||
None,
|
||||
CompareMOp::compare(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||
[
|
||||
|
|
@ -87,9 +88,12 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
|
|||
MOpRegNum::power_isa_gpr_reg_imm(5),
|
||||
],
|
||||
CompareMode.U32(),
|
||||
)
|
||||
}));
|
||||
retval.push(insn_single("cmpl 3, 1, 4, 5", 0x7da42840, None, || {
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"cmpl 3, 1, 4, 5",
|
||||
0x7da42840,
|
||||
None,
|
||||
CompareMOp::compare(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||
[
|
||||
|
|
@ -97,9 +101,12 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
|
|||
MOpRegNum::power_isa_gpr_reg_imm(5),
|
||||
],
|
||||
CompareMode.U64(),
|
||||
)
|
||||
}));
|
||||
retval.push(insn_single("cmprb 3, 0, 4, 5", 0x7d842980, None, || {
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"cmprb 3, 0, 4, 5",
|
||||
0x7d842980,
|
||||
None,
|
||||
CompareMOp::compare(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||
[
|
||||
|
|
@ -107,9 +114,12 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
|
|||
MOpRegNum::power_isa_gpr_reg_imm(5),
|
||||
],
|
||||
CompareMode.CmpRBOne(),
|
||||
)
|
||||
}));
|
||||
retval.push(insn_single("cmprb 3, 1, 4, 5", 0x7da42980, None, || {
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"cmprb 3, 1, 4, 5",
|
||||
0x7da42980,
|
||||
None,
|
||||
CompareMOp::compare(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||
[
|
||||
|
|
@ -117,9 +127,12 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
|
|||
MOpRegNum::power_isa_gpr_reg_imm(5),
|
||||
],
|
||||
CompareMode.CmpRBTwo(),
|
||||
)
|
||||
}));
|
||||
retval.push(insn_single("cmpeqb 3, 4, 5", 0x7d8429c0, None, || {
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"cmpeqb 3, 4, 5",
|
||||
0x7d8429c0,
|
||||
None,
|
||||
CompareMOp::compare(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||
[
|
||||
|
|
@ -127,6 +140,6 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
|
|||
MOpRegNum::power_isa_gpr_reg_imm(5),
|
||||
],
|
||||
CompareMode.CmpEqB(),
|
||||
)
|
||||
}));
|
||||
),
|
||||
));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,33 +21,31 @@ pub fn test_cases_book_i_3_3_2_fixed_point_load(retval: &mut Vec<TestCase>) {
|
|||
concat!($mnemonic, " ", $dest, ", ", $disp, "(", $ra, "), ", $r),
|
||||
$prefix,
|
||||
Some($suffix),
|
||||
|| {
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||
[
|
||||
if $r != 0 || $ra == 0 {
|
||||
MOpRegNum::const_zero()
|
||||
} else {
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra)
|
||||
},
|
||||
MOpRegNum::const_zero(),
|
||||
],
|
||||
($disp as i64).cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
$r != 0,
|
||||
),
|
||||
LoadMOp::load(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||
[MOpRegNum::power_isa_temp_reg()],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.$conversion(),
|
||||
),
|
||||
]
|
||||
},
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||
[
|
||||
if $r != 0 || $ra == 0 {
|
||||
MOpRegNum::const_zero()
|
||||
} else {
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra)
|
||||
},
|
||||
MOpRegNum::const_zero(),
|
||||
],
|
||||
($disp as i64).cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
$r != 0,
|
||||
),
|
||||
LoadMOp::load(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||
[MOpRegNum::power_isa_temp_reg()],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.$conversion(),
|
||||
),
|
||||
],
|
||||
));
|
||||
};
|
||||
}
|
||||
|
|
@ -62,33 +60,31 @@ pub fn test_cases_book_i_3_3_2_fixed_point_load(retval: &mut Vec<TestCase>) {
|
|||
concat!($mnemonic, " ", $dest, ", ", $disp, "(", $ra, ")"),
|
||||
$encoding,
|
||||
None,
|
||||
|| {
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||
[
|
||||
if $ra == 0 {
|
||||
MOpRegNum::const_zero()
|
||||
} else {
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra)
|
||||
},
|
||||
MOpRegNum::const_zero(),
|
||||
],
|
||||
($disp as i64).cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
LoadMOp::load(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||
[MOpRegNum::power_isa_temp_reg()],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.$conversion(),
|
||||
),
|
||||
]
|
||||
},
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||
[
|
||||
if $ra == 0 {
|
||||
MOpRegNum::const_zero()
|
||||
} else {
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra)
|
||||
},
|
||||
MOpRegNum::const_zero(),
|
||||
],
|
||||
($disp as i64).cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
LoadMOp::load(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||
[MOpRegNum::power_isa_temp_reg()],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.$conversion(),
|
||||
),
|
||||
],
|
||||
));
|
||||
};
|
||||
}
|
||||
|
|
@ -103,29 +99,27 @@ pub fn test_cases_book_i_3_3_2_fixed_point_load(retval: &mut Vec<TestCase>) {
|
|||
concat!($mnemonic, " ", $dest, ", ", $disp, "(", $ra, ")"),
|
||||
$encoding,
|
||||
None,
|
||||
|| {
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra),
|
||||
MOpRegNum::const_zero(),
|
||||
],
|
||||
($disp as i64).cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
LoadMOp::load(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||
[MOpRegNum::power_isa_gpr_reg_imm($ra)],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.$conversion(),
|
||||
),
|
||||
]
|
||||
},
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra),
|
||||
MOpRegNum::const_zero(),
|
||||
],
|
||||
($disp as i64).cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
LoadMOp::load(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||
[MOpRegNum::power_isa_gpr_reg_imm($ra)],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.$conversion(),
|
||||
),
|
||||
],
|
||||
));
|
||||
};
|
||||
}
|
||||
|
|
@ -140,33 +134,31 @@ pub fn test_cases_book_i_3_3_2_fixed_point_load(retval: &mut Vec<TestCase>) {
|
|||
concat!($mnemonic, " ", $dest, ", ", $ra, ", ", $rb),
|
||||
$encoding,
|
||||
None,
|
||||
|| {
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||
[
|
||||
if $ra == 0 {
|
||||
MOpRegNum::const_zero()
|
||||
} else {
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra)
|
||||
},
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rb),
|
||||
],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
LoadMOp::load(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||
[MOpRegNum::power_isa_temp_reg()],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.$conversion(),
|
||||
),
|
||||
]
|
||||
},
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||
[
|
||||
if $ra == 0 {
|
||||
MOpRegNum::const_zero()
|
||||
} else {
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra)
|
||||
},
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rb),
|
||||
],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
LoadMOp::load(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||
[MOpRegNum::power_isa_temp_reg()],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.$conversion(),
|
||||
),
|
||||
],
|
||||
));
|
||||
};
|
||||
}
|
||||
|
|
@ -181,29 +173,27 @@ pub fn test_cases_book_i_3_3_2_fixed_point_load(retval: &mut Vec<TestCase>) {
|
|||
concat!($mnemonic, " ", $dest, ", ", $ra, ", ", $rb),
|
||||
$encoding,
|
||||
None,
|
||||
|| {
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rb),
|
||||
],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
LoadMOp::load(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||
[MOpRegNum::power_isa_gpr_reg_imm($ra)],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.$conversion(),
|
||||
),
|
||||
]
|
||||
},
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rb),
|
||||
],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
LoadMOp::load(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||
[MOpRegNum::power_isa_gpr_reg_imm($ra)],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.$conversion(),
|
||||
),
|
||||
],
|
||||
));
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,23 +25,21 @@ pub fn test_cases_book_i_3_3_13_fixed_point_logical(retval: &mut Vec<TestCase>)
|
|||
),
|
||||
$encoding,
|
||||
None,
|
||||
|| {
|
||||
LogicalMOp::logical_i(
|
||||
MOpDestReg::new_sim(
|
||||
&[MOpRegNum::power_isa_gpr_reg_num($dest)],
|
||||
if $mnemonic.contains('.') {
|
||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM]
|
||||
} else {
|
||||
&[]
|
||||
},
|
||||
),
|
||||
[MOpRegNum::power_isa_gpr_reg_imm($src)],
|
||||
(($imm as u32) << if $mnemonic.contains('s') { 16 } else { 0 })
|
||||
.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
Lut4::from_fn(|$a, $b| $lut_fn),
|
||||
)
|
||||
},
|
||||
LogicalMOp::logical_i(
|
||||
MOpDestReg::new_sim(
|
||||
&[MOpRegNum::power_isa_gpr_reg_num($dest)],
|
||||
if $mnemonic.contains('.') {
|
||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM]
|
||||
} else {
|
||||
&[]
|
||||
},
|
||||
),
|
||||
[MOpRegNum::power_isa_gpr_reg_imm($src)],
|
||||
(($imm as u32) << if $mnemonic.contains('s') { 16 } else { 0 })
|
||||
.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
Lut4::from_fn(|$a, $b| $lut_fn),
|
||||
),
|
||||
));
|
||||
};
|
||||
}
|
||||
|
|
@ -100,25 +98,23 @@ pub fn test_cases_book_i_3_3_13_fixed_point_logical(retval: &mut Vec<TestCase>)
|
|||
),
|
||||
$encoding,
|
||||
None,
|
||||
|| {
|
||||
LogicalMOp::logical(
|
||||
MOpDestReg::new_sim(
|
||||
&[MOpRegNum::power_isa_gpr_reg_num($dest)],
|
||||
if $mnemonic.contains('.') {
|
||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM]
|
||||
} else {
|
||||
&[]
|
||||
},
|
||||
),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($src0),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($src1),
|
||||
],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
Lut4::from_fn(|$a, $b| $lut_fn),
|
||||
)
|
||||
},
|
||||
LogicalMOp::logical(
|
||||
MOpDestReg::new_sim(
|
||||
&[MOpRegNum::power_isa_gpr_reg_num($dest)],
|
||||
if $mnemonic.contains('.') {
|
||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM]
|
||||
} else {
|
||||
&[]
|
||||
},
|
||||
),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($src0),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($src1),
|
||||
],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
Lut4::from_fn(|$a, $b| $lut_fn),
|
||||
),
|
||||
));
|
||||
};
|
||||
}
|
||||
|
|
@ -161,13 +157,11 @@ pub fn test_cases_book_i_3_3_13_fixed_point_logical(retval: &mut Vec<TestCase>)
|
|||
"or 3, 4, 4", // mr 3, 4
|
||||
0x7c832378,
|
||||
None,
|
||||
|| {
|
||||
MoveRegMOp::move_reg(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||
[MOpRegNum::power_isa_gpr_reg_imm(4)],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
)
|
||||
},
|
||||
MoveRegMOp::move_reg(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||
[MOpRegNum::power_isa_gpr_reg_imm(4)],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
),
|
||||
));
|
||||
insn_logic! {
|
||||
"or." 3, 4, 5;
|
||||
|
|
@ -229,22 +223,20 @@ pub fn test_cases_book_i_3_3_13_fixed_point_logical(retval: &mut Vec<TestCase>)
|
|||
concat!($mnemonic, " ", stringify!($dest), ", ", stringify!($src)),
|
||||
$encoding,
|
||||
None,
|
||||
|| {
|
||||
LogicalMOp::logical_i(
|
||||
MOpDestReg::new_sim(
|
||||
&[MOpRegNum::power_isa_gpr_reg_num($dest)],
|
||||
if $mnemonic.contains('.') {
|
||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM]
|
||||
} else {
|
||||
&[]
|
||||
},
|
||||
),
|
||||
[MOpRegNum::power_isa_gpr_reg_imm($src)],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.$OutputIntegerMode(),
|
||||
Lut4::from_fn(|a, b| a | b),
|
||||
)
|
||||
},
|
||||
LogicalMOp::logical_i(
|
||||
MOpDestReg::new_sim(
|
||||
&[MOpRegNum::power_isa_gpr_reg_num($dest)],
|
||||
if $mnemonic.contains('.') {
|
||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM]
|
||||
} else {
|
||||
&[]
|
||||
},
|
||||
),
|
||||
[MOpRegNum::power_isa_gpr_reg_imm($src)],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.$OutputIntegerMode(),
|
||||
Lut4::from_fn(|a, b| a | b),
|
||||
),
|
||||
));
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
|||
),
|
||||
$encoding,
|
||||
None,
|
||||
|| ShiftRotateMOp::shift_rotate(
|
||||
ShiftRotateMOp::shift_rotate(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||
|
|
@ -131,7 +131,7 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
|||
),
|
||||
$encoding | 1,
|
||||
None,
|
||||
|| ShiftRotateMOp::shift_rotate(
|
||||
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),
|
||||
|
|
@ -168,7 +168,7 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
|||
),
|
||||
$encoding,
|
||||
None,
|
||||
|| ShiftRotateMOp::shift_rotate(
|
||||
ShiftRotateMOp::shift_rotate(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||
|
|
@ -199,7 +199,7 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
|||
),
|
||||
$encoding | 1,
|
||||
None,
|
||||
|| ShiftRotateMOp::shift_rotate(
|
||||
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),
|
||||
|
|
@ -855,23 +855,21 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
|||
),
|
||||
$encoding,
|
||||
None,
|
||||
|| {
|
||||
ShiftRotateMOp::shift_rotate(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||
MOpRegNum::const_zero(),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($amount),
|
||||
],
|
||||
shift_imm(
|
||||
None,
|
||||
false,
|
||||
ShiftAmountOverflowBehavior.$overflow_behavior(),
|
||||
),
|
||||
OutputIntegerMode.Full64(),
|
||||
ShiftRotateMode.$shift_rotate_mode(),
|
||||
)
|
||||
},
|
||||
ShiftRotateMOp::shift_rotate(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||
MOpRegNum::const_zero(),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($amount),
|
||||
],
|
||||
shift_imm(
|
||||
None,
|
||||
false,
|
||||
ShiftAmountOverflowBehavior.$overflow_behavior(),
|
||||
),
|
||||
OutputIntegerMode.Full64(),
|
||||
ShiftRotateMode.$shift_rotate_mode(),
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
concat!(
|
||||
|
|
@ -885,26 +883,24 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
|||
),
|
||||
$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),
|
||||
MOpRegNum::const_zero(),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($amount),
|
||||
],
|
||||
shift_imm(
|
||||
None,
|
||||
false,
|
||||
ShiftAmountOverflowBehavior.$overflow_behavior(),
|
||||
),
|
||||
OutputIntegerMode.Full64(),
|
||||
ShiftRotateMode.$shift_rotate_mode(),
|
||||
)
|
||||
},
|
||||
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),
|
||||
MOpRegNum::const_zero(),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($amount),
|
||||
],
|
||||
shift_imm(
|
||||
None,
|
||||
false,
|
||||
ShiftAmountOverflowBehavior.$overflow_behavior(),
|
||||
),
|
||||
OutputIntegerMode.Full64(),
|
||||
ShiftRotateMode.$shift_rotate_mode(),
|
||||
),
|
||||
));
|
||||
}};
|
||||
}
|
||||
|
|
@ -927,19 +923,17 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
|||
),
|
||||
$encoding,
|
||||
None,
|
||||
|| {
|
||||
ShiftRotateMOp::shift_rotate(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||
[
|
||||
MOpRegNum::const_zero(),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($amount),
|
||||
],
|
||||
shift_imm(None, true, ShiftAmountOverflowBehavior.$overflow_behavior()),
|
||||
OutputIntegerMode.Full64(),
|
||||
ShiftRotateMode.$shift_rotate_mode(),
|
||||
)
|
||||
},
|
||||
ShiftRotateMOp::shift_rotate(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||
[
|
||||
MOpRegNum::const_zero(),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($amount),
|
||||
],
|
||||
shift_imm(None, true, ShiftAmountOverflowBehavior.$overflow_behavior()),
|
||||
OutputIntegerMode.Full64(),
|
||||
ShiftRotateMode.$shift_rotate_mode(),
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
concat!(
|
||||
|
|
@ -953,22 +947,20 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
|||
),
|
||||
$encoding | 1,
|
||||
None,
|
||||
|| {
|
||||
ShiftRotateMOp::shift_rotate(
|
||||
MOpDestReg::new_sim(
|
||||
&[MOpRegNum::power_isa_gpr_reg_num($dest)],
|
||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
||||
),
|
||||
[
|
||||
MOpRegNum::const_zero(),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($amount),
|
||||
],
|
||||
shift_imm(None, true, ShiftAmountOverflowBehavior.$overflow_behavior()),
|
||||
OutputIntegerMode.Full64(),
|
||||
ShiftRotateMode.$shift_rotate_mode(),
|
||||
)
|
||||
},
|
||||
ShiftRotateMOp::shift_rotate(
|
||||
MOpDestReg::new_sim(
|
||||
&[MOpRegNum::power_isa_gpr_reg_num($dest)],
|
||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
||||
),
|
||||
[
|
||||
MOpRegNum::const_zero(),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($amount),
|
||||
],
|
||||
shift_imm(None, true, ShiftAmountOverflowBehavior.$overflow_behavior()),
|
||||
OutputIntegerMode.Full64(),
|
||||
ShiftRotateMode.$shift_rotate_mode(),
|
||||
),
|
||||
));
|
||||
}};
|
||||
}
|
||||
|
|
@ -991,25 +983,23 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
|||
),
|
||||
$encoding,
|
||||
None,
|
||||
|| {
|
||||
ShiftRotateMOp::shift_rotate(
|
||||
MOpDestReg::new_sim(
|
||||
&[
|
||||
MOpRegNum::power_isa_gpr_reg_num($dest),
|
||||
MOpRegNum::POWER_ISA_XER_CA_CA32_REG_NUM,
|
||||
],
|
||||
&[],
|
||||
),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||
MOpRegNum::const_zero(),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($amount),
|
||||
ShiftRotateMOp::shift_rotate(
|
||||
MOpDestReg::new_sim(
|
||||
&[
|
||||
MOpRegNum::power_isa_gpr_reg_num($dest),
|
||||
MOpRegNum::POWER_ISA_XER_CA_CA32_REG_NUM,
|
||||
],
|
||||
shift_imm(None, true, ShiftAmountOverflowBehavior.$overflow_behavior()),
|
||||
OutputIntegerMode.Full64(),
|
||||
ShiftRotateMode.$shift_rotate_mode(),
|
||||
)
|
||||
},
|
||||
&[],
|
||||
),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||
MOpRegNum::const_zero(),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($amount),
|
||||
],
|
||||
shift_imm(None, true, ShiftAmountOverflowBehavior.$overflow_behavior()),
|
||||
OutputIntegerMode.Full64(),
|
||||
ShiftRotateMode.$shift_rotate_mode(),
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
concat!(
|
||||
|
|
@ -1023,25 +1013,23 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
|||
),
|
||||
$encoding | 1,
|
||||
None,
|
||||
|| {
|
||||
ShiftRotateMOp::shift_rotate(
|
||||
MOpDestReg::new_sim(
|
||||
&[
|
||||
MOpRegNum::power_isa_gpr_reg_num($dest),
|
||||
MOpRegNum::POWER_ISA_XER_CA_CA32_REG_NUM,
|
||||
],
|
||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
||||
),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||
MOpRegNum::const_zero(),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($amount),
|
||||
ShiftRotateMOp::shift_rotate(
|
||||
MOpDestReg::new_sim(
|
||||
&[
|
||||
MOpRegNum::power_isa_gpr_reg_num($dest),
|
||||
MOpRegNum::POWER_ISA_XER_CA_CA32_REG_NUM,
|
||||
],
|
||||
shift_imm(None, true, ShiftAmountOverflowBehavior.$overflow_behavior()),
|
||||
OutputIntegerMode.Full64(),
|
||||
ShiftRotateMode.$shift_rotate_mode(),
|
||||
)
|
||||
},
|
||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
||||
),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||
MOpRegNum::const_zero(),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($amount),
|
||||
],
|
||||
shift_imm(None, true, ShiftAmountOverflowBehavior.$overflow_behavior()),
|
||||
OutputIntegerMode.Full64(),
|
||||
ShiftRotateMode.$shift_rotate_mode(),
|
||||
),
|
||||
));
|
||||
}};
|
||||
}
|
||||
|
|
@ -1063,29 +1051,27 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
|||
),
|
||||
$encoding,
|
||||
None,
|
||||
|| {
|
||||
ShiftRotateMOp::shift_rotate(
|
||||
MOpDestReg::new_sim(
|
||||
&[
|
||||
MOpRegNum::power_isa_gpr_reg_num($dest),
|
||||
MOpRegNum::POWER_ISA_XER_CA_CA32_REG_NUM,
|
||||
],
|
||||
&[],
|
||||
),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||
MOpRegNum::const_zero(),
|
||||
MOpRegNum::const_zero(),
|
||||
ShiftRotateMOp::shift_rotate(
|
||||
MOpDestReg::new_sim(
|
||||
&[
|
||||
MOpRegNum::power_isa_gpr_reg_num($dest),
|
||||
MOpRegNum::POWER_ISA_XER_CA_CA32_REG_NUM,
|
||||
],
|
||||
shift_imm(
|
||||
Some($amount),
|
||||
true,
|
||||
ShiftAmountOverflowBehavior.WrapToUInt6(),
|
||||
),
|
||||
OutputIntegerMode.Full64(),
|
||||
ShiftRotateMode.$shift_rotate_mode(),
|
||||
)
|
||||
},
|
||||
&[],
|
||||
),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||
MOpRegNum::const_zero(),
|
||||
MOpRegNum::const_zero(),
|
||||
],
|
||||
shift_imm(
|
||||
Some($amount),
|
||||
true,
|
||||
ShiftAmountOverflowBehavior.WrapToUInt6(),
|
||||
),
|
||||
OutputIntegerMode.Full64(),
|
||||
ShiftRotateMode.$shift_rotate_mode(),
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
concat!(
|
||||
|
|
@ -1099,29 +1085,27 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
|||
),
|
||||
$encoding | 1,
|
||||
None,
|
||||
|| {
|
||||
ShiftRotateMOp::shift_rotate(
|
||||
MOpDestReg::new_sim(
|
||||
&[
|
||||
MOpRegNum::power_isa_gpr_reg_num($dest),
|
||||
MOpRegNum::POWER_ISA_XER_CA_CA32_REG_NUM,
|
||||
],
|
||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
||||
),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||
MOpRegNum::const_zero(),
|
||||
MOpRegNum::const_zero(),
|
||||
ShiftRotateMOp::shift_rotate(
|
||||
MOpDestReg::new_sim(
|
||||
&[
|
||||
MOpRegNum::power_isa_gpr_reg_num($dest),
|
||||
MOpRegNum::POWER_ISA_XER_CA_CA32_REG_NUM,
|
||||
],
|
||||
shift_imm(
|
||||
Some($amount),
|
||||
true,
|
||||
ShiftAmountOverflowBehavior.WrapToUInt6(),
|
||||
),
|
||||
OutputIntegerMode.Full64(),
|
||||
ShiftRotateMode.$shift_rotate_mode(),
|
||||
)
|
||||
},
|
||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
||||
),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||
MOpRegNum::const_zero(),
|
||||
MOpRegNum::const_zero(),
|
||||
],
|
||||
shift_imm(
|
||||
Some($amount),
|
||||
true,
|
||||
ShiftAmountOverflowBehavior.WrapToUInt6(),
|
||||
),
|
||||
OutputIntegerMode.Full64(),
|
||||
ShiftRotateMode.$shift_rotate_mode(),
|
||||
),
|
||||
));
|
||||
}};
|
||||
}
|
||||
|
|
@ -1228,23 +1212,21 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
|||
),
|
||||
$encoding,
|
||||
None,
|
||||
|| {
|
||||
ShiftRotateMOp::shift_rotate(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||
MOpRegNum::const_zero(),
|
||||
MOpRegNum::const_zero(),
|
||||
],
|
||||
shift_imm(
|
||||
Some($amount),
|
||||
false,
|
||||
ShiftAmountOverflowBehavior.WrapToUInt6(),
|
||||
),
|
||||
OutputIntegerMode.Full64(),
|
||||
ShiftRotateMode.SignExt32To64BitThenShift(),
|
||||
)
|
||||
},
|
||||
ShiftRotateMOp::shift_rotate(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||
MOpRegNum::const_zero(),
|
||||
MOpRegNum::const_zero(),
|
||||
],
|
||||
shift_imm(
|
||||
Some($amount),
|
||||
false,
|
||||
ShiftAmountOverflowBehavior.WrapToUInt6(),
|
||||
),
|
||||
OutputIntegerMode.Full64(),
|
||||
ShiftRotateMode.SignExt32To64BitThenShift(),
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
concat!(
|
||||
|
|
@ -1258,26 +1240,24 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
|||
),
|
||||
$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),
|
||||
MOpRegNum::const_zero(),
|
||||
MOpRegNum::const_zero(),
|
||||
],
|
||||
shift_imm(
|
||||
Some($amount),
|
||||
false,
|
||||
ShiftAmountOverflowBehavior.WrapToUInt6(),
|
||||
),
|
||||
OutputIntegerMode.Full64(),
|
||||
ShiftRotateMode.SignExt32To64BitThenShift(),
|
||||
)
|
||||
},
|
||||
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),
|
||||
MOpRegNum::const_zero(),
|
||||
MOpRegNum::const_zero(),
|
||||
],
|
||||
shift_imm(
|
||||
Some($amount),
|
||||
false,
|
||||
ShiftAmountOverflowBehavior.WrapToUInt6(),
|
||||
),
|
||||
OutputIntegerMode.Full64(),
|
||||
ShiftRotateMode.SignExt32To64BitThenShift(),
|
||||
),
|
||||
));
|
||||
}};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,36 +20,34 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
|
|||
concat!($mnemonic, " ", $rs, ", ", $disp, "(", $ra, "), ", $r),
|
||||
$prefix,
|
||||
Some($suffix),
|
||||
|| {
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||
[
|
||||
if $r != 0 || $ra == 0 {
|
||||
MOpRegNum::const_zero()
|
||||
} else {
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra)
|
||||
},
|
||||
MOpRegNum::const_zero(),
|
||||
],
|
||||
($disp as i64).cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
$r != 0,
|
||||
),
|
||||
StoreMOp::store(
|
||||
MOpDestReg::new_sim(&[], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_temp_reg(),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rs),
|
||||
],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.ZeroExt(),
|
||||
),
|
||||
]
|
||||
},
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||
[
|
||||
if $r != 0 || $ra == 0 {
|
||||
MOpRegNum::const_zero()
|
||||
} else {
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra)
|
||||
},
|
||||
MOpRegNum::const_zero(),
|
||||
],
|
||||
($disp as i64).cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
$r != 0,
|
||||
),
|
||||
StoreMOp::store(
|
||||
MOpDestReg::new_sim(&[], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_temp_reg(),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rs),
|
||||
],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.ZeroExt(),
|
||||
),
|
||||
],
|
||||
));
|
||||
};
|
||||
}
|
||||
|
|
@ -63,36 +61,34 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
|
|||
concat!($mnemonic, " ", $rs, ", ", $disp, "(", $ra, ")"),
|
||||
$encoding,
|
||||
None,
|
||||
|| {
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||
[
|
||||
if $ra == 0 {
|
||||
MOpRegNum::const_zero()
|
||||
} else {
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra)
|
||||
},
|
||||
MOpRegNum::const_zero(),
|
||||
],
|
||||
($disp as i64).cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
StoreMOp::store(
|
||||
MOpDestReg::new_sim(&[], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_temp_reg(),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rs),
|
||||
],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.ZeroExt(),
|
||||
),
|
||||
]
|
||||
},
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||
[
|
||||
if $ra == 0 {
|
||||
MOpRegNum::const_zero()
|
||||
} else {
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra)
|
||||
},
|
||||
MOpRegNum::const_zero(),
|
||||
],
|
||||
($disp as i64).cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
StoreMOp::store(
|
||||
MOpDestReg::new_sim(&[], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_temp_reg(),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rs),
|
||||
],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.ZeroExt(),
|
||||
),
|
||||
],
|
||||
));
|
||||
};
|
||||
}
|
||||
|
|
@ -107,69 +103,65 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
|
|||
concat!($mnemonic, " ", $rs, ", ", $disp, "(", $ra, ")"),
|
||||
$encoding,
|
||||
None,
|
||||
|| {
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra),
|
||||
MOpRegNum::const_zero(),
|
||||
],
|
||||
($disp as i64).cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
StoreMOp::store(
|
||||
MOpDestReg::new_sim(&[], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_temp_reg(),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rs),
|
||||
],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.ZeroExt(),
|
||||
),
|
||||
MoveRegMOp::move_reg(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
||||
[MOpRegNum::power_isa_temp_reg()],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
),
|
||||
]
|
||||
},
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra),
|
||||
MOpRegNum::const_zero(),
|
||||
],
|
||||
($disp as i64).cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
StoreMOp::store(
|
||||
MOpDestReg::new_sim(&[], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_temp_reg(),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rs),
|
||||
],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.ZeroExt(),
|
||||
),
|
||||
MoveRegMOp::move_reg(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
||||
[MOpRegNum::power_isa_temp_reg()],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
),
|
||||
],
|
||||
));
|
||||
} else {
|
||||
retval.push(insn_double(
|
||||
concat!($mnemonic, " ", $rs, ", ", $disp, "(", $ra, ")"),
|
||||
$encoding,
|
||||
None,
|
||||
|| {
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra),
|
||||
MOpRegNum::const_zero(),
|
||||
],
|
||||
($disp as i64).cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
StoreMOp::store(
|
||||
MOpDestReg::new_sim(&[], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rs),
|
||||
],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.ZeroExt(),
|
||||
),
|
||||
]
|
||||
},
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra),
|
||||
MOpRegNum::const_zero(),
|
||||
],
|
||||
($disp as i64).cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
StoreMOp::store(
|
||||
MOpDestReg::new_sim(&[], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rs),
|
||||
],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.ZeroExt(),
|
||||
),
|
||||
],
|
||||
));
|
||||
}
|
||||
};
|
||||
|
|
@ -184,16 +176,53 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
|
|||
concat!($mnemonic, " ", $rs, ", ", $ra, ", ", $rb),
|
||||
$encoding,
|
||||
None,
|
||||
|| {
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||
[
|
||||
if $ra == 0 {
|
||||
MOpRegNum::const_zero()
|
||||
} else {
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra)
|
||||
},
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rb),
|
||||
],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
StoreMOp::store(
|
||||
MOpDestReg::new_sim(&[], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_temp_reg(),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rs),
|
||||
],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.ZeroExt(),
|
||||
),
|
||||
],
|
||||
));
|
||||
};
|
||||
}
|
||||
macro_rules! store_update_indexed {
|
||||
(
|
||||
$mnemonic:literal $rs:literal, $ra:literal, $rb:literal;
|
||||
$encoding:literal;
|
||||
$width:ident;
|
||||
) => {
|
||||
if $ra == $rs {
|
||||
retval.push(insn_triple(
|
||||
concat!($mnemonic, " ", $rs, ", ", $ra, ", ", $rb),
|
||||
$encoding,
|
||||
None,
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||
[
|
||||
if $ra == 0 {
|
||||
MOpRegNum::const_zero()
|
||||
} else {
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra)
|
||||
},
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rb),
|
||||
],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
|
|
@ -212,89 +241,46 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
|
|||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.ZeroExt(),
|
||||
),
|
||||
]
|
||||
},
|
||||
));
|
||||
};
|
||||
}
|
||||
macro_rules! store_update_indexed {
|
||||
(
|
||||
$mnemonic:literal $rs:literal, $ra:literal, $rb:literal;
|
||||
$encoding:literal;
|
||||
$width:ident;
|
||||
) => {
|
||||
if $ra == $rs {
|
||||
retval.push(insn_triple(
|
||||
concat!($mnemonic, " ", $rs, ", ", $ra, ", ", $rb),
|
||||
$encoding,
|
||||
None,
|
||||
|| {
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rb),
|
||||
],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
StoreMOp::store(
|
||||
MOpDestReg::new_sim(&[], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_temp_reg(),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rs),
|
||||
],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.ZeroExt(),
|
||||
),
|
||||
MoveRegMOp::move_reg(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
||||
[MOpRegNum::power_isa_temp_reg()],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
),
|
||||
]
|
||||
},
|
||||
MoveRegMOp::move_reg(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
||||
[MOpRegNum::power_isa_temp_reg()],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
),
|
||||
],
|
||||
));
|
||||
} else {
|
||||
retval.push(insn_double(
|
||||
concat!($mnemonic, " ", $rs, ", ", $ra, ", ", $rb),
|
||||
$encoding,
|
||||
None,
|
||||
|| {
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
||||
[
|
||||
if $ra == 0 {
|
||||
MOpRegNum::const_zero()
|
||||
} else {
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra)
|
||||
},
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rb),
|
||||
],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
StoreMOp::store(
|
||||
MOpDestReg::new_sim(&[], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rs),
|
||||
],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.ZeroExt(),
|
||||
),
|
||||
]
|
||||
},
|
||||
[
|
||||
AddSubMOp::add_sub_i(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
||||
[
|
||||
if $ra == 0 {
|
||||
MOpRegNum::const_zero()
|
||||
} else {
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra)
|
||||
},
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rb),
|
||||
],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
StoreMOp::store(
|
||||
MOpDestReg::new_sim(&[], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg_imm($ra),
|
||||
MOpRegNum::power_isa_gpr_reg_imm($rs),
|
||||
],
|
||||
LoadStoreWidth.$width(),
|
||||
LoadStoreConversion.ZeroExt(),
|
||||
),
|
||||
],
|
||||
));
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -23,7 +23,10 @@ pub fn test_cases_book_i_3_3_19_move_to_from_system_register(retval: &mut Vec<Te
|
|||
dest_count: 6usize.cast_to(LogicalFlagsMOpImm.dest_count),
|
||||
}
|
||||
}
|
||||
retval.push(insn_single("mcrxrx 3", 0x7d800480, None, || {
|
||||
retval.push(insn_single(
|
||||
"mcrxrx 3",
|
||||
0x7d800480,
|
||||
None,
|
||||
LogicalFlagsMOp::logical_flags(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||
[
|
||||
|
|
@ -33,114 +36,114 @@ pub fn test_cases_book_i_3_3_19_move_to_from_system_register(retval: &mut Vec<Te
|
|||
],
|
||||
mcrxrx_imm(),
|
||||
Lut4::from_fn(|a, b| a | b),
|
||||
)
|
||||
}));
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
/// covers instructions in PowerISA v3.1C Book III 5.4.4 Move To/From System Register Instructions
|
||||
pub fn test_cases_book_iii_5_4_4_move_to_from_system_register(retval: &mut Vec<TestCase>) {
|
||||
retval.push(insn_single("mflr 3", 0x7c6802a6, None, || {
|
||||
retval.push(insn_single(
|
||||
"mflr 3",
|
||||
0x7c6802a6,
|
||||
None,
|
||||
MoveRegMOp::move_reg(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||
[MOpRegNum::power_isa_lr_reg()],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
)
|
||||
}));
|
||||
retval.push(insn_single("mtlr 3", 0x7c6803a6, None, || {
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"mtlr 3",
|
||||
0x7c6803a6,
|
||||
None,
|
||||
MoveRegMOp::move_reg(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_LR_REG_NUM], &[]),
|
||||
[MOpRegNum::power_isa_gpr_reg_imm(3)],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
)
|
||||
}));
|
||||
retval.push(insn_single("mfctr 3", 0x7c6902a6, None, || {
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"mfctr 3",
|
||||
0x7c6902a6,
|
||||
None,
|
||||
MoveRegMOp::move_reg(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||
[MOpRegNum::power_isa_ctr_reg()],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
)
|
||||
}));
|
||||
retval.push(insn_single("mtctr 3", 0x7c6903a6, None, || {
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"mtctr 3",
|
||||
0x7c6903a6,
|
||||
None,
|
||||
MoveRegMOp::move_reg(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_CTR_REG_NUM], &[]),
|
||||
[MOpRegNum::power_isa_gpr_reg_imm(3)],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
)
|
||||
}));
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"mfspr 3, 815 # mftar 3",
|
||||
0x7c6fcaa6,
|
||||
None,
|
||||
|| {
|
||||
MoveRegMOp::move_reg(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||
[MOpRegNum::power_isa_tar_reg()],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
)
|
||||
},
|
||||
MoveRegMOp::move_reg(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||
[MOpRegNum::power_isa_tar_reg()],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"mtspr 815, 3 # mttar 3",
|
||||
0x7c6fcba6,
|
||||
None,
|
||||
|| {
|
||||
MoveRegMOp::move_reg(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TAR_REG_NUM], &[]),
|
||||
[MOpRegNum::power_isa_gpr_reg_imm(3)],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
)
|
||||
},
|
||||
MoveRegMOp::move_reg(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TAR_REG_NUM], &[]),
|
||||
[MOpRegNum::power_isa_gpr_reg_imm(3)],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
),
|
||||
));
|
||||
// make sure we generate mfspr and not the phased-out mftb
|
||||
retval.push(insn_single(
|
||||
"mfspr 3, 268 # mftb 3",
|
||||
0x7c6c42a6,
|
||||
None,
|
||||
|| {
|
||||
ReadSpecialMOp::read_special(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||
[MOpRegNum::const_zero(); 0],
|
||||
ReadSpecialMOpImm.PowerIsaTimeBase(),
|
||||
)
|
||||
},
|
||||
ReadSpecialMOp::read_special(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||
[MOpRegNum::const_zero(); 0],
|
||||
ReadSpecialMOpImm.PowerIsaTimeBase(),
|
||||
),
|
||||
));
|
||||
// make sure we generate mfspr and not the phased-out mftb
|
||||
retval.push(insn_single(
|
||||
"mfspr 3, 269 # mftbu 3",
|
||||
0x7c6d42a6,
|
||||
None,
|
||||
|| {
|
||||
ReadSpecialMOp::read_special(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||
[MOpRegNum::const_zero(); 0],
|
||||
ReadSpecialMOpImm.PowerIsaTimeBaseU(),
|
||||
)
|
||||
},
|
||||
ReadSpecialMOp::read_special(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||
[MOpRegNum::const_zero(); 0],
|
||||
ReadSpecialMOpImm.PowerIsaTimeBaseU(),
|
||||
),
|
||||
));
|
||||
// phased-out mftb -- not actually generated by the assembler so we have to use .long
|
||||
retval.push(insn_single(
|
||||
".long 0x7c6c42e6 # mftb 3, 268",
|
||||
0x7c6c42e6,
|
||||
None,
|
||||
|| {
|
||||
ReadSpecialMOp::read_special(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||
[MOpRegNum::const_zero(); 0],
|
||||
ReadSpecialMOpImm.PowerIsaTimeBase(),
|
||||
)
|
||||
},
|
||||
ReadSpecialMOp::read_special(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||
[MOpRegNum::const_zero(); 0],
|
||||
ReadSpecialMOpImm.PowerIsaTimeBase(),
|
||||
),
|
||||
));
|
||||
// phased-out mftb -- not actually generated by the assembler so we have to use .long
|
||||
retval.push(insn_single(
|
||||
".long 0x7c6d42e6 # mftb 3, 269",
|
||||
0x7c6d42e6,
|
||||
None,
|
||||
|| {
|
||||
ReadSpecialMOp::read_special(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||
[MOpRegNum::const_zero(); 0],
|
||||
ReadSpecialMOpImm.PowerIsaTimeBaseU(),
|
||||
)
|
||||
},
|
||||
ReadSpecialMOp::read_special(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||
[MOpRegNum::const_zero(); 0],
|
||||
ReadSpecialMOpImm.PowerIsaTimeBaseU(),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,9 @@ use std::num::NonZero;
|
|||
#[hdl_module]
|
||||
fn formal_harness(config: PhantomConst<CpuConfig>) {
|
||||
#[hdl]
|
||||
let cd: ClockDomain = m.input();
|
||||
let cd: ClockDomain = m.output();
|
||||
connect(cd.clk, fayalite::formal::formal_global_clock());
|
||||
connect(cd.rst, fayalite::formal::formal_reset().to_reset());
|
||||
|
||||
#[hdl]
|
||||
let input: DecodeAndRunSingleInsnInput<
|
||||
|
|
@ -97,21 +99,9 @@ fn formal_harness(config: PhantomConst<CpuConfig>) {
|
|||
|
||||
#[hdl_module]
|
||||
fn check_power_isa_add_formal(config: PhantomConst<CpuConfig>) {
|
||||
#[hdl]
|
||||
let clk: Clock = m.input();
|
||||
#[hdl]
|
||||
let cd = wire();
|
||||
connect(
|
||||
cd,
|
||||
#[hdl]
|
||||
ClockDomain {
|
||||
clk,
|
||||
rst: formal_reset().to_reset(),
|
||||
},
|
||||
);
|
||||
#[hdl]
|
||||
let harness = instance(formal_harness(config));
|
||||
connect(harness.cd, cd);
|
||||
let cd = harness.cd;
|
||||
#[hdl]
|
||||
let DecodeAndRunSingleInsnInput::<_, _> {
|
||||
decoder_input,
|
||||
|
|
@ -218,11 +208,11 @@ fn test_power_isa_add_formal() {
|
|||
vec![UnitConfig::new(UnitKind::AluBranch)],
|
||||
NonZero::new(20).unwrap(),
|
||||
));
|
||||
let m = check_power_isa_add_formal(config);
|
||||
let dut = check_power_isa_add_formal(config);
|
||||
println!("starting assert formal");
|
||||
assert_formal(
|
||||
"test_power_isa_add_formal",
|
||||
m,
|
||||
dut,
|
||||
FormalMode::Prove,
|
||||
10,
|
||||
None,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue