unit::alu_branch::compare: implement CmpRBOne/CmpRBTwo/CmpEqB
This commit is contained in:
parent
7481d079d5
commit
7acfaebfde
5 changed files with 5347 additions and 356 deletions
|
|
@ -927,9 +927,17 @@ fn compare<C: Type + PhantomConstCpuConfig, SrcCount: KnownSize>(config: C) {
|
|||
} = PRegFlags::view::<PRegFlagsPowerISA>(power_isa_flags);
|
||||
|
||||
let _ = so; // TODO: need to set from the global SO
|
||||
connect(cr_lt, lhs_casted.cmp_lt(rhs_casted));
|
||||
connect(cr_eq, lhs_casted.cmp_eq(rhs_casted));
|
||||
connect(cr_gt, !(cr_lt | cr_eq));
|
||||
|
||||
// create separate wires to avoid a combinatorial loop
|
||||
#[hdl]
|
||||
let power_isa_cr_lt = wire();
|
||||
#[hdl]
|
||||
let power_isa_cr_eq = wire();
|
||||
connect(power_isa_cr_lt, lhs_casted.cmp_lt(rhs_casted));
|
||||
connect(power_isa_cr_eq, lhs_casted.cmp_eq(rhs_casted));
|
||||
connect(cr_lt, power_isa_cr_lt);
|
||||
connect(cr_eq, power_isa_cr_eq);
|
||||
connect(cr_gt, !(power_isa_cr_lt | power_isa_cr_eq));
|
||||
}
|
||||
|
||||
let normal_compare = |x86_sub_mode_v: Expr<OutputIntegerMode>,
|
||||
|
|
@ -937,11 +945,6 @@ fn compare<C: Type + PhantomConstCpuConfig, SrcCount: KnownSize>(config: C) {
|
|||
connect(x86_sub_mode, x86_sub_mode_v);
|
||||
connect(lhs_casted, do_cast(lhs.int_fp));
|
||||
connect(rhs_casted, do_cast(rhs.int_fp));
|
||||
#[hdl]
|
||||
match flags_mode {
|
||||
FlagsMode::PowerISA(_) => connect(output.flags, power_isa_flags),
|
||||
FlagsMode::X86(_) => connect(output.flags, x86_flags),
|
||||
}
|
||||
};
|
||||
|
||||
fn do_cast<T: IntType + StaticType>(v: Expr<UInt<64>>) -> Expr<SInt<65>>
|
||||
|
|
@ -952,6 +955,42 @@ fn compare<C: Type + PhantomConstCpuConfig, SrcCount: KnownSize>(config: C) {
|
|||
v.cast_to_static::<T>().cast_to_static::<SInt<65>>()
|
||||
}
|
||||
|
||||
let connect_cmprb_cmpeqb_output = |matches| {
|
||||
connect(
|
||||
power_isa_flags,
|
||||
PRegFlags::from_view::<PRegFlagsPowerISA>(PRegFlagsPowerISAView {
|
||||
cr_gt: matches,
|
||||
..PRegFlagsPowerISAView::splat(false.to_expr())
|
||||
}),
|
||||
);
|
||||
// this isn't specifically matching any x86 instruction,
|
||||
// so this can be changed as necessary.
|
||||
connect(
|
||||
x86_flags,
|
||||
PRegFlags::from_view::<PRegFlagsX86>(PRegFlagsX86View {
|
||||
zf: matches,
|
||||
..PRegFlagsX86View::splat(false.to_expr())
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
#[hdl]
|
||||
let cmprb_cmpeqb_byte = wire();
|
||||
connect(cmprb_cmpeqb_byte, lhs.int_fp.cast_to_static::<UInt<8>>());
|
||||
|
||||
#[hdl]
|
||||
let cmprb_low_0: UInt<8> = wire();
|
||||
connect_any(cmprb_low_0, rhs.int_fp[0..8]);
|
||||
#[hdl]
|
||||
let cmprb_high_0: UInt<8> = wire();
|
||||
connect_any(cmprb_high_0, rhs.int_fp[8..16]);
|
||||
#[hdl]
|
||||
let cmprb_low_1: UInt<8> = wire();
|
||||
connect_any(cmprb_low_1, rhs.int_fp[16..24]);
|
||||
#[hdl]
|
||||
let cmprb_high_1: UInt<8> = wire();
|
||||
connect_any(cmprb_high_1, rhs.int_fp[24..32]);
|
||||
|
||||
#[hdl]
|
||||
match compare_mode {
|
||||
CompareMode::U64 => normal_compare(OutputIntegerMode.Full64(), do_cast::<UInt<64>>),
|
||||
|
|
@ -962,9 +1001,28 @@ fn compare<C: Type + PhantomConstCpuConfig, SrcCount: KnownSize>(config: C) {
|
|||
CompareMode::S16 => normal_compare(OutputIntegerMode.SignExt16(), do_cast::<SInt<16>>),
|
||||
CompareMode::U8 => normal_compare(OutputIntegerMode.ZeroExt8(), do_cast::<UInt<8>>),
|
||||
CompareMode::S8 => normal_compare(OutputIntegerMode.SignExt8(), do_cast::<SInt<8>>),
|
||||
CompareMode::CmpRBOne | CompareMode::CmpRBTwo | CompareMode::CmpEqB => {
|
||||
// TODO
|
||||
}
|
||||
CompareMode::CmpRBOne => connect_cmprb_cmpeqb_output(
|
||||
cmprb_cmpeqb_byte.cmp_ge(cmprb_low_0) & cmprb_cmpeqb_byte.cmp_le(cmprb_high_0),
|
||||
),
|
||||
CompareMode::CmpRBTwo => connect_cmprb_cmpeqb_output(
|
||||
(cmprb_cmpeqb_byte.cmp_ge(cmprb_low_0) & cmprb_cmpeqb_byte.cmp_le(cmprb_high_0))
|
||||
| (cmprb_cmpeqb_byte.cmp_ge(cmprb_low_1) & cmprb_cmpeqb_byte.cmp_le(cmprb_high_1)),
|
||||
),
|
||||
CompareMode::CmpEqB => connect_cmprb_cmpeqb_output(
|
||||
rhs.int_fp
|
||||
.cast_bits_to(u64::to_le_bytes(0).ty())
|
||||
.into_iter()
|
||||
.map(|b| cmprb_cmpeqb_byte.cmp_eq(b))
|
||||
.collect::<Vec<_>>()
|
||||
.cast_to_bits()
|
||||
.any_one_bits(),
|
||||
),
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
match flags_mode {
|
||||
FlagsMode::PowerISA(_) => connect(output.flags, power_isa_flags),
|
||||
FlagsMode::X86(_) => connect(output.flags, x86_flags),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue