add PowerISA decoder #7
6 changed files with 3730 additions and 1532 deletions
|
|
@ -1,7 +1,9 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
// See Notices.txt for copyright information
|
||||
|
||||
use crate::instruction::{AddSubMOp, MOpDestReg, MOpRegNum, OutputIntegerMode};
|
||||
use crate::instruction::{
|
||||
AddSubMOp, CompareMOp, CompareMode, MOpDestReg, MOpRegNum, OutputIntegerMode,
|
||||
};
|
||||
use crate::powerisa_instructions_xml::{
|
||||
InstructionBitFieldName, InstructionBitFieldsInner, TextLineItem,
|
||||
};
|
||||
|
|
@ -177,6 +179,8 @@ macro_rules! impl_fields {
|
|||
}
|
||||
|
||||
impl_fields! {
|
||||
#[name = "BF"]
|
||||
struct FieldBF(FieldCrf);
|
||||
#[name = "RA"]
|
||||
struct FieldRA(FieldGpr);
|
||||
#[name = "RB"]
|
||||
|
|
@ -189,12 +193,16 @@ impl_fields! {
|
|||
struct FieldSi0(SInt<18>);
|
||||
#[name = "si1"]
|
||||
struct FieldSi1(UInt<16>);
|
||||
#[name = "UI"]
|
||||
struct FieldUI(UInt<16>);
|
||||
#[name = "d0"]
|
||||
struct FieldAddPcISD0(SInt<10>);
|
||||
#[name = "d1"]
|
||||
struct FieldAddPcISD1(UInt<5>);
|
||||
#[name = "d2"]
|
||||
struct FieldAddPcISD2(UInt<1>);
|
||||
#[name = "L"]
|
||||
struct FieldL(Bool);
|
||||
#[name = "OE"]
|
||||
struct FieldOE(Bool);
|
||||
#[name = "R"]
|
||||
|
|
@ -203,11 +211,18 @@ impl_fields! {
|
|||
struct FieldRc(Bool);
|
||||
}
|
||||
|
||||
/// general-purpose register
|
||||
#[hdl]
|
||||
struct FieldGpr {
|
||||
reg_num: UInt<5>,
|
||||
}
|
||||
|
||||
/// condition register field -- a 4-bit field of the condition register
|
||||
#[hdl]
|
||||
struct FieldCrf {
|
||||
reg_num: UInt<3>,
|
||||
}
|
||||
|
||||
fn gpr(this: impl ToExpr<Type = FieldGpr>) -> Expr<MOpRegNum> {
|
||||
MOpRegNum::power_isa_gpr_reg(this.to_expr().reg_num)
|
||||
}
|
||||
|
|
@ -216,6 +231,10 @@ fn gpr_or_zero(this: impl ToExpr<Type = FieldGpr>) -> Expr<MOpRegNum> {
|
|||
MOpRegNum::power_isa_gpr_or_zero_reg(this.to_expr().reg_num)
|
||||
}
|
||||
|
||||
fn crf(this: impl ToExpr<Type = FieldCrf>) -> Expr<MOpRegNum> {
|
||||
MOpRegNum::power_isa_cr_reg(this.to_expr().reg_num)
|
||||
}
|
||||
|
||||
impl DecodeState {
|
||||
fn form(&self) -> &'static str {
|
||||
let mut title_words = self
|
||||
|
|
@ -839,6 +858,172 @@ impl DecodeState {
|
|||
},
|
||||
);
|
||||
}
|
||||
/// for `cmpi`
|
||||
#[hdl]
|
||||
fn decode_cmpi(&mut self) {
|
||||
self.decode_scope(|this, (FieldBF(bf), FieldL(l), FieldRA(ra), FieldSI(si))| {
|
||||
// TODO: handle SO propagation
|
||||
connect(
|
||||
ArrayVec::len(this.output),
|
||||
1usize.cast_to_static::<Length<_>>(),
|
||||
);
|
||||
#[hdl]
|
||||
let compare_mode = wire();
|
||||
#[hdl]
|
||||
if l {
|
||||
connect(compare_mode, CompareMode.S64());
|
||||
} else {
|
||||
connect(compare_mode, CompareMode.S32());
|
||||
}
|
||||
connect(
|
||||
this.output[0],
|
||||
CompareMOp::compare_i(
|
||||
MOpDestReg::new([crf(bf)], []),
|
||||
[gpr(ra).value],
|
||||
si.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
compare_mode,
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
/// for `cmp`
|
||||
#[hdl]
|
||||
fn decode_cmp(&mut self) {
|
||||
self.decode_scope(|this, (FieldBF(bf), FieldL(l), FieldRA(ra), FieldRB(rb))| {
|
||||
// TODO: handle SO propagation
|
||||
connect(
|
||||
ArrayVec::len(this.output),
|
||||
1usize.cast_to_static::<Length<_>>(),
|
||||
);
|
||||
#[hdl]
|
||||
let compare_mode = wire();
|
||||
#[hdl]
|
||||
if l {
|
||||
connect(compare_mode, CompareMode.S64());
|
||||
} else {
|
||||
connect(compare_mode, CompareMode.S32());
|
||||
}
|
||||
connect(
|
||||
this.output[0],
|
||||
CompareMOp::compare(
|
||||
MOpDestReg::new([crf(bf)], []),
|
||||
[gpr(ra).value, gpr(rb).value],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
compare_mode,
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
/// for `cmpli`
|
||||
#[hdl]
|
||||
fn decode_cmpli(&mut self) {
|
||||
self.decode_scope(|this, (FieldBF(bf), FieldL(l), FieldRA(ra), FieldUI(ui))| {
|
||||
// TODO: handle SO propagation
|
||||
connect(
|
||||
ArrayVec::len(this.output),
|
||||
1usize.cast_to_static::<Length<_>>(),
|
||||
);
|
||||
#[hdl]
|
||||
let compare_mode = wire();
|
||||
#[hdl]
|
||||
if l {
|
||||
connect(compare_mode, CompareMode.U64());
|
||||
} else {
|
||||
connect(compare_mode, CompareMode.U32());
|
||||
}
|
||||
connect(
|
||||
this.output[0],
|
||||
CompareMOp::compare_i(
|
||||
MOpDestReg::new([crf(bf)], []),
|
||||
[gpr(ra).value],
|
||||
ui.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
compare_mode,
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
/// for `cmpl`
|
||||
#[hdl]
|
||||
fn decode_cmpl(&mut self) {
|
||||
self.decode_scope(|this, (FieldBF(bf), FieldL(l), FieldRA(ra), FieldRB(rb))| {
|
||||
// TODO: handle SO propagation
|
||||
connect(
|
||||
ArrayVec::len(this.output),
|
||||
1usize.cast_to_static::<Length<_>>(),
|
||||
);
|
||||
#[hdl]
|
||||
let compare_mode = wire();
|
||||
#[hdl]
|
||||
if l {
|
||||
connect(compare_mode, CompareMode.U64());
|
||||
} else {
|
||||
connect(compare_mode, CompareMode.U32());
|
||||
}
|
||||
connect(
|
||||
this.output[0],
|
||||
CompareMOp::compare(
|
||||
MOpDestReg::new([crf(bf)], []),
|
||||
[gpr(ra).value, gpr(rb).value],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
compare_mode,
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
/// for `cmprb`
|
||||
#[hdl]
|
||||
fn decode_cmprb(&mut self) {
|
||||
self.decode_scope(|this, (FieldBF(bf), FieldL(l), FieldRA(ra), FieldRB(rb))| {
|
||||
// TODO: handle SO propagation
|
||||
connect(
|
||||
ArrayVec::len(this.output),
|
||||
1usize.cast_to_static::<Length<_>>(),
|
||||
);
|
||||
#[hdl]
|
||||
let compare_mode = wire();
|
||||
#[hdl]
|
||||
if l {
|
||||
connect(compare_mode, CompareMode.CmpRBTwo());
|
||||
} else {
|
||||
connect(compare_mode, CompareMode.CmpRBOne());
|
||||
}
|
||||
connect(
|
||||
this.output[0],
|
||||
CompareMOp::compare(
|
||||
MOpDestReg::new([crf(bf)], []),
|
||||
[gpr(ra).value, gpr(rb).value],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
compare_mode,
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
/// for `cmpeqb`
|
||||
#[hdl]
|
||||
fn decode_cmpeqb(&mut self) {
|
||||
self.decode_scope(|this, (FieldBF(bf), FieldRA(ra), FieldRB(rb))| {
|
||||
// TODO: handle SO propagation
|
||||
connect(
|
||||
ArrayVec::len(this.output),
|
||||
1usize.cast_to_static::<Length<_>>(),
|
||||
);
|
||||
connect(
|
||||
this.output[0],
|
||||
CompareMOp::compare(
|
||||
MOpDestReg::new([crf(bf)], []),
|
||||
[gpr(ra).value, gpr(rb).value],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
OutputIntegerMode.Full64(),
|
||||
CompareMode.CmpEqB(),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
type DecodeFn = fn(&mut DecodeState);
|
||||
|
|
@ -982,12 +1167,12 @@ const DECODE_FNS: &[(&[&str], DecodeFn)] = &[
|
|||
// TODO
|
||||
},
|
||||
),
|
||||
(&["cmpi", "cmp", "cmpli", "cmpl"], |_state| {
|
||||
// TODO
|
||||
}),
|
||||
(&["cmprb", "cmpeqb"], |_state| {
|
||||
// TODO
|
||||
}),
|
||||
(&["cmpi"], DecodeState::decode_cmpi),
|
||||
(&["cmp"], DecodeState::decode_cmp),
|
||||
(&["cmpli"], DecodeState::decode_cmpli),
|
||||
(&["cmpl"], DecodeState::decode_cmpl),
|
||||
(&["cmprb"], DecodeState::decode_cmprb),
|
||||
(&["cmpeqb"], DecodeState::decode_cmpeqb),
|
||||
(&["twi", "tw", "tdi", "td"], |_state| {
|
||||
// TODO
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -736,6 +736,120 @@ impl<DestReg: Type, SrcRegWidth: Size> LogicalMOp<DestReg, SrcRegWidth> {
|
|||
}
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
pub enum CompareMode {
|
||||
U64,
|
||||
S64,
|
||||
U32,
|
||||
S32,
|
||||
U16,
|
||||
S16,
|
||||
U8,
|
||||
S8,
|
||||
/// compare one ranged byte -- like the PowerISA `cmprb _, 0, ..` instruction
|
||||
CmpRBOne,
|
||||
/// compare two ranged bytes -- like the PowerISA `cmprb _, 1, ..` instruction
|
||||
CmpRBTwo,
|
||||
/// like the PowerISA `cmpeqb` instruction
|
||||
CmpEqB,
|
||||
}
|
||||
|
||||
impl HdlPartialEqImpl<Self> for CompareMode {
|
||||
#[track_caller]
|
||||
fn cmp_value_eq(
|
||||
lhs: Self,
|
||||
lhs_value: Cow<'_, Self::SimValue>,
|
||||
rhs: Self,
|
||||
rhs_value: Cow<'_, Self::SimValue>,
|
||||
) -> bool {
|
||||
SimValue::opaque(&SimValue::from_value(lhs, lhs_value.into_owned()))
|
||||
== SimValue::opaque(&SimValue::from_value(rhs, rhs_value.into_owned()))
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn cmp_sim_value_eq(
|
||||
lhs: Cow<'_, SimValue<Self>>,
|
||||
rhs: Cow<'_, SimValue<Self>>,
|
||||
) -> SimValue<Bool> {
|
||||
(SimValue::opaque(&lhs) == SimValue::opaque(&rhs)).to_sim_value()
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn cmp_sim_value_ne(
|
||||
lhs: Cow<'_, SimValue<Self>>,
|
||||
rhs: Cow<'_, SimValue<Self>>,
|
||||
) -> SimValue<Bool> {
|
||||
(SimValue::opaque(&lhs) != SimValue::opaque(&rhs)).to_sim_value()
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn cmp_expr_eq(lhs: Expr<Self>, rhs: Expr<Self>) -> Expr<Bool> {
|
||||
lhs.cast_to_bits().cmp_eq(rhs.cast_to_bits())
|
||||
}
|
||||
}
|
||||
|
||||
common_mop_struct! {
|
||||
#[mapped(<NewDestReg, NewSrcRegWidth> CompareMOp<NewDestReg, NewSrcRegWidth, SrcCount>)]
|
||||
#[hdl(cmp_eq)]
|
||||
pub struct CompareMOp<DestReg: Type, SrcRegWidth: Size, SrcCount: KnownSize> {
|
||||
#[common]
|
||||
pub alu_common: AluCommonMOp<DestReg, SrcRegWidth, SrcCount>,
|
||||
pub compare_mode: CompareMode,
|
||||
}
|
||||
}
|
||||
|
||||
impl<DestReg: Type, SrcRegWidth: Size> CompareMOp<DestReg, SrcRegWidth, ConstUsize<2>> {
|
||||
#[hdl]
|
||||
pub fn compare<Target: MOpTrait>(
|
||||
dest: impl ToExpr<Type = DestReg>,
|
||||
src: impl ToExpr<Type = Array<UIntType<SrcRegWidth>, 2>>,
|
||||
imm: impl ToExpr<Type = SInt<{ COMMON_MOP_2_IMM_WIDTH }>>,
|
||||
output_integer_mode: impl ToExpr<Type = OutputIntegerMode>,
|
||||
compare_mode: impl ToExpr<Type = CompareMode>,
|
||||
) -> Expr<Target>
|
||||
where
|
||||
Self: MOpInto<Target>,
|
||||
{
|
||||
MOpInto::mop_into(
|
||||
#[hdl]
|
||||
CompareMOp {
|
||||
alu_common: #[hdl]
|
||||
AluCommonMOp {
|
||||
common: CommonMOp::new(0_hdl_u0, dest, src, Expr::as_dyn_int(imm.to_expr())),
|
||||
output_integer_mode,
|
||||
},
|
||||
compare_mode,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<DestReg: Type, SrcRegWidth: Size> CompareMOp<DestReg, SrcRegWidth, ConstUsize<1>> {
|
||||
#[hdl]
|
||||
pub fn compare_i<Target: MOpTrait>(
|
||||
dest: impl ToExpr<Type = DestReg>,
|
||||
src: impl ToExpr<Type = Array<UIntType<SrcRegWidth>, 1>>,
|
||||
imm: impl ToExpr<Type = SInt<{ COMMON_MOP_1_IMM_WIDTH }>>,
|
||||
output_integer_mode: impl ToExpr<Type = OutputIntegerMode>,
|
||||
compare_mode: impl ToExpr<Type = CompareMode>,
|
||||
) -> Expr<Target>
|
||||
where
|
||||
Self: MOpInto<Target>,
|
||||
{
|
||||
MOpInto::mop_into(
|
||||
#[hdl]
|
||||
CompareMOp {
|
||||
alu_common: #[hdl]
|
||||
AluCommonMOp {
|
||||
common: CommonMOp::new(0_hdl_u0, dest, src, Expr::as_dyn_int(imm.to_expr())),
|
||||
output_integer_mode,
|
||||
},
|
||||
compare_mode,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
common_mop_struct! {
|
||||
#[mapped(<NewDestReg, NewSrcRegWidth> BranchMOp<NewDestReg, NewSrcRegWidth>)]
|
||||
#[hdl(cmp_eq)]
|
||||
|
|
@ -753,6 +867,8 @@ mop_enum! {
|
|||
AddSub(AddSubMOp<DestReg, SrcRegWidth, ConstUsize<3>>),
|
||||
AddSubI(AddSubMOp<DestReg, SrcRegWidth, ConstUsize<2>>),
|
||||
Logical(LogicalMOp<DestReg, SrcRegWidth>),
|
||||
Compare(CompareMOp<DestReg, SrcRegWidth, ConstUsize<2>>),
|
||||
CompareI(CompareMOp<DestReg, SrcRegWidth, ConstUsize<1>>),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ impl MOpRegNum {
|
|||
} else {
|
||||
connect_any(
|
||||
power_isa_cr_reg.value,
|
||||
Self::POWER_ISA_CR_1_THRU_7_REG_NUMS.start + field_num,
|
||||
Self::POWER_ISA_CR_1_THRU_7_REG_NUMS.start - 1 + field_num,
|
||||
);
|
||||
}
|
||||
power_isa_cr_reg
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
use crate::{
|
||||
config::CpuConfig,
|
||||
instruction::{
|
||||
AddSubMOp, AluBranchMOp, AluCommonMOp, COMMON_MOP_SRC_LEN, CommonMOp, LogicalMOp, MOpTrait,
|
||||
OutputIntegerMode, RenamedMOp, UnitOutRegNum,
|
||||
AddSubMOp, AluBranchMOp, AluCommonMOp, COMMON_MOP_SRC_LEN, CommonMOp, CompareMOp,
|
||||
LogicalMOp, MOpTrait, OutputIntegerMode, RenamedMOp, UnitOutRegNum,
|
||||
},
|
||||
register::{FlagsMode, PRegFlagsPowerISA, PRegFlagsX86, PRegValue},
|
||||
unit::{
|
||||
|
|
@ -244,6 +244,20 @@ fn logical(
|
|||
}
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
fn compare<SrcCount: KnownSize>(
|
||||
mop: Expr<CompareMOp<UnitOutRegNum<DynSize>, DynSize, SrcCount>>,
|
||||
flags_mode: Expr<FlagsMode>,
|
||||
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
|
||||
) -> Expr<UnitResultCompleted<()>> {
|
||||
// TODO: finish
|
||||
#[hdl]
|
||||
UnitResultCompleted::<_> {
|
||||
value: PRegValue::zeroed(),
|
||||
extra_out: (),
|
||||
}
|
||||
}
|
||||
|
||||
#[hdl_module]
|
||||
pub fn alu_branch(config: &CpuConfig, unit_index: usize) {
|
||||
#[hdl]
|
||||
|
|
@ -336,6 +350,40 @@ pub fn alu_branch(config: &CpuConfig, unit_index: usize) {
|
|||
},
|
||||
),
|
||||
),
|
||||
AluBranchMOp::<_, _>::Compare(mop) => connect(
|
||||
unit_base.execute_end,
|
||||
HdlSome(
|
||||
#[hdl]
|
||||
ExecuteEnd::<_, _> {
|
||||
unit_output: #[hdl]
|
||||
UnitOutput::<_, _> {
|
||||
which: MOpTrait::dest_reg(mop),
|
||||
result: UnitResult[()].Completed(compare(
|
||||
mop,
|
||||
global_state.flags_mode,
|
||||
src_values,
|
||||
)),
|
||||
},
|
||||
},
|
||||
),
|
||||
),
|
||||
AluBranchMOp::<_, _>::CompareI(mop) => connect(
|
||||
unit_base.execute_end,
|
||||
HdlSome(
|
||||
#[hdl]
|
||||
ExecuteEnd::<_, _> {
|
||||
unit_output: #[hdl]
|
||||
UnitOutput::<_, _> {
|
||||
which: MOpTrait::dest_reg(mop),
|
||||
result: UnitResult[()].Completed(compare(
|
||||
mop,
|
||||
global_state.flags_mode,
|
||||
src_values,
|
||||
)),
|
||||
},
|
||||
},
|
||||
),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -3,7 +3,9 @@
|
|||
|
||||
use cpu::{
|
||||
decoder::simple_power_isa::decode_one_insn,
|
||||
instruction::{AddSubMOp, MOp, MOpDestReg, MOpRegNum, OutputIntegerMode},
|
||||
instruction::{
|
||||
AddSubMOp, CompareMOp, CompareMode, MOp, MOpDestReg, MOpRegNum, OutputIntegerMode,
|
||||
},
|
||||
util::array_vec::ArrayVec,
|
||||
};
|
||||
use fayalite::{prelude::*, sim::vcd::VcdWriterDecls, util::RcWriter};
|
||||
|
|
@ -486,6 +488,181 @@ fn test_cases() -> Vec<TestCase> {
|
|||
false,
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"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(4_hdl_u5).value],
|
||||
0x1234.cast_to_static::<SInt<_>>(),
|
||||
#[hdl(sim)]
|
||||
OutputIntegerMode::Full64(),
|
||||
#[hdl(sim)]
|
||||
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(4_hdl_u5).value],
|
||||
(0x89abu16 as i16).cast_to_static::<SInt<_>>(),
|
||||
#[hdl(sim)]
|
||||
OutputIntegerMode::Full64(),
|
||||
#[hdl(sim)]
|
||||
CompareMode::S64(),
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"cmp 3, 0, 4, 5",
|
||||
0x7d842800,
|
||||
None,
|
||||
CompareMOp::compare(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg(4_hdl_u5).value,
|
||||
MOpRegNum::power_isa_gpr_reg(5_hdl_u5).value,
|
||||
],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
#[hdl(sim)]
|
||||
OutputIntegerMode::Full64(),
|
||||
#[hdl(sim)]
|
||||
CompareMode::S32(),
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"cmp 3, 1, 4, 5",
|
||||
0x7da42800,
|
||||
None,
|
||||
CompareMOp::compare(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg(4_hdl_u5).value,
|
||||
MOpRegNum::power_isa_gpr_reg(5_hdl_u5).value,
|
||||
],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
#[hdl(sim)]
|
||||
OutputIntegerMode::Full64(),
|
||||
#[hdl(sim)]
|
||||
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(4_hdl_u5).value],
|
||||
0x1234.cast_to_static::<SInt<_>>(),
|
||||
#[hdl(sim)]
|
||||
OutputIntegerMode::Full64(),
|
||||
#[hdl(sim)]
|
||||
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(4_hdl_u5).value],
|
||||
0x89ab.cast_to_static::<SInt<_>>(),
|
||||
#[hdl(sim)]
|
||||
OutputIntegerMode::Full64(),
|
||||
#[hdl(sim)]
|
||||
CompareMode::U64(),
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"cmpl 3, 0, 4, 5",
|
||||
0x7d842840,
|
||||
None,
|
||||
CompareMOp::compare(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg(4_hdl_u5).value,
|
||||
MOpRegNum::power_isa_gpr_reg(5_hdl_u5).value,
|
||||
],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
#[hdl(sim)]
|
||||
OutputIntegerMode::Full64(),
|
||||
#[hdl(sim)]
|
||||
CompareMode::U32(),
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"cmpl 3, 1, 4, 5",
|
||||
0x7da42840,
|
||||
None,
|
||||
CompareMOp::compare(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg(4_hdl_u5).value,
|
||||
MOpRegNum::power_isa_gpr_reg(5_hdl_u5).value,
|
||||
],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
#[hdl(sim)]
|
||||
OutputIntegerMode::Full64(),
|
||||
#[hdl(sim)]
|
||||
CompareMode::U64(),
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"cmprb 3, 0, 4, 5",
|
||||
0x7d842980,
|
||||
None,
|
||||
CompareMOp::compare(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg(4_hdl_u5).value,
|
||||
MOpRegNum::power_isa_gpr_reg(5_hdl_u5).value,
|
||||
],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
#[hdl(sim)]
|
||||
OutputIntegerMode::Full64(),
|
||||
#[hdl(sim)]
|
||||
CompareMode::CmpRBOne(),
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"cmprb 3, 1, 4, 5",
|
||||
0x7da42980,
|
||||
None,
|
||||
CompareMOp::compare(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg(4_hdl_u5).value,
|
||||
MOpRegNum::power_isa_gpr_reg(5_hdl_u5).value,
|
||||
],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
#[hdl(sim)]
|
||||
OutputIntegerMode::Full64(),
|
||||
#[hdl(sim)]
|
||||
CompareMode::CmpRBTwo(),
|
||||
),
|
||||
));
|
||||
retval.push(insn_single(
|
||||
"cmpeqb 3, 4, 5",
|
||||
0x7d8429c0,
|
||||
None,
|
||||
CompareMOp::compare(
|
||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||
[
|
||||
MOpRegNum::power_isa_gpr_reg(4_hdl_u5).value,
|
||||
MOpRegNum::power_isa_gpr_reg(5_hdl_u5).value,
|
||||
],
|
||||
0.cast_to_static::<SInt<_>>(),
|
||||
#[hdl(sim)]
|
||||
OutputIntegerMode::Full64(),
|
||||
#[hdl(sim)]
|
||||
CompareMode::CmpEqB(),
|
||||
),
|
||||
));
|
||||
retval
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue