add a procedural implementation of rename_execute_retire #12
38 changed files with 615322 additions and 36446 deletions
8
Cargo.lock
generated
8
Cargo.lock
generated
|
|
@ -388,7 +388,7 @@ checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fayalite"
|
name = "fayalite"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#80b92c7dd3adcad8487a3f8224846e381219bfa6"
|
source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#cf3e6cfc6bc33eebf2d2862c7a1948b9cf40ecac"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"bitvec",
|
"bitvec",
|
||||||
|
|
@ -417,7 +417,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fayalite-proc-macros"
|
name = "fayalite-proc-macros"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#80b92c7dd3adcad8487a3f8224846e381219bfa6"
|
source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#cf3e6cfc6bc33eebf2d2862c7a1948b9cf40ecac"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fayalite-proc-macros-impl",
|
"fayalite-proc-macros-impl",
|
||||||
]
|
]
|
||||||
|
|
@ -425,7 +425,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fayalite-proc-macros-impl"
|
name = "fayalite-proc-macros-impl"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#80b92c7dd3adcad8487a3f8224846e381219bfa6"
|
source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#cf3e6cfc6bc33eebf2d2862c7a1948b9cf40ecac"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base16ct 0.2.0",
|
"base16ct 0.2.0",
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
|
|
@ -440,7 +440,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fayalite-visit-gen"
|
name = "fayalite-visit-gen"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#80b92c7dd3adcad8487a3f8224846e381219bfa6"
|
source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#cf3e6cfc6bc33eebf2d2862c7a1948b9cf40ecac"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"prettyplease",
|
"prettyplease",
|
||||||
|
|
|
||||||
|
|
@ -33,3 +33,6 @@ hex-literal.workspace = true
|
||||||
regex = "1.12.2"
|
regex = "1.12.2"
|
||||||
sha2.workspace = true
|
sha2.workspace = true
|
||||||
which.workspace = true
|
which.workspace = true
|
||||||
|
|
||||||
|
[lints.rust]
|
||||||
|
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(todo)'] }
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,7 @@
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
// See Notices.txt for copyright information
|
// See Notices.txt for copyright information
|
||||||
use crate::{
|
use crate::{instruction::CONST_ZERO_UNIT_NUM, unit::UnitKind};
|
||||||
instruction::{CONST_ZERO_UNIT_NUM, MOpTrait, PRegNum, RenamedMOp, UnitNum, UnitOutRegNum},
|
use fayalite::{expr::HdlPartialOrdImpl, prelude::*};
|
||||||
unit::{
|
|
||||||
UnitCancelInput, UnitKind, UnitOutputWrite,
|
|
||||||
unit_base::{UnitForwardingInfo, UnitToRegAlloc},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
use fayalite::prelude::*;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
|
|
||||||
|
|
@ -101,54 +95,20 @@ impl CpuConfig {
|
||||||
pub fn unit_num_width(&self) -> usize {
|
pub fn unit_num_width(&self) -> usize {
|
||||||
UInt::range(CONST_ZERO_UNIT_NUM..self.non_const_unit_nums().end).width()
|
UInt::range(CONST_ZERO_UNIT_NUM..self.non_const_unit_nums().end).width()
|
||||||
}
|
}
|
||||||
pub fn unit_num(&self) -> UnitNum<DynSize> {
|
|
||||||
UnitNum[self.unit_num_width()]
|
|
||||||
}
|
|
||||||
pub fn unit_out_reg_num(&self) -> UnitOutRegNum<DynSize> {
|
|
||||||
UnitOutRegNum[self.out_reg_num_width]
|
|
||||||
}
|
|
||||||
pub fn p_reg_num(&self) -> PRegNum<DynSize, DynSize> {
|
|
||||||
PRegNum[self.unit_num_width()][self.out_reg_num_width]
|
|
||||||
}
|
|
||||||
pub fn p_reg_num_width(&self) -> usize {
|
pub fn p_reg_num_width(&self) -> usize {
|
||||||
self.unit_num_width() + self.out_reg_num_width
|
self.unit_num_width() + self.out_reg_num_width
|
||||||
}
|
}
|
||||||
pub fn renamed_mop_in_unit(&self) -> RenamedMOp<UnitOutRegNum<DynSize>, DynSize> {
|
|
||||||
RenamedMOp[self.unit_out_reg_num()][self.p_reg_num_width()]
|
|
||||||
}
|
|
||||||
pub fn unit_output_write(&self) -> UnitOutputWrite<DynSize> {
|
|
||||||
UnitOutputWrite[self.out_reg_num_width]
|
|
||||||
}
|
|
||||||
pub fn unit_output_writes(&self) -> Array<HdlOption<UnitOutputWrite<DynSize>>> {
|
|
||||||
Array[HdlOption[self.unit_output_write()]][self.non_const_unit_nums().len()]
|
|
||||||
}
|
|
||||||
pub fn unit_cancel_input(&self) -> UnitCancelInput<DynSize> {
|
|
||||||
UnitCancelInput[self.out_reg_num_width]
|
|
||||||
}
|
|
||||||
pub fn unit_forwarding_info(&self) -> UnitForwardingInfo<DynSize, DynSize, DynSize> {
|
|
||||||
UnitForwardingInfo[self.unit_num_width()][self.out_reg_num_width]
|
|
||||||
[self.non_const_unit_nums().len()]
|
|
||||||
}
|
|
||||||
pub fn unit_max_in_flight(&self, unit_index: usize) -> NonZeroUsize {
|
pub fn unit_max_in_flight(&self, unit_index: usize) -> NonZeroUsize {
|
||||||
self.units[unit_index]
|
self.units[unit_index]
|
||||||
.max_in_flight
|
.max_in_flight
|
||||||
.unwrap_or(self.default_unit_max_in_flight)
|
.unwrap_or(self.default_unit_max_in_flight)
|
||||||
}
|
}
|
||||||
pub fn unit_to_reg_alloc<
|
/// the maximum of all [`unit_max_in_flight()`][Self::unit_max_in_flight()]
|
||||||
MOp: Type + MOpTrait<DestReg = UnitOutRegNum<DynSize>, SrcRegWidth = DynSize>,
|
pub fn max_unit_max_in_flight(&self) -> NonZeroUsize {
|
||||||
ExtraOut: Type,
|
(0..self.units.len())
|
||||||
>(
|
.map(|unit_index| self.unit_max_in_flight(unit_index))
|
||||||
&self,
|
.max()
|
||||||
mop_ty: MOp,
|
.unwrap_or(self.default_unit_max_in_flight)
|
||||||
extra_out_ty: ExtraOut,
|
|
||||||
) -> UnitToRegAlloc<MOp, ExtraOut, DynSize, DynSize, DynSize> {
|
|
||||||
assert_eq!(
|
|
||||||
mop_ty.dest_reg_ty(),
|
|
||||||
self.unit_out_reg_num(),
|
|
||||||
"inconsistent types",
|
|
||||||
);
|
|
||||||
UnitToRegAlloc[mop_ty][extra_out_ty][self.unit_num_width()][self.out_reg_num_width]
|
|
||||||
[self.non_const_unit_nums().len()]
|
|
||||||
}
|
}
|
||||||
pub fn fetch_width_in_bytes(&self) -> usize {
|
pub fn fetch_width_in_bytes(&self) -> usize {
|
||||||
1usize
|
1usize
|
||||||
|
|
@ -188,6 +148,21 @@ impl CpuConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[hdl(get(|c| c.out_reg_num_width))]
|
||||||
|
pub type CpuConfigOutRegNumWidth<C: PhantomConstGet<CpuConfig>> = DynSize;
|
||||||
|
|
||||||
|
#[hdl(get(|c| c.unit_num_width()))]
|
||||||
|
pub type CpuConfigUnitNumWidth<C: PhantomConstGet<CpuConfig>> = DynSize;
|
||||||
|
|
||||||
|
#[hdl(get(|c| c.p_reg_num_width()))]
|
||||||
|
pub type CpuConfigPRegNumWidth<C: PhantomConstGet<CpuConfig>> = DynSize;
|
||||||
|
|
||||||
|
#[hdl(get(|c| 1 << c.out_reg_num_width))]
|
||||||
|
pub type CpuConfig2PowOutRegNumWidth<C: PhantomConstGet<CpuConfig>> = DynSize;
|
||||||
|
|
||||||
|
#[hdl(get(|c| c.units.len()))]
|
||||||
|
pub type CpuConfigUnitCount<C: PhantomConstGet<CpuConfig>> = DynSize;
|
||||||
|
|
||||||
#[hdl(get(|c| c.fetch_width.get()))]
|
#[hdl(get(|c| c.fetch_width.get()))]
|
||||||
pub type CpuConfigFetchWidth<C: PhantomConstGet<CpuConfig>> = DynSize;
|
pub type CpuConfigFetchWidth<C: PhantomConstGet<CpuConfig>> = DynSize;
|
||||||
|
|
||||||
|
|
@ -236,6 +211,10 @@ pub type CpuConfigL1ICacheMaxMissesInFlight<C: PhantomConstGet<CpuConfig>> = Dyn
|
||||||
#[hdl(get(|c| c.rob_size.get()))]
|
#[hdl(get(|c| c.rob_size.get()))]
|
||||||
pub type CpuConfigRobSize<C: PhantomConstGet<CpuConfig>> = DynSize;
|
pub type CpuConfigRobSize<C: PhantomConstGet<CpuConfig>> = DynSize;
|
||||||
|
|
||||||
|
/// the maximum of all [`unit_max_in_flight()`][CpuConfig::unit_max_in_flight()]
|
||||||
|
#[hdl(get(|c| c.max_unit_max_in_flight().get()))]
|
||||||
|
pub type CpuConfigMaxUnitMaxInFlight<C: PhantomConstGet<CpuConfig>> = DynSize;
|
||||||
|
|
||||||
pub trait PhantomConstCpuConfig:
|
pub trait PhantomConstCpuConfig:
|
||||||
PhantomConstGet<CpuConfig>
|
PhantomConstGet<CpuConfig>
|
||||||
+ Into<PhantomConst<CpuConfig>>
|
+ Into<PhantomConst<CpuConfig>>
|
||||||
|
|
@ -243,6 +222,7 @@ pub trait PhantomConstCpuConfig:
|
||||||
+ Type
|
+ Type
|
||||||
+ ToSimValue<Type = Self>
|
+ ToSimValue<Type = Self>
|
||||||
+ ToExpr<Type = Self>
|
+ ToExpr<Type = Self>
|
||||||
|
+ HdlPartialOrdImpl<Self>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@ use crate::{
|
||||||
AddSubMOp, BranchMOp, CompareMOp, CompareMode, ConditionMode, LoadMOp, LoadStoreConversion,
|
AddSubMOp, BranchMOp, CompareMOp, CompareMode, ConditionMode, LoadMOp, LoadStoreConversion,
|
||||||
LoadStoreWidth, LogicalFlagsMOp, LogicalFlagsMOpImm, LogicalMOp, Lut4, MOp, MOpDestReg,
|
LoadStoreWidth, LogicalFlagsMOp, LogicalFlagsMOpImm, LogicalMOp, Lut4, MOp, MOpDestReg,
|
||||||
MOpRegNum, MoveRegMOp, OutputIntegerMode, ReadSpecialMOp, ReadSpecialMOpImm,
|
MOpRegNum, MoveRegMOp, OutputIntegerMode, ReadSpecialMOp, ReadSpecialMOpImm,
|
||||||
ShiftRotateDestLogicOp, ShiftRotateMOp, ShiftRotateMOpImm, ShiftRotateMode, StoreMOp,
|
ShiftAmountOverflowBehavior, ShiftRotateDestLogicOp, ShiftRotateMOp, ShiftRotateMOpImm,
|
||||||
power_isa::PowerIsaSprEnum,
|
ShiftRotateMode, StoreMOp, power_isa::PowerIsaSprEnum,
|
||||||
},
|
},
|
||||||
powerisa_instructions_xml::{
|
powerisa_instructions_xml::{
|
||||||
InstructionBitFieldName, InstructionBitFieldsInner, Instructions, TextLineItem,
|
InstructionBitFieldName, InstructionBitFieldsInner, Instructions, TextLineItem,
|
||||||
|
|
@ -604,7 +604,7 @@ impl DecodeState<'_> {
|
||||||
}],
|
}],
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
MOpRegNum::const_zero().value,
|
[MOpRegNum::const_zero(); 2],
|
||||||
(li << 2).cast_to_static(),
|
(li << 2).cast_to_static(),
|
||||||
!aa,
|
!aa,
|
||||||
lk,
|
lk,
|
||||||
|
|
@ -646,7 +646,7 @@ impl DecodeState<'_> {
|
||||||
#[hdl]
|
#[hdl]
|
||||||
let branch_ctr_reg: MOpRegNum = wire();
|
let branch_ctr_reg: MOpRegNum = wire();
|
||||||
let dest = MOpDestReg::new([branch_lr_dest_reg], []);
|
let dest = MOpDestReg::new([branch_lr_dest_reg], []);
|
||||||
let src1 = addr_reg.unwrap_or_else(|| MOpRegNum::const_zero()).value;
|
let src1 = addr_reg.unwrap_or_else(|| MOpRegNum::const_zero());
|
||||||
let imm: Expr<SInt<_>> = (bd.unwrap_or(0_hdl_i14) << 2).cast_to_static();
|
let imm: Expr<SInt<_>> = (bd.unwrap_or(0_hdl_i14) << 2).cast_to_static();
|
||||||
let invert_src2_eq_zero = !use_eq_for_ctr_compare;
|
let invert_src2_eq_zero = !use_eq_for_ctr_compare;
|
||||||
let pc_relative = match aa {
|
let pc_relative = match aa {
|
||||||
|
|
@ -659,7 +659,7 @@ impl DecodeState<'_> {
|
||||||
branch_mop,
|
branch_mop,
|
||||||
BranchMOp::branch_i(
|
BranchMOp::branch_i(
|
||||||
dest,
|
dest,
|
||||||
src1,
|
[MOpRegNum::const_zero(), src1],
|
||||||
imm.cast_to_static::<SInt<_>>(),
|
imm.cast_to_static::<SInt<_>>(),
|
||||||
pc_relative,
|
pc_relative,
|
||||||
lk,
|
lk,
|
||||||
|
|
@ -671,8 +671,7 @@ impl DecodeState<'_> {
|
||||||
branch_mop,
|
branch_mop,
|
||||||
BranchMOp::branch_ctr(
|
BranchMOp::branch_ctr(
|
||||||
dest,
|
dest,
|
||||||
src1,
|
[MOpRegNum::const_zero(), src1, branch_ctr_reg],
|
||||||
branch_ctr_reg.value,
|
|
||||||
imm,
|
imm,
|
||||||
invert_src2_eq_zero,
|
invert_src2_eq_zero,
|
||||||
pc_relative,
|
pc_relative,
|
||||||
|
|
@ -685,7 +684,7 @@ impl DecodeState<'_> {
|
||||||
branch_mop,
|
branch_mop,
|
||||||
BranchMOp::branch_cond_ctr(
|
BranchMOp::branch_cond_ctr(
|
||||||
dest,
|
dest,
|
||||||
[cr_field.value, src1, branch_ctr_reg.value],
|
[cr_field, src1, branch_ctr_reg],
|
||||||
imm,
|
imm,
|
||||||
!expected_cr_bit_value,
|
!expected_cr_bit_value,
|
||||||
condition_mode,
|
condition_mode,
|
||||||
|
|
@ -713,10 +712,7 @@ impl DecodeState<'_> {
|
||||||
this.output[0],
|
this.output[0],
|
||||||
AddSubMOp::add_sub_i(
|
AddSubMOp::add_sub_i(
|
||||||
MOpDestReg::new([MOpRegNum::power_isa_ctr_reg()], []),
|
MOpDestReg::new([MOpRegNum::power_isa_ctr_reg()], []),
|
||||||
[
|
[MOpRegNum::power_isa_ctr_reg(), MOpRegNum::const_zero()],
|
||||||
MOpRegNum::power_isa_ctr_reg().value,
|
|
||||||
MOpRegNum::const_zero().value,
|
|
||||||
],
|
|
||||||
(-1).cast_to_static::<SInt<_>>(),
|
(-1).cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -789,7 +785,7 @@ impl DecodeState<'_> {
|
||||||
this.output[0],
|
this.output[0],
|
||||||
LogicalFlagsMOp::logical_flags(
|
LogicalFlagsMOp::logical_flags(
|
||||||
MOpDestReg::new([bt_reg], []),
|
MOpDestReg::new([bt_reg], []),
|
||||||
[ba_reg.value, bb_reg.value, bt_reg.value],
|
[ba_reg, bb_reg, bt_reg],
|
||||||
#[hdl]
|
#[hdl]
|
||||||
LogicalFlagsMOpImm {
|
LogicalFlagsMOpImm {
|
||||||
src0_start: src0_start.cast_to(LogicalFlagsMOpImm.src0_start),
|
src0_start: src0_start.cast_to(LogicalFlagsMOpImm.src0_start),
|
||||||
|
|
@ -815,7 +811,7 @@ impl DecodeState<'_> {
|
||||||
this.output[0],
|
this.output[0],
|
||||||
MoveRegMOp::move_reg(
|
MoveRegMOp::move_reg(
|
||||||
MOpDestReg::new([crf(bf)], []),
|
MOpDestReg::new([crf(bf)], []),
|
||||||
[crf(bfa).value],
|
[crf(bfa)],
|
||||||
0i8.cast_to_static::<SInt<_>>(),
|
0i8.cast_to_static::<SInt<_>>(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -892,7 +888,7 @@ impl DecodeState<'_> {
|
||||||
this.output[0],
|
this.output[0],
|
||||||
AddSubMOp::add_sub_i(
|
AddSubMOp::add_sub_i(
|
||||||
MOpDestReg::new([ea_reg], []),
|
MOpDestReg::new([ea_reg], []),
|
||||||
[MOpRegNum::const_zero().value; 2],
|
[MOpRegNum::const_zero(); 2],
|
||||||
d,
|
d,
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -906,7 +902,7 @@ impl DecodeState<'_> {
|
||||||
this.output[0],
|
this.output[0],
|
||||||
AddSubMOp::add_sub_i(
|
AddSubMOp::add_sub_i(
|
||||||
MOpDestReg::new([ea_reg], []),
|
MOpDestReg::new([ea_reg], []),
|
||||||
[gpr_or_zero(ra).value, MOpRegNum::const_zero().value],
|
[gpr_or_zero(ra), MOpRegNum::const_zero()],
|
||||||
d,
|
d,
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -918,12 +914,7 @@ impl DecodeState<'_> {
|
||||||
}
|
}
|
||||||
connect(
|
connect(
|
||||||
this.output[1],
|
this.output[1],
|
||||||
LoadMOp::load(
|
LoadMOp::load(MOpDestReg::new([gpr(rt)], []), [ea_reg], width, conversion),
|
||||||
MOpDestReg::new([gpr(rt)], []),
|
|
||||||
[ea_reg.value],
|
|
||||||
width,
|
|
||||||
conversion,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -939,7 +930,7 @@ impl DecodeState<'_> {
|
||||||
this.output[0],
|
this.output[0],
|
||||||
AddSubMOp::add_sub_i(
|
AddSubMOp::add_sub_i(
|
||||||
MOpDestReg::new([ea_reg], []),
|
MOpDestReg::new([ea_reg], []),
|
||||||
[gpr_or_zero(ra).value, gpr(rb).value],
|
[gpr_or_zero(ra), gpr(rb)],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -950,12 +941,7 @@ impl DecodeState<'_> {
|
||||||
);
|
);
|
||||||
connect(
|
connect(
|
||||||
this.output[1],
|
this.output[1],
|
||||||
LoadMOp::load(
|
LoadMOp::load(MOpDestReg::new([gpr(rt)], []), [ea_reg], width, conversion),
|
||||||
MOpDestReg::new([gpr(rt)], []),
|
|
||||||
[ea_reg.value],
|
|
||||||
width,
|
|
||||||
conversion,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
} else if self.arguments == Some("RT,disp(RA)") {
|
} else if self.arguments == Some("RT,disp(RA)") {
|
||||||
|
|
@ -969,7 +955,7 @@ impl DecodeState<'_> {
|
||||||
this.output[0],
|
this.output[0],
|
||||||
AddSubMOp::add_sub_i(
|
AddSubMOp::add_sub_i(
|
||||||
MOpDestReg::new([ea_reg], []),
|
MOpDestReg::new([ea_reg], []),
|
||||||
[gpr_or_zero(ra).value, MOpRegNum::const_zero().value],
|
[gpr_or_zero(ra), MOpRegNum::const_zero()],
|
||||||
(ds << 2).cast_to_static::<SInt<_>>(),
|
(ds << 2).cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -980,12 +966,7 @@ impl DecodeState<'_> {
|
||||||
);
|
);
|
||||||
connect(
|
connect(
|
||||||
this.output[1],
|
this.output[1],
|
||||||
LoadMOp::load(
|
LoadMOp::load(MOpDestReg::new([gpr(rt)], []), [ea_reg], width, conversion),
|
||||||
MOpDestReg::new([gpr(rt)], []),
|
|
||||||
[ea_reg.value],
|
|
||||||
width,
|
|
||||||
conversion,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1005,7 +986,7 @@ impl DecodeState<'_> {
|
||||||
this.output[0],
|
this.output[0],
|
||||||
AddSubMOp::add_sub_i(
|
AddSubMOp::add_sub_i(
|
||||||
MOpDestReg::new([ea_reg], []),
|
MOpDestReg::new([ea_reg], []),
|
||||||
[gpr_or_zero(ra).value, MOpRegNum::const_zero().value],
|
[gpr_or_zero(ra), MOpRegNum::const_zero()],
|
||||||
d.cast_to_static::<SInt<_>>(),
|
d.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -1016,12 +997,7 @@ impl DecodeState<'_> {
|
||||||
);
|
);
|
||||||
connect(
|
connect(
|
||||||
this.output[1],
|
this.output[1],
|
||||||
LoadMOp::load(
|
LoadMOp::load(MOpDestReg::new([gpr(rt)], []), [ea_reg], width, conversion),
|
||||||
MOpDestReg::new([gpr(rt)], []),
|
|
||||||
[ea_reg.value],
|
|
||||||
width,
|
|
||||||
conversion,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -1092,7 +1068,7 @@ impl DecodeState<'_> {
|
||||||
this.output[1],
|
this.output[1],
|
||||||
StoreMOp::store(
|
StoreMOp::store(
|
||||||
MOpDestReg::new([], []),
|
MOpDestReg::new([], []),
|
||||||
[ea_reg.value, gpr(rs).value],
|
[ea_reg, gpr(rs)],
|
||||||
width,
|
width,
|
||||||
LoadStoreConversion.ZeroExt(),
|
LoadStoreConversion.ZeroExt(),
|
||||||
),
|
),
|
||||||
|
|
@ -1107,7 +1083,7 @@ impl DecodeState<'_> {
|
||||||
this.output[2],
|
this.output[2],
|
||||||
MoveRegMOp::move_reg(
|
MoveRegMOp::move_reg(
|
||||||
MOpDestReg::new([gpr(ra)], []),
|
MOpDestReg::new([gpr(ra)], []),
|
||||||
[ea_reg.value],
|
[ea_reg],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -1126,7 +1102,7 @@ impl DecodeState<'_> {
|
||||||
insn,
|
insn,
|
||||||
AddSubMOp::add_sub_i(
|
AddSubMOp::add_sub_i(
|
||||||
MOpDestReg::new([ea_reg], []),
|
MOpDestReg::new([ea_reg], []),
|
||||||
[MOpRegNum::const_zero().value; 2],
|
[MOpRegNum::const_zero(); 2],
|
||||||
d,
|
d,
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -1140,7 +1116,7 @@ impl DecodeState<'_> {
|
||||||
insn,
|
insn,
|
||||||
AddSubMOp::add_sub_i(
|
AddSubMOp::add_sub_i(
|
||||||
MOpDestReg::new([ea_reg], []),
|
MOpDestReg::new([ea_reg], []),
|
||||||
[gpr_or_zero(ra).value, MOpRegNum::const_zero().value],
|
[gpr_or_zero(ra), MOpRegNum::const_zero()],
|
||||||
d,
|
d,
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -1161,7 +1137,7 @@ impl DecodeState<'_> {
|
||||||
insn,
|
insn,
|
||||||
AddSubMOp::add_sub_i(
|
AddSubMOp::add_sub_i(
|
||||||
MOpDestReg::new([ea_reg], []),
|
MOpDestReg::new([ea_reg], []),
|
||||||
[gpr_or_zero(ra).value, gpr(rb).value],
|
[gpr_or_zero(ra), gpr(rb)],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -1179,7 +1155,7 @@ impl DecodeState<'_> {
|
||||||
insn,
|
insn,
|
||||||
AddSubMOp::add_sub_i(
|
AddSubMOp::add_sub_i(
|
||||||
MOpDestReg::new([ea_reg], []),
|
MOpDestReg::new([ea_reg], []),
|
||||||
[gpr_or_zero(ra).value, MOpRegNum::const_zero().value],
|
[gpr_or_zero(ra), MOpRegNum::const_zero()],
|
||||||
(ds << 2).cast_to_static::<SInt<_>>(),
|
(ds << 2).cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -1203,7 +1179,7 @@ impl DecodeState<'_> {
|
||||||
insn,
|
insn,
|
||||||
AddSubMOp::add_sub_i(
|
AddSubMOp::add_sub_i(
|
||||||
MOpDestReg::new([ea_reg], []),
|
MOpDestReg::new([ea_reg], []),
|
||||||
[gpr_or_zero(ra).value, MOpRegNum::const_zero().value],
|
[gpr_or_zero(ra), MOpRegNum::const_zero()],
|
||||||
d.cast_to_static::<SInt<_>>(),
|
d.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -1230,7 +1206,7 @@ impl DecodeState<'_> {
|
||||||
AddSubMOp::add_sub_i(
|
AddSubMOp::add_sub_i(
|
||||||
MOpDestReg::new([gpr(rt)], []),
|
MOpDestReg::new([gpr(rt)], []),
|
||||||
#[hdl]
|
#[hdl]
|
||||||
[gpr_or_zero(ra).value, MOpRegNum::const_zero().value],
|
[gpr_or_zero(ra), MOpRegNum::const_zero()],
|
||||||
si.cast_to_static(),
|
si.cast_to_static(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -1253,7 +1229,7 @@ impl DecodeState<'_> {
|
||||||
AddSubMOp::add_sub_i(
|
AddSubMOp::add_sub_i(
|
||||||
MOpDestReg::new([gpr(rt)], []),
|
MOpDestReg::new([gpr(rt)], []),
|
||||||
#[hdl]
|
#[hdl]
|
||||||
[gpr_or_zero(ra).value, MOpRegNum::const_zero().value],
|
[gpr_or_zero(ra), MOpRegNum::const_zero()],
|
||||||
((si0 << 16) + si1.cast_to(SInt[34])).cast_to_static(),
|
((si0 << 16) + si1.cast_to(SInt[34])).cast_to_static(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -1280,7 +1256,7 @@ impl DecodeState<'_> {
|
||||||
AddSubMOp::add_sub_i(
|
AddSubMOp::add_sub_i(
|
||||||
MOpDestReg::new([gpr(rt)], []),
|
MOpDestReg::new([gpr(rt)], []),
|
||||||
#[hdl]
|
#[hdl]
|
||||||
[gpr_or_zero(ra).value, MOpRegNum::const_zero().value],
|
[gpr_or_zero(ra), MOpRegNum::const_zero()],
|
||||||
(si << 16).cast_to_static(),
|
(si << 16).cast_to_static(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -1307,7 +1283,7 @@ impl DecodeState<'_> {
|
||||||
AddSubMOp::add_sub_i(
|
AddSubMOp::add_sub_i(
|
||||||
MOpDestReg::new([gpr(rt)], []),
|
MOpDestReg::new([gpr(rt)], []),
|
||||||
#[hdl]
|
#[hdl]
|
||||||
[MOpRegNum::const_zero().value; 2],
|
[MOpRegNum::const_zero(); 2],
|
||||||
(4i8 + (d << 16)).cast_to_static(),
|
(4i8 + (d << 16)).cast_to_static(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -1340,7 +1316,7 @@ impl DecodeState<'_> {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
#[hdl]
|
#[hdl]
|
||||||
[gpr(ra).value, gpr(rb).value, MOpRegNum::const_zero().value],
|
[gpr(ra), gpr(rb), MOpRegNum::const_zero()],
|
||||||
0i8.cast_to_static::<SInt<_>>(),
|
0i8.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -1371,7 +1347,7 @@ impl DecodeState<'_> {
|
||||||
)],
|
)],
|
||||||
),
|
),
|
||||||
#[hdl]
|
#[hdl]
|
||||||
[gpr(ra).value, MOpRegNum::const_zero().value],
|
[gpr(ra), MOpRegNum::const_zero()],
|
||||||
si.cast_to_static(),
|
si.cast_to_static(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -1410,7 +1386,7 @@ impl DecodeState<'_> {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
#[hdl]
|
#[hdl]
|
||||||
[gpr(ra).value, gpr(rb).value, MOpRegNum::const_zero().value],
|
[gpr(ra), gpr(rb), MOpRegNum::const_zero()],
|
||||||
0i8.cast_to_static::<SInt<_>>(),
|
0i8.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
true,
|
true,
|
||||||
|
|
@ -1440,7 +1416,7 @@ impl DecodeState<'_> {
|
||||||
)],
|
)],
|
||||||
),
|
),
|
||||||
#[hdl]
|
#[hdl]
|
||||||
[gpr(ra).value, MOpRegNum::const_zero().value],
|
[gpr(ra), MOpRegNum::const_zero()],
|
||||||
si.cast_to_static(),
|
si.cast_to_static(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
true,
|
true,
|
||||||
|
|
@ -1472,7 +1448,7 @@ impl DecodeState<'_> {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
#[hdl]
|
#[hdl]
|
||||||
[gpr(ra).value, gpr(rb).value, MOpRegNum::const_zero().value],
|
[gpr(ra), gpr(rb), MOpRegNum::const_zero()],
|
||||||
0i8.cast_to_static::<SInt<_>>(),
|
0i8.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -1505,11 +1481,7 @@ impl DecodeState<'_> {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
#[hdl]
|
#[hdl]
|
||||||
[
|
[gpr(ra), MOpRegNum::power_isa_xer_ca_ca32_reg(), gpr(rb)],
|
||||||
gpr(ra).value,
|
|
||||||
MOpRegNum::power_isa_xer_ca_ca32_reg().value,
|
|
||||||
gpr(rb).value,
|
|
||||||
],
|
|
||||||
0i8.cast_to_static::<SInt<_>>(),
|
0i8.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -1542,11 +1514,7 @@ impl DecodeState<'_> {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
#[hdl]
|
#[hdl]
|
||||||
[
|
[gpr(ra), MOpRegNum::power_isa_xer_ca_ca32_reg(), gpr(rb)],
|
||||||
gpr(ra).value,
|
|
||||||
MOpRegNum::power_isa_xer_ca_ca32_reg().value,
|
|
||||||
gpr(rb).value,
|
|
||||||
],
|
|
||||||
0i8.cast_to_static::<SInt<_>>(),
|
0i8.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
true,
|
true,
|
||||||
|
|
@ -1580,9 +1548,9 @@ impl DecodeState<'_> {
|
||||||
),
|
),
|
||||||
#[hdl]
|
#[hdl]
|
||||||
[
|
[
|
||||||
gpr(ra).value,
|
gpr(ra),
|
||||||
MOpRegNum::power_isa_xer_ca_ca32_reg().value,
|
MOpRegNum::power_isa_xer_ca_ca32_reg(),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
],
|
],
|
||||||
if this.mnemonic.contains('m') { -1i8 } else { 0 }
|
if this.mnemonic.contains('m') { -1i8 } else { 0 }
|
||||||
.cast_to_static::<SInt<_>>(),
|
.cast_to_static::<SInt<_>>(),
|
||||||
|
|
@ -1617,11 +1585,7 @@ impl DecodeState<'_> {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
#[hdl]
|
#[hdl]
|
||||||
[
|
[gpr(ra), MOpRegNum::const_zero(), MOpRegNum::const_zero()],
|
||||||
gpr(ra).value,
|
|
||||||
MOpRegNum::const_zero().value,
|
|
||||||
MOpRegNum::const_zero().value,
|
|
||||||
],
|
|
||||||
0i8.cast_to_static::<SInt<_>>(),
|
0i8.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
true,
|
true,
|
||||||
|
|
@ -1654,9 +1618,8 @@ impl DecodeState<'_> {
|
||||||
this.output[0],
|
this.output[0],
|
||||||
CompareMOp::compare_i(
|
CompareMOp::compare_i(
|
||||||
MOpDestReg::new([crf(bf)], []),
|
MOpDestReg::new([crf(bf)], []),
|
||||||
[gpr(ra).value],
|
[gpr(ra)],
|
||||||
si.cast_to_static::<SInt<_>>(),
|
si.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
|
||||||
compare_mode,
|
compare_mode,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -1683,9 +1646,7 @@ impl DecodeState<'_> {
|
||||||
this.output[0],
|
this.output[0],
|
||||||
CompareMOp::compare(
|
CompareMOp::compare(
|
||||||
MOpDestReg::new([crf(bf)], []),
|
MOpDestReg::new([crf(bf)], []),
|
||||||
[gpr(ra).value, gpr(rb).value],
|
[gpr(ra), gpr(rb)],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
|
||||||
OutputIntegerMode.Full64(),
|
|
||||||
compare_mode,
|
compare_mode,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -1712,9 +1673,8 @@ impl DecodeState<'_> {
|
||||||
this.output[0],
|
this.output[0],
|
||||||
CompareMOp::compare_i(
|
CompareMOp::compare_i(
|
||||||
MOpDestReg::new([crf(bf)], []),
|
MOpDestReg::new([crf(bf)], []),
|
||||||
[gpr(ra).value],
|
[gpr(ra)],
|
||||||
ui.cast_to_static::<SInt<_>>(),
|
ui.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
|
||||||
compare_mode,
|
compare_mode,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -1741,9 +1701,7 @@ impl DecodeState<'_> {
|
||||||
this.output[0],
|
this.output[0],
|
||||||
CompareMOp::compare(
|
CompareMOp::compare(
|
||||||
MOpDestReg::new([crf(bf)], []),
|
MOpDestReg::new([crf(bf)], []),
|
||||||
[gpr(ra).value, gpr(rb).value],
|
[gpr(ra), gpr(rb)],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
|
||||||
OutputIntegerMode.Full64(),
|
|
||||||
compare_mode,
|
compare_mode,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -1770,9 +1728,7 @@ impl DecodeState<'_> {
|
||||||
this.output[0],
|
this.output[0],
|
||||||
CompareMOp::compare(
|
CompareMOp::compare(
|
||||||
MOpDestReg::new([crf(bf)], []),
|
MOpDestReg::new([crf(bf)], []),
|
||||||
[gpr(ra).value, gpr(rb).value],
|
[gpr(ra), gpr(rb)],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
|
||||||
OutputIntegerMode.Full64(),
|
|
||||||
compare_mode,
|
compare_mode,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -1791,9 +1747,7 @@ impl DecodeState<'_> {
|
||||||
this.output[0],
|
this.output[0],
|
||||||
CompareMOp::compare(
|
CompareMOp::compare(
|
||||||
MOpDestReg::new([crf(bf)], []),
|
MOpDestReg::new([crf(bf)], []),
|
||||||
[gpr(ra).value, gpr(rb).value],
|
[gpr(ra), gpr(rb)],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
|
||||||
OutputIntegerMode.Full64(),
|
|
||||||
CompareMode.CmpEqB(),
|
CompareMode.CmpEqB(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -1825,7 +1779,7 @@ impl DecodeState<'_> {
|
||||||
this.mnemonic.contains('.').to_expr(),
|
this.mnemonic.contains('.').to_expr(),
|
||||||
)],
|
)],
|
||||||
),
|
),
|
||||||
[gpr(rs).value],
|
[gpr(rs)],
|
||||||
if this.mnemonic.contains('s') {
|
if this.mnemonic.contains('s') {
|
||||||
(ui << 16).cast_to_static::<SInt<_>>()
|
(ui << 16).cast_to_static::<SInt<_>>()
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1873,7 +1827,7 @@ impl DecodeState<'_> {
|
||||||
this.output[0],
|
this.output[0],
|
||||||
LogicalMOp::logical(
|
LogicalMOp::logical(
|
||||||
MOpDestReg::new([gpr(ra)], [(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc)]),
|
MOpDestReg::new([gpr(ra)], [(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc)]),
|
||||||
[gpr(rs).value, gpr(rb).value],
|
[gpr(rs), gpr(rb)],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
lut,
|
lut,
|
||||||
|
|
@ -1887,7 +1841,7 @@ impl DecodeState<'_> {
|
||||||
this.output[0],
|
this.output[0],
|
||||||
MoveRegMOp::move_reg(
|
MoveRegMOp::move_reg(
|
||||||
MOpDestReg::new([gpr(ra)], []),
|
MOpDestReg::new([gpr(ra)], []),
|
||||||
[gpr(rs).value],
|
[gpr(rs)],
|
||||||
0i8.cast_to_static::<SInt<_>>(),
|
0i8.cast_to_static::<SInt<_>>(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -1916,7 +1870,7 @@ impl DecodeState<'_> {
|
||||||
this.output[0],
|
this.output[0],
|
||||||
LogicalMOp::logical_i(
|
LogicalMOp::logical_i(
|
||||||
MOpDestReg::new([gpr(ra)], [(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc)]),
|
MOpDestReg::new([gpr(ra)], [(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc)]),
|
||||||
[gpr(rs).value],
|
[gpr(rs)],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
output_integer_mode,
|
output_integer_mode,
|
||||||
Lut4::from_fn(|a, b| a | b),
|
Lut4::from_fn(|a, b| a | b),
|
||||||
|
|
@ -1994,11 +1948,12 @@ impl DecodeState<'_> {
|
||||||
self.output[0],
|
self.output[0],
|
||||||
ShiftRotateMOp::shift_rotate(
|
ShiftRotateMOp::shift_rotate(
|
||||||
MOpDestReg::new([gpr(ra.0)], [(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc.0)]),
|
MOpDestReg::new([gpr(ra.0)], [(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc.0)]),
|
||||||
[gpr(rs.0).value, gpr(rs.0).value, gpr(rb.0).value],
|
[gpr(rs.0), gpr(rs.0), gpr(rb.0)],
|
||||||
#[hdl]
|
#[hdl]
|
||||||
ShiftRotateMOpImm {
|
ShiftRotateMOpImm {
|
||||||
shift_rotate_amount: HdlNone(),
|
shift_rotate_amount: HdlNone(),
|
||||||
shift_rotate_right: false,
|
shift_rotate_right: false,
|
||||||
|
shift_amount_overflow_behavior: ShiftAmountOverflowBehavior.WrapToWidth(),
|
||||||
dest_logic_op,
|
dest_logic_op,
|
||||||
},
|
},
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -2031,24 +1986,25 @@ impl DecodeState<'_> {
|
||||||
self.rotate_dest_logic_op(msb0_mask_begin, msb0_mask_end, fallback_is_src2);
|
self.rotate_dest_logic_op(msb0_mask_begin, msb0_mask_end, fallback_is_src2);
|
||||||
#[hdl]
|
#[hdl]
|
||||||
let rotate_imm_src2 = wire();
|
let rotate_imm_src2 = wire();
|
||||||
connect(rotate_imm_src2, MOpRegNum::const_zero().value);
|
connect(rotate_imm_src2, MOpRegNum::const_zero());
|
||||||
// if dest_logic_op is HdlNone, we don't need to read from src2
|
// if dest_logic_op is HdlNone, we don't need to read from src2
|
||||||
#[hdl]
|
#[hdl]
|
||||||
if let HdlSome(dest_logic_op) = dest_logic_op {
|
if let HdlSome(dest_logic_op) = dest_logic_op {
|
||||||
#[hdl]
|
#[hdl]
|
||||||
if dest_logic_op.fallback_is_src2 {
|
if dest_logic_op.fallback_is_src2 {
|
||||||
connect(rotate_imm_src2, gpr(ra.0).value);
|
connect(rotate_imm_src2, gpr(ra.0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
connect(
|
connect(
|
||||||
self.output[0],
|
self.output[0],
|
||||||
ShiftRotateMOp::shift_rotate(
|
ShiftRotateMOp::shift_rotate(
|
||||||
MOpDestReg::new([gpr(ra.0)], [(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc.0)]),
|
MOpDestReg::new([gpr(ra.0)], [(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc.0)]),
|
||||||
[gpr(rs.0).value, gpr(rs.0).value, rotate_imm_src2],
|
[gpr(rs.0), gpr(rs.0), rotate_imm_src2],
|
||||||
#[hdl]
|
#[hdl]
|
||||||
ShiftRotateMOpImm {
|
ShiftRotateMOpImm {
|
||||||
shift_rotate_amount: HdlSome(rotate_amount),
|
shift_rotate_amount: HdlSome(rotate_amount),
|
||||||
shift_rotate_right: false,
|
shift_rotate_right: false,
|
||||||
|
shift_amount_overflow_behavior: ShiftAmountOverflowBehavior.WrapToWidth(),
|
||||||
dest_logic_op,
|
dest_logic_op,
|
||||||
},
|
},
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -2194,15 +2150,13 @@ impl DecodeState<'_> {
|
||||||
[gpr(ra), MOpRegNum::power_isa_xer_ca_ca32_reg()],
|
[gpr(ra), MOpRegNum::power_isa_xer_ca_ca32_reg()],
|
||||||
[(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc)],
|
[(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc)],
|
||||||
),
|
),
|
||||||
[
|
[gpr(rs), MOpRegNum::const_zero(), MOpRegNum::const_zero()],
|
||||||
gpr(rs).value,
|
|
||||||
MOpRegNum::const_zero().value,
|
|
||||||
MOpRegNum::const_zero().value,
|
|
||||||
],
|
|
||||||
#[hdl]
|
#[hdl]
|
||||||
ShiftRotateMOpImm {
|
ShiftRotateMOpImm {
|
||||||
shift_rotate_amount: HdlSome(sh.cast_to_static::<UInt<_>>()),
|
shift_rotate_amount: HdlSome(sh.cast_to_static::<UInt<_>>()),
|
||||||
shift_rotate_right: true,
|
shift_rotate_right: true,
|
||||||
|
shift_amount_overflow_behavior: ShiftAmountOverflowBehavior
|
||||||
|
.WrapToWidth(),
|
||||||
dest_logic_op: HdlNone(),
|
dest_logic_op: HdlNone(),
|
||||||
},
|
},
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -2226,15 +2180,13 @@ impl DecodeState<'_> {
|
||||||
[gpr(ra), MOpRegNum::power_isa_xer_ca_ca32_reg()],
|
[gpr(ra), MOpRegNum::power_isa_xer_ca_ca32_reg()],
|
||||||
[(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc)],
|
[(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc)],
|
||||||
),
|
),
|
||||||
[
|
[gpr(rs), MOpRegNum::const_zero(), MOpRegNum::const_zero()],
|
||||||
gpr(rs).value,
|
|
||||||
MOpRegNum::const_zero().value,
|
|
||||||
MOpRegNum::const_zero().value,
|
|
||||||
],
|
|
||||||
#[hdl]
|
#[hdl]
|
||||||
ShiftRotateMOpImm {
|
ShiftRotateMOpImm {
|
||||||
shift_rotate_amount: HdlSome(sh.rotate_right(1)),
|
shift_rotate_amount: HdlSome(sh.rotate_right(1)),
|
||||||
shift_rotate_right: true,
|
shift_rotate_right: true,
|
||||||
|
shift_amount_overflow_behavior: ShiftAmountOverflowBehavior
|
||||||
|
.WrapToWidth(),
|
||||||
dest_logic_op: HdlNone(),
|
dest_logic_op: HdlNone(),
|
||||||
},
|
},
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -2268,14 +2220,16 @@ impl DecodeState<'_> {
|
||||||
[(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc)],
|
[(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc)],
|
||||||
),
|
),
|
||||||
if !is_signed && is_right_shift {
|
if !is_signed && is_right_shift {
|
||||||
[MOpRegNum::const_zero().value, gpr(rs).value, gpr(rb).value]
|
[MOpRegNum::const_zero(), gpr(rs), gpr(rb)]
|
||||||
} else {
|
} else {
|
||||||
[gpr(rs).value, MOpRegNum::const_zero().value, gpr(rb).value]
|
[gpr(rs), MOpRegNum::const_zero(), gpr(rb)]
|
||||||
},
|
},
|
||||||
#[hdl]
|
#[hdl]
|
||||||
ShiftRotateMOpImm {
|
ShiftRotateMOpImm {
|
||||||
shift_rotate_amount: HdlNone(),
|
shift_rotate_amount: HdlNone(),
|
||||||
shift_rotate_right: is_right_shift,
|
shift_rotate_right: is_right_shift,
|
||||||
|
shift_amount_overflow_behavior: ShiftAmountOverflowBehavior
|
||||||
|
.WrapToTwiceWidth(),
|
||||||
dest_logic_op: HdlNone(),
|
dest_logic_op: HdlNone(),
|
||||||
},
|
},
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -2306,15 +2260,13 @@ impl DecodeState<'_> {
|
||||||
this.output[0],
|
this.output[0],
|
||||||
ShiftRotateMOp::shift_rotate(
|
ShiftRotateMOp::shift_rotate(
|
||||||
MOpDestReg::new([gpr(ra)], [(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc)]),
|
MOpDestReg::new([gpr(ra)], [(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc)]),
|
||||||
[
|
[gpr(rs), MOpRegNum::const_zero(), MOpRegNum::const_zero()],
|
||||||
gpr(rs).value,
|
|
||||||
MOpRegNum::const_zero().value,
|
|
||||||
MOpRegNum::const_zero().value,
|
|
||||||
],
|
|
||||||
#[hdl]
|
#[hdl]
|
||||||
ShiftRotateMOpImm {
|
ShiftRotateMOpImm {
|
||||||
shift_rotate_amount: HdlSome(sh.rotate_right(1)),
|
shift_rotate_amount: HdlSome(sh.rotate_right(1)),
|
||||||
shift_rotate_right: false,
|
shift_rotate_right: false,
|
||||||
|
shift_amount_overflow_behavior: ShiftAmountOverflowBehavior
|
||||||
|
.WrapToWidth(),
|
||||||
dest_logic_op: HdlNone(),
|
dest_logic_op: HdlNone(),
|
||||||
},
|
},
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -2340,7 +2292,7 @@ impl DecodeState<'_> {
|
||||||
self.output[0],
|
self.output[0],
|
||||||
MoveRegMOp::move_reg(
|
MoveRegMOp::move_reg(
|
||||||
MOpDestReg::new([spr], []),
|
MOpDestReg::new([spr], []),
|
||||||
[gpr(reg).value],
|
[gpr(reg)],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -2349,7 +2301,7 @@ impl DecodeState<'_> {
|
||||||
self.output[0],
|
self.output[0],
|
||||||
MoveRegMOp::move_reg(
|
MoveRegMOp::move_reg(
|
||||||
MOpDestReg::new([gpr(reg)], []),
|
MOpDestReg::new([gpr(reg)], []),
|
||||||
[spr.value],
|
[spr],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -2365,7 +2317,7 @@ impl DecodeState<'_> {
|
||||||
self.output[0],
|
self.output[0],
|
||||||
ReadSpecialMOp::read_special(
|
ReadSpecialMOp::read_special(
|
||||||
MOpDestReg::new([gpr(reg)], []),
|
MOpDestReg::new([gpr(reg)], []),
|
||||||
[MOpRegNum::const_zero().value; 0],
|
[MOpRegNum::const_zero(); 0],
|
||||||
imm,
|
imm,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -2441,9 +2393,9 @@ impl DecodeState<'_> {
|
||||||
LogicalFlagsMOp::logical_flags(
|
LogicalFlagsMOp::logical_flags(
|
||||||
MOpDestReg::new([crf(bf)], []),
|
MOpDestReg::new([crf(bf)], []),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_xer_ca_ca32_reg().value,
|
MOpRegNum::power_isa_xer_ca_ca32_reg(),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
MOpRegNum::power_isa_xer_so_ov_ov32_reg().value,
|
MOpRegNum::power_isa_xer_so_ov_ov32_reg(),
|
||||||
],
|
],
|
||||||
LogicalFlagsMOpImm::from_swizzle_fn::<PRegFlagsPowerISA>(|src0, src1, src2| {
|
LogicalFlagsMOpImm::from_swizzle_fn::<PRegFlagsPowerISA>(|src0, src1, src2| {
|
||||||
let mut dest = PRegFlagsPowerISAView::splat(None);
|
let mut dest = PRegFlagsPowerISAView::splat(None);
|
||||||
|
|
|
||||||
|
|
@ -523,7 +523,7 @@ impl<C: PhantomConstCpuConfig> L1ICacheStateSim<C> {
|
||||||
kind,
|
kind,
|
||||||
read_data,
|
read_data,
|
||||||
config: _,
|
config: _,
|
||||||
} = memory_operation_finish;
|
} = memory_operation_finish.into_sim_value();
|
||||||
#[hdl(sim)]
|
#[hdl(sim)]
|
||||||
match kind {
|
match kind {
|
||||||
MemoryOperationFinishKind::Success(success) =>
|
MemoryOperationFinishKind::Success(success) =>
|
||||||
|
|
@ -746,7 +746,7 @@ impl<C: PhantomConstCpuConfig> L1ICacheStateSim<C> {
|
||||||
let NextPcToFetchInterfaceInner {
|
let NextPcToFetchInterfaceInner {
|
||||||
start_pc,
|
start_pc,
|
||||||
fetch_block_id,
|
fetch_block_id,
|
||||||
} = fetch;
|
} = fetch.into_sim_value();
|
||||||
let entry_ty = FetchQueueEntry[config];
|
let entry_ty = FetchQueueEntry[config];
|
||||||
self.queue.push_back(
|
self.queue.push_back(
|
||||||
#[hdl(sim)]
|
#[hdl(sim)]
|
||||||
|
|
@ -895,7 +895,7 @@ impl<C: PhantomConstCpuConfig> L1ICacheStateSim<C> {
|
||||||
let CacheReadData::<_> {
|
let CacheReadData::<_> {
|
||||||
cache_line_index: read_cache_line_index,
|
cache_line_index: read_cache_line_index,
|
||||||
cache_line,
|
cache_line,
|
||||||
} = cache_read_data;
|
} = cache_read_data.into_sim_value();
|
||||||
let config = self.config();
|
let config = self.config();
|
||||||
for entry in &mut self.queue {
|
for entry in &mut self.queue {
|
||||||
#[hdl(sim)]
|
#[hdl(sim)]
|
||||||
|
|
@ -1151,8 +1151,6 @@ fn l1_i_cache_impl(config: PhantomConst<CpuConfig>) {
|
||||||
sim.wait_for_clock_edge(cd.clk).await;
|
sim.wait_for_clock_edge(cd.clk).await;
|
||||||
}
|
}
|
||||||
sim.write(from_next_pc.cancel.ready, true).await;
|
sim.write(from_next_pc.cancel.ready, true).await;
|
||||||
let memory_interface_start_data_ty = memory_interface.start.data.ty();
|
|
||||||
let to_decode_fetched_data_ty = to_decode_fetched.data.ty();
|
|
||||||
let cache_read_data_ty = CacheReadData[config];
|
let cache_read_data_ty = CacheReadData[config];
|
||||||
let mut state = L1ICacheStateSim::new(state_expr);
|
let mut state = L1ICacheStateSim::new(state_expr);
|
||||||
loop {
|
loop {
|
||||||
|
|
@ -1168,26 +1166,11 @@ fn l1_i_cache_impl(config: PhantomConst<CpuConfig>) {
|
||||||
.await;
|
.await;
|
||||||
sim.write(
|
sim.write(
|
||||||
memory_interface.start.data,
|
memory_interface.start.data,
|
||||||
if let Some(v) = state.clone().try_start_memory_operation() {
|
state.clone().try_start_memory_operation(),
|
||||||
#[hdl(sim)]
|
|
||||||
memory_interface_start_data_ty.HdlSome(v)
|
|
||||||
} else {
|
|
||||||
#[hdl(sim)]
|
|
||||||
memory_interface_start_data_ty.HdlNone()
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
sim.write(
|
|
||||||
to_decode_fetched.data,
|
|
||||||
if let Some(v) = state.clone().to_decode_fetched() {
|
|
||||||
#[hdl(sim)]
|
|
||||||
to_decode_fetched_data_ty.HdlSome(v)
|
|
||||||
} else {
|
|
||||||
#[hdl(sim)]
|
|
||||||
to_decode_fetched_data_ty.HdlNone()
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
sim.write(to_decode_fetched.data, state.clone().to_decode_fetched())
|
||||||
|
.await;
|
||||||
state.write_debug_state(&mut sim).await;
|
state.write_debug_state(&mut sim).await;
|
||||||
sim.write(max_cancel_in_fetch, state.queue.len()).await;
|
sim.write(max_cancel_in_fetch, state.queue.len()).await;
|
||||||
state
|
state
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -25,89 +25,206 @@ pub struct PowerIsaCrBitNum {
|
||||||
pub bit_in_field: UInt<2>,
|
pub bit_in_field: UInt<2>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MOpRegNum {
|
macro_rules! suffix_str_with_0_to_31 {
|
||||||
pub const POWER_ISA_LR_REG_NUM: u32 = 1;
|
($str:literal) => {
|
||||||
#[hdl]
|
suffix_str_with_0_to_31!(
|
||||||
pub fn power_isa_lr_reg() -> Expr<Self> {
|
$str,
|
||||||
#[hdl]
|
[
|
||||||
Self {
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
|
||||||
value: Self::POWER_ISA_LR_REG_NUM.cast_to_static::<UInt<_>>(),
|
23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||||
}
|
]
|
||||||
}
|
)
|
||||||
pub const POWER_ISA_CTR_REG_NUM: u32 = 2;
|
};
|
||||||
#[hdl]
|
($str:literal, [$($num:literal),* $(,)?]) => {
|
||||||
pub fn power_isa_ctr_reg() -> Expr<Self> {
|
[$(concat!($str, $num)),*]
|
||||||
#[hdl]
|
};
|
||||||
Self {
|
}
|
||||||
value: Self::POWER_ISA_CTR_REG_NUM.cast_to_static::<UInt<_>>(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub const POWER_ISA_TAR_REG_NUM: u32 = 3;
|
|
||||||
#[hdl]
|
|
||||||
pub fn power_isa_tar_reg() -> Expr<Self> {
|
|
||||||
#[hdl]
|
|
||||||
Self {
|
|
||||||
value: Self::POWER_ISA_TAR_REG_NUM.cast_to_static::<UInt<_>>(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const fn fill_names_range<'a>(dest: &mut [Option<&'a str>], range: Range<u32>, src: &[&'a str]) {
|
||||||
|
assert!((range.end - range.start) as usize == src.len());
|
||||||
|
let mut i = 0;
|
||||||
|
while i < src.len() {
|
||||||
|
dest[i + range.start as usize] = Some(src[i]);
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! power_isa_regs {
|
||||||
|
(
|
||||||
|
$(
|
||||||
|
#[name_str = $name_str:literal, expr_fn = $expr_fn:ident, sim_fn = $sim_fn:ident]
|
||||||
|
$(#[doc = $($doc:tt)*])*
|
||||||
|
pub const $REG_NUM:ident: u32 = $reg_num_expr:expr;
|
||||||
|
)*
|
||||||
|
$(
|
||||||
|
#[names_fn = |$names_var:ident| $names_body:expr $(,
|
||||||
|
reg_num_fn = $reg_num_fn_multi:ident,
|
||||||
|
expr_fn = $expr_fn_multi:ident($fn_multi_arg:ty),
|
||||||
|
expr_imm_fn = $expr_imm_fn_multi:ident,
|
||||||
|
sim_fn = $sim_fn_multi:ident,)?
|
||||||
|
]
|
||||||
|
$(#[doc = $($doc_multi:tt)*])*
|
||||||
|
pub const $REG_NUM_MULTI:ident: Range<u32> = $reg_num_multi_expr:expr;
|
||||||
|
)*
|
||||||
|
) => {
|
||||||
|
impl MOpRegNum {
|
||||||
|
pub const POWER_ISA_REG_NAMES: &[Option<&str>; 1 << Self::WIDTH] = &{
|
||||||
|
let mut retval = [None; _];
|
||||||
|
$(retval[Self::$REG_NUM as usize] = Some($name_str);)*
|
||||||
|
$({
|
||||||
|
let $names_var = &mut retval;
|
||||||
|
$names_body
|
||||||
|
})*
|
||||||
|
retval
|
||||||
|
};
|
||||||
|
$(
|
||||||
|
$(#[doc = $($doc)*])*
|
||||||
|
pub const $REG_NUM: u32 = $reg_num_expr;
|
||||||
|
$(#[doc = $($doc)*])*
|
||||||
|
#[hdl]
|
||||||
|
pub fn $expr_fn() -> Expr<Self> {
|
||||||
|
#[hdl]
|
||||||
|
Self {
|
||||||
|
value: Self::$REG_NUM.cast_to_static::<UInt<_>>(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$(#[doc = $($doc)*])*
|
||||||
|
#[hdl]
|
||||||
|
pub fn $sim_fn() -> SimValue<Self> {
|
||||||
|
#[hdl(sim)]
|
||||||
|
Self {
|
||||||
|
value: Self::$REG_NUM.cast_to_static::<UInt<_>>(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
$(
|
||||||
|
$(#[doc = $($doc_multi)*])*
|
||||||
|
pub const $REG_NUM_MULTI: Range<u32> = $reg_num_multi_expr;
|
||||||
|
power_isa_regs! {
|
||||||
|
@helper_fns
|
||||||
|
#[names_fn = |$names_var| $names_body $(,
|
||||||
|
reg_num_fn = $reg_num_fn_multi,
|
||||||
|
expr_fn = $expr_fn_multi($fn_multi_arg),
|
||||||
|
expr_imm_fn = $expr_imm_fn_multi,
|
||||||
|
sim_fn = $sim_fn_multi,)?
|
||||||
|
]
|
||||||
|
$(#[doc = $($doc_multi)*])*
|
||||||
|
pub const $REG_NUM_MULTI: Range<u32> = $reg_num_multi_expr;
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
};
|
||||||
|
(
|
||||||
|
@helper_fns
|
||||||
|
#[names_fn = |$names_var:ident| $names_body:expr]
|
||||||
|
$(#[doc = $($doc_multi:tt)*])*
|
||||||
|
pub const $REG_NUM_MULTI:ident: Range<u32> = $reg_num_multi_expr:expr;
|
||||||
|
) => {};
|
||||||
|
(
|
||||||
|
@helper_fns
|
||||||
|
#[
|
||||||
|
names_fn = |$names_var:ident| $names_body:expr,
|
||||||
|
reg_num_fn = $reg_num_fn_multi:ident,
|
||||||
|
expr_fn = $expr_fn_multi:ident($fn_multi_arg:ty),
|
||||||
|
expr_imm_fn = $expr_imm_fn_multi:ident,
|
||||||
|
sim_fn = $sim_fn_multi:ident,
|
||||||
|
]
|
||||||
|
$(#[doc = $($doc_multi:tt)*])*
|
||||||
|
pub const $REG_NUM_MULTI:ident: Range<u32> = $reg_num_multi_expr:expr;
|
||||||
|
) => {
|
||||||
|
$(#[doc = $($doc_multi)*])*
|
||||||
|
pub const fn $reg_num_fn_multi(index: usize) -> u32 {
|
||||||
|
range_u32_nth_or_panic(&Self::$REG_NUM_MULTI, index)
|
||||||
|
}
|
||||||
|
$(#[doc = $($doc_multi)*])*
|
||||||
|
#[hdl]
|
||||||
|
pub fn $expr_fn_multi(input: Expr<$fn_multi_arg>) -> Expr<Self> {
|
||||||
|
#[hdl]
|
||||||
|
Self {
|
||||||
|
value: (Self::$REG_NUM_MULTI.start + input).cast_to_static::<UInt<_>>(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$(#[doc = $($doc_multi)*])*
|
||||||
|
#[hdl]
|
||||||
|
pub fn $expr_imm_fn_multi(input: usize) -> Expr<Self> {
|
||||||
|
#[hdl]
|
||||||
|
Self {
|
||||||
|
value: Self::$reg_num_fn_multi(input).cast_to_static::<UInt<_>>(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$(#[doc = $($doc_multi)*])*
|
||||||
|
#[hdl]
|
||||||
|
pub fn $sim_fn_multi(reg_num: &SimValue<$fn_multi_arg>) -> SimValue<Self> {
|
||||||
|
#[hdl(sim)]
|
||||||
|
Self {
|
||||||
|
value: (Self::$REG_NUM_MULTI.start + reg_num).cast_to_static::<UInt<_>>(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
power_isa_regs! {
|
||||||
|
#[name_str = "lr", expr_fn = power_isa_lr_reg, sim_fn = power_isa_lr_reg_sim]
|
||||||
|
pub const POWER_ISA_LR_REG_NUM: u32 = 1;
|
||||||
|
#[name_str = "ctr", expr_fn = power_isa_ctr_reg, sim_fn = power_isa_ctr_reg_sim]
|
||||||
|
pub const POWER_ISA_CTR_REG_NUM: u32 = 2;
|
||||||
|
#[name_str = "tar", expr_fn = power_isa_tar_reg, sim_fn = power_isa_tar_reg_sim]
|
||||||
|
pub const POWER_ISA_TAR_REG_NUM: u32 = 3;
|
||||||
|
|
||||||
|
#[name_str = "xer[so,ov,ov32]", expr_fn = power_isa_xer_so_ov_ov32_reg, sim_fn = power_isa_xer_so_ov_ov32_reg_sim]
|
||||||
/// SO, OV, and OV32 XER bits -- in [`PRegValue.flags`]
|
/// SO, OV, and OV32 XER bits -- in [`PRegValue.flags`]
|
||||||
///
|
///
|
||||||
/// [`PRegValue.flags`]: struct@crate::register::PRegValue
|
/// [`PRegValue.flags`]: struct@crate::register::PRegValue
|
||||||
pub const POWER_ISA_XER_SO_OV_OV32_REG_NUM: u32 =
|
pub const POWER_ISA_XER_SO_OV_OV32_REG_NUM: u32 =
|
||||||
range_u32_nth_or_panic(&Self::FLAG_REG_NUMS, 0);
|
range_u32_nth_or_panic(&Self::FLAG_REG_NUMS, 0);
|
||||||
|
|
||||||
|
#[name_str = "xer[ca,ca32]", expr_fn = power_isa_xer_ca_ca32_reg, sim_fn = power_isa_xer_ca_ca32_reg_sim]
|
||||||
/// CA and CA32 XER bits -- in [`PRegValue.flags`]
|
/// CA and CA32 XER bits -- in [`PRegValue.flags`]
|
||||||
///
|
///
|
||||||
/// [`PRegValue.flags`]: struct@crate::register::PRegValue
|
/// [`PRegValue.flags`]: struct@crate::register::PRegValue
|
||||||
pub const POWER_ISA_XER_CA_CA32_REG_NUM: u32 = 4;
|
pub const POWER_ISA_XER_CA_CA32_REG_NUM: u32 = 4;
|
||||||
|
|
||||||
|
#[name_str = "xer[other]", expr_fn = power_isa_xer_other_reg, sim_fn = power_isa_xer_other_reg_sim]
|
||||||
/// only the XER bits that don't exist in [`PRegValue.flags`]
|
/// only the XER bits that don't exist in [`PRegValue.flags`]
|
||||||
///
|
///
|
||||||
/// [`PRegValue.flags`]: struct@crate::register::PRegValue
|
/// [`PRegValue.flags`]: struct@crate::register::PRegValue
|
||||||
pub const POWER_ISA_XER_OTHER_REG_NUM: u32 = 5;
|
pub const POWER_ISA_XER_OTHER_REG_NUM: u32 = 5;
|
||||||
|
|
||||||
|
#[name_str = "temp", expr_fn = power_isa_temp_reg, sim_fn = power_isa_temp_reg_sim]
|
||||||
/// used as a temporary for things like computing the effective address before loading/storing memory
|
/// used as a temporary for things like computing the effective address before loading/storing memory
|
||||||
pub const POWER_ISA_TEMP_REG_NUM: u32 = 8;
|
pub const POWER_ISA_TEMP_REG_NUM: u32 = 8;
|
||||||
#[hdl]
|
|
||||||
pub fn power_isa_temp_reg() -> Expr<Self> {
|
|
||||||
#[hdl]
|
|
||||||
Self {
|
|
||||||
value: Self::POWER_ISA_TEMP_REG_NUM.cast_to_static::<UInt<_>>(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// SO, OV, and OV32 XER bits -- in [`PRegValue.flags`]
|
|
||||||
///
|
|
||||||
/// [`PRegValue.flags`]: struct@crate::register::PRegValue
|
|
||||||
#[hdl]
|
|
||||||
pub fn power_isa_xer_so_ov_ov32_reg() -> Expr<Self> {
|
|
||||||
#[hdl]
|
|
||||||
Self {
|
|
||||||
value: Self::POWER_ISA_XER_SO_OV_OV32_REG_NUM.cast_to_static::<UInt<_>>(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// CA and CA32 XER bits -- in [`PRegValue.flags`]
|
|
||||||
///
|
|
||||||
/// [`PRegValue.flags`]: struct@crate::register::PRegValue
|
|
||||||
#[hdl]
|
|
||||||
pub fn power_isa_xer_ca_ca32_reg() -> Expr<Self> {
|
|
||||||
#[hdl]
|
|
||||||
Self {
|
|
||||||
value: Self::POWER_ISA_XER_CA_CA32_REG_NUM.cast_to_static::<UInt<_>>(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// only the XER bits that don't exist in [`PRegValue.flags`]
|
|
||||||
///
|
|
||||||
/// [`PRegValue.flags`]: struct@crate::register::PRegValue
|
|
||||||
#[hdl]
|
|
||||||
pub fn power_isa_xer_other_reg() -> Expr<Self> {
|
|
||||||
#[hdl]
|
|
||||||
Self {
|
|
||||||
value: Self::POWER_ISA_XER_OTHER_REG_NUM.cast_to_static::<UInt<_>>(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#[name_str = "cr0", expr_fn = power_isa_cr_0_reg, sim_fn = power_isa_cr_0_reg_sim]
|
||||||
pub const POWER_ISA_CR_0_REG_NUM: u32 = range_u32_nth_or_panic(&Self::FLAG_REG_NUMS, 1);
|
pub const POWER_ISA_CR_0_REG_NUM: u32 = range_u32_nth_or_panic(&Self::FLAG_REG_NUMS, 1);
|
||||||
|
#[names_fn = |names| {
|
||||||
|
fill_names_range(names, Self::POWER_ISA_CR_1_THRU_7_REG_NUMS, &["cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7"]);
|
||||||
|
}]
|
||||||
pub const POWER_ISA_CR_1_THRU_7_REG_NUMS: Range<u32> = 9..16;
|
pub const POWER_ISA_CR_1_THRU_7_REG_NUMS: Range<u32> = 9..16;
|
||||||
|
|
||||||
|
#[
|
||||||
|
names_fn = |names| {
|
||||||
|
fill_names_range(names, Self::POWER_ISA_GPR_REG_NUMS, &suffix_str_with_0_to_31!("r"));
|
||||||
|
},
|
||||||
|
reg_num_fn = power_isa_gpr_reg_num,
|
||||||
|
expr_fn = power_isa_gpr_reg(UInt<5>),
|
||||||
|
expr_imm_fn = power_isa_gpr_reg_imm,
|
||||||
|
sim_fn = power_isa_gpr_reg_sim,
|
||||||
|
]
|
||||||
|
pub const POWER_ISA_GPR_REG_NUMS: Range<u32> = 32..64;
|
||||||
|
|
||||||
|
#[
|
||||||
|
names_fn = |names| {
|
||||||
|
fill_names_range(names, Self::POWER_ISA_FPR_REG_NUMS, &suffix_str_with_0_to_31!("f"));
|
||||||
|
},
|
||||||
|
reg_num_fn = power_isa_fpr_reg_num,
|
||||||
|
expr_fn = power_isa_fpr_reg(UInt<5>),
|
||||||
|
expr_imm_fn = power_isa_fpr_reg_imm,
|
||||||
|
sim_fn = power_isa_fpr_reg_sim,
|
||||||
|
]
|
||||||
|
pub const POWER_ISA_FPR_REG_NUMS: Range<u32> = 64..96;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MOpRegNum {
|
||||||
pub const fn power_isa_cr_reg_num(index: usize) -> u32 {
|
pub const fn power_isa_cr_reg_num(index: usize) -> u32 {
|
||||||
if index == 0 {
|
if index == 0 {
|
||||||
Self::POWER_ISA_CR_0_REG_NUM
|
Self::POWER_ISA_CR_0_REG_NUM
|
||||||
|
|
@ -148,31 +265,6 @@ impl MOpRegNum {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const POWER_ISA_GPR_REG_NUMS: Range<u32> = 32..64;
|
|
||||||
pub const fn power_isa_gpr_reg_num(index: usize) -> u32 {
|
|
||||||
range_u32_nth_or_panic(&Self::POWER_ISA_GPR_REG_NUMS, index)
|
|
||||||
}
|
|
||||||
#[hdl]
|
|
||||||
pub fn power_isa_gpr_reg(reg_num: Expr<UInt<5>>) -> Expr<Self> {
|
|
||||||
#[hdl]
|
|
||||||
Self {
|
|
||||||
value: (Self::POWER_ISA_GPR_REG_NUMS.start + reg_num).cast_to_static::<UInt<_>>(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[hdl]
|
|
||||||
pub fn power_isa_gpr_reg_imm(index: usize) -> Expr<Self> {
|
|
||||||
#[hdl]
|
|
||||||
Self {
|
|
||||||
value: Self::power_isa_gpr_reg_num(index).cast_to_static::<UInt<_>>(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[hdl]
|
|
||||||
pub fn power_isa_gpr_reg_sim(reg_num: &SimValue<UInt<5>>) -> SimValue<Self> {
|
|
||||||
#[hdl(sim)]
|
|
||||||
Self {
|
|
||||||
value: (Self::POWER_ISA_GPR_REG_NUMS.start + reg_num).cast_to_static::<UInt<_>>(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub const fn power_isa_gpr_or_zero_reg_num(index: usize) -> u32 {
|
pub const fn power_isa_gpr_or_zero_reg_num(index: usize) -> u32 {
|
||||||
if index == 0 {
|
if index == 0 {
|
||||||
Self::CONST_ZERO_REG_NUM
|
Self::CONST_ZERO_REG_NUM
|
||||||
|
|
@ -192,6 +284,13 @@ impl MOpRegNum {
|
||||||
power_isa_gpr_or_zero_reg
|
power_isa_gpr_or_zero_reg
|
||||||
}
|
}
|
||||||
#[hdl]
|
#[hdl]
|
||||||
|
pub fn power_isa_gpr_or_zero_reg_imm(index: usize) -> Expr<Self> {
|
||||||
|
#[hdl]
|
||||||
|
Self {
|
||||||
|
value: Self::power_isa_gpr_or_zero_reg_num(index).cast_to_static::<UInt<_>>(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[hdl]
|
||||||
pub fn power_isa_gpr_or_zero_reg_sim(reg_num: &SimValue<UInt<5>>) -> SimValue<Self> {
|
pub fn power_isa_gpr_or_zero_reg_sim(reg_num: &SimValue<UInt<5>>) -> SimValue<Self> {
|
||||||
#[hdl(sim)]
|
#[hdl(sim)]
|
||||||
Self {
|
Self {
|
||||||
|
|
@ -201,25 +300,6 @@ impl MOpRegNum {
|
||||||
.cast_to_static::<UInt<_>>(),
|
.cast_to_static::<UInt<_>>(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const POWER_ISA_FPR_REG_NUMS: Range<u32> = 64..96;
|
|
||||||
pub const fn power_isa_fpr_reg_num(index: usize) -> u32 {
|
|
||||||
range_u32_nth_or_panic(&Self::POWER_ISA_FPR_REG_NUMS, index)
|
|
||||||
}
|
|
||||||
#[hdl]
|
|
||||||
pub fn power_isa_fpr_reg(reg_num: Expr<UInt<5>>) -> Expr<Self> {
|
|
||||||
#[hdl]
|
|
||||||
Self {
|
|
||||||
value: (Self::POWER_ISA_FPR_REG_NUMS.start + reg_num).cast_to_static::<UInt<_>>(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[hdl]
|
|
||||||
pub fn power_isa_fpr_reg_sim(reg_num: &SimValue<UInt<5>>) -> SimValue<Self> {
|
|
||||||
#[hdl(sim)]
|
|
||||||
Self {
|
|
||||||
value: (Self::POWER_ISA_FPR_REG_NUMS.start + reg_num).cast_to_static::<UInt<_>>(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[hdl(cmp_eq)]
|
#[hdl(cmp_eq)]
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,9 @@ pub mod instruction;
|
||||||
pub mod main_memory_and_io;
|
pub mod main_memory_and_io;
|
||||||
pub mod next_pc;
|
pub mod next_pc;
|
||||||
pub mod powerisa_instructions_xml;
|
pub mod powerisa_instructions_xml;
|
||||||
|
#[cfg(todo)]
|
||||||
pub mod reg_alloc;
|
pub mod reg_alloc;
|
||||||
pub mod register;
|
pub mod register;
|
||||||
|
pub mod rename_execute_retire;
|
||||||
pub mod unit;
|
pub mod unit;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
|
|
|
||||||
|
|
@ -20,17 +20,16 @@ use crate::{
|
||||||
CpuConfig, CpuConfigFetchWidth, CpuConfigMaxFetchesInFlight, CpuConfigRobSize,
|
CpuConfig, CpuConfigFetchWidth, CpuConfigMaxFetchesInFlight, CpuConfigRobSize,
|
||||||
PhantomConstCpuConfig, TwiceCpuConfigFetchWidth,
|
PhantomConstCpuConfig, TwiceCpuConfigFetchWidth,
|
||||||
},
|
},
|
||||||
util::array_vec::ArrayVec,
|
util::{LFSR31, array_vec::ArrayVec},
|
||||||
};
|
};
|
||||||
use fayalite::{
|
use fayalite::{
|
||||||
expr::HdlPartialEqImpl,
|
|
||||||
int::{UIntInRange, UIntInRangeInclusive, UIntInRangeInclusiveType, UIntInRangeType},
|
int::{UIntInRange, UIntInRangeInclusive, UIntInRangeInclusiveType, UIntInRangeType},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
sim::value::SimOnlyValueTrait,
|
sim::value::SimOnlyValueTrait,
|
||||||
ty::StaticType,
|
ty::StaticType,
|
||||||
util::{DebugAsDisplay, ready_valid::ReadyValid},
|
util::{DebugAsDisplay, ready_valid::ReadyValid},
|
||||||
};
|
};
|
||||||
use std::{borrow::Cow, fmt};
|
use std::fmt;
|
||||||
|
|
||||||
pub const FETCH_BLOCK_ID_WIDTH: usize = FetchBlockIdInt::BITS as usize;
|
pub const FETCH_BLOCK_ID_WIDTH: usize = FetchBlockIdInt::BITS as usize;
|
||||||
type FetchBlockIdInt = u8;
|
type FetchBlockIdInt = u8;
|
||||||
|
|
@ -53,7 +52,7 @@ pub struct NextPcToFetchInterface<C: PhantomConstGet<CpuConfig>> {
|
||||||
pub config: C,
|
pub config: C,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[hdl]
|
#[hdl(cmp_eq)]
|
||||||
/// WIP version of decoded instruction just good enough to represent stuff needed for [`next_pc()`]
|
/// WIP version of decoded instruction just good enough to represent stuff needed for [`next_pc()`]
|
||||||
/// since the actual instruction definition isn't finalized yet.
|
/// since the actual instruction definition isn't finalized yet.
|
||||||
/// This will be replaced at a later point.
|
/// This will be replaced at a later point.
|
||||||
|
|
@ -93,101 +92,6 @@ impl WipDecodedInsnKind {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: replace with #[hdl(cmp_eq)] when that's implemented for enums
|
|
||||||
impl HdlPartialEqImpl<Self> for WipDecodedInsnKind {
|
|
||||||
#[track_caller]
|
|
||||||
fn cmp_value_eq(
|
|
||||||
lhs: Self,
|
|
||||||
lhs_value: Cow<'_, Self::SimValue>,
|
|
||||||
rhs: Self,
|
|
||||||
rhs_value: Cow<'_, Self::SimValue>,
|
|
||||||
) -> bool {
|
|
||||||
*Self::cmp_sim_value_eq(
|
|
||||||
Cow::Owned(SimValue::from_value(lhs, lhs_value.into_owned())),
|
|
||||||
Cow::Owned(SimValue::from_value(rhs, rhs_value.into_owned())),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[hdl]
|
|
||||||
#[track_caller]
|
|
||||||
fn cmp_sim_value_eq(
|
|
||||||
lhs: Cow<'_, SimValue<Self>>,
|
|
||||||
rhs: Cow<'_, SimValue<Self>>,
|
|
||||||
) -> SimValue<Bool> {
|
|
||||||
let clear_unused_bits = |v: Cow<'_, SimValue<Self>>| {
|
|
||||||
#[hdl(sim)]
|
|
||||||
match &*v {
|
|
||||||
Self::NonBranch =>
|
|
||||||
{
|
|
||||||
#[hdl(sim)]
|
|
||||||
Self::NonBranch()
|
|
||||||
}
|
|
||||||
Self::Branch(target) =>
|
|
||||||
{
|
|
||||||
#[hdl(sim)]
|
|
||||||
Self::Branch(target)
|
|
||||||
}
|
|
||||||
Self::BranchCond(target) =>
|
|
||||||
{
|
|
||||||
#[hdl(sim)]
|
|
||||||
Self::BranchCond(target)
|
|
||||||
}
|
|
||||||
Self::IndirectBranch =>
|
|
||||||
{
|
|
||||||
#[hdl(sim)]
|
|
||||||
Self::IndirectBranch()
|
|
||||||
}
|
|
||||||
Self::Call(target) =>
|
|
||||||
{
|
|
||||||
#[hdl(sim)]
|
|
||||||
Self::Call(target)
|
|
||||||
}
|
|
||||||
Self::CallCond(target) =>
|
|
||||||
{
|
|
||||||
#[hdl(sim)]
|
|
||||||
Self::CallCond(target)
|
|
||||||
}
|
|
||||||
Self::IndirectCall =>
|
|
||||||
{
|
|
||||||
#[hdl(sim)]
|
|
||||||
Self::IndirectCall()
|
|
||||||
}
|
|
||||||
Self::Ret =>
|
|
||||||
{
|
|
||||||
#[hdl(sim)]
|
|
||||||
Self::Ret()
|
|
||||||
}
|
|
||||||
Self::RetCond =>
|
|
||||||
{
|
|
||||||
#[hdl(sim)]
|
|
||||||
Self::RetCond()
|
|
||||||
}
|
|
||||||
Self::Interrupt(target) =>
|
|
||||||
{
|
|
||||||
#[hdl(sim)]
|
|
||||||
Self::Interrupt(target)
|
|
||||||
}
|
|
||||||
Self::Unknown => v.into_owned(),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
(SimValue::bits(&clear_unused_bits(lhs)) == SimValue::bits(&clear_unused_bits(rhs)))
|
|
||||||
.to_sim_value()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[track_caller]
|
|
||||||
fn cmp_sim_value_ne(
|
|
||||||
lhs: Cow<'_, SimValue<Self>>,
|
|
||||||
rhs: Cow<'_, SimValue<Self>>,
|
|
||||||
) -> SimValue<Bool> {
|
|
||||||
!Self::cmp_sim_value_eq(lhs, rhs)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[track_caller]
|
|
||||||
fn cmp_expr_eq(lhs: Expr<Self>, rhs: Expr<Self>) -> Expr<Bool> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[hdl(cmp_eq)]
|
#[hdl(cmp_eq)]
|
||||||
/// WIP version of decoded instruction just good enough to represent stuff needed for [`next_pc()`]
|
/// WIP version of decoded instruction just good enough to represent stuff needed for [`next_pc()`]
|
||||||
/// since the actual instruction definition isn't finalized yet.
|
/// since the actual instruction definition isn't finalized yet.
|
||||||
|
|
@ -2781,8 +2685,10 @@ impl<T: SimValueDefault, N: Size> SimValueDefault for ArrayType<T, N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Type> SimValueDefault for HdlOption<T> {
|
impl<T: Type> SimValueDefault for HdlOption<T> {
|
||||||
|
#[hdl]
|
||||||
fn sim_value_default(self) -> SimValue<Self> {
|
fn sim_value_default(self) -> SimValue<Self> {
|
||||||
self.HdlNone().to_sim_value_with_type(self)
|
#[hdl(sim)]
|
||||||
|
self.HdlNone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2911,50 +2817,13 @@ impl ResetSteps for CallStack {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[hdl]
|
#[hdl(cmp_eq)]
|
||||||
enum BTBEntryInsnKind {
|
enum BTBEntryInsnKind {
|
||||||
Branch,
|
Branch,
|
||||||
Call,
|
Call,
|
||||||
Ret,
|
Ret,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: replace with #[hdl(cmp_eq)] when that's implemented for enums
|
|
||||||
impl HdlPartialEqImpl<Self> for BTBEntryInsnKind {
|
|
||||||
#[track_caller]
|
|
||||||
fn cmp_value_eq(
|
|
||||||
lhs: Self,
|
|
||||||
lhs_value: Cow<'_, Self::SimValue>,
|
|
||||||
rhs: Self,
|
|
||||||
rhs_value: Cow<'_, Self::SimValue>,
|
|
||||||
) -> bool {
|
|
||||||
*Self::cmp_sim_value_eq(
|
|
||||||
Cow::Owned(SimValue::from_value(lhs, lhs_value.into_owned())),
|
|
||||||
Cow::Owned(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::bits(&*lhs) == SimValue::bits(&*rhs)).to_sim_value()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[track_caller]
|
|
||||||
fn cmp_sim_value_ne(
|
|
||||||
lhs: Cow<'_, SimValue<Self>>,
|
|
||||||
rhs: Cow<'_, SimValue<Self>>,
|
|
||||||
) -> SimValue<Bool> {
|
|
||||||
(SimValue::bits(&*lhs) != SimValue::bits(&*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())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BTBEntryInsnKind {
|
impl BTBEntryInsnKind {
|
||||||
#[hdl]
|
#[hdl]
|
||||||
fn try_from_decoded_insn_kind(kind: &SimValue<WipDecodedInsnKind>) -> Option<SimValue<Self>> {
|
fn try_from_decoded_insn_kind(kind: &SimValue<WipDecodedInsnKind>) -> Option<SimValue<Self>> {
|
||||||
|
|
@ -2983,7 +2852,7 @@ impl BTBEntryInsnKind {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[hdl]
|
#[hdl(cmp_eq)]
|
||||||
enum BTBEntryAddrKind {
|
enum BTBEntryAddrKind {
|
||||||
Unconditional,
|
Unconditional,
|
||||||
Indirect,
|
Indirect,
|
||||||
|
|
@ -2991,43 +2860,6 @@ enum BTBEntryAddrKind {
|
||||||
CondNotTaken,
|
CondNotTaken,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: replace with #[hdl(cmp_eq)] when that's implemented for enums
|
|
||||||
impl HdlPartialEqImpl<Self> for BTBEntryAddrKind {
|
|
||||||
#[track_caller]
|
|
||||||
fn cmp_value_eq(
|
|
||||||
lhs: Self,
|
|
||||||
lhs_value: Cow<'_, Self::SimValue>,
|
|
||||||
rhs: Self,
|
|
||||||
rhs_value: Cow<'_, Self::SimValue>,
|
|
||||||
) -> bool {
|
|
||||||
*Self::cmp_sim_value_eq(
|
|
||||||
Cow::Owned(SimValue::from_value(lhs, lhs_value.into_owned())),
|
|
||||||
Cow::Owned(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::bits(&*lhs) == SimValue::bits(&*rhs)).to_sim_value()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[track_caller]
|
|
||||||
fn cmp_sim_value_ne(
|
|
||||||
lhs: Cow<'_, SimValue<Self>>,
|
|
||||||
rhs: Cow<'_, SimValue<Self>>,
|
|
||||||
) -> SimValue<Bool> {
|
|
||||||
(SimValue::bits(&*lhs) != SimValue::bits(&*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())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BTBEntryAddrKind {
|
impl BTBEntryAddrKind {
|
||||||
#[hdl]
|
#[hdl]
|
||||||
fn taken(this: &SimValue<Self>) -> bool {
|
fn taken(this: &SimValue<Self>) -> bool {
|
||||||
|
|
@ -3123,33 +2955,9 @@ impl BTBEntry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[hdl]
|
|
||||||
struct LFSR31 {
|
|
||||||
// MSB is always zero, 32 bits makes it easier to manipulate
|
|
||||||
state: UInt<32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SimValueDefault for LFSR31 {
|
impl SimValueDefault for LFSR31 {
|
||||||
#[hdl]
|
|
||||||
fn sim_value_default(self) -> SimValue<Self> {
|
fn sim_value_default(self) -> SimValue<Self> {
|
||||||
#[hdl(sim)]
|
Self::new()
|
||||||
Self { state: 1u32 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LFSR31 {
|
|
||||||
fn next(this: &mut SimValue<Self>) -> u32 {
|
|
||||||
let state = this.state.as_int();
|
|
||||||
let state = if state == 0 {
|
|
||||||
1u32
|
|
||||||
} else {
|
|
||||||
// a maximal-length 31-bit LFSR
|
|
||||||
let lsb = ((state >> 30) ^ (state >> 27)) & 1;
|
|
||||||
let msb = (state << 1) & ((1 << 31) - 1);
|
|
||||||
lsb | msb
|
|
||||||
};
|
|
||||||
*this.state = state.into();
|
|
||||||
state
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3163,7 +2971,7 @@ impl BranchTargetBuffer {
|
||||||
const LOG2_SIZE: usize = 4;
|
const LOG2_SIZE: usize = 4;
|
||||||
const SIZE: usize = 1 << Self::LOG2_SIZE;
|
const SIZE: usize = 1 << Self::LOG2_SIZE;
|
||||||
fn next_index_to_replace(this: &mut SimValue<Self>) -> usize {
|
fn next_index_to_replace(this: &mut SimValue<Self>) -> usize {
|
||||||
LFSR31::next(&mut this.next_index_to_replace_lfsr) as usize % Self::SIZE
|
LFSR31::next_sim(&mut this.next_index_to_replace_lfsr) as usize % Self::SIZE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@ use fayalite::{
|
||||||
expr::CastToImpl,
|
expr::CastToImpl,
|
||||||
int::{BoolOrIntType, UIntInRange},
|
int::{BoolOrIntType, UIntInRange},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
ty::StaticType,
|
ty::{SimValueDebug, StaticType},
|
||||||
};
|
};
|
||||||
use std::fmt;
|
use std::{any::Any, fmt};
|
||||||
|
|
||||||
#[hdl]
|
#[hdl]
|
||||||
pub enum FlagsMode {
|
pub enum FlagsMode {
|
||||||
|
|
@ -47,6 +47,12 @@ pub trait PRegFlagsViewTrait: Type + PRegFlagsViewTraitSealed {
|
||||||
fn from_view_sim<T: ToSimValue>(view: Self::View<T>) -> SimValue<PRegFlags<T::Type>>;
|
fn from_view_sim<T: ToSimValue>(view: Self::View<T>) -> SimValue<PRegFlags<T::Type>>;
|
||||||
fn view_unused_into_view<T>(unused: ViewUnused<T, PRegFlagsAllUnused>) -> Self::View<T>;
|
fn view_unused_into_view<T>(unused: ViewUnused<T, PRegFlagsAllUnused>) -> Self::View<T>;
|
||||||
fn view_into_view_unused<T>(view: Self::View<T>) -> ViewUnused<T, PRegFlagsAllUnused>;
|
fn view_into_view_unused<T>(view: Self::View<T>) -> ViewUnused<T, PRegFlagsAllUnused>;
|
||||||
|
fn debug_fmt<'a, T: 'a, F: FnMut(&'a T, bool) -> Option<D>, D: fmt::Debug>(
|
||||||
|
view: &'a Self::View<T>,
|
||||||
|
type_name: Option<&str>,
|
||||||
|
field: F,
|
||||||
|
f: &mut fmt::Formatter<'_>,
|
||||||
|
) -> fmt::Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ViewUnused<T, V: PRegFlagsViewTrait>(V::UnusedInner<T>);
|
pub struct ViewUnused<T, V: PRegFlagsViewTrait>(V::UnusedInner<T>);
|
||||||
|
|
@ -467,6 +473,34 @@ macro_rules! impl_view_trait {
|
||||||
};
|
};
|
||||||
fields.into_view_unused()
|
fields.into_view_unused()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn debug_fmt<'a, T: 'a, F: FnMut(&'a T, bool) -> Option<D>, D: fmt::Debug>(
|
||||||
|
view: &'a Self::View<T>,
|
||||||
|
type_name: Option<&str>,
|
||||||
|
mut field: F,
|
||||||
|
f: &mut fmt::Formatter<'_>,
|
||||||
|
) -> fmt::Result {
|
||||||
|
let $View {
|
||||||
|
$unused: ViewUnused([$($unused_field,)*]),
|
||||||
|
$($view_field: $flags_field,)*
|
||||||
|
} = view;
|
||||||
|
let mut debug_struct = f.debug_struct(type_name.unwrap_or(stringify!($FlagsMode)));
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
let mut any_skipped = false;
|
||||||
|
$(if let Some(v) = field($flags_field, true) {
|
||||||
|
debug_struct.field(stringify!($view_field), &v);
|
||||||
|
} else {
|
||||||
|
any_skipped = true;
|
||||||
|
})*
|
||||||
|
$(if let Some(v) = field($unused_field, false) {
|
||||||
|
debug_struct.field(stringify!($unused_field), &v);
|
||||||
|
})*
|
||||||
|
if any_skipped {
|
||||||
|
debug_struct.finish_non_exhaustive()
|
||||||
|
} else {
|
||||||
|
debug_struct.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -739,6 +773,46 @@ impl<T: Type> PRegFlags<T> {
|
||||||
pub fn splat_sim(v: impl ToSimValue<Type = T>) -> SimValue<Self> {
|
pub fn splat_sim(v: impl ToSimValue<Type = T>) -> SimValue<Self> {
|
||||||
Self::from_fields_sim(ViewUnused::splat(v.into_sim_value()))
|
Self::from_fields_sim(ViewUnused::splat(v.into_sim_value()))
|
||||||
}
|
}
|
||||||
|
#[hdl]
|
||||||
|
pub fn debug_fmt<V: PRegFlagsViewTrait>(
|
||||||
|
this: &SimValue<Self>,
|
||||||
|
type_name: Option<&str>,
|
||||||
|
f: &mut fmt::Formatter<'_>,
|
||||||
|
) -> fmt::Result {
|
||||||
|
if let Some(this) = <dyn Any>::downcast_ref::<SimValue<PRegFlags>>(this) {
|
||||||
|
V::debug_fmt(
|
||||||
|
&PRegFlags::view_sim_ref::<V>(this),
|
||||||
|
type_name,
|
||||||
|
|v, _| v.then_some(*v),
|
||||||
|
f,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
V::debug_fmt(
|
||||||
|
&PRegFlags::view_sim_ref::<V>(this),
|
||||||
|
type_name,
|
||||||
|
|v, _| Some(*v),
|
||||||
|
f,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[hdl]
|
||||||
|
pub fn debug_fmt_mode(
|
||||||
|
this: &SimValue<Self>,
|
||||||
|
short_name: bool,
|
||||||
|
mode: &SimValue<FlagsMode>,
|
||||||
|
) -> impl fmt::Debug {
|
||||||
|
fmt::from_fn(move |f| {
|
||||||
|
#[hdl(sim)]
|
||||||
|
match mode {
|
||||||
|
FlagsMode::PowerISA(_) => {
|
||||||
|
Self::debug_fmt::<PRegFlagsPowerISA>(this, short_name.then_some("Pwr"), f)
|
||||||
|
}
|
||||||
|
FlagsMode::X86(_) => {
|
||||||
|
Self::debug_fmt::<PRegFlagsX86>(this, short_name.then_some("X86"), f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PRegFlags<UIntInRange<0, { PRegFlags::FLAG_COUNT }>> {
|
impl PRegFlags<UIntInRange<0, { PRegFlags::FLAG_COUNT }>> {
|
||||||
|
|
@ -762,7 +836,7 @@ impl PRegFlags {
|
||||||
pub const FLAG_COUNT: usize = PRegFlagsAllUnused::UNUSED_INNER_LEN;
|
pub const FLAG_COUNT: usize = PRegFlagsAllUnused::UNUSED_INNER_LEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[hdl(cmp_eq)]
|
#[hdl(cmp_eq, custom_debug(sim))]
|
||||||
/// Unit output register's value -- a combination of an integer/fp register
|
/// Unit output register's value -- a combination of an integer/fp register
|
||||||
/// and flags register and CR field.
|
/// and flags register and CR field.
|
||||||
///
|
///
|
||||||
|
|
@ -773,6 +847,15 @@ pub struct PRegValue {
|
||||||
pub flags: PRegFlags,
|
pub flags: PRegFlags,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SimValueDebug for PRegValue {
|
||||||
|
fn sim_value_debug(
|
||||||
|
value: &<Self as Type>::SimValue,
|
||||||
|
f: &mut fmt::Formatter<'_>,
|
||||||
|
) -> fmt::Result {
|
||||||
|
fmt::Debug::fmt(&Self::debug_fmt::<PRegFlagsPowerISA>(value, Some("Pwr")), f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PRegValue {
|
impl PRegValue {
|
||||||
#[hdl]
|
#[hdl]
|
||||||
pub fn zeroed() -> Expr<Self> {
|
pub fn zeroed() -> Expr<Self> {
|
||||||
|
|
@ -782,4 +865,47 @@ impl PRegValue {
|
||||||
flags: PRegFlags::zeroed(),
|
flags: PRegFlags::zeroed(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[hdl]
|
||||||
|
pub fn zeroed_sim() -> SimValue<Self> {
|
||||||
|
#[hdl(sim)]
|
||||||
|
Self {
|
||||||
|
int_fp: 0u64,
|
||||||
|
flags: PRegFlags::zeroed_sim(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[hdl]
|
||||||
|
pub fn debug_fmt<V: PRegFlagsViewTrait>(
|
||||||
|
this: &<Self as Type>::SimValue,
|
||||||
|
flags_type_name: Option<&str>,
|
||||||
|
) -> impl fmt::Debug {
|
||||||
|
fmt::from_fn(move |f| {
|
||||||
|
#[hdl(sim)]
|
||||||
|
let Self { int_fp, flags } = this;
|
||||||
|
f.debug_struct("PRegValue")
|
||||||
|
.field("int_fp", int_fp)
|
||||||
|
.field(
|
||||||
|
"flags",
|
||||||
|
&fmt::from_fn(|f| PRegFlags::debug_fmt::<V>(flags, flags_type_name, f)),
|
||||||
|
)
|
||||||
|
.finish()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
#[hdl]
|
||||||
|
pub fn debug_fmt_mode(
|
||||||
|
this: &SimValue<Self>,
|
||||||
|
flags_short_name: bool,
|
||||||
|
mode: &SimValue<FlagsMode>,
|
||||||
|
) -> impl fmt::Debug {
|
||||||
|
fmt::from_fn(move |f| {
|
||||||
|
#[hdl(sim)]
|
||||||
|
let Self { int_fp, flags } = this;
|
||||||
|
f.debug_struct("PRegValue")
|
||||||
|
.field("int_fp", int_fp)
|
||||||
|
.field(
|
||||||
|
"flags",
|
||||||
|
&PRegFlags::debug_fmt_mode(flags, flags_short_name, mode),
|
||||||
|
)
|
||||||
|
.finish()
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1978
crates/cpu/src/rename_execute_retire.rs
Normal file
1978
crates/cpu/src/rename_execute_retire.rs
Normal file
File diff suppressed because it is too large
Load diff
311
crates/cpu/src/rename_execute_retire/rename_table.rs
Normal file
311
crates/cpu/src/rename_execute_retire/rename_table.rs
Normal file
|
|
@ -0,0 +1,311 @@
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// See Notices.txt for copyright information
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
config::{CpuConfig, CpuConfig2PowOutRegNumWidth, CpuConfigUnitCount, PhantomConstCpuConfig},
|
||||||
|
instruction::{L2RegNum, MOpRegNum, PRegNum, UnitNum, UnitOutRegNum},
|
||||||
|
rename_execute_retire::L2RegFileLen,
|
||||||
|
};
|
||||||
|
use fayalite::{int::UIntInRangeInclusiveType, prelude::*};
|
||||||
|
|
||||||
|
#[hdl(no_static)]
|
||||||
|
pub(crate) struct RenameTableEntry<C: PhantomConstGet<CpuConfig>> {
|
||||||
|
pub(crate) l1: HdlOption<PRegNum<C>>,
|
||||||
|
pub(crate) l2: HdlOption<L2RegNum>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: PhantomConstCpuConfig> RenameTableEntry<C> {
|
||||||
|
#[hdl]
|
||||||
|
pub(crate) fn const_zero(self) -> SimValue<Self> {
|
||||||
|
#[hdl(sim)]
|
||||||
|
Self {
|
||||||
|
l1: #[hdl(sim)]
|
||||||
|
(self.l1).HdlSome(self.l1.HdlSome.const_zero()),
|
||||||
|
l2: #[hdl(sim)]
|
||||||
|
HdlNone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// make arrays dynamically-sized to avoid putting large types on the stack
|
||||||
|
#[hdl(get(|c| 1 << MOpRegNum::WIDTH))]
|
||||||
|
type MOpRegCount<C: PhantomConstGet<CpuConfig>> = DynSize;
|
||||||
|
|
||||||
|
#[hdl(no_static)]
|
||||||
|
pub(crate) struct RenameTableDebugState<C: PhantomConstGet<CpuConfig>> {
|
||||||
|
entries: ArrayType<TraceAsString<RenameTableEntry<C>>, MOpRegCount<C>>,
|
||||||
|
l1_ref_counts: ArrayType<
|
||||||
|
ArrayType<
|
||||||
|
UIntInRangeInclusiveType<ConstUsize<0>, MOpRegCount<C>>,
|
||||||
|
CpuConfig2PowOutRegNumWidth<C>,
|
||||||
|
>,
|
||||||
|
CpuConfigUnitCount<C>,
|
||||||
|
>,
|
||||||
|
l2_ref_counts:
|
||||||
|
ArrayType<UIntInRangeInclusiveType<ConstUsize<0>, MOpRegCount<C>>, L2RegFileLen<C>>,
|
||||||
|
config: C,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) struct RenameTable<C: PhantomConstCpuConfig> {
|
||||||
|
entries: Box<[SimValue<TraceAsString<RenameTableEntry<C>>>; 1 << MOpRegNum::WIDTH]>,
|
||||||
|
l1_ref_counts: Box<[Box<[usize]>]>,
|
||||||
|
l2_ref_counts: Box<[usize]>,
|
||||||
|
config: C,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: PhantomConstCpuConfig> Clone for RenameTable<C> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
entries: self.entries.clone(),
|
||||||
|
config: self.config.clone(),
|
||||||
|
l1_ref_counts: self.l1_ref_counts.clone(),
|
||||||
|
l2_ref_counts: self.l2_ref_counts.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn clone_from(&mut self, source: &Self) {
|
||||||
|
let Self {
|
||||||
|
entries,
|
||||||
|
l1_ref_counts,
|
||||||
|
l2_ref_counts,
|
||||||
|
config,
|
||||||
|
} = self;
|
||||||
|
entries.clone_from(&source.entries);
|
||||||
|
l1_ref_counts.clone_from(&source.l1_ref_counts);
|
||||||
|
l2_ref_counts.clone_from(&source.l2_ref_counts);
|
||||||
|
*config = source.config;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub(crate) enum RenameTableUpdate<C: PhantomConstCpuConfig> {
|
||||||
|
Write {
|
||||||
|
unrenamed_reg_num: u32,
|
||||||
|
new: SimValue<TraceAsString<RenameTableEntry<C>>>,
|
||||||
|
},
|
||||||
|
UpdateForReadL2Reg {
|
||||||
|
dest: SimValue<PRegNum<C>>,
|
||||||
|
src: SimValue<L2RegNum>,
|
||||||
|
},
|
||||||
|
UpdateForWriteL2Reg {
|
||||||
|
dest: SimValue<L2RegNum>,
|
||||||
|
src: SimValue<PRegNum<C>>,
|
||||||
|
},
|
||||||
|
DropAllL2RegFileOutputs,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: PhantomConstCpuConfig> RenameTable<C> {
|
||||||
|
pub(crate) fn new(config: C) -> Self {
|
||||||
|
let entries: Box<[SimValue<TraceAsString<RenameTableEntry<C>>>; 1 << MOpRegNum::WIDTH]> =
|
||||||
|
vec![
|
||||||
|
RenameTableEntry[config].const_zero().into_trace_as_string();
|
||||||
|
1 << MOpRegNum::WIDTH
|
||||||
|
]
|
||||||
|
.try_into()
|
||||||
|
.expect("size is known to match");
|
||||||
|
Self {
|
||||||
|
entries,
|
||||||
|
l1_ref_counts: vec![
|
||||||
|
vec![0; CpuConfig2PowOutRegNumWidth[config]].into_boxed_slice();
|
||||||
|
CpuConfigUnitCount[config]
|
||||||
|
]
|
||||||
|
.into_boxed_slice(),
|
||||||
|
l2_ref_counts: vec![0; L2RegFileLen[config]].into_boxed_slice(),
|
||||||
|
config,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub(crate) fn entries(
|
||||||
|
&self,
|
||||||
|
) -> &[SimValue<TraceAsString<RenameTableEntry<C>>>; 1 << MOpRegNum::WIDTH] {
|
||||||
|
&self.entries
|
||||||
|
}
|
||||||
|
#[hdl]
|
||||||
|
pub(crate) fn to_debug_state(&self) -> SimValue<RenameTableDebugState<C>> {
|
||||||
|
let Self {
|
||||||
|
entries,
|
||||||
|
l1_ref_counts,
|
||||||
|
l2_ref_counts,
|
||||||
|
config,
|
||||||
|
} = self;
|
||||||
|
let ty = RenameTableDebugState[*config];
|
||||||
|
#[hdl(sim)]
|
||||||
|
RenameTableDebugState::<_> {
|
||||||
|
entries: entries.to_sim_value_with_type(ty.entries),
|
||||||
|
l1_ref_counts: l1_ref_counts.to_sim_value_with_type(ty.l1_ref_counts),
|
||||||
|
l2_ref_counts: l2_ref_counts.to_sim_value_with_type(ty.l2_ref_counts),
|
||||||
|
config,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[hdl]
|
||||||
|
pub(crate) fn l1_ref_counts(&self) -> &[Box<[usize]>] {
|
||||||
|
let mut expected = vec![
|
||||||
|
vec![0usize; CpuConfig2PowOutRegNumWidth[self.config]]
|
||||||
|
.into_boxed_slice();
|
||||||
|
CpuConfigUnitCount[self.config]
|
||||||
|
];
|
||||||
|
for entry in self.entries.iter() {
|
||||||
|
#[hdl(sim)]
|
||||||
|
let RenameTableEntry::<_> { l1, l2: _ } = entry.inner();
|
||||||
|
#[hdl(sim)]
|
||||||
|
if let HdlSome(l1) = l1 {
|
||||||
|
if let Some(unit_index) = UnitNum::index_sim(&l1.unit_num) {
|
||||||
|
expected[unit_index][UnitOutRegNum::value_sim(&l1.unit_out_reg)] += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_eq!(*expected, *self.l1_ref_counts);
|
||||||
|
&self.l1_ref_counts
|
||||||
|
}
|
||||||
|
#[hdl]
|
||||||
|
pub(crate) fn l2_ref_counts(&self) -> &[usize] {
|
||||||
|
let mut expected = vec![0usize; L2RegNum.l2_reg_count()];
|
||||||
|
for entry in self.entries.iter() {
|
||||||
|
#[hdl(sim)]
|
||||||
|
let RenameTableEntry::<_> { l1: _, l2 } = entry.inner();
|
||||||
|
#[hdl(sim)]
|
||||||
|
if let HdlSome(l2) = l2 {
|
||||||
|
expected[L2RegNum::value_sim(l2)] += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_eq!(*expected, *self.l2_ref_counts);
|
||||||
|
&self.l2_ref_counts
|
||||||
|
}
|
||||||
|
#[hdl]
|
||||||
|
pub(crate) fn update<'a>(&mut self, update: &RenameTableUpdate<C>, rename_table_name: &str) {
|
||||||
|
let mut update_entry =
|
||||||
|
|entry: &mut SimValue<TraceAsString<RenameTableEntry<C>>>,
|
||||||
|
new: SimValue<TraceAsString<RenameTableEntry<C>>>| {
|
||||||
|
#[hdl(sim)]
|
||||||
|
let RenameTableEntry::<_> { l1, l2 } = entry.inner();
|
||||||
|
#[hdl(sim)]
|
||||||
|
if let HdlSome(l1) = l1 {
|
||||||
|
if let Some(unit_index) = UnitNum::index_sim(&l1.unit_num) {
|
||||||
|
let ref_count = &mut self.l1_ref_counts[unit_index]
|
||||||
|
[UnitOutRegNum::value_sim(&l1.unit_out_reg)];
|
||||||
|
*ref_count = ref_count.checked_sub(1).unwrap_or_else(|| {
|
||||||
|
unreachable!("{rename_table_name}: l1 ref count went negative: {l1:?}")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[hdl(sim)]
|
||||||
|
if let HdlSome(l2) = l2 {
|
||||||
|
let ref_count = &mut self.l2_ref_counts[L2RegNum::value_sim(l2)];
|
||||||
|
*ref_count = ref_count.checked_sub(1).unwrap_or_else(|| {
|
||||||
|
unreachable!("{rename_table_name}: l2 ref count went negative: {l2:?}")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#[hdl(sim)]
|
||||||
|
let RenameTableEntry::<_> { l1, l2 } = new.inner();
|
||||||
|
#[hdl(sim)]
|
||||||
|
if let HdlSome(l1) = l1 {
|
||||||
|
if let Some(unit_index) = UnitNum::index_sim(&l1.unit_num) {
|
||||||
|
let ref_count = &mut self.l1_ref_counts[unit_index]
|
||||||
|
[UnitOutRegNum::value_sim(&l1.unit_out_reg)];
|
||||||
|
*ref_count += 1;
|
||||||
|
assert!(
|
||||||
|
*ref_count <= 1 << MOpRegNum::WIDTH,
|
||||||
|
"{rename_table_name}: l1 ref count overflowed: {l1:?}",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[hdl(sim)]
|
||||||
|
if let HdlSome(l2) = l2 {
|
||||||
|
let ref_count = &mut self.l2_ref_counts[L2RegNum::value_sim(l2)];
|
||||||
|
*ref_count += 1;
|
||||||
|
assert!(
|
||||||
|
*ref_count <= 1 << MOpRegNum::WIDTH,
|
||||||
|
"{rename_table_name}: l2 ref count overflowed: {l2:?}",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
*entry = new;
|
||||||
|
};
|
||||||
|
match update {
|
||||||
|
RenameTableUpdate::Write {
|
||||||
|
unrenamed_reg_num,
|
||||||
|
new,
|
||||||
|
} => {
|
||||||
|
if *unrenamed_reg_num == MOpRegNum::CONST_ZERO_REG_NUM {
|
||||||
|
// writing to const zero reg does nothing
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
println!("{rename_table_name}: Write: {unrenamed_reg_num:#x} <- {new:?}");
|
||||||
|
update_entry(&mut self.entries[*unrenamed_reg_num as usize], new.clone());
|
||||||
|
}
|
||||||
|
RenameTableUpdate::UpdateForReadL2Reg { dest, src } => {
|
||||||
|
let new = #[hdl(sim)]
|
||||||
|
RenameTableEntry::<_> {
|
||||||
|
l1: #[hdl(sim)]
|
||||||
|
(HdlOption[dest.ty()]).HdlSome(dest),
|
||||||
|
l2: #[hdl(sim)]
|
||||||
|
HdlSome(src),
|
||||||
|
};
|
||||||
|
for (unrenamed_reg_num, entry) in self.entries.iter_mut().enumerate() {
|
||||||
|
#[hdl(sim)]
|
||||||
|
if let HdlSome(l2) = &entry.inner().l2 {
|
||||||
|
if L2RegNum::value_sim(l2) == L2RegNum::value_sim(src) {
|
||||||
|
println!(
|
||||||
|
"{rename_table_name}: UpdateForReadL2Reg: {unrenamed_reg_num:#x} \
|
||||||
|
updating from {entry:?} to {new:?}",
|
||||||
|
);
|
||||||
|
#[hdl(sim)]
|
||||||
|
if let HdlSome(_) = &entry.inner().l1 {
|
||||||
|
unreachable!("l1 should be HdlNone: {entry:?}");
|
||||||
|
}
|
||||||
|
update_entry(entry, new.to_trace_as_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RenameTableUpdate::UpdateForWriteL2Reg { dest, src } => {
|
||||||
|
let new = #[hdl(sim)]
|
||||||
|
RenameTableEntry::<_> {
|
||||||
|
l1: #[hdl(sim)]
|
||||||
|
(HdlOption[src.ty()]).HdlNone(),
|
||||||
|
l2: #[hdl(sim)]
|
||||||
|
HdlSome(dest),
|
||||||
|
};
|
||||||
|
for (unrenamed_reg_num, entry) in self.entries.iter_mut().enumerate() {
|
||||||
|
#[hdl(sim)]
|
||||||
|
if let HdlSome(l1) = &entry.inner().l1 {
|
||||||
|
if l1 == src {
|
||||||
|
println!(
|
||||||
|
"{rename_table_name}: UpdateForWriteL2Reg: {unrenamed_reg_num:#x} \
|
||||||
|
updating from {entry:?} to {new:?}",
|
||||||
|
);
|
||||||
|
#[hdl(sim)]
|
||||||
|
if let HdlSome(_) = &entry.inner().l2 {
|
||||||
|
unreachable!("l2 should be HdlNone: {entry:?}");
|
||||||
|
}
|
||||||
|
update_entry(entry, new.to_trace_as_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RenameTableUpdate::DropAllL2RegFileOutputs => {
|
||||||
|
for (unrenamed_reg_num, entry) in self.entries.iter_mut().enumerate() {
|
||||||
|
#[hdl(sim)]
|
||||||
|
if let HdlSome(_) = &entry.inner().l1 {
|
||||||
|
#[hdl(sim)]
|
||||||
|
if let HdlSome(_) = &entry.inner().l2 {
|
||||||
|
let mut new = entry.inner().clone();
|
||||||
|
new.l1 = #[hdl(sim)]
|
||||||
|
(new.l1.ty()).HdlNone();
|
||||||
|
println!(
|
||||||
|
"{rename_table_name}: DropAllL2RegFileOutputs: {unrenamed_reg_num:#x} \
|
||||||
|
updating from {entry:?} to {new:?}",
|
||||||
|
);
|
||||||
|
update_entry(entry, new.to_trace_as_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[hdl]
|
||||||
|
pub(crate) fn used_unit_out_reg_count(&self, unit_index: usize) -> usize {
|
||||||
|
self.l1_ref_counts()[unit_index]
|
||||||
|
.iter()
|
||||||
|
.filter(|ref_count| **ref_count != 0)
|
||||||
|
.count()
|
||||||
|
}
|
||||||
|
}
|
||||||
564
crates/cpu/src/rename_execute_retire/reorder_buffer.rs
Normal file
564
crates/cpu/src/rename_execute_retire/reorder_buffer.rs
Normal file
|
|
@ -0,0 +1,564 @@
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// See Notices.txt for copyright information
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
config::{
|
||||||
|
CpuConfig, CpuConfig2PowOutRegNumWidth, CpuConfigRobSize, CpuConfigUnitCount,
|
||||||
|
PhantomConstCpuConfig,
|
||||||
|
},
|
||||||
|
instruction::{
|
||||||
|
COMMON_MOP_SRC_LEN, L2RegNum, L2RegisterFileMOp, MOp, MOpTrait, PRegNum, UnitNum,
|
||||||
|
UnitOutRegNum,
|
||||||
|
},
|
||||||
|
next_pc::SimValueDefault,
|
||||||
|
rename_execute_retire::{
|
||||||
|
L2RegFileLen, MOpId, MOpInUnitState, MOpInstance, NextPcPredictorOp, RenamedMOp,
|
||||||
|
UnitCausedCancel, rename_table::RenameTableUpdate, zeroed,
|
||||||
|
},
|
||||||
|
util::array_vec::ArrayVec,
|
||||||
|
};
|
||||||
|
use fayalite::{
|
||||||
|
int::{UIntInRangeInclusiveType, UIntInRangeType},
|
||||||
|
prelude::*,
|
||||||
|
ty::StaticType,
|
||||||
|
};
|
||||||
|
use std::{collections::VecDeque, mem};
|
||||||
|
|
||||||
|
#[hdl]
|
||||||
|
type SimOnlyMOpInUnitState = SimOnly<MOpInUnitState>;
|
||||||
|
|
||||||
|
#[hdl(no_static)]
|
||||||
|
struct RobEntryDebugState<C: PhantomConstGet<CpuConfig>> {
|
||||||
|
/// See [`RobEntry::is_register_fence`]
|
||||||
|
is_register_fence: Bool,
|
||||||
|
/// See [`RobEntry::is_register_fence`]
|
||||||
|
done_waiting_for_register_fences: Bool,
|
||||||
|
mop: MOpInstance<RenamedMOp<C>>,
|
||||||
|
unit_index: UIntInRangeType<ConstUsize<0>, CpuConfigUnitCount<C>>,
|
||||||
|
mop_in_unit_state: SimOnlyMOpInUnitState,
|
||||||
|
is_speculative: Bool,
|
||||||
|
all_prior_mops_finished_and_or_caused_cancel: Bool,
|
||||||
|
output: HdlOption<NextPcPredictorOp<C>>,
|
||||||
|
caused_cancel: HdlOption<UnitCausedCancel<C>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: PhantomConstCpuConfig> SimValueDefault for RobEntryDebugState<C> {
|
||||||
|
#[hdl]
|
||||||
|
fn sim_value_default(self) -> SimValue<Self> {
|
||||||
|
let Self {
|
||||||
|
mop,
|
||||||
|
is_register_fence: _,
|
||||||
|
done_waiting_for_register_fences: _,
|
||||||
|
unit_index,
|
||||||
|
mop_in_unit_state: _,
|
||||||
|
is_speculative: _,
|
||||||
|
all_prior_mops_finished_and_or_caused_cancel: _,
|
||||||
|
output,
|
||||||
|
caused_cancel,
|
||||||
|
} = self;
|
||||||
|
#[hdl(sim)]
|
||||||
|
Self {
|
||||||
|
mop: zeroed(mop),
|
||||||
|
is_register_fence: false,
|
||||||
|
done_waiting_for_register_fences: false,
|
||||||
|
unit_index: zeroed(unit_index),
|
||||||
|
mop_in_unit_state: SimOnlyValue::default(),
|
||||||
|
is_speculative: false,
|
||||||
|
all_prior_mops_finished_and_or_caused_cancel: false,
|
||||||
|
output: #[hdl(sim)]
|
||||||
|
output.HdlNone(),
|
||||||
|
caused_cancel: #[hdl(sim)]
|
||||||
|
caused_cancel.HdlNone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) struct RobEntry<C: PhantomConstCpuConfig> {
|
||||||
|
/// Block this and all later µOps until all prior µOps are finished and didn't cause a cancel.
|
||||||
|
/// Not to be confused with memory fences.
|
||||||
|
pub(crate) is_register_fence: bool,
|
||||||
|
/// See [`Self::is_register_fence`]
|
||||||
|
pub(crate) done_waiting_for_register_fences: bool,
|
||||||
|
pub(crate) mop: SimValue<MOpInstance<RenamedMOp<C>>>,
|
||||||
|
pub(crate) unit_index: usize,
|
||||||
|
pub(crate) mop_in_unit_state: MOpInUnitState,
|
||||||
|
pub(crate) is_speculative: bool,
|
||||||
|
pub(crate) all_prior_mops_finished_and_or_caused_cancel: bool,
|
||||||
|
pub(crate) output: Option<SimValue<NextPcPredictorOp<C>>>,
|
||||||
|
pub(crate) caused_cancel: Option<SimValue<UnitCausedCancel<C>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: PhantomConstCpuConfig> RobEntry<C> {
|
||||||
|
pub(crate) fn new(
|
||||||
|
mop: SimValue<MOpInstance<RenamedMOp<C>>>,
|
||||||
|
unit_index: usize,
|
||||||
|
is_register_fence: bool,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
mop,
|
||||||
|
is_register_fence,
|
||||||
|
done_waiting_for_register_fences: false,
|
||||||
|
unit_index,
|
||||||
|
mop_in_unit_state: MOpInUnitState::NotYetEnqueued,
|
||||||
|
is_speculative: true,
|
||||||
|
all_prior_mops_finished_and_or_caused_cancel: false,
|
||||||
|
output: None,
|
||||||
|
caused_cancel: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn dest_reg(&self) -> Option<&SimValue<PRegNum<C>>> {
|
||||||
|
let dest_reg = MOpTrait::dest_reg_sim_ref(self.mop.mop.inner());
|
||||||
|
let unit_index = UnitNum::index_sim(&dest_reg.unit_num)?;
|
||||||
|
assert_eq!(unit_index, self.unit_index);
|
||||||
|
Some(dest_reg)
|
||||||
|
}
|
||||||
|
fn unit_out_reg(&self) -> Option<&SimValue<UnitOutRegNum<C>>> {
|
||||||
|
Some(&self.dest_reg()?.unit_out_reg)
|
||||||
|
}
|
||||||
|
pub(crate) fn unit_out_reg_index(&self) -> Option<usize> {
|
||||||
|
Some(UnitOutRegNum::value_sim(self.unit_out_reg()?))
|
||||||
|
}
|
||||||
|
#[hdl]
|
||||||
|
fn debug_state(&self, config: C) -> SimValue<RobEntryDebugState<C>> {
|
||||||
|
let Self {
|
||||||
|
is_register_fence,
|
||||||
|
done_waiting_for_register_fences,
|
||||||
|
mop,
|
||||||
|
unit_index,
|
||||||
|
mop_in_unit_state,
|
||||||
|
is_speculative,
|
||||||
|
all_prior_mops_finished_and_or_caused_cancel,
|
||||||
|
output,
|
||||||
|
caused_cancel,
|
||||||
|
} = self;
|
||||||
|
let ret_ty = RobEntryDebugState[config];
|
||||||
|
#[hdl(sim)]
|
||||||
|
RobEntryDebugState::<C> {
|
||||||
|
is_register_fence,
|
||||||
|
done_waiting_for_register_fences,
|
||||||
|
mop,
|
||||||
|
unit_index: unit_index.into_sim_value_with_type(ret_ty.unit_index),
|
||||||
|
mop_in_unit_state: SimOnlyValue::new(*mop_in_unit_state),
|
||||||
|
is_speculative,
|
||||||
|
all_prior_mops_finished_and_or_caused_cancel,
|
||||||
|
output: output.into_sim_value_with_type(ret_ty.output),
|
||||||
|
caused_cancel: caused_cancel.into_sim_value_with_type(ret_ty.caused_cancel),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[hdl]
|
||||||
|
fn for_each_reg<S>(
|
||||||
|
&self,
|
||||||
|
mut shared_state: S,
|
||||||
|
mut l1_reg: impl FnMut(&mut S, &SimValue<PRegNum<C>>),
|
||||||
|
mut l2_reg: impl FnMut(&mut S, &SimValue<L2RegNum>),
|
||||||
|
) {
|
||||||
|
l1_reg(
|
||||||
|
&mut shared_state,
|
||||||
|
MOpTrait::dest_reg_sim_ref(self.mop.mop.inner()),
|
||||||
|
);
|
||||||
|
MOpTrait::for_each_src_reg_sim_ref(self.mop.mop.inner(), &mut |l1, _| {
|
||||||
|
l1_reg(&mut shared_state, l1);
|
||||||
|
});
|
||||||
|
#[hdl(sim)]
|
||||||
|
if let RenamedMOp::<_>::TransformedMove(mop) = self.mop.mop.inner() {
|
||||||
|
#[hdl(sim)]
|
||||||
|
match mop {
|
||||||
|
L2RegisterFileMOp::<_, _>::ReadL2Reg(v) => {
|
||||||
|
l2_reg(&mut shared_state, &v.common.imm);
|
||||||
|
}
|
||||||
|
L2RegisterFileMOp::<_, _>::WriteL2Reg(v) => {
|
||||||
|
l2_reg(&mut shared_state, &v.common.imm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[hdl]
|
||||||
|
struct RobEntriesDebugState {
|
||||||
|
unrenamed: MOpInstance<MOp>,
|
||||||
|
/// number of renamed µOps that this unrenamed µOp corresponds to
|
||||||
|
renamed_entries_len: UInt<8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SimValueDefault for RobEntriesDebugState {
|
||||||
|
#[hdl]
|
||||||
|
fn sim_value_default(self) -> SimValue<Self> {
|
||||||
|
let Self {
|
||||||
|
unrenamed,
|
||||||
|
renamed_entries_len,
|
||||||
|
} = self;
|
||||||
|
#[hdl(sim)]
|
||||||
|
Self {
|
||||||
|
unrenamed: zeroed(unrenamed),
|
||||||
|
renamed_entries_len: renamed_entries_len.sim_value_default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct RobEntries<C: PhantomConstCpuConfig> {
|
||||||
|
unrenamed: SimValue<MOpInstance<MOp>>,
|
||||||
|
rename_table_updates: Vec<RenameTableUpdate<C>>,
|
||||||
|
renamed_entries: VecDeque<RobEntry<C>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: PhantomConstCpuConfig> RobEntries<C> {
|
||||||
|
#[hdl]
|
||||||
|
fn debug_state(&self) -> SimValue<RobEntriesDebugState> {
|
||||||
|
let Self {
|
||||||
|
unrenamed,
|
||||||
|
rename_table_updates: _,
|
||||||
|
renamed_entries,
|
||||||
|
} = self;
|
||||||
|
#[hdl(sim)]
|
||||||
|
RobEntriesDebugState {
|
||||||
|
unrenamed,
|
||||||
|
renamed_entries_len: u8::try_from(renamed_entries.len())
|
||||||
|
.expect("renamed_entries.len() should fit in u8"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[hdl(get(|c| c.rob_size.get() * (1 + COMMON_MOP_SRC_LEN)))]
|
||||||
|
type L1RegMaxRefCount<C: PhantomConstGet<CpuConfig>> = DynSize;
|
||||||
|
|
||||||
|
#[hdl(no_static)]
|
||||||
|
pub(crate) struct ReorderBufferDebugState<C: PhantomConstGet<CpuConfig>> {
|
||||||
|
next_renamed_mop_id: MOpId,
|
||||||
|
entries: ArrayVec<RobEntriesDebugState, CpuConfigRobSize<C>>,
|
||||||
|
incomplete_back_entry: HdlOption<RobEntriesDebugState>,
|
||||||
|
renamed: ArrayVec<RobEntryDebugState<C>, CpuConfigRobSize<C>>,
|
||||||
|
l1_reg_ref_counts: ArrayType<
|
||||||
|
ArrayType<
|
||||||
|
UIntInRangeInclusiveType<ConstUsize<0>, L1RegMaxRefCount<C>>,
|
||||||
|
CpuConfig2PowOutRegNumWidth<C>,
|
||||||
|
>,
|
||||||
|
CpuConfigUnitCount<C>,
|
||||||
|
>,
|
||||||
|
l2_reg_ref_counts:
|
||||||
|
ArrayType<UIntInRangeInclusiveType<ConstUsize<0>, CpuConfigRobSize<C>>, L2RegFileLen<C>>,
|
||||||
|
config: C,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: PhantomConstCpuConfig> SimValueDefault for ReorderBufferDebugState<C> {
|
||||||
|
#[hdl]
|
||||||
|
fn sim_value_default(self) -> SimValue<Self> {
|
||||||
|
let Self {
|
||||||
|
next_renamed_mop_id,
|
||||||
|
entries,
|
||||||
|
incomplete_back_entry,
|
||||||
|
renamed,
|
||||||
|
l1_reg_ref_counts,
|
||||||
|
l2_reg_ref_counts,
|
||||||
|
config,
|
||||||
|
} = self;
|
||||||
|
#[hdl(sim)]
|
||||||
|
Self {
|
||||||
|
next_renamed_mop_id: next_renamed_mop_id.sim_value_default(),
|
||||||
|
entries: entries.sim_value_default(),
|
||||||
|
incomplete_back_entry: incomplete_back_entry.sim_value_default(),
|
||||||
|
renamed: renamed.sim_value_default(),
|
||||||
|
l1_reg_ref_counts: zeroed(l1_reg_ref_counts),
|
||||||
|
l2_reg_ref_counts: zeroed(l2_reg_ref_counts),
|
||||||
|
config,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) struct ReorderBuffer<C: PhantomConstCpuConfig> {
|
||||||
|
next_renamed_mop_id: SimValue<MOpId>,
|
||||||
|
entries: VecDeque<RobEntries<C>>,
|
||||||
|
incomplete_back_entry: Option<RobEntries<C>>,
|
||||||
|
l1_reg_ref_counts: Box<[Box<[usize]>]>,
|
||||||
|
l2_reg_ref_counts: Box<[usize]>,
|
||||||
|
config: C,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: PhantomConstCpuConfig> ReorderBuffer<C> {
|
||||||
|
pub(crate) fn new(config: C) -> Self {
|
||||||
|
Self {
|
||||||
|
next_renamed_mop_id: MOpId.zero().into_sim_value(),
|
||||||
|
entries: VecDeque::new(),
|
||||||
|
incomplete_back_entry: None,
|
||||||
|
l1_reg_ref_counts: vec![
|
||||||
|
vec![0; CpuConfig2PowOutRegNumWidth[config]].into_boxed_slice();
|
||||||
|
CpuConfigUnitCount[config]
|
||||||
|
]
|
||||||
|
.into_boxed_slice(),
|
||||||
|
l2_reg_ref_counts: vec![0; L2RegNum.l2_reg_count()].into_boxed_slice(),
|
||||||
|
config,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[hdl]
|
||||||
|
pub(crate) fn l1_reg_ref_counts(&self) -> &[Box<[usize]>] {
|
||||||
|
let mut expected = vec![
|
||||||
|
vec![0usize; CpuConfig2PowOutRegNumWidth[self.config]]
|
||||||
|
.into_boxed_slice();
|
||||||
|
CpuConfigUnitCount[self.config]
|
||||||
|
];
|
||||||
|
for entry in self.renamed() {
|
||||||
|
entry.for_each_reg(
|
||||||
|
(),
|
||||||
|
|(), l1| {
|
||||||
|
if let Some(unit_index) = UnitNum::index_sim(&l1.unit_num) {
|
||||||
|
expected[unit_index][UnitOutRegNum::value_sim(&l1.unit_out_reg)] += 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|(), _l2| {},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
assert_eq!(*expected, *self.l1_reg_ref_counts);
|
||||||
|
&self.l1_reg_ref_counts
|
||||||
|
}
|
||||||
|
#[hdl]
|
||||||
|
pub(crate) fn l2_reg_ref_counts(&self) -> &[usize] {
|
||||||
|
let mut expected = vec![0usize; L2RegNum.l2_reg_count()];
|
||||||
|
for entry in self.renamed() {
|
||||||
|
entry.for_each_reg(
|
||||||
|
(),
|
||||||
|
|(), _l1| {},
|
||||||
|
|(), l2| expected[L2RegNum::value_sim(l2)] += 1,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
assert_eq!(*expected, *self.l2_reg_ref_counts);
|
||||||
|
&self.l2_reg_ref_counts
|
||||||
|
}
|
||||||
|
#[hdl]
|
||||||
|
pub(crate) fn debug_state(&self) -> SimValue<ReorderBufferDebugState<C>> {
|
||||||
|
let Self {
|
||||||
|
next_renamed_mop_id,
|
||||||
|
entries,
|
||||||
|
incomplete_back_entry,
|
||||||
|
l1_reg_ref_counts,
|
||||||
|
l2_reg_ref_counts,
|
||||||
|
config,
|
||||||
|
} = self;
|
||||||
|
let ty = ReorderBufferDebugState[*config];
|
||||||
|
#[hdl(sim)]
|
||||||
|
ReorderBufferDebugState::<_> {
|
||||||
|
next_renamed_mop_id,
|
||||||
|
entries: ty
|
||||||
|
.entries
|
||||||
|
.from_iter_sim(
|
||||||
|
zeroed(StaticType::TYPE),
|
||||||
|
entries.iter().map(RobEntries::debug_state),
|
||||||
|
)
|
||||||
|
.expect("known to fit"),
|
||||||
|
incomplete_back_entry: incomplete_back_entry.as_ref().map(|v| v.debug_state()),
|
||||||
|
renamed: ty
|
||||||
|
.renamed
|
||||||
|
.from_iter_sim(
|
||||||
|
ty.renamed.element().sim_value_default(),
|
||||||
|
self.renamed().map(|v| v.debug_state(*config)),
|
||||||
|
)
|
||||||
|
.ok()
|
||||||
|
.expect("known to fit"),
|
||||||
|
l1_reg_ref_counts: l1_reg_ref_counts.to_sim_value_with_type(ty.l1_reg_ref_counts),
|
||||||
|
l2_reg_ref_counts: l2_reg_ref_counts.to_sim_value_with_type(ty.l2_reg_ref_counts),
|
||||||
|
config,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub(crate) fn unrenamed_len(&self) -> usize {
|
||||||
|
self.entries.len()
|
||||||
|
}
|
||||||
|
pub(crate) fn unrenamed(
|
||||||
|
&self,
|
||||||
|
) -> impl DoubleEndedIterator<Item = &SimValue<MOpInstance<MOp>>> + Clone {
|
||||||
|
self.entries.iter().map(|v| &v.unrenamed)
|
||||||
|
}
|
||||||
|
fn retire_groups_unrenamed_ranges(
|
||||||
|
&self,
|
||||||
|
) -> impl Clone + Iterator<Item = std::ops::Range<usize>> {
|
||||||
|
let mut next_group_start = 0;
|
||||||
|
self.entries
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter_map(move |(index, entry)| {
|
||||||
|
if *entry.unrenamed.is_last_mop_in_insn {
|
||||||
|
let group_start = next_group_start;
|
||||||
|
next_group_start = index + 1;
|
||||||
|
Some(group_start..next_group_start)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
pub(crate) fn retire_groups(
|
||||||
|
&self,
|
||||||
|
) -> impl Clone + Iterator<Item: DoubleEndedIterator<Item = &VecDeque<RobEntry<C>>> + Clone>
|
||||||
|
{
|
||||||
|
self.retire_groups_unrenamed_ranges().map(|range| {
|
||||||
|
self.entries
|
||||||
|
.range(range)
|
||||||
|
.map(|entries| &entries.renamed_entries)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
pub(crate) fn renamed_len(&self) -> usize {
|
||||||
|
let Self {
|
||||||
|
next_renamed_mop_id: _,
|
||||||
|
entries,
|
||||||
|
incomplete_back_entry,
|
||||||
|
l1_reg_ref_counts: _,
|
||||||
|
l2_reg_ref_counts: _,
|
||||||
|
config: _,
|
||||||
|
} = self;
|
||||||
|
entries
|
||||||
|
.iter()
|
||||||
|
.chain(incomplete_back_entry)
|
||||||
|
.map(|entries| entries.renamed_entries.len())
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
pub(crate) fn renamed(&self) -> impl DoubleEndedIterator<Item = &RobEntry<C>> + Clone {
|
||||||
|
let Self {
|
||||||
|
next_renamed_mop_id: _,
|
||||||
|
entries,
|
||||||
|
incomplete_back_entry,
|
||||||
|
l1_reg_ref_counts: _,
|
||||||
|
l2_reg_ref_counts: _,
|
||||||
|
config: _,
|
||||||
|
} = self;
|
||||||
|
entries
|
||||||
|
.iter()
|
||||||
|
.chain(incomplete_back_entry)
|
||||||
|
.flat_map(|entries| &entries.renamed_entries)
|
||||||
|
}
|
||||||
|
pub(crate) fn renamed_mut(&mut self) -> impl DoubleEndedIterator<Item = &mut RobEntry<C>> {
|
||||||
|
let Self {
|
||||||
|
next_renamed_mop_id: _,
|
||||||
|
entries,
|
||||||
|
incomplete_back_entry,
|
||||||
|
l1_reg_ref_counts: _,
|
||||||
|
l2_reg_ref_counts: _,
|
||||||
|
config: _,
|
||||||
|
} = self;
|
||||||
|
entries
|
||||||
|
.iter_mut()
|
||||||
|
.chain(incomplete_back_entry)
|
||||||
|
.flat_map(|entries| &mut entries.renamed_entries)
|
||||||
|
}
|
||||||
|
fn try_renamed_by_id_mut(&mut self, id: &SimValue<MOpId>) -> Option<&mut RobEntry<C>> {
|
||||||
|
self.renamed_mut().find(|v| v.mop.id == *id)
|
||||||
|
}
|
||||||
|
pub(crate) fn renamed_by_id_mut(&mut self, id: &SimValue<MOpId>) -> &mut RobEntry<C> {
|
||||||
|
match self.try_renamed_by_id_mut(id) {
|
||||||
|
Some(v) => v,
|
||||||
|
None => panic!("MOpId not found: {id:?}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub(crate) fn renamed_push_back_with_new_id(
|
||||||
|
&mut self,
|
||||||
|
unrenamed: &SimValue<MOpInstance<MOp>>,
|
||||||
|
mut renamed: RobEntry<C>,
|
||||||
|
) -> &SimValue<MOpId> {
|
||||||
|
let replacement_id = self
|
||||||
|
.next_renamed_mop_id
|
||||||
|
.as_int()
|
||||||
|
.wrapping_add(1)
|
||||||
|
.into_sim_value();
|
||||||
|
renamed.mop.id = mem::replace(&mut self.next_renamed_mop_id, replacement_id);
|
||||||
|
println!("renamed_push_back_with_new_id: {:?}", renamed.mop);
|
||||||
|
renamed.for_each_reg(
|
||||||
|
(),
|
||||||
|
|(), l1| {
|
||||||
|
if let Some(unit_index) = UnitNum::index_sim(&l1.unit_num) {
|
||||||
|
self.l1_reg_ref_counts[unit_index]
|
||||||
|
[UnitOutRegNum::value_sim(&l1.unit_out_reg)] += 1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|(), l2| self.l2_reg_ref_counts[L2RegNum::value_sim(l2)] += 1,
|
||||||
|
);
|
||||||
|
let renamed_entries = &mut self
|
||||||
|
.incomplete_back_entry
|
||||||
|
.get_or_insert_with(|| RobEntries {
|
||||||
|
unrenamed: unrenamed.clone(),
|
||||||
|
rename_table_updates: Vec::new(),
|
||||||
|
renamed_entries: VecDeque::new(),
|
||||||
|
})
|
||||||
|
.renamed_entries;
|
||||||
|
renamed_entries.push_back(renamed);
|
||||||
|
&renamed_entries.back().expect("just pushed").mop.id
|
||||||
|
}
|
||||||
|
pub(crate) fn has_incomplete_back_entry(&self) -> bool {
|
||||||
|
self.incomplete_back_entry.is_some()
|
||||||
|
}
|
||||||
|
pub(crate) fn finished_unrenamed_push_back(&mut self, unrenamed: &SimValue<MOpInstance<MOp>>) {
|
||||||
|
let entry = self
|
||||||
|
.incomplete_back_entry
|
||||||
|
.take()
|
||||||
|
.unwrap_or_else(|| RobEntries {
|
||||||
|
unrenamed: unrenamed.clone(),
|
||||||
|
rename_table_updates: Vec::new(),
|
||||||
|
renamed_entries: VecDeque::new(),
|
||||||
|
});
|
||||||
|
self.entries.push_back(entry);
|
||||||
|
}
|
||||||
|
pub(crate) fn clear(&mut self) {
|
||||||
|
let Self {
|
||||||
|
next_renamed_mop_id: _,
|
||||||
|
entries,
|
||||||
|
incomplete_back_entry,
|
||||||
|
l1_reg_ref_counts,
|
||||||
|
l2_reg_ref_counts,
|
||||||
|
config: _,
|
||||||
|
} = self;
|
||||||
|
entries.clear();
|
||||||
|
l2_reg_ref_counts.fill(0);
|
||||||
|
for i in l1_reg_ref_counts {
|
||||||
|
i.fill(0);
|
||||||
|
}
|
||||||
|
*incomplete_back_entry = None;
|
||||||
|
}
|
||||||
|
pub(crate) fn unrenamed_back_append_rename_table_update(
|
||||||
|
&mut self,
|
||||||
|
unrenamed: &SimValue<MOpInstance<MOp>>,
|
||||||
|
update: RenameTableUpdate<C>,
|
||||||
|
) {
|
||||||
|
self.incomplete_back_entry
|
||||||
|
.get_or_insert_with(|| RobEntries {
|
||||||
|
unrenamed: unrenamed.clone(),
|
||||||
|
rename_table_updates: Vec::new(),
|
||||||
|
renamed_entries: VecDeque::new(),
|
||||||
|
})
|
||||||
|
.rename_table_updates
|
||||||
|
.push(update);
|
||||||
|
}
|
||||||
|
pub(crate) fn all_mops_are_finished_and_or_caused_cancel(&self) -> bool {
|
||||||
|
self.renamed().next().is_none_or(|entry| {
|
||||||
|
entry.all_prior_mops_finished_and_or_caused_cancel
|
||||||
|
&& entry.mop_in_unit_state.is_finished_and_or_caused_cancel()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
pub(crate) fn entries_pop_front(
|
||||||
|
&mut self,
|
||||||
|
) -> Option<(Vec<RenameTableUpdate<C>>, VecDeque<RobEntry<C>>)> {
|
||||||
|
let RobEntries {
|
||||||
|
unrenamed: _,
|
||||||
|
rename_table_updates,
|
||||||
|
renamed_entries,
|
||||||
|
} = self.entries.pop_front()?;
|
||||||
|
for entry in &renamed_entries {
|
||||||
|
entry.for_each_reg(
|
||||||
|
(),
|
||||||
|
|(), l1| {
|
||||||
|
if let Some(unit_index) = UnitNum::index_sim(&l1.unit_num) {
|
||||||
|
let ref_count = &mut self.l1_reg_ref_counts[unit_index]
|
||||||
|
[UnitOutRegNum::value_sim(&l1.unit_out_reg)];
|
||||||
|
*ref_count = ref_count.checked_sub(1).unwrap_or_else(|| {
|
||||||
|
unreachable!("ReorderBuffer: l1 ref count went negative: {l1:?}")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|(), l2| {
|
||||||
|
let ref_count = &mut self.l2_reg_ref_counts[L2RegNum::value_sim(l2)];
|
||||||
|
*ref_count = ref_count.checked_sub(1).unwrap_or_else(|| {
|
||||||
|
unreachable!("ReorderBuffer: l2 ref count went negative: {l2:?}")
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Some((rename_table_updates, renamed_entries))
|
||||||
|
}
|
||||||
|
}
|
||||||
207
crates/cpu/src/rename_execute_retire/to_unit_interfaces.rs
Normal file
207
crates/cpu/src/rename_execute_retire/to_unit_interfaces.rs
Normal file
|
|
@ -0,0 +1,207 @@
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// See Notices.txt for copyright information
|
||||||
|
|
||||||
|
use crate::{config::CpuConfig, rename_execute_retire::ExecuteToUnitInterface};
|
||||||
|
use fayalite::{
|
||||||
|
bundle::{BundleField, BundleType, NoBuilder},
|
||||||
|
expr::ops::FieldAccess,
|
||||||
|
intern::{Intern, Interned, Memoize},
|
||||||
|
prelude::*,
|
||||||
|
ty::{
|
||||||
|
OpaqueSimValue, OpaqueSimValueSlice, OpaqueSimValueWriter, OpaqueSimValueWritten,
|
||||||
|
SimValueDebug,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
use std::{fmt, marker::PhantomData, ops::Index};
|
||||||
|
|
||||||
|
/// a bundle with fields of type [`ExecuteToUnitInterface<C>`] for each unit
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub struct ExecuteToUnitInterfaces<C: Type + PhantomConstGet<CpuConfig>> {
|
||||||
|
bundle_ty: Bundle,
|
||||||
|
config: C,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: Type + PhantomConstGet<CpuConfig>> fmt::Debug for ExecuteToUnitInterfaces<C> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
f.write_str("ExecuteToUnitInterfaces ")?;
|
||||||
|
let fields = self.bundle_ty.fields();
|
||||||
|
let field_offsets = self.bundle_ty.field_offsets();
|
||||||
|
f.debug_set()
|
||||||
|
.entries(
|
||||||
|
fields.iter().enumerate().map(|(index, field)| {
|
||||||
|
field.fmt_debug_in_struct(field_offsets[index].bit_width)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const CONFIG_FIELD_NAME: &str = "config";
|
||||||
|
|
||||||
|
impl<C: Type + PhantomConstGet<CpuConfig>> ExecuteToUnitInterfaces<C> {
|
||||||
|
pub fn new(config: C) -> Self {
|
||||||
|
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
|
||||||
|
struct MyMemoize<C>(PhantomData<C>);
|
||||||
|
impl<C: Type + PhantomConstGet<CpuConfig>> Memoize for MyMemoize<C> {
|
||||||
|
type Input = C;
|
||||||
|
type InputOwned = C;
|
||||||
|
type Output = ExecuteToUnitInterfaces<C>;
|
||||||
|
|
||||||
|
fn inner(self, &config: &Self::Input) -> Self::Output {
|
||||||
|
let unit_ty = ExecuteToUnitInterface[config].canonical();
|
||||||
|
let bundle_ty = Bundle::new(
|
||||||
|
(0..config.get().units.len())
|
||||||
|
.map(|unit_index| BundleField {
|
||||||
|
name: format!(
|
||||||
|
"u{unit_index}_{:?}",
|
||||||
|
config.get().units[unit_index].kind,
|
||||||
|
)
|
||||||
|
.intern_deref(),
|
||||||
|
flipped: false,
|
||||||
|
ty: unit_ty,
|
||||||
|
})
|
||||||
|
.chain([BundleField {
|
||||||
|
name: CONFIG_FIELD_NAME.intern(),
|
||||||
|
flipped: false,
|
||||||
|
ty: config.canonical(),
|
||||||
|
}])
|
||||||
|
.collect(),
|
||||||
|
);
|
||||||
|
ExecuteToUnitInterfaces { bundle_ty, config }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MyMemoize(PhantomData).get_owned(config)
|
||||||
|
}
|
||||||
|
pub fn bundle_ty(self) -> Bundle {
|
||||||
|
self.bundle_ty
|
||||||
|
}
|
||||||
|
pub fn config(self) -> C {
|
||||||
|
self.config
|
||||||
|
}
|
||||||
|
#[track_caller]
|
||||||
|
pub fn unit_field_name(self, unit_index: usize) -> Interned<str> {
|
||||||
|
assert!(unit_index < self.config.get().units.len());
|
||||||
|
self.bundle_ty.fields()[unit_index].name
|
||||||
|
}
|
||||||
|
pub fn unit_fields(
|
||||||
|
this: impl ToExpr<Type = Self>,
|
||||||
|
) -> Interned<[Expr<ExecuteToUnitInterface<C>>]> {
|
||||||
|
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
|
||||||
|
struct MyMemoize<C>(PhantomData<C>);
|
||||||
|
impl<C: Type + PhantomConstGet<CpuConfig>> Memoize for MyMemoize<C> {
|
||||||
|
type Input = Expr<ExecuteToUnitInterfaces<C>>;
|
||||||
|
type InputOwned = Expr<ExecuteToUnitInterfaces<C>>;
|
||||||
|
type Output = Interned<[Expr<ExecuteToUnitInterface<C>>]>;
|
||||||
|
|
||||||
|
fn inner(self, this: &Self::Input) -> Self::Output {
|
||||||
|
let bundle = Expr::as_bundle(*this);
|
||||||
|
(0..this.ty().config.get().units.len())
|
||||||
|
.map(|unit_index| FieldAccess::new_by_index(bundle, unit_index).to_expr())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MyMemoize(PhantomData).get_owned(this.to_expr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub struct ExecuteToUnitInterfacesWithoutGenerics(());
|
||||||
|
|
||||||
|
#[expect(non_upper_case_globals)]
|
||||||
|
pub const ExecuteToUnitInterfaces: ExecuteToUnitInterfacesWithoutGenerics =
|
||||||
|
ExecuteToUnitInterfacesWithoutGenerics(());
|
||||||
|
|
||||||
|
impl<C: Type + PhantomConstGet<CpuConfig>> Index<C> for ExecuteToUnitInterfacesWithoutGenerics {
|
||||||
|
type Output = ExecuteToUnitInterfaces<C>;
|
||||||
|
|
||||||
|
fn index(&self, config: C) -> &Self::Output {
|
||||||
|
Interned::into_inner(ExecuteToUnitInterfaces::new(config).intern())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: Type + PhantomConstGet<CpuConfig>> SimValueDebug for ExecuteToUnitInterfaces<C> {
|
||||||
|
fn sim_value_debug(
|
||||||
|
value: &<Self as Type>::SimValue,
|
||||||
|
f: &mut fmt::Formatter<'_>,
|
||||||
|
) -> fmt::Result {
|
||||||
|
fmt::Debug::fmt(value, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: Type + PhantomConstGet<CpuConfig>> Type for ExecuteToUnitInterfaces<C> {
|
||||||
|
type BaseType = Bundle;
|
||||||
|
type MaskType = Bundle;
|
||||||
|
type SimValue = OpaqueSimValue;
|
||||||
|
type MatchVariant = <Bundle as Type>::MatchVariant;
|
||||||
|
type MatchActiveScope = <Bundle as Type>::MatchActiveScope;
|
||||||
|
type MatchVariantAndInactiveScope = <Bundle as Type>::MatchVariantAndInactiveScope;
|
||||||
|
type MatchVariantsIter = <Bundle as Type>::MatchVariantsIter;
|
||||||
|
|
||||||
|
fn match_variants(
|
||||||
|
this: Expr<Self>,
|
||||||
|
source_location: SourceLocation,
|
||||||
|
) -> Self::MatchVariantsIter {
|
||||||
|
Type::match_variants(Expr::as_bundle(this), source_location)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mask_type(&self) -> Self::MaskType {
|
||||||
|
self.bundle_ty.mask_type()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn canonical(&self) -> CanonicalType {
|
||||||
|
self.bundle_ty.canonical()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_canonical(canonical_type: CanonicalType) -> Self {
|
||||||
|
let bundle_ty = Bundle::from_canonical(canonical_type);
|
||||||
|
let config = if let Some(BundleField {
|
||||||
|
name,
|
||||||
|
flipped: false,
|
||||||
|
ty,
|
||||||
|
}) = bundle_ty.fields().last()
|
||||||
|
&& **name == *CONFIG_FIELD_NAME
|
||||||
|
{
|
||||||
|
C::from_canonical(*ty)
|
||||||
|
} else {
|
||||||
|
panic!(
|
||||||
|
"ExecuteToUnitInterfaces must have `{}` field",
|
||||||
|
CONFIG_FIELD_NAME
|
||||||
|
);
|
||||||
|
};
|
||||||
|
let retval = Self::new(config);
|
||||||
|
assert_eq!(bundle_ty, retval.bundle_ty);
|
||||||
|
retval
|
||||||
|
}
|
||||||
|
|
||||||
|
fn source_location() -> SourceLocation {
|
||||||
|
SourceLocation::caller()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sim_value_from_opaque(&self, opaque: OpaqueSimValueSlice<'_>) -> Self::SimValue {
|
||||||
|
<Bundle as Type>::sim_value_from_opaque(&self.bundle_ty, opaque)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sim_value_clone_from_opaque(
|
||||||
|
&self,
|
||||||
|
value: &mut Self::SimValue,
|
||||||
|
opaque: OpaqueSimValueSlice<'_>,
|
||||||
|
) {
|
||||||
|
<Bundle as Type>::sim_value_clone_from_opaque(&self.bundle_ty, value, opaque)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sim_value_to_opaque<'w>(
|
||||||
|
&self,
|
||||||
|
value: &Self::SimValue,
|
||||||
|
writer: OpaqueSimValueWriter<'w>,
|
||||||
|
) -> OpaqueSimValueWritten<'w> {
|
||||||
|
<Bundle as Type>::sim_value_to_opaque(&self.bundle_ty, value, writer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: Type + PhantomConstGet<CpuConfig>> BundleType for ExecuteToUnitInterfaces<C> {
|
||||||
|
type Builder = NoBuilder;
|
||||||
|
|
||||||
|
fn fields(&self) -> Interned<[BundleField]> {
|
||||||
|
self.bundle_ty.fields()
|
||||||
|
}
|
||||||
|
}
|
||||||
41
crates/cpu/src/rename_execute_retire/unit.mermaid
Normal file
41
crates/cpu/src/rename_execute_retire/unit.mermaid
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
%% SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
%% See Notices.txt for copyright information
|
||||||
|
stateDiagram-v2
|
||||||
|
direction LR
|
||||||
|
|
||||||
|
state "Inputs not ready<br/>Speculative<br/>Can cause cancel" as inr_s_c
|
||||||
|
state "Inputs not ready<br/>Speculative" as inr_s
|
||||||
|
state "Inputs ready<br/>Speculative<br/>Can cause cancel" as ir_s_c
|
||||||
|
state "Inputs ready<br/>Speculative" as ir_s
|
||||||
|
state "Inputs ready<br/>Can cause cancel" as ir_c
|
||||||
|
state "Inputs ready" as ir
|
||||||
|
state "Output ready<br/>Speculative<br/>Can cause cancel" as or_s_c
|
||||||
|
state "Output ready<br/>Can cause cancel" as or_c
|
||||||
|
state "Output ready<br/>Speculative" as or_s
|
||||||
|
state "Output ready" as or
|
||||||
|
|
||||||
|
[*] --> inr_s_c: Enqueue
|
||||||
|
|
||||||
|
inr_s_c --> inr_s: Can't cause cancel
|
||||||
|
ir_s_c --> ir_s: Can't cause cancel
|
||||||
|
ir_c --> ir: Can't cause cancel
|
||||||
|
or_s_c --> or_s: Can't cause cancel
|
||||||
|
or_c --> or: Can't cause cancel
|
||||||
|
|
||||||
|
ir_s_c --> ir_c: No longer speculative
|
||||||
|
ir_s --> ir: No longer speculative
|
||||||
|
or_s_c --> or_c: No longer speculative
|
||||||
|
or_s --> or: No longer speculative
|
||||||
|
|
||||||
|
inr_s_c --> ir_s_c: Inputs ready
|
||||||
|
inr_s --> ir_s: Inputs ready
|
||||||
|
|
||||||
|
ir_s_c --> or_s_c: Output Ready
|
||||||
|
ir_c --> or_c: Output Ready
|
||||||
|
ir_s --> or_s: Output Ready
|
||||||
|
ir --> or: Output Ready
|
||||||
|
|
||||||
|
or_s_c --> [*]: Finish
|
||||||
|
or_c --> [*]: Finish
|
||||||
|
or_s --> [*]: Finish
|
||||||
|
or --> [*]: Finish
|
||||||
|
|
@ -2,11 +2,11 @@
|
||||||
// See Notices.txt for copyright information
|
// See Notices.txt for copyright information
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::CpuConfig,
|
config::{CpuConfig, PhantomConstCpuConfig},
|
||||||
instruction::{
|
instruction::{
|
||||||
AluBranchMOp, LoadStoreMOp, MOp, MOpDestReg, MOpInto, MOpRegNum, MOpTrait,
|
AluBranchMOp, LoadStoreMOp, MOp, MOpDestReg, MOpInto, MOpRegNum, MOpTrait,
|
||||||
MOpVariantVisitOps, MOpVariantVisitor, MOpVisitVariants, RenamedMOp, UnitOutRegNum,
|
MOpVariantVisitOps, MOpVariantVisitor, MOpVisitVariants, PRegNum, RenamedMOp,
|
||||||
mop_enum,
|
UnitOutRegNum, mop_enum,
|
||||||
},
|
},
|
||||||
register::{FlagsMode, PRegValue},
|
register::{FlagsMode, PRegValue},
|
||||||
unit::unit_base::UnitToRegAlloc,
|
unit::unit_base::UnitToRegAlloc,
|
||||||
|
|
@ -26,13 +26,13 @@ macro_rules! all_units {
|
||||||
(
|
(
|
||||||
#[hdl_unit_kind = $HdlUnitKind:ident]
|
#[hdl_unit_kind = $HdlUnitKind:ident]
|
||||||
#[unit_kind = $UnitKind:ident]
|
#[unit_kind = $UnitKind:ident]
|
||||||
#[hdl]
|
#[hdl(custom_debug(sim))]
|
||||||
$(#[$enum_meta:meta])*
|
$(#[$enum_meta:meta])*
|
||||||
$vis:vis enum $UnitMOpEnum:ident<$DestReg:ident: Type, $SrcRegWidth:ident: Size, #[MOp(get_ty = $transformed_move_op_get_ty:expr)] $TransformedMoveOp:ident: Type> {
|
$vis:vis enum $UnitMOpEnum:ident<$DestReg:ident: Type, $SrcReg:ident: Type, #[MOp(get_ty = $transformed_move_op_get_ty:expr)] $TransformedMoveOp:ident: Type> {
|
||||||
$(
|
$(
|
||||||
$(#[transformed_move $($transformed_move:tt)*])?
|
$(#[transformed_move $($transformed_move:tt)*])?
|
||||||
#[create_dyn_unit_fn = $create_dyn_unit_fn:expr]
|
#[create_dyn_unit_fn = $create_dyn_unit_fn:expr]
|
||||||
#[extract = $extract:ident]
|
#[extract($extract:ident, $extract_sim:ident, $extract_sim_ref:ident, $extract_sim_mut:ident)]
|
||||||
$(#[$variant_meta:meta])*
|
$(#[$variant_meta:meta])*
|
||||||
$Unit:ident($Op:ty),
|
$Unit:ident($Op:ty),
|
||||||
)*
|
)*
|
||||||
|
|
@ -48,7 +48,7 @@ macro_rules! all_units {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl $UnitKind {
|
impl $UnitKind {
|
||||||
pub fn unit(self, config: &CpuConfig, unit_index: usize) -> DynUnit {
|
pub fn unit(self, config: PhantomConst<CpuConfig>, unit_index: usize) -> DynUnit {
|
||||||
match self {
|
match self {
|
||||||
$($UnitKind::$Unit => $create_dyn_unit_fn(config, unit_index),)*
|
$($UnitKind::$Unit => $create_dyn_unit_fn(config, unit_index),)*
|
||||||
}
|
}
|
||||||
|
|
@ -83,15 +83,15 @@ macro_rules! all_units {
|
||||||
|
|
||||||
mop_enum! {
|
mop_enum! {
|
||||||
#[impl_mop_into = false]
|
#[impl_mop_into = false]
|
||||||
#[hdl]
|
#[hdl(custom_debug(sim))]
|
||||||
$(#[$enum_meta])*
|
$(#[$enum_meta])*
|
||||||
$vis enum $UnitMOpEnum<
|
$vis enum $UnitMOpEnum<
|
||||||
$DestReg: Type,
|
$DestReg: Type,
|
||||||
$SrcRegWidth: Size,
|
$SrcReg: Type,
|
||||||
#[MOp(get_ty = $transformed_move_op_get_ty)] $TransformedMoveOp: Type,
|
#[MOp(get_ty = $transformed_move_op_get_ty)] $TransformedMoveOp: Type,
|
||||||
#[MOpVisitVariants] [
|
#[MOpVisitVariants] [
|
||||||
$TransformedMoveOp: MOpVisitVariants<DestReg = $DestReg, SrcRegWidth = $SrcRegWidth>,
|
$TransformedMoveOp: MOpVisitVariants<DestReg = $DestReg, SrcReg = $SrcReg>,
|
||||||
$($Op: MOpVisitVariants<DestReg = $DestReg, SrcRegWidth = $SrcRegWidth>,)*
|
$($Op: MOpVisitVariants<DestReg = $DestReg, SrcReg = $SrcReg>,)*
|
||||||
]
|
]
|
||||||
> {
|
> {
|
||||||
$(
|
$(
|
||||||
|
|
@ -101,7 +101,7 @@ macro_rules! all_units {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<$DestReg: Type, $SrcRegWidth: Size, $TransformedMoveOp: Type> $UnitMOpEnum<$DestReg, $SrcRegWidth, $TransformedMoveOp> {
|
impl<$DestReg: Type, $SrcReg: Type, $TransformedMoveOp: Type> $UnitMOpEnum<$DestReg, $SrcReg, $TransformedMoveOp> {
|
||||||
#[hdl]
|
#[hdl]
|
||||||
$vis fn kind(expr: impl ToExpr<Type = Self>) -> Expr<$HdlUnitKind> {
|
$vis fn kind(expr: impl ToExpr<Type = Self>) -> Expr<$HdlUnitKind> {
|
||||||
#[hdl]
|
#[hdl]
|
||||||
|
|
@ -112,6 +112,15 @@ macro_rules! all_units {
|
||||||
}
|
}
|
||||||
unit_kind
|
unit_kind
|
||||||
}
|
}
|
||||||
|
#[hdl]
|
||||||
|
$vis fn kind_sim(expr: &SimValue<Self>) -> UnitKind {
|
||||||
|
#![allow(unreachable_patterns)]
|
||||||
|
#[hdl(sim)]
|
||||||
|
match expr {
|
||||||
|
$(Self::$Unit(_) => $UnitKind::$Unit,)*
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
$(
|
$(
|
||||||
#[hdl]
|
#[hdl]
|
||||||
$vis fn $extract(expr: impl ToExpr<Type = Self>) -> Expr<HdlOption<$Op>> {
|
$vis fn $extract(expr: impl ToExpr<Type = Self>) -> Expr<HdlOption<$Op>> {
|
||||||
|
|
@ -126,19 +135,47 @@ macro_rules! all_units {
|
||||||
}
|
}
|
||||||
$extract
|
$extract
|
||||||
}
|
}
|
||||||
|
#[hdl]
|
||||||
|
$vis fn $extract_sim(expr: impl ToSimValue<Type = Self>) -> Option<SimValue<$Op>> {
|
||||||
|
let expr = expr.into_sim_value();
|
||||||
|
#[hdl(sim)]
|
||||||
|
if let Self::$Unit(v) = expr {
|
||||||
|
Some(v)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[hdl]
|
||||||
|
$vis fn $extract_sim_ref(expr: &SimValue<Self>) -> Option<&SimValue<$Op>> {
|
||||||
|
#[hdl(sim)]
|
||||||
|
if let Self::$Unit(v) = expr {
|
||||||
|
Some(v)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[hdl]
|
||||||
|
$vis fn $extract_sim_mut(expr: &mut SimValue<Self>) -> Option<&mut SimValue<$Op>> {
|
||||||
|
#[hdl(sim)]
|
||||||
|
if let Self::$Unit(v) = expr {
|
||||||
|
Some(v)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
)*
|
)*
|
||||||
$vis fn with_transformed_move_op_ty<T>(self, new_transformed_move_op_ty: T) -> $UnitMOpEnum<$DestReg, $SrcRegWidth, T>
|
$vis fn with_transformed_move_op_ty<T>(self, new_transformed_move_op_ty: T) -> $UnitMOpEnum<$DestReg, $SrcReg, T>
|
||||||
where
|
where
|
||||||
T: MOpTrait<DestReg = $DestReg, SrcRegWidth = $SrcRegWidth>,
|
T: MOpTrait<DestReg = $DestReg, SrcReg = $SrcReg>,
|
||||||
$TransformedMoveOp: MOpTrait<DestReg = $DestReg, SrcRegWidth = $SrcRegWidth>,
|
$TransformedMoveOp: MOpTrait<DestReg = $DestReg, SrcReg = $SrcReg>,
|
||||||
{
|
{
|
||||||
$UnitMOpEnum[self.dest_reg_ty()][self.src_reg_width()][new_transformed_move_op_ty]
|
$UnitMOpEnum[self.dest_reg_ty()][self.src_reg_ty()][new_transformed_move_op_ty]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
all_units! {
|
all_units! {
|
||||||
@split_by_transformed_move
|
@split_by_transformed_move
|
||||||
$vis enum $UnitMOpEnum<$DestReg: Type, $SrcRegWidth: Size, $TransformedMoveOp: Type> {
|
$vis enum $UnitMOpEnum<$DestReg: Type, $SrcReg: Type, $TransformedMoveOp: Type> {
|
||||||
$(
|
$(
|
||||||
$(#[transformed_move $($transformed_move)*])?
|
$(#[transformed_move $($transformed_move)*])?
|
||||||
$Unit($Op),
|
$Unit($Op),
|
||||||
|
|
@ -163,23 +200,23 @@ macro_rules! all_units {
|
||||||
};
|
};
|
||||||
(
|
(
|
||||||
@split_by_transformed_move
|
@split_by_transformed_move
|
||||||
$vis:vis enum $UnitMOpEnum:ident<$DestReg:ident: Type, $SrcRegWidth:ident: Size, $TransformedMoveOp:ident: Type> {
|
$vis:vis enum $UnitMOpEnum:ident<$DestReg:ident: Type, $SrcReg:ident: Type, $TransformedMoveOp:ident: Type> {
|
||||||
$($BeforeUnit:ident($BeforeOp:ty),)*
|
$($BeforeUnit:ident($BeforeOp:ty),)*
|
||||||
#[transformed_move]
|
#[transformed_move]
|
||||||
$TransformedMove:ident($TransformedMoveOp2:ty),
|
$TransformedMove:ident($TransformedMoveOp2:ty),
|
||||||
$($AfterUnit:ident($AfterOp:ty),)*
|
$($AfterUnit:ident($AfterOp:ty),)*
|
||||||
}
|
}
|
||||||
) => {
|
) => {
|
||||||
impl<$DestReg: Type, $SrcRegWidth: Size, $TransformedMoveOp: Type> $UnitMOpEnum<$DestReg, $SrcRegWidth, $TransformedMoveOp> {
|
impl<$DestReg: Type, $SrcReg: Type, $TransformedMoveOp: Type> $UnitMOpEnum<$DestReg, $SrcReg, $TransformedMoveOp> {
|
||||||
#[hdl]
|
#[hdl]
|
||||||
$vis fn try_with_transformed_move_op<T>(
|
$vis fn try_with_transformed_move_op<T>(
|
||||||
this: impl ToExpr<Type = Self>,
|
this: impl ToExpr<Type = Self>,
|
||||||
new_transformed_move_op_ty: T,
|
new_transformed_move_op_ty: T,
|
||||||
connect_transformed_move_op: impl FnOnce(Expr<HdlOption<$UnitMOpEnum<$DestReg, $SrcRegWidth, T>>>, Expr<$TransformedMoveOp>),
|
connect_transformed_move_op: impl FnOnce(Expr<HdlOption<$UnitMOpEnum<$DestReg, $SrcReg, T>>>, Expr<$TransformedMoveOp>),
|
||||||
) -> Expr<HdlOption<$UnitMOpEnum<$DestReg, $SrcRegWidth, T>>>
|
) -> Expr<HdlOption<$UnitMOpEnum<$DestReg, $SrcReg, T>>>
|
||||||
where
|
where
|
||||||
T: MOpTrait<DestReg = $DestReg, SrcRegWidth = $SrcRegWidth>,
|
T: MOpTrait<DestReg = $DestReg, SrcReg = $SrcReg>,
|
||||||
$TransformedMoveOp: MOpTrait<DestReg = $DestReg, SrcRegWidth = $SrcRegWidth>,
|
$TransformedMoveOp: MOpTrait<DestReg = $DestReg, SrcReg = $SrcReg>,
|
||||||
{
|
{
|
||||||
let this = this.to_expr();
|
let this = this.to_expr();
|
||||||
let new_ty = this.ty().with_transformed_move_op_ty(new_transformed_move_op_ty);
|
let new_ty = this.ty().with_transformed_move_op_ty(new_transformed_move_op_ty);
|
||||||
|
|
@ -196,12 +233,51 @@ macro_rules! all_units {
|
||||||
}
|
}
|
||||||
with_transformed_move_op
|
with_transformed_move_op
|
||||||
}
|
}
|
||||||
|
#[hdl]
|
||||||
|
$vis fn try_with_transformed_move_op_sim<T, E>(
|
||||||
|
this: impl ToSimValue<Type = Self>,
|
||||||
|
new_transformed_move_op_ty: T,
|
||||||
|
f: impl FnOnce(SimValue<$TransformedMoveOp>) -> Result<SimValue<$UnitMOpEnum<$DestReg, $SrcReg, T>>, E>,
|
||||||
|
) -> Result<SimValue<$UnitMOpEnum<$DestReg, $SrcReg, T>>, E>
|
||||||
|
where
|
||||||
|
T: MOpTrait<DestReg = $DestReg, SrcReg = $SrcReg>,
|
||||||
|
$TransformedMoveOp: MOpTrait<DestReg = $DestReg, SrcReg = $SrcReg>,
|
||||||
|
{
|
||||||
|
#![allow(unreachable_patterns)]
|
||||||
|
let this = this.into_sim_value();
|
||||||
|
let new_ty = this.ty().with_transformed_move_op_ty(new_transformed_move_op_ty);
|
||||||
|
#[hdl(sim)]
|
||||||
|
match this {
|
||||||
|
$(Self::$BeforeUnit(unit) => Ok(
|
||||||
|
#[hdl(sim)]
|
||||||
|
new_ty.$BeforeUnit(unit)
|
||||||
|
),)*
|
||||||
|
Self::$TransformedMove(unit) => f(unit),
|
||||||
|
$(Self::$AfterUnit(unit) => Ok(
|
||||||
|
#[hdl(sim)]
|
||||||
|
new_ty.$AfterUnit(unit)
|
||||||
|
),)*
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$vis fn with_transformed_move_op_sim<T>(
|
||||||
|
this: impl ToSimValue<Type = Self>,
|
||||||
|
new_transformed_move_op_ty: T,
|
||||||
|
f: impl FnOnce(SimValue<$TransformedMoveOp>) -> SimValue<$UnitMOpEnum<$DestReg, $SrcReg, T>>,
|
||||||
|
) -> SimValue<$UnitMOpEnum<$DestReg, $SrcReg, T>>
|
||||||
|
where
|
||||||
|
T: MOpTrait<DestReg = $DestReg, SrcReg = $SrcReg>,
|
||||||
|
$TransformedMoveOp: MOpTrait<DestReg = $DestReg, SrcReg = $SrcReg>,
|
||||||
|
{
|
||||||
|
let Ok::<_, std::convert::Infallible>(retval) = Self::try_with_transformed_move_op_sim(this, new_transformed_move_op_ty, move |v| Ok(f(v)));
|
||||||
|
retval
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const _: () = {
|
const _: () = {
|
||||||
#[hdl]
|
#[hdl]
|
||||||
type $DestReg = MOpDestReg;
|
type $DestReg = MOpDestReg;
|
||||||
type $SrcRegWidth = ConstUsize<{ MOpRegNum::WIDTH }>;
|
type $SrcReg = MOpRegNum;
|
||||||
|
|
||||||
$(impl MOpInto<MOp> for $BeforeOp {
|
$(impl MOpInto<MOp> for $BeforeOp {
|
||||||
fn mop_into_ty(self) -> MOp {
|
fn mop_into_ty(self) -> MOp {
|
||||||
|
|
@ -222,21 +298,21 @@ macro_rules! all_units {
|
||||||
})*
|
})*
|
||||||
};
|
};
|
||||||
|
|
||||||
$(impl<$DestReg: Type, $SrcRegWidth: Size> MOpInto<RenamedMOp<$DestReg, $SrcRegWidth>> for $BeforeOp {
|
$(impl<$DestReg: Type, $SrcReg: Type> MOpInto<RenamedMOp<$DestReg, $SrcReg>> for $BeforeOp {
|
||||||
fn mop_into_ty(self) -> RenamedMOp<$DestReg, $SrcRegWidth> {
|
fn mop_into_ty(self) -> RenamedMOp<$DestReg, $SrcReg> {
|
||||||
RenamedMOp[MOpTrait::dest_reg_ty(self)][MOpTrait::src_reg_width(self)]
|
RenamedMOp[MOpTrait::dest_reg_ty(self)][MOpTrait::src_reg_ty(self)]
|
||||||
}
|
}
|
||||||
fn mop_into(this: Expr<Self>) -> Expr<RenamedMOp<$DestReg, $SrcRegWidth>> {
|
fn mop_into(this: Expr<Self>) -> Expr<RenamedMOp<$DestReg, $SrcReg>> {
|
||||||
MOpInto::<RenamedMOp<$DestReg, $SrcRegWidth>>::mop_into_ty(this.ty()).$BeforeUnit(this)
|
MOpInto::<RenamedMOp<$DestReg, $SrcReg>>::mop_into_ty(this.ty()).$BeforeUnit(this)
|
||||||
}
|
}
|
||||||
})*
|
})*
|
||||||
|
|
||||||
$(impl<$DestReg: Type, $SrcRegWidth: Size> MOpInto<RenamedMOp<$DestReg, $SrcRegWidth>> for $AfterOp {
|
$(impl<$DestReg: Type, $SrcReg: Type> MOpInto<RenamedMOp<$DestReg, $SrcReg>> for $AfterOp {
|
||||||
fn mop_into_ty(self) -> RenamedMOp<$DestReg, $SrcRegWidth> {
|
fn mop_into_ty(self) -> RenamedMOp<$DestReg, $SrcReg> {
|
||||||
RenamedMOp[MOpTrait::dest_reg_ty(self)][MOpTrait::src_reg_width(self)]
|
RenamedMOp[MOpTrait::dest_reg_ty(self)][MOpTrait::src_reg_ty(self)]
|
||||||
}
|
}
|
||||||
fn mop_into(this: Expr<Self>) -> Expr<RenamedMOp<$DestReg, $SrcRegWidth>> {
|
fn mop_into(this: Expr<Self>) -> Expr<RenamedMOp<$DestReg, $SrcReg>> {
|
||||||
MOpInto::<RenamedMOp<$DestReg, $SrcRegWidth>>::mop_into_ty(this.ty()).$AfterUnit(this)
|
MOpInto::<RenamedMOp<$DestReg, $SrcReg>>::mop_into_ty(this.ty()).$AfterUnit(this)
|
||||||
}
|
}
|
||||||
})*
|
})*
|
||||||
};
|
};
|
||||||
|
|
@ -245,24 +321,24 @@ macro_rules! all_units {
|
||||||
all_units! {
|
all_units! {
|
||||||
#[hdl_unit_kind = HdlUnitKind]
|
#[hdl_unit_kind = HdlUnitKind]
|
||||||
#[unit_kind = UnitKind]
|
#[unit_kind = UnitKind]
|
||||||
#[hdl]
|
#[hdl(custom_debug(sim))]
|
||||||
pub enum UnitMOp<
|
pub enum UnitMOp<
|
||||||
DestReg: Type,
|
DestReg: Type,
|
||||||
SrcRegWidth: Size,
|
SrcReg: Type,
|
||||||
#[MOp(get_ty = |this: UnitMOp<DestReg, SrcRegWidth, TransformedMoveOp>, new_dest_reg, new_src_reg_width| {
|
#[MOp(get_ty = |this: UnitMOp<DestReg, SrcReg, TransformedMoveOp>, new_dest_reg, new_src_reg| {
|
||||||
this.TransformedMove.mapped_ty(new_dest_reg, new_src_reg_width)
|
this.TransformedMove.mapped_ty(new_dest_reg, new_src_reg)
|
||||||
})] TransformedMoveOp: Type
|
})] TransformedMoveOp: Type
|
||||||
> {
|
> {
|
||||||
#[create_dyn_unit_fn = |config, unit_index| alu_branch::AluBranch::new(config, unit_index).to_dyn()]
|
#[create_dyn_unit_fn = |config, unit_index| alu_branch::AluBranch::new(config, unit_index).to_dyn()]
|
||||||
#[extract = alu_branch_mop]
|
#[extract(alu_branch_mop, alu_branch_mop_sim, alu_branch_mop_sim_ref, alu_branch_mop_sim_mut)]
|
||||||
AluBranch(AluBranchMOp<DestReg, SrcRegWidth>),
|
AluBranch(AluBranchMOp<DestReg, SrcReg>),
|
||||||
#[transformed_move]
|
#[transformed_move]
|
||||||
#[create_dyn_unit_fn = |config, unit_index| todo!()]
|
#[create_dyn_unit_fn = |config, unit_index| todo!()]
|
||||||
#[extract = transformed_move_mop]
|
#[extract(transformed_move_mop, transformed_move_mop_sim, transformed_move_mop_sim_ref, transformed_move_mop_sim_mut)]
|
||||||
TransformedMove(TransformedMoveOp),
|
TransformedMove(TransformedMoveOp),
|
||||||
#[create_dyn_unit_fn = |config, unit_index| todo!()]
|
#[create_dyn_unit_fn = |config, unit_index| todo!()]
|
||||||
#[extract = load_store_mop]
|
#[extract(load_store_mop, load_store_mop_sim, load_store_mop_sim_ref, load_store_mop_sim_mut)]
|
||||||
LoadStore(LoadStoreMOp<DestReg, SrcRegWidth>),
|
LoadStore(LoadStoreMOp<DestReg, SrcReg>),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -277,9 +353,9 @@ pub struct UnitResultCompleted<ExtraOut> {
|
||||||
pub extra_out: ExtraOut,
|
pub extra_out: ExtraOut,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[hdl(cmp_eq)]
|
#[hdl(cmp_eq, no_static)]
|
||||||
pub struct UnitOutputWrite<OutRegNumWidth: Size> {
|
pub struct UnitOutputWrite<C: PhantomConstGet<CpuConfig>> {
|
||||||
pub which: UnitOutRegNum<OutRegNumWidth>,
|
pub which: UnitOutRegNum<C>,
|
||||||
pub value: PRegValue,
|
pub value: PRegValue,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -300,21 +376,21 @@ impl<ExtraOut: Type> UnitResult<ExtraOut> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[hdl]
|
#[hdl(no_static)]
|
||||||
pub struct UnitOutput<OutRegNumWidth: Size, ExtraOut> {
|
pub struct UnitOutput<C: PhantomConstGet<CpuConfig>, ExtraOut> {
|
||||||
pub which: UnitOutRegNum<OutRegNumWidth>,
|
pub which: UnitOutRegNum<C>,
|
||||||
pub result: UnitResult<ExtraOut>,
|
pub result: UnitResult<ExtraOut>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<OutRegNumWidth: Size, ExtraOut: Type> UnitOutput<OutRegNumWidth, ExtraOut> {
|
impl<C: PhantomConstCpuConfig, ExtraOut: Type> UnitOutput<C, ExtraOut> {
|
||||||
pub fn extra_out_ty(self) -> ExtraOut {
|
pub fn extra_out_ty(self) -> ExtraOut {
|
||||||
self.result.extra_out_ty()
|
self.result.extra_out_ty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[hdl(cmp_eq)]
|
#[hdl(cmp_eq, no_static)]
|
||||||
pub struct UnitCancelInput<OutRegNumWidth: Size> {
|
pub struct UnitCancelInput<C: PhantomConstGet<CpuConfig>> {
|
||||||
pub which: UnitOutRegNum<OutRegNumWidth>,
|
pub which: UnitOutRegNum<C>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait UnitTrait:
|
pub trait UnitTrait:
|
||||||
|
|
@ -332,7 +408,9 @@ pub trait UnitTrait:
|
||||||
|
|
||||||
fn extract_mop(
|
fn extract_mop(
|
||||||
&self,
|
&self,
|
||||||
mop: Expr<RenamedMOp<UnitOutRegNum<DynSize>, DynSize>>,
|
mop: Expr<
|
||||||
|
RenamedMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, PRegNum<PhantomConst<CpuConfig>>>,
|
||||||
|
>,
|
||||||
) -> Expr<HdlOption<Self::MOp>>;
|
) -> Expr<HdlOption<Self::MOp>>;
|
||||||
|
|
||||||
fn module(&self) -> Interned<Module<Self::Type>>;
|
fn module(&self) -> Interned<Module<Self::Type>>;
|
||||||
|
|
@ -340,7 +418,7 @@ pub trait UnitTrait:
|
||||||
fn unit_to_reg_alloc(
|
fn unit_to_reg_alloc(
|
||||||
&self,
|
&self,
|
||||||
this: Expr<Self::Type>,
|
this: Expr<Self::Type>,
|
||||||
) -> Expr<UnitToRegAlloc<Self::MOp, Self::ExtraOut, DynSize, DynSize, DynSize>>;
|
) -> Expr<UnitToRegAlloc<PhantomConst<CpuConfig>, Self::MOp, Self::ExtraOut>>;
|
||||||
|
|
||||||
fn cd(&self, this: Expr<Self::Type>) -> Expr<ClockDomain>;
|
fn cd(&self, this: Expr<Self::Type>) -> Expr<ClockDomain>;
|
||||||
|
|
||||||
|
|
@ -390,7 +468,9 @@ impl UnitTrait for DynUnit {
|
||||||
|
|
||||||
fn extract_mop(
|
fn extract_mop(
|
||||||
&self,
|
&self,
|
||||||
mop: Expr<RenamedMOp<UnitOutRegNum<DynSize>, DynSize>>,
|
mop: Expr<
|
||||||
|
RenamedMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, PRegNum<PhantomConst<CpuConfig>>>,
|
||||||
|
>,
|
||||||
) -> Expr<HdlOption<Self::MOp>> {
|
) -> Expr<HdlOption<Self::MOp>> {
|
||||||
self.unit.extract_mop(mop)
|
self.unit.extract_mop(mop)
|
||||||
}
|
}
|
||||||
|
|
@ -402,7 +482,7 @@ impl UnitTrait for DynUnit {
|
||||||
fn unit_to_reg_alloc(
|
fn unit_to_reg_alloc(
|
||||||
&self,
|
&self,
|
||||||
this: Expr<Self::Type>,
|
this: Expr<Self::Type>,
|
||||||
) -> Expr<UnitToRegAlloc<Self::MOp, Self::ExtraOut, DynSize, DynSize, DynSize>> {
|
) -> Expr<UnitToRegAlloc<PhantomConst<CpuConfig>, Self::MOp, Self::ExtraOut>> {
|
||||||
self.unit.unit_to_reg_alloc(this)
|
self.unit.unit_to_reg_alloc(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -445,7 +525,9 @@ impl<T: UnitTrait + Clone + std::hash::Hash + Eq> UnitTrait for DynUnitWrapper<T
|
||||||
|
|
||||||
fn extract_mop(
|
fn extract_mop(
|
||||||
&self,
|
&self,
|
||||||
mop: Expr<RenamedMOp<UnitOutRegNum<DynSize>, DynSize>>,
|
mop: Expr<
|
||||||
|
RenamedMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, PRegNum<PhantomConst<CpuConfig>>>,
|
||||||
|
>,
|
||||||
) -> Expr<HdlOption<Self::MOp>> {
|
) -> Expr<HdlOption<Self::MOp>> {
|
||||||
Expr::from_enum(Expr::as_enum(self.0.extract_mop(mop)))
|
Expr::from_enum(Expr::as_enum(self.0.extract_mop(mop)))
|
||||||
}
|
}
|
||||||
|
|
@ -457,7 +539,7 @@ impl<T: UnitTrait + Clone + std::hash::Hash + Eq> UnitTrait for DynUnitWrapper<T
|
||||||
fn unit_to_reg_alloc(
|
fn unit_to_reg_alloc(
|
||||||
&self,
|
&self,
|
||||||
this: Expr<Self::Type>,
|
this: Expr<Self::Type>,
|
||||||
) -> Expr<UnitToRegAlloc<Self::MOp, Self::ExtraOut, DynSize, DynSize, DynSize>> {
|
) -> Expr<UnitToRegAlloc<PhantomConst<CpuConfig>, Self::MOp, Self::ExtraOut>> {
|
||||||
Expr::from_bundle(Expr::as_bundle(
|
Expr::from_bundle(Expr::as_bundle(
|
||||||
self.0.unit_to_reg_alloc(Expr::from_bundle(this)),
|
self.0.unit_to_reg_alloc(Expr::from_bundle(this)),
|
||||||
))
|
))
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ use crate::{
|
||||||
config::CpuConfig,
|
config::CpuConfig,
|
||||||
instruction::{
|
instruction::{
|
||||||
AddSubMOp, AluBranchMOp, AluCommonMOp, BranchMOp, COMMON_MOP_SRC_LEN, CommonMOpDefaultImm,
|
AddSubMOp, AluBranchMOp, AluCommonMOp, BranchMOp, COMMON_MOP_SRC_LEN, CommonMOpDefaultImm,
|
||||||
CompareMOp, LogicalFlagsMOp, LogicalMOp, MOpTrait, OutputIntegerMode, ReadSpecialMOp,
|
CompareMOp, LogicalFlagsMOp, LogicalMOp, MOpTrait, OutputIntegerMode, PRegNum,
|
||||||
RenamedMOp, ShiftRotateMOp, UnitOutRegNum,
|
ReadSpecialMOp, RenamedMOp, ShiftRotateMOp, UnitOutRegNum,
|
||||||
},
|
},
|
||||||
register::{
|
register::{
|
||||||
FlagsMode, PRegFlagsPowerISA, PRegFlagsPowerISAView, PRegFlagsViewTrait, PRegFlagsX86,
|
FlagsMode, PRegFlagsPowerISA, PRegFlagsPowerISAView, PRegFlagsViewTrait, PRegFlagsX86,
|
||||||
|
|
@ -19,16 +19,19 @@ use crate::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use fayalite::{
|
use fayalite::{
|
||||||
intern::{Intern, Interned},
|
intern::Interned, module::wire_with_loc, prelude::*, util::ready_valid::ReadyValid,
|
||||||
module::wire_with_loc,
|
|
||||||
prelude::*,
|
|
||||||
util::ready_valid::ReadyValid,
|
|
||||||
};
|
};
|
||||||
use std::{collections::HashMap, ops::RangeTo};
|
use std::{collections::HashMap, ops::RangeTo};
|
||||||
|
|
||||||
#[hdl]
|
#[hdl]
|
||||||
fn add_sub<SrcCount: KnownSize>(
|
fn add_sub<SrcCount: KnownSize>(
|
||||||
mop: Expr<AddSubMOp<UnitOutRegNum<DynSize>, DynSize, SrcCount>>,
|
mop: Expr<
|
||||||
|
AddSubMOp<
|
||||||
|
UnitOutRegNum<PhantomConst<CpuConfig>>,
|
||||||
|
PRegNum<PhantomConst<CpuConfig>>,
|
||||||
|
SrcCount,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
pc: Expr<UInt<64>>,
|
pc: Expr<UInt<64>>,
|
||||||
flags_mode: Expr<FlagsMode>,
|
flags_mode: Expr<FlagsMode>,
|
||||||
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
|
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
|
||||||
|
|
@ -245,7 +248,9 @@ fn add_sub<SrcCount: KnownSize>(
|
||||||
|
|
||||||
#[hdl]
|
#[hdl]
|
||||||
fn logical_flags(
|
fn logical_flags(
|
||||||
mop: Expr<LogicalFlagsMOp<UnitOutRegNum<DynSize>, DynSize>>,
|
mop: Expr<
|
||||||
|
LogicalFlagsMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, PRegNum<PhantomConst<CpuConfig>>>,
|
||||||
|
>,
|
||||||
flags_mode: Expr<FlagsMode>,
|
flags_mode: Expr<FlagsMode>,
|
||||||
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
|
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
|
||||||
) -> Expr<UnitResultCompleted<()>> {
|
) -> Expr<UnitResultCompleted<()>> {
|
||||||
|
|
@ -259,7 +264,13 @@ fn logical_flags(
|
||||||
|
|
||||||
#[hdl]
|
#[hdl]
|
||||||
fn logical(
|
fn logical(
|
||||||
mop: Expr<LogicalMOp<UnitOutRegNum<DynSize>, DynSize, ConstUsize<2>>>,
|
mop: Expr<
|
||||||
|
LogicalMOp<
|
||||||
|
UnitOutRegNum<PhantomConst<CpuConfig>>,
|
||||||
|
PRegNum<PhantomConst<CpuConfig>>,
|
||||||
|
ConstUsize<2>,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
flags_mode: Expr<FlagsMode>,
|
flags_mode: Expr<FlagsMode>,
|
||||||
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
|
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
|
||||||
) -> Expr<UnitResultCompleted<()>> {
|
) -> Expr<UnitResultCompleted<()>> {
|
||||||
|
|
@ -273,7 +284,13 @@ fn logical(
|
||||||
|
|
||||||
#[hdl]
|
#[hdl]
|
||||||
fn logical_i(
|
fn logical_i(
|
||||||
mop: Expr<LogicalMOp<UnitOutRegNum<DynSize>, DynSize, ConstUsize<1>>>,
|
mop: Expr<
|
||||||
|
LogicalMOp<
|
||||||
|
UnitOutRegNum<PhantomConst<CpuConfig>>,
|
||||||
|
PRegNum<PhantomConst<CpuConfig>>,
|
||||||
|
ConstUsize<1>,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
flags_mode: Expr<FlagsMode>,
|
flags_mode: Expr<FlagsMode>,
|
||||||
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
|
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
|
||||||
) -> Expr<UnitResultCompleted<()>> {
|
) -> Expr<UnitResultCompleted<()>> {
|
||||||
|
|
@ -287,7 +304,9 @@ fn logical_i(
|
||||||
|
|
||||||
#[hdl]
|
#[hdl]
|
||||||
fn shift_rotate(
|
fn shift_rotate(
|
||||||
mop: Expr<ShiftRotateMOp<UnitOutRegNum<DynSize>, DynSize>>,
|
mop: Expr<
|
||||||
|
ShiftRotateMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, PRegNum<PhantomConst<CpuConfig>>>,
|
||||||
|
>,
|
||||||
flags_mode: Expr<FlagsMode>,
|
flags_mode: Expr<FlagsMode>,
|
||||||
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
|
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
|
||||||
) -> Expr<UnitResultCompleted<()>> {
|
) -> Expr<UnitResultCompleted<()>> {
|
||||||
|
|
@ -301,7 +320,13 @@ fn shift_rotate(
|
||||||
|
|
||||||
#[hdl]
|
#[hdl]
|
||||||
fn compare<SrcCount: KnownSize>(
|
fn compare<SrcCount: KnownSize>(
|
||||||
mop: Expr<CompareMOp<UnitOutRegNum<DynSize>, DynSize, SrcCount>>,
|
mop: Expr<
|
||||||
|
CompareMOp<
|
||||||
|
UnitOutRegNum<PhantomConst<CpuConfig>>,
|
||||||
|
PRegNum<PhantomConst<CpuConfig>>,
|
||||||
|
SrcCount,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
flags_mode: Expr<FlagsMode>,
|
flags_mode: Expr<FlagsMode>,
|
||||||
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
|
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
|
||||||
) -> Expr<UnitResultCompleted<()>> {
|
) -> Expr<UnitResultCompleted<()>> {
|
||||||
|
|
@ -315,7 +340,13 @@ fn compare<SrcCount: KnownSize>(
|
||||||
|
|
||||||
#[hdl]
|
#[hdl]
|
||||||
fn branch<SrcCount: KnownSize>(
|
fn branch<SrcCount: KnownSize>(
|
||||||
mop: Expr<BranchMOp<UnitOutRegNum<DynSize>, DynSize, SrcCount>>,
|
mop: Expr<
|
||||||
|
BranchMOp<
|
||||||
|
UnitOutRegNum<PhantomConst<CpuConfig>>,
|
||||||
|
PRegNum<PhantomConst<CpuConfig>>,
|
||||||
|
SrcCount,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
pc: Expr<UInt<64>>,
|
pc: Expr<UInt<64>>,
|
||||||
flags_mode: Expr<FlagsMode>,
|
flags_mode: Expr<FlagsMode>,
|
||||||
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
|
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
|
||||||
|
|
@ -330,7 +361,9 @@ fn branch<SrcCount: KnownSize>(
|
||||||
|
|
||||||
#[hdl]
|
#[hdl]
|
||||||
fn read_special(
|
fn read_special(
|
||||||
mop: Expr<ReadSpecialMOp<UnitOutRegNum<DynSize>, DynSize>>,
|
mop: Expr<
|
||||||
|
ReadSpecialMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, PRegNum<PhantomConst<CpuConfig>>>,
|
||||||
|
>,
|
||||||
pc: Expr<UInt<64>>,
|
pc: Expr<UInt<64>>,
|
||||||
flags_mode: Expr<FlagsMode>,
|
flags_mode: Expr<FlagsMode>,
|
||||||
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
|
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
|
||||||
|
|
@ -344,20 +377,15 @@ fn read_special(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[hdl_module]
|
#[hdl_module]
|
||||||
pub fn alu_branch(config: &CpuConfig, unit_index: usize) {
|
pub fn alu_branch(config: PhantomConst<CpuConfig>, unit_index: usize) {
|
||||||
#[hdl]
|
#[hdl]
|
||||||
let cd: ClockDomain = m.input();
|
let cd: ClockDomain = m.input();
|
||||||
#[hdl]
|
#[hdl]
|
||||||
let unit_to_reg_alloc: UnitToRegAlloc<
|
let unit_to_reg_alloc: UnitToRegAlloc<
|
||||||
AluBranchMOp<UnitOutRegNum<DynSize>, DynSize>,
|
PhantomConst<CpuConfig>,
|
||||||
|
AluBranchMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, PRegNum<PhantomConst<CpuConfig>>>,
|
||||||
(),
|
(),
|
||||||
DynSize,
|
> = m.output(UnitToRegAlloc[config][AluBranchMOp[UnitOutRegNum[config]][PRegNum[config]]][()]);
|
||||||
DynSize,
|
|
||||||
DynSize,
|
|
||||||
> = m.output(config.unit_to_reg_alloc(
|
|
||||||
AluBranchMOp[config.unit_out_reg_num()][config.p_reg_num_width()],
|
|
||||||
(),
|
|
||||||
));
|
|
||||||
#[hdl]
|
#[hdl]
|
||||||
let global_state: GlobalState = m.input();
|
let global_state: GlobalState = m.input();
|
||||||
|
|
||||||
|
|
@ -375,10 +403,11 @@ pub fn alu_branch(config: &CpuConfig, unit_index: usize) {
|
||||||
#[hdl]
|
#[hdl]
|
||||||
if let HdlSome(execute_start) = ReadyValid::firing_data(unit_base.execute_start) {
|
if let HdlSome(execute_start) = ReadyValid::firing_data(unit_base.execute_start) {
|
||||||
#[hdl]
|
#[hdl]
|
||||||
let ExecuteStart::<_> {
|
let ExecuteStart::<_, _> {
|
||||||
mop,
|
mop,
|
||||||
pc,
|
pc,
|
||||||
src_values,
|
src_values,
|
||||||
|
config: _,
|
||||||
} = execute_start;
|
} = execute_start;
|
||||||
#[hdl]
|
#[hdl]
|
||||||
match mop {
|
match mop {
|
||||||
|
|
@ -580,14 +609,14 @@ pub fn alu_branch(config: &CpuConfig, unit_index: usize) {
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct AluBranch {
|
pub struct AluBranch {
|
||||||
config: Interned<CpuConfig>,
|
config: PhantomConst<CpuConfig>,
|
||||||
module: Interned<Module<alu_branch>>,
|
module: Interned<Module<alu_branch>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AluBranch {
|
impl AluBranch {
|
||||||
pub fn new(config: &CpuConfig, unit_index: usize) -> Self {
|
pub fn new(config: PhantomConst<CpuConfig>, unit_index: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
config: config.intern(),
|
config,
|
||||||
module: alu_branch(config, unit_index),
|
module: alu_branch(config, unit_index),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -596,7 +625,8 @@ impl AluBranch {
|
||||||
impl UnitTrait for AluBranch {
|
impl UnitTrait for AluBranch {
|
||||||
type Type = alu_branch;
|
type Type = alu_branch;
|
||||||
type ExtraOut = ();
|
type ExtraOut = ();
|
||||||
type MOp = AluBranchMOp<UnitOutRegNum<DynSize>, DynSize>;
|
type MOp =
|
||||||
|
AluBranchMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, PRegNum<PhantomConst<CpuConfig>>>;
|
||||||
|
|
||||||
fn ty(&self) -> Self::Type {
|
fn ty(&self) -> Self::Type {
|
||||||
self.module.io_ty()
|
self.module.io_ty()
|
||||||
|
|
@ -616,7 +646,9 @@ impl UnitTrait for AluBranch {
|
||||||
|
|
||||||
fn extract_mop(
|
fn extract_mop(
|
||||||
&self,
|
&self,
|
||||||
mop: Expr<RenamedMOp<UnitOutRegNum<DynSize>, DynSize>>,
|
mop: Expr<
|
||||||
|
RenamedMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, PRegNum<PhantomConst<CpuConfig>>>,
|
||||||
|
>,
|
||||||
) -> Expr<HdlOption<Self::MOp>> {
|
) -> Expr<HdlOption<Self::MOp>> {
|
||||||
UnitMOp::alu_branch_mop(mop)
|
UnitMOp::alu_branch_mop(mop)
|
||||||
}
|
}
|
||||||
|
|
@ -628,7 +660,7 @@ impl UnitTrait for AluBranch {
|
||||||
fn unit_to_reg_alloc(
|
fn unit_to_reg_alloc(
|
||||||
&self,
|
&self,
|
||||||
this: Expr<Self::Type>,
|
this: Expr<Self::Type>,
|
||||||
) -> Expr<UnitToRegAlloc<Self::MOp, Self::ExtraOut, DynSize, DynSize, DynSize>> {
|
) -> Expr<UnitToRegAlloc<PhantomConst<CpuConfig>, Self::MOp, Self::ExtraOut>> {
|
||||||
this.unit_to_reg_alloc
|
this.unit_to_reg_alloc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// See Notices.txt for copyright information
|
// See Notices.txt for copyright information
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::CpuConfig,
|
config::{CpuConfig, CpuConfigUnitCount, PhantomConstCpuConfig},
|
||||||
instruction::{COMMON_MOP_SRC_LEN, MOpTrait, PRegNum, UnitNum, UnitOutRegNum},
|
instruction::{COMMON_MOP_SRC_LEN, MOpTrait, PRegNum, UnitNum, UnitOutRegNum},
|
||||||
register::PRegValue,
|
register::PRegValue,
|
||||||
unit::{UnitCancelInput, UnitOutput, UnitOutputWrite},
|
unit::{UnitCancelInput, UnitOutput, UnitOutputWrite},
|
||||||
|
|
@ -15,13 +15,11 @@ use fayalite::{
|
||||||
ty::StaticType,
|
ty::StaticType,
|
||||||
util::ready_valid::ReadyValid,
|
util::ready_valid::ReadyValid,
|
||||||
};
|
};
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
#[hdl]
|
#[hdl(no_static)]
|
||||||
pub struct UnitForwardingInfo<UnitNumWidth: Size, OutRegNumWidth: Size, UnitCount: Size> {
|
pub struct UnitForwardingInfo<C: PhantomConstGet<CpuConfig>> {
|
||||||
pub unit_output_writes: ArrayType<HdlOption<UnitOutputWrite<OutRegNumWidth>>, UnitCount>,
|
pub unit_output_writes: ArrayType<HdlOption<UnitOutputWrite<C>>, CpuConfigUnitCount<C>>,
|
||||||
pub unit_reg_frees: ArrayType<HdlOption<UnitOutRegNum<OutRegNumWidth>>, UnitCount>,
|
pub unit_reg_frees: ArrayType<HdlOption<UnitOutRegNum<C>>, CpuConfigUnitCount<C>>,
|
||||||
pub _phantom: PhantomData<UnitNumWidth>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[hdl]
|
#[hdl]
|
||||||
|
|
@ -30,26 +28,18 @@ pub struct UnitInput<MOp: Type> {
|
||||||
pub pc: UInt<64>,
|
pub pc: UInt<64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[hdl]
|
#[hdl(no_static)]
|
||||||
pub struct UnitToRegAlloc<
|
pub struct UnitToRegAlloc<C: PhantomConstGet<CpuConfig>, MOp: Type, ExtraOut: Type> {
|
||||||
MOp: Type,
|
|
||||||
ExtraOut: Type,
|
|
||||||
UnitNumWidth: Size,
|
|
||||||
OutRegNumWidth: Size,
|
|
||||||
UnitCount: Size,
|
|
||||||
> {
|
|
||||||
#[hdl(flip)]
|
#[hdl(flip)]
|
||||||
pub unit_forwarding_info: UnitForwardingInfo<UnitNumWidth, OutRegNumWidth, UnitCount>,
|
pub unit_forwarding_info: UnitForwardingInfo<C>,
|
||||||
#[hdl(flip)]
|
#[hdl(flip)]
|
||||||
pub input: ReadyValid<UnitInput<MOp>>,
|
pub input: ReadyValid<UnitInput<MOp>>,
|
||||||
#[hdl(flip)]
|
#[hdl(flip)]
|
||||||
pub cancel_input: HdlOption<UnitCancelInput<OutRegNumWidth>>,
|
pub cancel_input: HdlOption<UnitCancelInput<C>>,
|
||||||
pub output: HdlOption<UnitOutput<OutRegNumWidth, ExtraOut>>,
|
pub output: HdlOption<UnitOutput<C, ExtraOut>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<MOp: Type, ExtraOut: Type, UnitNumWidth: Size, OutRegNumWidth: Size, UnitCount: Size>
|
impl<C: PhantomConstCpuConfig, MOp: Type, ExtraOut: Type> UnitToRegAlloc<C, MOp, ExtraOut> {
|
||||||
UnitToRegAlloc<MOp, ExtraOut, UnitNumWidth, OutRegNumWidth, UnitCount>
|
|
||||||
{
|
|
||||||
pub fn mop_ty(self) -> MOp {
|
pub fn mop_ty(self) -> MOp {
|
||||||
self.input.data.HdlSome.mop
|
self.input.data.HdlSome.mop
|
||||||
}
|
}
|
||||||
|
|
@ -58,16 +48,20 @@ impl<MOp: Type, ExtraOut: Type, UnitNumWidth: Size, OutRegNumWidth: Size, UnitCo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[hdl]
|
#[hdl(no_static)]
|
||||||
pub struct ExecuteStart<MOp: Type + MOpTrait<DestReg = UnitOutRegNum<DynSize>>> {
|
pub struct ExecuteStart<
|
||||||
|
C: PhantomConstGet<CpuConfig>,
|
||||||
|
MOp: Type + MOpTrait<DestReg = UnitOutRegNum<C>>,
|
||||||
|
> {
|
||||||
pub mop: MOp,
|
pub mop: MOp,
|
||||||
pub pc: UInt<64>,
|
pub pc: UInt<64>,
|
||||||
pub src_values: Array<PRegValue, { COMMON_MOP_SRC_LEN }>,
|
pub src_values: Array<PRegValue, { COMMON_MOP_SRC_LEN }>,
|
||||||
|
pub config: C,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[hdl]
|
#[hdl(no_static)]
|
||||||
pub struct ExecuteEnd<OutRegNumWidth: Size, ExtraOut> {
|
pub struct ExecuteEnd<C: PhantomConstGet<CpuConfig>, ExtraOut> {
|
||||||
pub unit_output: UnitOutput<OutRegNumWidth, ExtraOut>,
|
pub unit_output: UnitOutput<C, ExtraOut>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[hdl]
|
#[hdl]
|
||||||
|
|
@ -240,10 +234,14 @@ impl InFlightOpsSummary<DynSize> {
|
||||||
|
|
||||||
#[hdl_module]
|
#[hdl_module]
|
||||||
pub fn unit_base<
|
pub fn unit_base<
|
||||||
MOp: Type + MOpTrait<DestReg = UnitOutRegNum<DynSize>, SrcRegWidth = DynSize>,
|
MOp: Type
|
||||||
|
+ MOpTrait<
|
||||||
|
DestReg = UnitOutRegNum<PhantomConst<CpuConfig>>,
|
||||||
|
SrcReg = PRegNum<PhantomConst<CpuConfig>>,
|
||||||
|
>,
|
||||||
ExtraOut: Type,
|
ExtraOut: Type,
|
||||||
>(
|
>(
|
||||||
config: &CpuConfig,
|
config: PhantomConst<CpuConfig>,
|
||||||
unit_index: usize,
|
unit_index: usize,
|
||||||
mop_ty: MOp,
|
mop_ty: MOp,
|
||||||
extra_out_ty: ExtraOut,
|
extra_out_ty: ExtraOut,
|
||||||
|
|
@ -251,17 +249,18 @@ pub fn unit_base<
|
||||||
#[hdl]
|
#[hdl]
|
||||||
let cd: ClockDomain = m.input();
|
let cd: ClockDomain = m.input();
|
||||||
#[hdl]
|
#[hdl]
|
||||||
let unit_to_reg_alloc: UnitToRegAlloc<MOp, ExtraOut, DynSize, DynSize, DynSize> =
|
let unit_to_reg_alloc: UnitToRegAlloc<PhantomConst<CpuConfig>, MOp, ExtraOut> =
|
||||||
m.output(config.unit_to_reg_alloc(mop_ty, extra_out_ty));
|
m.output(UnitToRegAlloc[config][mop_ty][extra_out_ty]);
|
||||||
#[hdl]
|
#[hdl]
|
||||||
let execute_start: ReadyValid<ExecuteStart<MOp>> = m.output(ReadyValid[ExecuteStart[mop_ty]]);
|
let execute_start: ReadyValid<ExecuteStart<PhantomConst<CpuConfig>, MOp>> =
|
||||||
|
m.output(ReadyValid[ExecuteStart[config][mop_ty]]);
|
||||||
#[hdl]
|
#[hdl]
|
||||||
let execute_end: HdlOption<ExecuteEnd<DynSize, ExtraOut>> =
|
let execute_end: HdlOption<ExecuteEnd<PhantomConst<CpuConfig>, ExtraOut>> =
|
||||||
m.input(HdlOption[ExecuteEnd[config.out_reg_num_width][extra_out_ty]]);
|
m.input(HdlOption[ExecuteEnd[config][extra_out_ty]]);
|
||||||
|
|
||||||
connect(execute_start.data, execute_start.ty().data.HdlNone());
|
connect(execute_start.data, execute_start.ty().data.HdlNone());
|
||||||
|
|
||||||
let max_in_flight = config.unit_max_in_flight(unit_index).get();
|
let max_in_flight = config.get().unit_max_in_flight(unit_index).get();
|
||||||
let in_flight_op_ty = InFlightOp[mop_ty];
|
let in_flight_op_ty = InFlightOp[mop_ty];
|
||||||
#[hdl]
|
#[hdl]
|
||||||
let in_flight_ops = reg_builder()
|
let in_flight_ops = reg_builder()
|
||||||
|
|
@ -279,16 +278,15 @@ pub fn unit_base<
|
||||||
);
|
);
|
||||||
|
|
||||||
#[hdl]
|
#[hdl]
|
||||||
let UnitForwardingInfo::<_, _, _> {
|
let UnitForwardingInfo::<_> {
|
||||||
unit_output_writes,
|
unit_output_writes,
|
||||||
unit_reg_frees,
|
unit_reg_frees,
|
||||||
_phantom: _,
|
|
||||||
} = unit_to_reg_alloc.unit_forwarding_info;
|
} = unit_to_reg_alloc.unit_forwarding_info;
|
||||||
#[hdl]
|
#[hdl]
|
||||||
let read_src_regs = wire(mop_ty.src_regs_ty());
|
let read_src_regs = wire(mop_ty.src_regs_ty());
|
||||||
connect(
|
connect(
|
||||||
read_src_regs,
|
read_src_regs,
|
||||||
repeat(config.p_reg_num().const_zero().cast_to_bits(), ConstUsize),
|
repeat(PRegNum[config].const_zero(), ConstUsize),
|
||||||
);
|
);
|
||||||
#[hdl]
|
#[hdl]
|
||||||
let read_src_values = wire();
|
let read_src_values = wire();
|
||||||
|
|
@ -297,7 +295,7 @@ pub fn unit_base<
|
||||||
let input_src_regs = wire(mop_ty.src_regs_ty());
|
let input_src_regs = wire(mop_ty.src_regs_ty());
|
||||||
connect(
|
connect(
|
||||||
input_src_regs,
|
input_src_regs,
|
||||||
repeat(config.p_reg_num().const_zero().cast_to_bits(), ConstUsize),
|
repeat(PRegNum[config].const_zero(), ConstUsize),
|
||||||
);
|
);
|
||||||
#[hdl]
|
#[hdl]
|
||||||
let input_src_regs_valid = wire();
|
let input_src_regs_valid = wire();
|
||||||
|
|
@ -309,7 +307,7 @@ pub fn unit_base<
|
||||||
Bool,
|
Bool,
|
||||||
SourceLocation::caller(),
|
SourceLocation::caller(),
|
||||||
);
|
);
|
||||||
mem.depth(1 << config.out_reg_num_width);
|
mem.depth(1 << config.get().out_reg_num_width);
|
||||||
mem
|
mem
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
@ -319,11 +317,11 @@ pub fn unit_base<
|
||||||
PRegValue,
|
PRegValue,
|
||||||
SourceLocation::caller(),
|
SourceLocation::caller(),
|
||||||
);
|
);
|
||||||
unit_output_regs.depth(1 << config.out_reg_num_width);
|
unit_output_regs.depth(1 << config.get().out_reg_num_width);
|
||||||
|
|
||||||
for src_index in 0..COMMON_MOP_SRC_LEN {
|
for src_index in 0..COMMON_MOP_SRC_LEN {
|
||||||
let read_port = unit_output_regs.new_read_port();
|
let read_port = unit_output_regs.new_read_port();
|
||||||
let p_reg_num = read_src_regs[src_index].cast_bits_to(config.p_reg_num());
|
let p_reg_num = read_src_regs[src_index];
|
||||||
connect_any(read_port.addr, p_reg_num.unit_out_reg.value);
|
connect_any(read_port.addr, p_reg_num.unit_out_reg.value);
|
||||||
connect(read_port.en, false);
|
connect(read_port.en, false);
|
||||||
connect(read_port.clk, cd.clk);
|
connect(read_port.clk, cd.clk);
|
||||||
|
|
@ -336,7 +334,7 @@ pub fn unit_base<
|
||||||
|
|
||||||
for src_index in 0..COMMON_MOP_SRC_LEN {
|
for src_index in 0..COMMON_MOP_SRC_LEN {
|
||||||
let read_port = unit_output_regs_valid[unit_index].new_read_port();
|
let read_port = unit_output_regs_valid[unit_index].new_read_port();
|
||||||
let p_reg_num = input_src_regs[src_index].cast_bits_to(config.p_reg_num());
|
let p_reg_num = input_src_regs[src_index];
|
||||||
connect_any(read_port.addr, p_reg_num.unit_out_reg.value);
|
connect_any(read_port.addr, p_reg_num.unit_out_reg.value);
|
||||||
connect(read_port.en, false);
|
connect(read_port.en, false);
|
||||||
connect(read_port.clk, cd.clk);
|
connect(read_port.clk, cd.clk);
|
||||||
|
|
@ -367,13 +365,13 @@ pub fn unit_base<
|
||||||
connect_any(ready_write_port.addr, unit_output_write.which.value);
|
connect_any(ready_write_port.addr, unit_output_write.which.value);
|
||||||
connect(ready_write_port.en, true);
|
connect(ready_write_port.en, true);
|
||||||
let p_reg_num = #[hdl]
|
let p_reg_num = #[hdl]
|
||||||
PRegNum::<_, _> {
|
PRegNum::<_> {
|
||||||
unit_num: config.unit_num().from_index(unit_index),
|
unit_num: UnitNum[config].from_index(unit_index),
|
||||||
unit_out_reg: unit_output_write.which,
|
unit_out_reg: unit_output_write.which,
|
||||||
};
|
};
|
||||||
for src_index in 0..COMMON_MOP_SRC_LEN {
|
for src_index in 0..COMMON_MOP_SRC_LEN {
|
||||||
#[hdl]
|
#[hdl]
|
||||||
if input_src_regs[src_index].cmp_eq(p_reg_num.cast_to_bits()) {
|
if input_src_regs[src_index].cmp_eq(p_reg_num) {
|
||||||
connect(input_src_regs_valid[src_index], true);
|
connect(input_src_regs_valid[src_index], true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -399,10 +397,11 @@ pub fn unit_base<
|
||||||
execute_start.data,
|
execute_start.data,
|
||||||
HdlSome(
|
HdlSome(
|
||||||
#[hdl]
|
#[hdl]
|
||||||
ExecuteStart::<_> {
|
ExecuteStart::<_, _> {
|
||||||
mop: in_flight_op.mop,
|
mop: in_flight_op.mop,
|
||||||
pc: in_flight_op.pc,
|
pc: in_flight_op.pc,
|
||||||
src_values: read_src_values,
|
src_values: read_src_values,
|
||||||
|
config,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -425,7 +424,7 @@ pub fn unit_base<
|
||||||
let input_mop_src_regs = wire(mop_ty.src_regs_ty());
|
let input_mop_src_regs = wire(mop_ty.src_regs_ty());
|
||||||
connect(
|
connect(
|
||||||
input_mop_src_regs,
|
input_mop_src_regs,
|
||||||
repeat(config.p_reg_num().const_zero().cast_to_bits(), ConstUsize),
|
repeat(PRegNum[config].const_zero(), ConstUsize),
|
||||||
);
|
);
|
||||||
MOp::connect_src_regs(mop, input_mop_src_regs);
|
MOp::connect_src_regs(mop, input_mop_src_regs);
|
||||||
let src_ready_flags = wire_with_loc(
|
let src_ready_flags = wire_with_loc(
|
||||||
|
|
@ -495,10 +494,7 @@ pub fn unit_base<
|
||||||
SourceLocation::caller(),
|
SourceLocation::caller(),
|
||||||
mop_ty.src_regs_ty(),
|
mop_ty.src_regs_ty(),
|
||||||
);
|
);
|
||||||
connect(
|
connect(src_regs, repeat(PRegNum[config].const_zero(), ConstUsize));
|
||||||
src_regs,
|
|
||||||
repeat(config.p_reg_num().const_zero().cast_to_bits(), ConstUsize),
|
|
||||||
);
|
|
||||||
MOp::connect_src_regs(mop, src_regs);
|
MOp::connect_src_regs(mop, src_regs);
|
||||||
|
|
||||||
#[hdl]
|
#[hdl]
|
||||||
|
|
@ -521,13 +517,13 @@ pub fn unit_base<
|
||||||
value: _,
|
value: _,
|
||||||
} = unit_output_write;
|
} = unit_output_write;
|
||||||
let p_reg_num = #[hdl]
|
let p_reg_num = #[hdl]
|
||||||
PRegNum::<_, _> {
|
PRegNum::<_> {
|
||||||
unit_num: config.unit_num().from_index(unit_index),
|
unit_num: UnitNum[config].from_index(unit_index),
|
||||||
unit_out_reg,
|
unit_out_reg,
|
||||||
};
|
};
|
||||||
for src_index in 0..COMMON_MOP_SRC_LEN {
|
for src_index in 0..COMMON_MOP_SRC_LEN {
|
||||||
#[hdl]
|
#[hdl]
|
||||||
if p_reg_num.cast_to_bits().cmp_eq(src_regs[src_index]) {
|
if p_reg_num.cmp_eq(src_regs[src_index]) {
|
||||||
connect(
|
connect(
|
||||||
in_flight_op_next_src_ready_flags[in_flight_op_index][src_index],
|
in_flight_op_next_src_ready_flags[in_flight_op_index][src_index],
|
||||||
true,
|
true,
|
||||||
|
|
|
||||||
|
|
@ -280,3 +280,33 @@ impl<T: Type, N: Size> Rotate<usize> for SimValue<ArrayType<T, N>> {
|
||||||
retval
|
retval
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[hdl]
|
||||||
|
pub struct LFSR31 {
|
||||||
|
// MSB is always zero, 32 bits makes it easier to manipulate
|
||||||
|
state: UInt<32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LFSR31 {
|
||||||
|
#[hdl]
|
||||||
|
pub fn new() -> SimValue<Self> {
|
||||||
|
#[hdl(sim)]
|
||||||
|
Self { state: 1u32 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LFSR31 {
|
||||||
|
pub fn next_sim(this: &mut SimValue<Self>) -> u32 {
|
||||||
|
let state = this.state.as_int();
|
||||||
|
let state = if state == 0 {
|
||||||
|
1u32
|
||||||
|
} else {
|
||||||
|
// a maximal-length 31-bit LFSR
|
||||||
|
let lsb = ((state >> 30) ^ (state >> 27)) & 1;
|
||||||
|
let msb = (state << 1) & ((1 << 31) - 1);
|
||||||
|
lsb | msb
|
||||||
|
};
|
||||||
|
*this.state = state.into();
|
||||||
|
state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
75480
crates/cpu/tests/expected/rename_execute_retire_fibonacci_combinatorial.vcd
generated
Normal file
75480
crates/cpu/tests/expected/rename_execute_retire_fibonacci_combinatorial.vcd
generated
Normal file
File diff suppressed because it is too large
Load diff
86043
crates/cpu/tests/expected/rename_execute_retire_fibonacci_non_combinatorial.vcd
generated
Normal file
86043
crates/cpu/tests/expected/rename_execute_retire_fibonacci_non_combinatorial.vcd
generated
Normal file
File diff suppressed because it is too large
Load diff
105609
crates/cpu/tests/expected/rename_execute_retire_head_n1.vcd
generated
Normal file
105609
crates/cpu/tests/expected/rename_execute_retire_head_n1.vcd
generated
Normal file
File diff suppressed because it is too large
Load diff
184771
crates/cpu/tests/expected/rename_execute_retire_save_restore_gprs.vcd
generated
Normal file
184771
crates/cpu/tests/expected/rename_execute_retire_save_restore_gprs.vcd
generated
Normal file
File diff suppressed because it is too large
Load diff
118860
crates/cpu/tests/expected/rename_execute_retire_slow_loop.vcd
generated
Normal file
118860
crates/cpu/tests/expected/rename_execute_retire_slow_loop.vcd
generated
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1163,13 +1163,7 @@ impl MockExecuteState {
|
||||||
id: &insn.id,
|
id: &insn.id,
|
||||||
next_pc,
|
next_pc,
|
||||||
call_stack_op: mock_insn.call_stack_op(pc),
|
call_stack_op: mock_insn.call_stack_op(pc),
|
||||||
cond_br_taken: if let Some(cond_br_taken) = cond_br_taken {
|
cond_br_taken,
|
||||||
#[hdl(sim)]
|
|
||||||
HdlSome(cond_br_taken)
|
|
||||||
} else {
|
|
||||||
#[hdl(sim)]
|
|
||||||
HdlNone()
|
|
||||||
},
|
|
||||||
config: self.config,
|
config: self.config,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
// See Notices.txt for copyright information
|
// See Notices.txt for copyright information
|
||||||
|
#![cfg(todo)]
|
||||||
|
|
||||||
use cpu::{
|
use cpu::{
|
||||||
config::{CpuConfig, UnitConfig},
|
config::{CpuConfig, UnitConfig},
|
||||||
|
|
|
||||||
4605
crates/cpu/tests/rename_execute_retire.rs
Normal file
4605
crates/cpu/tests/rename_execute_retire.rs
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -152,16 +152,7 @@ fn test_decode_insn() {
|
||||||
} in test_cases::test_cases()
|
} in test_cases::test_cases()
|
||||||
{
|
{
|
||||||
sim.write(sim.io().first_input, first_input);
|
sim.write(sim.io().first_input, first_input);
|
||||||
sim.write(
|
sim.write(sim.io().second_input, second_input);
|
||||||
sim.io().second_input,
|
|
||||||
if let Some(v) = second_input {
|
|
||||||
#[hdl(sim)]
|
|
||||||
HdlSome(v)
|
|
||||||
} else {
|
|
||||||
#[hdl(sim)]
|
|
||||||
HdlNone()
|
|
||||||
},
|
|
||||||
);
|
|
||||||
sim.advance_time(SimDuration::from_micros(1));
|
sim.advance_time(SimDuration::from_micros(1));
|
||||||
let second_input_used = sim.read_bool(sim.io().second_input_used);
|
let second_input_used = sim.read_bool(sim.io().second_input_used);
|
||||||
let is_illegal = sim.read_bool(sim.io().is_illegal);
|
let is_illegal = sim.read_bool(sim.io().is_illegal);
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
||||||
None,
|
None,
|
||||||
BranchMOp::branch_i(
|
BranchMOp::branch_i(
|
||||||
MOpDestReg::new_sim(&[], &[]),
|
MOpDestReg::new_sim(&[], &[]),
|
||||||
MOpRegNum::const_zero().value,
|
[MOpRegNum::const_zero(); 2],
|
||||||
0x345678.cast_to_static::<SInt<_>>(),
|
0x345678.cast_to_static::<SInt<_>>(),
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
|
|
@ -28,7 +28,7 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
||||||
None,
|
None,
|
||||||
BranchMOp::branch_i(
|
BranchMOp::branch_i(
|
||||||
MOpDestReg::new_sim(&[], &[]),
|
MOpDestReg::new_sim(&[], &[]),
|
||||||
MOpRegNum::const_zero().value,
|
[MOpRegNum::const_zero(); 2],
|
||||||
0x345678.cast_to_static::<SInt<_>>(),
|
0x345678.cast_to_static::<SInt<_>>(),
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
|
@ -41,7 +41,7 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
||||||
None,
|
None,
|
||||||
BranchMOp::branch_i(
|
BranchMOp::branch_i(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_LR_REG_NUM], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_LR_REG_NUM], &[]),
|
||||||
MOpRegNum::const_zero().value,
|
[MOpRegNum::const_zero(); 2],
|
||||||
0x345678.cast_to_static::<SInt<_>>(),
|
0x345678.cast_to_static::<SInt<_>>(),
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
|
|
@ -54,7 +54,7 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
||||||
None,
|
None,
|
||||||
BranchMOp::branch_i(
|
BranchMOp::branch_i(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_LR_REG_NUM], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_LR_REG_NUM], &[]),
|
||||||
MOpRegNum::const_zero().value,
|
[MOpRegNum::const_zero(); 2],
|
||||||
0x345678.cast_to_static::<SInt<_>>(),
|
0x345678.cast_to_static::<SInt<_>>(),
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
|
|
@ -74,10 +74,7 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
||||||
[
|
[
|
||||||
AddSubMOp::add_sub_i::<MOp>(
|
AddSubMOp::add_sub_i::<MOp>(
|
||||||
MOpDestReg::new([MOpRegNum::power_isa_ctr_reg()], []),
|
MOpDestReg::new([MOpRegNum::power_isa_ctr_reg()], []),
|
||||||
[
|
[MOpRegNum::power_isa_ctr_reg(), MOpRegNum::const_zero()],
|
||||||
MOpRegNum::power_isa_ctr_reg().value,
|
|
||||||
MOpRegNum::const_zero().value,
|
|
||||||
],
|
|
||||||
(-1).cast_to_static::<SInt<_>>(),
|
(-1).cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -143,9 +140,9 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
||||||
BranchMOp::branch_cond_ctr(
|
BranchMOp::branch_cond_ctr(
|
||||||
$dest,
|
$dest,
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_cr_reg_imm(0).value,
|
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||||
$src1,
|
$src1,
|
||||||
MOpRegNum::power_isa_ctr_reg().value,
|
MOpRegNum::power_isa_ctr_reg(),
|
||||||
],
|
],
|
||||||
$imm.cast_to_static::<SInt<_>>(),
|
$imm.cast_to_static::<SInt<_>>(),
|
||||||
true,
|
true,
|
||||||
|
|
@ -163,9 +160,9 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
||||||
BranchMOp::branch_cond_ctr(
|
BranchMOp::branch_cond_ctr(
|
||||||
$dest,
|
$dest,
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_cr_reg_imm(0).value,
|
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||||
$src1,
|
$src1,
|
||||||
MOpRegNum::power_isa_ctr_reg().value,
|
MOpRegNum::power_isa_ctr_reg(),
|
||||||
],
|
],
|
||||||
$imm.cast_to_static::<SInt<_>>(),
|
$imm.cast_to_static::<SInt<_>>(),
|
||||||
true,
|
true,
|
||||||
|
|
@ -183,9 +180,9 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
||||||
BranchMOp::branch_cond_ctr(
|
BranchMOp::branch_cond_ctr(
|
||||||
$dest,
|
$dest,
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_cr_reg_imm(0).value,
|
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||||
$src1,
|
$src1,
|
||||||
MOpRegNum::power_isa_ctr_reg().value,
|
MOpRegNum::power_isa_ctr_reg(),
|
||||||
],
|
],
|
||||||
$imm.cast_to_static::<SInt<_>>(),
|
$imm.cast_to_static::<SInt<_>>(),
|
||||||
true,
|
true,
|
||||||
|
|
@ -203,9 +200,9 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
||||||
BranchMOp::branch_cond_ctr(
|
BranchMOp::branch_cond_ctr(
|
||||||
$dest,
|
$dest,
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_cr_reg_imm(0).value,
|
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||||
$src1,
|
$src1,
|
||||||
MOpRegNum::power_isa_ctr_reg().value,
|
MOpRegNum::power_isa_ctr_reg(),
|
||||||
],
|
],
|
||||||
$imm.cast_to_static::<SInt<_>>(),
|
$imm.cast_to_static::<SInt<_>>(),
|
||||||
true,
|
true,
|
||||||
|
|
@ -223,9 +220,9 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
||||||
BranchMOp::branch_cond_ctr(
|
BranchMOp::branch_cond_ctr(
|
||||||
$dest,
|
$dest,
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_cr_reg_imm(2).value,
|
MOpRegNum::power_isa_cr_reg_imm(2),
|
||||||
$src1,
|
$src1,
|
||||||
MOpRegNum::power_isa_ctr_reg().value,
|
MOpRegNum::power_isa_ctr_reg(),
|
||||||
],
|
],
|
||||||
$imm.cast_to_static::<SInt<_>>(),
|
$imm.cast_to_static::<SInt<_>>(),
|
||||||
true,
|
true,
|
||||||
|
|
@ -243,9 +240,9 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
||||||
BranchMOp::branch_cond_ctr(
|
BranchMOp::branch_cond_ctr(
|
||||||
$dest,
|
$dest,
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_cr_reg_imm(0).value,
|
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||||
$src1,
|
$src1,
|
||||||
MOpRegNum::power_isa_ctr_reg().value,
|
MOpRegNum::power_isa_ctr_reg(),
|
||||||
],
|
],
|
||||||
$imm.cast_to_static::<SInt<_>>(),
|
$imm.cast_to_static::<SInt<_>>(),
|
||||||
true,
|
true,
|
||||||
|
|
@ -264,9 +261,9 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
||||||
BranchMOp::branch_cond_ctr(
|
BranchMOp::branch_cond_ctr(
|
||||||
$dest,
|
$dest,
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_cr_reg_imm(0).value,
|
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||||
$src1,
|
$src1,
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
],
|
],
|
||||||
$imm.cast_to_static::<SInt<_>>(),
|
$imm.cast_to_static::<SInt<_>>(),
|
||||||
true,
|
true,
|
||||||
|
|
@ -285,9 +282,9 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
||||||
BranchMOp::branch_cond_ctr(
|
BranchMOp::branch_cond_ctr(
|
||||||
$dest,
|
$dest,
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_cr_reg_imm(0).value,
|
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||||
$src1,
|
$src1,
|
||||||
MOpRegNum::power_isa_ctr_reg().value,
|
MOpRegNum::power_isa_ctr_reg(),
|
||||||
],
|
],
|
||||||
$imm.cast_to_static::<SInt<_>>(),
|
$imm.cast_to_static::<SInt<_>>(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -305,9 +302,9 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
||||||
BranchMOp::branch_cond_ctr(
|
BranchMOp::branch_cond_ctr(
|
||||||
$dest,
|
$dest,
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_cr_reg_imm(0).value,
|
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||||
$src1,
|
$src1,
|
||||||
MOpRegNum::power_isa_ctr_reg().value,
|
MOpRegNum::power_isa_ctr_reg(),
|
||||||
],
|
],
|
||||||
$imm.cast_to_static::<SInt<_>>(),
|
$imm.cast_to_static::<SInt<_>>(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -326,9 +323,9 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
||||||
BranchMOp::branch_cond_ctr(
|
BranchMOp::branch_cond_ctr(
|
||||||
$dest,
|
$dest,
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_cr_reg_imm(0).value,
|
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||||
$src1,
|
$src1,
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
],
|
],
|
||||||
$imm.cast_to_static::<SInt<_>>(),
|
$imm.cast_to_static::<SInt<_>>(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -346,8 +343,11 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
||||||
None,
|
None,
|
||||||
BranchMOp::branch_ctr(
|
BranchMOp::branch_ctr(
|
||||||
$dest,
|
$dest,
|
||||||
$src1,
|
[
|
||||||
MOpRegNum::power_isa_ctr_reg().value,
|
MOpRegNum::const_zero(),
|
||||||
|
$src1,
|
||||||
|
MOpRegNum::power_isa_ctr_reg(),
|
||||||
|
],
|
||||||
$imm.cast_to_static::<SInt<_>>(),
|
$imm.cast_to_static::<SInt<_>>(),
|
||||||
true,
|
true,
|
||||||
$pc_relative,
|
$pc_relative,
|
||||||
|
|
@ -361,8 +361,11 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
||||||
None,
|
None,
|
||||||
BranchMOp::branch_ctr(
|
BranchMOp::branch_ctr(
|
||||||
$dest,
|
$dest,
|
||||||
$src1,
|
[
|
||||||
MOpRegNum::power_isa_ctr_reg().value,
|
MOpRegNum::const_zero(),
|
||||||
|
$src1,
|
||||||
|
MOpRegNum::power_isa_ctr_reg(),
|
||||||
|
],
|
||||||
$imm.cast_to_static::<SInt<_>>(),
|
$imm.cast_to_static::<SInt<_>>(),
|
||||||
false,
|
false,
|
||||||
$pc_relative,
|
$pc_relative,
|
||||||
|
|
@ -377,7 +380,7 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
||||||
None,
|
None,
|
||||||
BranchMOp::branch_i(
|
BranchMOp::branch_i(
|
||||||
$dest,
|
$dest,
|
||||||
$src1,
|
[MOpRegNum::const_zero(), $src1],
|
||||||
$imm.cast_to_static::<SInt<_>>(),
|
$imm.cast_to_static::<SInt<_>>(),
|
||||||
$pc_relative,
|
$pc_relative,
|
||||||
$lk,
|
$lk,
|
||||||
|
|
@ -392,7 +395,7 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
||||||
asm_last_arg = "0x1234";
|
asm_last_arg = "0x1234";
|
||||||
imm = 0x1234;
|
imm = 0x1234;
|
||||||
encoding = 0x40001234;
|
encoding = 0x40001234;
|
||||||
src1 = MOpRegNum::const_zero().value;
|
src1 = MOpRegNum::const_zero();
|
||||||
pc_relative = true;
|
pc_relative = true;
|
||||||
is_ret = false;
|
is_ret = false;
|
||||||
}
|
}
|
||||||
|
|
@ -402,7 +405,7 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
||||||
asm_last_arg = "0x1234";
|
asm_last_arg = "0x1234";
|
||||||
imm = 0x1234;
|
imm = 0x1234;
|
||||||
encoding = 0x40001236;
|
encoding = 0x40001236;
|
||||||
src1 = MOpRegNum::const_zero().value;
|
src1 = MOpRegNum::const_zero();
|
||||||
pc_relative = false;
|
pc_relative = false;
|
||||||
is_ret = false;
|
is_ret = false;
|
||||||
}
|
}
|
||||||
|
|
@ -412,7 +415,7 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
||||||
asm_last_arg = "0";
|
asm_last_arg = "0";
|
||||||
imm = 0;
|
imm = 0;
|
||||||
encoding = 0x4c000020;
|
encoding = 0x4c000020;
|
||||||
src1 = MOpRegNum::power_isa_lr_reg().value;
|
src1 = MOpRegNum::power_isa_lr_reg();
|
||||||
pc_relative = false;
|
pc_relative = false;
|
||||||
is_ret = true;
|
is_ret = true;
|
||||||
}
|
}
|
||||||
|
|
@ -422,7 +425,7 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
||||||
asm_last_arg = "0";
|
asm_last_arg = "0";
|
||||||
imm = 0;
|
imm = 0;
|
||||||
encoding = 0x4c000420;
|
encoding = 0x4c000420;
|
||||||
src1 = MOpRegNum::power_isa_ctr_reg().value;
|
src1 = MOpRegNum::power_isa_ctr_reg();
|
||||||
pc_relative = false;
|
pc_relative = false;
|
||||||
is_ret = false;
|
is_ret = false;
|
||||||
}
|
}
|
||||||
|
|
@ -434,8 +437,11 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
|
||||||
None,
|
None,
|
||||||
BranchMOp::branch_ctr(
|
BranchMOp::branch_ctr(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_LR_REG_NUM], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_LR_REG_NUM], &[]),
|
||||||
MOpRegNum::power_isa_tar_reg().value,
|
[
|
||||||
MOpRegNum::power_isa_ctr_reg().value,
|
MOpRegNum::const_zero(),
|
||||||
|
MOpRegNum::power_isa_tar_reg(),
|
||||||
|
MOpRegNum::power_isa_ctr_reg(),
|
||||||
|
],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@ pub fn test_cases_book_i_2_5_condition_register(retval: &mut Vec<TestCase>) {
|
||||||
LogicalFlagsMOp::logical_flags(
|
LogicalFlagsMOp::logical_flags(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_cr_reg_imm(1).value,
|
MOpRegNum::power_isa_cr_reg_imm(1),
|
||||||
MOpRegNum::power_isa_cr_reg_imm(5).value,
|
MOpRegNum::power_isa_cr_reg_imm(5),
|
||||||
MOpRegNum::power_isa_cr_reg_imm(3).value,
|
MOpRegNum::power_isa_cr_reg_imm(3),
|
||||||
],
|
],
|
||||||
LogicalFlagsMOpImm::from_swizzle_fn::<PRegFlagsPowerISA>(|src0, src1, src2| {
|
LogicalFlagsMOpImm::from_swizzle_fn::<PRegFlagsPowerISA>(|src0, src1, src2| {
|
||||||
let mut dest = src2.map(|v| Some(v.into()));
|
let mut dest = src2.map(|v| Some(v.into()));
|
||||||
|
|
@ -42,9 +42,9 @@ pub fn test_cases_book_i_2_5_condition_register(retval: &mut Vec<TestCase>) {
|
||||||
LogicalFlagsMOp::logical_flags(
|
LogicalFlagsMOp::logical_flags(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(0)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(0)], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_cr_reg_imm(0).value,
|
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||||
MOpRegNum::power_isa_cr_reg_imm(0).value,
|
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||||
MOpRegNum::power_isa_cr_reg_imm(0).value,
|
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||||
],
|
],
|
||||||
LogicalFlagsMOpImm::from_swizzle_fn::<PRegFlagsPowerISA>(|src0, src1, src2| {
|
LogicalFlagsMOpImm::from_swizzle_fn::<PRegFlagsPowerISA>(|src0, src1, src2| {
|
||||||
let mut dest = src2.map(|v| Some(v.into()));
|
let mut dest = src2.map(|v| Some(v.into()));
|
||||||
|
|
@ -61,9 +61,9 @@ pub fn test_cases_book_i_2_5_condition_register(retval: &mut Vec<TestCase>) {
|
||||||
LogicalFlagsMOp::logical_flags(
|
LogicalFlagsMOp::logical_flags(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(0)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(0)], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_cr_reg_imm(0).value,
|
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||||
MOpRegNum::power_isa_cr_reg_imm(0).value,
|
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||||
MOpRegNum::power_isa_cr_reg_imm(0).value,
|
MOpRegNum::power_isa_cr_reg_imm(0),
|
||||||
],
|
],
|
||||||
LogicalFlagsMOpImm::from_swizzle_fn::<PRegFlagsPowerISA>(|src0, src1, src2| {
|
LogicalFlagsMOpImm::from_swizzle_fn::<PRegFlagsPowerISA>(|src0, src1, src2| {
|
||||||
let mut dest = src2.map(|v| Some(v.into()));
|
let mut dest = src2.map(|v| Some(v.into()));
|
||||||
|
|
@ -91,7 +91,7 @@ pub fn test_cases_book_i_2_5_condition_register(retval: &mut Vec<TestCase>) {
|
||||||
None,
|
None,
|
||||||
MoveRegMOp::move_reg(
|
MoveRegMOp::move_reg(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num($dest)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num($dest)], &[]),
|
||||||
[MOpRegNum::power_isa_cr_reg_imm($src).value],
|
[MOpRegNum::power_isa_cr_reg_imm($src)],
|
||||||
0i8.cast_to_static::<SInt<_>>(),
|
0i8.cast_to_static::<SInt<_>>(),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,7 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
||||||
None,
|
None,
|
||||||
AddSubMOp::add_sub_i(
|
AddSubMOp::add_sub_i(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||||
[
|
[MOpRegNum::power_isa_gpr_reg_imm(4), MOpRegNum::const_zero()],
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(4).value,
|
|
||||||
MOpRegNum::const_zero().value,
|
|
||||||
],
|
|
||||||
0x1234.cast_to_static::<SInt<_>>(),
|
0x1234.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -31,10 +28,7 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
||||||
Some(0x38646789),
|
Some(0x38646789),
|
||||||
AddSubMOp::add_sub_i(
|
AddSubMOp::add_sub_i(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||||
[
|
[MOpRegNum::power_isa_gpr_reg_imm(4), MOpRegNum::const_zero()],
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(4).value,
|
|
||||||
MOpRegNum::const_zero().value,
|
|
||||||
],
|
|
||||||
0x123456789i64.cast_to_static::<SInt<_>>(),
|
0x123456789i64.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -49,7 +43,7 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
||||||
Some(0x38606789),
|
Some(0x38606789),
|
||||||
AddSubMOp::add_sub_i(
|
AddSubMOp::add_sub_i(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||||
[MOpRegNum::const_zero().value, MOpRegNum::const_zero().value],
|
[MOpRegNum::const_zero(), MOpRegNum::const_zero()],
|
||||||
0x123456789i64.cast_to_static::<SInt<_>>(),
|
0x123456789i64.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -64,10 +58,7 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
||||||
None,
|
None,
|
||||||
AddSubMOp::add_sub_i(
|
AddSubMOp::add_sub_i(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||||
[
|
[MOpRegNum::power_isa_gpr_reg_imm(4), MOpRegNum::const_zero()],
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(4).value,
|
|
||||||
MOpRegNum::const_zero().value,
|
|
||||||
],
|
|
||||||
0x12340000.cast_to_static::<SInt<_>>(),
|
0x12340000.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -82,7 +73,7 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
||||||
None,
|
None,
|
||||||
AddSubMOp::add_sub_i(
|
AddSubMOp::add_sub_i(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||||
[MOpRegNum::const_zero().value; _],
|
[MOpRegNum::const_zero(); _],
|
||||||
0x12340004.cast_to_static::<SInt<_>>(),
|
0x12340004.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -101,9 +92,9 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
||||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(4).value,
|
MOpRegNum::power_isa_gpr_reg_imm(4),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(5).value,
|
MOpRegNum::power_isa_gpr_reg_imm(5),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
],
|
],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -125,10 +116,7 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
||||||
],
|
],
|
||||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
||||||
),
|
),
|
||||||
[
|
[MOpRegNum::power_isa_gpr_reg_imm(4), MOpRegNum::const_zero()],
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(4).value,
|
|
||||||
MOpRegNum::const_zero().value,
|
|
||||||
],
|
|
||||||
0x1234.cast_to_static::<SInt<_>>(),
|
0x1234.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
false,
|
false,
|
||||||
|
|
@ -147,9 +135,9 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
||||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(4).value,
|
MOpRegNum::power_isa_gpr_reg_imm(4),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(5).value,
|
MOpRegNum::power_isa_gpr_reg_imm(5),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
],
|
],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -171,10 +159,7 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
||||||
],
|
],
|
||||||
&[],
|
&[],
|
||||||
),
|
),
|
||||||
[
|
[MOpRegNum::power_isa_gpr_reg_imm(4), MOpRegNum::const_zero()],
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(4).value,
|
|
||||||
MOpRegNum::const_zero().value,
|
|
||||||
],
|
|
||||||
0x1234.cast_to_static::<SInt<_>>(),
|
0x1234.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
true,
|
true,
|
||||||
|
|
@ -196,9 +181,9 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
||||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(4).value,
|
MOpRegNum::power_isa_gpr_reg_imm(4),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(5).value,
|
MOpRegNum::power_isa_gpr_reg_imm(5),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
],
|
],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -221,9 +206,9 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
||||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(4).value,
|
MOpRegNum::power_isa_gpr_reg_imm(4),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(5).value,
|
MOpRegNum::power_isa_gpr_reg_imm(5),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
],
|
],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -246,9 +231,9 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
||||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(4).value,
|
MOpRegNum::power_isa_gpr_reg_imm(4),
|
||||||
MOpRegNum::power_isa_xer_ca_ca32_reg().value,
|
MOpRegNum::power_isa_xer_ca_ca32_reg(),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(5).value,
|
MOpRegNum::power_isa_gpr_reg_imm(5),
|
||||||
],
|
],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -271,9 +256,9 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
||||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(4).value,
|
MOpRegNum::power_isa_gpr_reg_imm(4),
|
||||||
MOpRegNum::power_isa_xer_ca_ca32_reg().value,
|
MOpRegNum::power_isa_xer_ca_ca32_reg(),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(5).value,
|
MOpRegNum::power_isa_gpr_reg_imm(5),
|
||||||
],
|
],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -296,9 +281,9 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
||||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(4).value,
|
MOpRegNum::power_isa_gpr_reg_imm(4),
|
||||||
MOpRegNum::power_isa_xer_ca_ca32_reg().value,
|
MOpRegNum::power_isa_xer_ca_ca32_reg(),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
],
|
],
|
||||||
(-1i8).cast_to_static::<SInt<_>>(),
|
(-1i8).cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -321,9 +306,9 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
||||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(4).value,
|
MOpRegNum::power_isa_gpr_reg_imm(4),
|
||||||
MOpRegNum::power_isa_xer_ca_ca32_reg().value,
|
MOpRegNum::power_isa_xer_ca_ca32_reg(),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
],
|
],
|
||||||
(-1i8).cast_to_static::<SInt<_>>(),
|
(-1i8).cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -346,9 +331,9 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
||||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(4).value,
|
MOpRegNum::power_isa_gpr_reg_imm(4),
|
||||||
MOpRegNum::power_isa_xer_ca_ca32_reg().value,
|
MOpRegNum::power_isa_xer_ca_ca32_reg(),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
],
|
],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -371,9 +356,9 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
||||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(4).value,
|
MOpRegNum::power_isa_gpr_reg_imm(4),
|
||||||
MOpRegNum::power_isa_xer_ca_ca32_reg().value,
|
MOpRegNum::power_isa_xer_ca_ca32_reg(),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
],
|
],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -393,9 +378,9 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
|
||||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(4).value,
|
MOpRegNum::power_isa_gpr_reg_imm(4),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
],
|
],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// See Notices.txt for copyright information
|
// See Notices.txt for copyright information
|
||||||
|
|
||||||
use crate::test_cases::{TestCase, insn_single};
|
use crate::test_cases::{TestCase, insn_single};
|
||||||
use cpu::instruction::{CompareMOp, CompareMode, MOpDestReg, MOpRegNum, OutputIntegerMode};
|
use cpu::instruction::{CompareMOp, CompareMode, MOpDestReg, MOpRegNum};
|
||||||
use fayalite::prelude::*;
|
use fayalite::prelude::*;
|
||||||
|
|
||||||
/// covers instructions in PowerISA v3.1C Book I 3.3.10 Fixed-Point Compare Instructions
|
/// covers instructions in PowerISA v3.1C Book I 3.3.10 Fixed-Point Compare Instructions
|
||||||
|
|
@ -13,9 +13,8 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
|
||||||
None,
|
None,
|
||||||
CompareMOp::compare_i(
|
CompareMOp::compare_i(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||||
[MOpRegNum::power_isa_gpr_reg_imm(4).value],
|
[MOpRegNum::power_isa_gpr_reg_imm(4)],
|
||||||
0x1234.cast_to_static::<SInt<_>>(),
|
0x1234.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
|
||||||
CompareMode.S32(),
|
CompareMode.S32(),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
@ -25,9 +24,8 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
|
||||||
None,
|
None,
|
||||||
CompareMOp::compare_i(
|
CompareMOp::compare_i(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||||
[MOpRegNum::power_isa_gpr_reg_imm(4).value],
|
[MOpRegNum::power_isa_gpr_reg_imm(4)],
|
||||||
(0x89abu16 as i16).cast_to_static::<SInt<_>>(),
|
(0x89abu16 as i16).cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
|
||||||
CompareMode.S64(),
|
CompareMode.S64(),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
@ -38,11 +36,9 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
|
||||||
CompareMOp::compare(
|
CompareMOp::compare(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(4).value,
|
MOpRegNum::power_isa_gpr_reg_imm(4),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(5).value,
|
MOpRegNum::power_isa_gpr_reg_imm(5),
|
||||||
],
|
],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
|
||||||
OutputIntegerMode.Full64(),
|
|
||||||
CompareMode.S32(),
|
CompareMode.S32(),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
@ -53,11 +49,9 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
|
||||||
CompareMOp::compare(
|
CompareMOp::compare(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(4).value,
|
MOpRegNum::power_isa_gpr_reg_imm(4),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(5).value,
|
MOpRegNum::power_isa_gpr_reg_imm(5),
|
||||||
],
|
],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
|
||||||
OutputIntegerMode.Full64(),
|
|
||||||
CompareMode.S64(),
|
CompareMode.S64(),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
@ -67,9 +61,8 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
|
||||||
None,
|
None,
|
||||||
CompareMOp::compare_i(
|
CompareMOp::compare_i(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||||
[MOpRegNum::power_isa_gpr_reg_imm(4).value],
|
[MOpRegNum::power_isa_gpr_reg_imm(4)],
|
||||||
0x1234.cast_to_static::<SInt<_>>(),
|
0x1234.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
|
||||||
CompareMode.U32(),
|
CompareMode.U32(),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
@ -79,9 +72,8 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
|
||||||
None,
|
None,
|
||||||
CompareMOp::compare_i(
|
CompareMOp::compare_i(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||||
[MOpRegNum::power_isa_gpr_reg_imm(4).value],
|
[MOpRegNum::power_isa_gpr_reg_imm(4)],
|
||||||
0x89ab.cast_to_static::<SInt<_>>(),
|
0x89ab.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
|
||||||
CompareMode.U64(),
|
CompareMode.U64(),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
@ -92,11 +84,9 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
|
||||||
CompareMOp::compare(
|
CompareMOp::compare(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(4).value,
|
MOpRegNum::power_isa_gpr_reg_imm(4),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(5).value,
|
MOpRegNum::power_isa_gpr_reg_imm(5),
|
||||||
],
|
],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
|
||||||
OutputIntegerMode.Full64(),
|
|
||||||
CompareMode.U32(),
|
CompareMode.U32(),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
@ -107,11 +97,9 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
|
||||||
CompareMOp::compare(
|
CompareMOp::compare(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(4).value,
|
MOpRegNum::power_isa_gpr_reg_imm(4),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(5).value,
|
MOpRegNum::power_isa_gpr_reg_imm(5),
|
||||||
],
|
],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
|
||||||
OutputIntegerMode.Full64(),
|
|
||||||
CompareMode.U64(),
|
CompareMode.U64(),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
@ -122,11 +110,9 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
|
||||||
CompareMOp::compare(
|
CompareMOp::compare(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(4).value,
|
MOpRegNum::power_isa_gpr_reg_imm(4),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(5).value,
|
MOpRegNum::power_isa_gpr_reg_imm(5),
|
||||||
],
|
],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
|
||||||
OutputIntegerMode.Full64(),
|
|
||||||
CompareMode.CmpRBOne(),
|
CompareMode.CmpRBOne(),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
@ -137,11 +123,9 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
|
||||||
CompareMOp::compare(
|
CompareMOp::compare(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(4).value,
|
MOpRegNum::power_isa_gpr_reg_imm(4),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(5).value,
|
MOpRegNum::power_isa_gpr_reg_imm(5),
|
||||||
],
|
],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
|
||||||
OutputIntegerMode.Full64(),
|
|
||||||
CompareMode.CmpRBTwo(),
|
CompareMode.CmpRBTwo(),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
@ -152,11 +136,9 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
|
||||||
CompareMOp::compare(
|
CompareMOp::compare(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(4).value,
|
MOpRegNum::power_isa_gpr_reg_imm(4),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm(5).value,
|
MOpRegNum::power_isa_gpr_reg_imm(5),
|
||||||
],
|
],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
|
||||||
OutputIntegerMode.Full64(),
|
|
||||||
CompareMode.CmpEqB(),
|
CompareMode.CmpEqB(),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,11 @@ pub fn test_cases_book_i_3_3_2_fixed_point_load(retval: &mut Vec<TestCase>) {
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||||
[
|
[
|
||||||
if $r != 0 || $ra == 0 {
|
if $r != 0 || $ra == 0 {
|
||||||
MOpRegNum::const_zero().value
|
MOpRegNum::const_zero()
|
||||||
} else {
|
} else {
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($ra).value
|
MOpRegNum::power_isa_gpr_reg_imm($ra)
|
||||||
},
|
},
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
],
|
],
|
||||||
($disp as i64).cast_to_static::<SInt<_>>(),
|
($disp as i64).cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -41,7 +41,7 @@ pub fn test_cases_book_i_3_3_2_fixed_point_load(retval: &mut Vec<TestCase>) {
|
||||||
),
|
),
|
||||||
LoadMOp::load(
|
LoadMOp::load(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||||
[MOpRegNum::power_isa_temp_reg().value],
|
[MOpRegNum::power_isa_temp_reg()],
|
||||||
LoadStoreWidth.$width(),
|
LoadStoreWidth.$width(),
|
||||||
LoadStoreConversion.$conversion(),
|
LoadStoreConversion.$conversion(),
|
||||||
),
|
),
|
||||||
|
|
@ -65,11 +65,11 @@ pub fn test_cases_book_i_3_3_2_fixed_point_load(retval: &mut Vec<TestCase>) {
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||||
[
|
[
|
||||||
if $ra == 0 {
|
if $ra == 0 {
|
||||||
MOpRegNum::const_zero().value
|
MOpRegNum::const_zero()
|
||||||
} else {
|
} else {
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($ra).value
|
MOpRegNum::power_isa_gpr_reg_imm($ra)
|
||||||
},
|
},
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
],
|
],
|
||||||
($disp as i64).cast_to_static::<SInt<_>>(),
|
($disp as i64).cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -80,7 +80,7 @@ pub fn test_cases_book_i_3_3_2_fixed_point_load(retval: &mut Vec<TestCase>) {
|
||||||
),
|
),
|
||||||
LoadMOp::load(
|
LoadMOp::load(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||||
[MOpRegNum::power_isa_temp_reg().value],
|
[MOpRegNum::power_isa_temp_reg()],
|
||||||
LoadStoreWidth.$width(),
|
LoadStoreWidth.$width(),
|
||||||
LoadStoreConversion.$conversion(),
|
LoadStoreConversion.$conversion(),
|
||||||
),
|
),
|
||||||
|
|
@ -103,8 +103,8 @@ pub fn test_cases_book_i_3_3_2_fixed_point_load(retval: &mut Vec<TestCase>) {
|
||||||
AddSubMOp::add_sub_i(
|
AddSubMOp::add_sub_i(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($ra).value,
|
MOpRegNum::power_isa_gpr_reg_imm($ra),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
],
|
],
|
||||||
($disp as i64).cast_to_static::<SInt<_>>(),
|
($disp as i64).cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -115,7 +115,7 @@ pub fn test_cases_book_i_3_3_2_fixed_point_load(retval: &mut Vec<TestCase>) {
|
||||||
),
|
),
|
||||||
LoadMOp::load(
|
LoadMOp::load(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||||
[MOpRegNum::power_isa_gpr_reg_imm($ra).value],
|
[MOpRegNum::power_isa_gpr_reg_imm($ra)],
|
||||||
LoadStoreWidth.$width(),
|
LoadStoreWidth.$width(),
|
||||||
LoadStoreConversion.$conversion(),
|
LoadStoreConversion.$conversion(),
|
||||||
),
|
),
|
||||||
|
|
@ -139,11 +139,11 @@ pub fn test_cases_book_i_3_3_2_fixed_point_load(retval: &mut Vec<TestCase>) {
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||||
[
|
[
|
||||||
if $ra == 0 {
|
if $ra == 0 {
|
||||||
MOpRegNum::const_zero().value
|
MOpRegNum::const_zero()
|
||||||
} else {
|
} else {
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($ra).value
|
MOpRegNum::power_isa_gpr_reg_imm($ra)
|
||||||
},
|
},
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($rb).value,
|
MOpRegNum::power_isa_gpr_reg_imm($rb),
|
||||||
],
|
],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -154,7 +154,7 @@ pub fn test_cases_book_i_3_3_2_fixed_point_load(retval: &mut Vec<TestCase>) {
|
||||||
),
|
),
|
||||||
LoadMOp::load(
|
LoadMOp::load(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||||
[MOpRegNum::power_isa_temp_reg().value],
|
[MOpRegNum::power_isa_temp_reg()],
|
||||||
LoadStoreWidth.$width(),
|
LoadStoreWidth.$width(),
|
||||||
LoadStoreConversion.$conversion(),
|
LoadStoreConversion.$conversion(),
|
||||||
),
|
),
|
||||||
|
|
@ -177,8 +177,8 @@ pub fn test_cases_book_i_3_3_2_fixed_point_load(retval: &mut Vec<TestCase>) {
|
||||||
AddSubMOp::add_sub_i(
|
AddSubMOp::add_sub_i(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($ra).value,
|
MOpRegNum::power_isa_gpr_reg_imm($ra),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($rb).value,
|
MOpRegNum::power_isa_gpr_reg_imm($rb),
|
||||||
],
|
],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -189,7 +189,7 @@ pub fn test_cases_book_i_3_3_2_fixed_point_load(retval: &mut Vec<TestCase>) {
|
||||||
),
|
),
|
||||||
LoadMOp::load(
|
LoadMOp::load(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||||
[MOpRegNum::power_isa_gpr_reg_imm($ra).value],
|
[MOpRegNum::power_isa_gpr_reg_imm($ra)],
|
||||||
LoadStoreWidth.$width(),
|
LoadStoreWidth.$width(),
|
||||||
LoadStoreConversion.$conversion(),
|
LoadStoreConversion.$conversion(),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ pub fn test_cases_book_i_3_3_13_fixed_point_logical(retval: &mut Vec<TestCase>)
|
||||||
&[]
|
&[]
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
[MOpRegNum::power_isa_gpr_reg_imm($src).value],
|
[MOpRegNum::power_isa_gpr_reg_imm($src)],
|
||||||
(($imm as u32) << if $mnemonic.contains('s') { 16 } else { 0 })
|
(($imm as u32) << if $mnemonic.contains('s') { 16 } else { 0 })
|
||||||
.cast_to_static::<SInt<_>>(),
|
.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -108,8 +108,8 @@ pub fn test_cases_book_i_3_3_13_fixed_point_logical(retval: &mut Vec<TestCase>)
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($src0).value,
|
MOpRegNum::power_isa_gpr_reg_imm($src0),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($src1).value,
|
MOpRegNum::power_isa_gpr_reg_imm($src1),
|
||||||
],
|
],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -159,7 +159,7 @@ pub fn test_cases_book_i_3_3_13_fixed_point_logical(retval: &mut Vec<TestCase>)
|
||||||
None,
|
None,
|
||||||
MoveRegMOp::move_reg(
|
MoveRegMOp::move_reg(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||||
[MOpRegNum::power_isa_gpr_reg_imm(4).value],
|
[MOpRegNum::power_isa_gpr_reg_imm(4)],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
@ -232,7 +232,7 @@ pub fn test_cases_book_i_3_3_13_fixed_point_logical(retval: &mut Vec<TestCase>)
|
||||||
&[]
|
&[]
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
[MOpRegNum::power_isa_gpr_reg_imm($src).value],
|
[MOpRegNum::power_isa_gpr_reg_imm($src)],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.$OutputIntegerMode(),
|
OutputIntegerMode.$OutputIntegerMode(),
|
||||||
Lut4::from_fn(|a, b| a | b),
|
Lut4::from_fn(|a, b| a | b),
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
use crate::test_cases::{TestCase, insn_single};
|
use crate::test_cases::{TestCase, insn_single};
|
||||||
use cpu::instruction::{
|
use cpu::instruction::{
|
||||||
MOpDestReg, MOpRegNum, OutputIntegerMode, ShiftRotateDestLogicOp, ShiftRotateMOp,
|
MOpDestReg, MOpRegNum, OutputIntegerMode, ShiftAmountOverflowBehavior, ShiftRotateDestLogicOp,
|
||||||
ShiftRotateMOpImm, ShiftRotateMode,
|
ShiftRotateMOp, ShiftRotateMOpImm, ShiftRotateMode,
|
||||||
};
|
};
|
||||||
use fayalite::prelude::*;
|
use fayalite::prelude::*;
|
||||||
|
|
||||||
|
|
@ -18,6 +18,11 @@ fn shift_imm(amount: Option<u8>, shift_right: bool) -> Expr<ShiftRotateMOpImm> {
|
||||||
HdlNone()
|
HdlNone()
|
||||||
},
|
},
|
||||||
shift_rotate_right: shift_right,
|
shift_rotate_right: shift_right,
|
||||||
|
shift_amount_overflow_behavior: if amount.is_some() {
|
||||||
|
ShiftAmountOverflowBehavior.WrapToWidth()
|
||||||
|
} else {
|
||||||
|
ShiftAmountOverflowBehavior.WrapToTwiceWidth()
|
||||||
|
},
|
||||||
dest_logic_op: HdlNone(),
|
dest_logic_op: HdlNone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -30,14 +35,9 @@ fn rotate_imm(
|
||||||
) -> SimValue<ShiftRotateMOpImm> {
|
) -> SimValue<ShiftRotateMOpImm> {
|
||||||
#[hdl(sim)]
|
#[hdl(sim)]
|
||||||
ShiftRotateMOpImm {
|
ShiftRotateMOpImm {
|
||||||
shift_rotate_amount: if let Some(amount) = amount {
|
shift_rotate_amount: amount.map(|amount| amount.cast_to_static::<UInt<_>>()),
|
||||||
#[hdl(sim)]
|
|
||||||
HdlSome(amount.cast_to_static::<UInt<_>>())
|
|
||||||
} else {
|
|
||||||
#[hdl(sim)]
|
|
||||||
HdlNone()
|
|
||||||
},
|
|
||||||
shift_rotate_right: false,
|
shift_rotate_right: false,
|
||||||
|
shift_amount_overflow_behavior: ShiftAmountOverflowBehavior.WrapToWidth(),
|
||||||
dest_logic_op: if let Some((rotated_output_start, rotated_output_len)) =
|
dest_logic_op: if let Some((rotated_output_start, rotated_output_len)) =
|
||||||
rotated_output_start_and_len
|
rotated_output_start_and_len
|
||||||
{
|
{
|
||||||
|
|
@ -101,9 +101,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
||||||
ShiftRotateMOp::shift_rotate(
|
ShiftRotateMOp::shift_rotate(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($src).value,
|
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($src).value,
|
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||||
src2.value,
|
src2,
|
||||||
],
|
],
|
||||||
&imm,
|
&imm,
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -127,9 +127,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
||||||
ShiftRotateMOp::shift_rotate(
|
ShiftRotateMOp::shift_rotate(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($src).value,
|
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($src).value,
|
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||||
src2.value,
|
src2,
|
||||||
],
|
],
|
||||||
imm,
|
imm,
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -162,9 +162,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
||||||
ShiftRotateMOp::shift_rotate(
|
ShiftRotateMOp::shift_rotate(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($src).value,
|
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($src).value,
|
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($amount).value,
|
MOpRegNum::power_isa_gpr_reg_imm($amount),
|
||||||
],
|
],
|
||||||
rotate_imm(None, $rotated_output_start_and_len, false),
|
rotate_imm(None, $rotated_output_start_and_len, false),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -188,9 +188,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
||||||
ShiftRotateMOp::shift_rotate(
|
ShiftRotateMOp::shift_rotate(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($src).value,
|
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($src).value,
|
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($amount).value,
|
MOpRegNum::power_isa_gpr_reg_imm($amount),
|
||||||
],
|
],
|
||||||
rotate_imm(None, $rotated_output_start_and_len, false),
|
rotate_imm(None, $rotated_output_start_and_len, false),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -745,9 +745,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
||||||
ShiftRotateMOp::shift_rotate(
|
ShiftRotateMOp::shift_rotate(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($src).value,
|
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($amount).value,
|
MOpRegNum::power_isa_gpr_reg_imm($amount),
|
||||||
],
|
],
|
||||||
shift_imm(None, false),
|
shift_imm(None, false),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -772,9 +772,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
||||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($src).value,
|
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($amount).value,
|
MOpRegNum::power_isa_gpr_reg_imm($amount),
|
||||||
],
|
],
|
||||||
shift_imm(None, false),
|
shift_imm(None, false),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -804,9 +804,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
||||||
ShiftRotateMOp::shift_rotate(
|
ShiftRotateMOp::shift_rotate(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($src).value,
|
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($amount).value,
|
MOpRegNum::power_isa_gpr_reg_imm($amount),
|
||||||
],
|
],
|
||||||
shift_imm(None, true),
|
shift_imm(None, true),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -831,9 +831,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
||||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($src).value,
|
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($amount).value,
|
MOpRegNum::power_isa_gpr_reg_imm($amount),
|
||||||
],
|
],
|
||||||
shift_imm(None, true),
|
shift_imm(None, true),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -869,9 +869,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
||||||
&[],
|
&[],
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($src).value,
|
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($amount).value,
|
MOpRegNum::power_isa_gpr_reg_imm($amount),
|
||||||
],
|
],
|
||||||
shift_imm(None, true),
|
shift_imm(None, true),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -899,9 +899,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
||||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($src).value,
|
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($amount).value,
|
MOpRegNum::power_isa_gpr_reg_imm($amount),
|
||||||
],
|
],
|
||||||
shift_imm(None, true),
|
shift_imm(None, true),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -937,9 +937,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
||||||
&[],
|
&[],
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($src).value,
|
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
],
|
],
|
||||||
shift_imm(Some($amount), true),
|
shift_imm(Some($amount), true),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -967,9 +967,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
||||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($src).value,
|
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
],
|
],
|
||||||
shift_imm(Some($amount), true),
|
shift_imm(Some($amount), true),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -1078,9 +1078,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
||||||
ShiftRotateMOp::shift_rotate(
|
ShiftRotateMOp::shift_rotate(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($src).value,
|
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
],
|
],
|
||||||
shift_imm(Some($amount), false),
|
shift_imm(Some($amount), false),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -1105,9 +1105,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
|
||||||
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($src).value,
|
MOpRegNum::power_isa_gpr_reg_imm($src),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
],
|
],
|
||||||
shift_imm(Some($amount), false),
|
shift_imm(Some($amount), false),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,11 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||||
[
|
[
|
||||||
if $r != 0 || $ra == 0 {
|
if $r != 0 || $ra == 0 {
|
||||||
MOpRegNum::const_zero().value
|
MOpRegNum::const_zero()
|
||||||
} else {
|
} else {
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($ra).value
|
MOpRegNum::power_isa_gpr_reg_imm($ra)
|
||||||
},
|
},
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
],
|
],
|
||||||
($disp as i64).cast_to_static::<SInt<_>>(),
|
($disp as i64).cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -41,8 +41,8 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
|
||||||
StoreMOp::store(
|
StoreMOp::store(
|
||||||
MOpDestReg::new_sim(&[], &[]),
|
MOpDestReg::new_sim(&[], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_temp_reg().value,
|
MOpRegNum::power_isa_temp_reg(),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($rs).value,
|
MOpRegNum::power_isa_gpr_reg_imm($rs),
|
||||||
],
|
],
|
||||||
LoadStoreWidth.$width(),
|
LoadStoreWidth.$width(),
|
||||||
LoadStoreConversion.ZeroExt(),
|
LoadStoreConversion.ZeroExt(),
|
||||||
|
|
@ -66,11 +66,11 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||||
[
|
[
|
||||||
if $ra == 0 {
|
if $ra == 0 {
|
||||||
MOpRegNum::const_zero().value
|
MOpRegNum::const_zero()
|
||||||
} else {
|
} else {
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($ra).value
|
MOpRegNum::power_isa_gpr_reg_imm($ra)
|
||||||
},
|
},
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
],
|
],
|
||||||
($disp as i64).cast_to_static::<SInt<_>>(),
|
($disp as i64).cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -82,8 +82,8 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
|
||||||
StoreMOp::store(
|
StoreMOp::store(
|
||||||
MOpDestReg::new_sim(&[], &[]),
|
MOpDestReg::new_sim(&[], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_temp_reg().value,
|
MOpRegNum::power_isa_temp_reg(),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($rs).value,
|
MOpRegNum::power_isa_gpr_reg_imm($rs),
|
||||||
],
|
],
|
||||||
LoadStoreWidth.$width(),
|
LoadStoreWidth.$width(),
|
||||||
LoadStoreConversion.ZeroExt(),
|
LoadStoreConversion.ZeroExt(),
|
||||||
|
|
@ -107,8 +107,8 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
|
||||||
AddSubMOp::add_sub_i(
|
AddSubMOp::add_sub_i(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($ra).value,
|
MOpRegNum::power_isa_gpr_reg_imm($ra),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
],
|
],
|
||||||
($disp as i64).cast_to_static::<SInt<_>>(),
|
($disp as i64).cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -120,15 +120,15 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
|
||||||
StoreMOp::store(
|
StoreMOp::store(
|
||||||
MOpDestReg::new_sim(&[], &[]),
|
MOpDestReg::new_sim(&[], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_temp_reg().value,
|
MOpRegNum::power_isa_temp_reg(),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($rs).value,
|
MOpRegNum::power_isa_gpr_reg_imm($rs),
|
||||||
],
|
],
|
||||||
LoadStoreWidth.$width(),
|
LoadStoreWidth.$width(),
|
||||||
LoadStoreConversion.ZeroExt(),
|
LoadStoreConversion.ZeroExt(),
|
||||||
),
|
),
|
||||||
MoveRegMOp::move_reg(
|
MoveRegMOp::move_reg(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
||||||
[MOpRegNum::power_isa_temp_reg().value],
|
[MOpRegNum::power_isa_temp_reg()],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
@ -142,8 +142,8 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
|
||||||
AddSubMOp::add_sub_i(
|
AddSubMOp::add_sub_i(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($ra).value,
|
MOpRegNum::power_isa_gpr_reg_imm($ra),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
],
|
],
|
||||||
($disp as i64).cast_to_static::<SInt<_>>(),
|
($disp as i64).cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -155,8 +155,8 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
|
||||||
StoreMOp::store(
|
StoreMOp::store(
|
||||||
MOpDestReg::new_sim(&[], &[]),
|
MOpDestReg::new_sim(&[], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($ra).value,
|
MOpRegNum::power_isa_gpr_reg_imm($ra),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($rs).value,
|
MOpRegNum::power_isa_gpr_reg_imm($rs),
|
||||||
],
|
],
|
||||||
LoadStoreWidth.$width(),
|
LoadStoreWidth.$width(),
|
||||||
LoadStoreConversion.ZeroExt(),
|
LoadStoreConversion.ZeroExt(),
|
||||||
|
|
@ -181,11 +181,11 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||||
[
|
[
|
||||||
if $ra == 0 {
|
if $ra == 0 {
|
||||||
MOpRegNum::const_zero().value
|
MOpRegNum::const_zero()
|
||||||
} else {
|
} else {
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($ra).value
|
MOpRegNum::power_isa_gpr_reg_imm($ra)
|
||||||
},
|
},
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($rb).value,
|
MOpRegNum::power_isa_gpr_reg_imm($rb),
|
||||||
],
|
],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -197,8 +197,8 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
|
||||||
StoreMOp::store(
|
StoreMOp::store(
|
||||||
MOpDestReg::new_sim(&[], &[]),
|
MOpDestReg::new_sim(&[], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_temp_reg().value,
|
MOpRegNum::power_isa_temp_reg(),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($rs).value,
|
MOpRegNum::power_isa_gpr_reg_imm($rs),
|
||||||
],
|
],
|
||||||
LoadStoreWidth.$width(),
|
LoadStoreWidth.$width(),
|
||||||
LoadStoreConversion.ZeroExt(),
|
LoadStoreConversion.ZeroExt(),
|
||||||
|
|
@ -222,8 +222,8 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
|
||||||
AddSubMOp::add_sub_i(
|
AddSubMOp::add_sub_i(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($ra).value,
|
MOpRegNum::power_isa_gpr_reg_imm($ra),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($rb).value,
|
MOpRegNum::power_isa_gpr_reg_imm($rb),
|
||||||
],
|
],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -235,15 +235,15 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
|
||||||
StoreMOp::store(
|
StoreMOp::store(
|
||||||
MOpDestReg::new_sim(&[], &[]),
|
MOpDestReg::new_sim(&[], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_temp_reg().value,
|
MOpRegNum::power_isa_temp_reg(),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($rs).value,
|
MOpRegNum::power_isa_gpr_reg_imm($rs),
|
||||||
],
|
],
|
||||||
LoadStoreWidth.$width(),
|
LoadStoreWidth.$width(),
|
||||||
LoadStoreConversion.ZeroExt(),
|
LoadStoreConversion.ZeroExt(),
|
||||||
),
|
),
|
||||||
MoveRegMOp::move_reg(
|
MoveRegMOp::move_reg(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
||||||
[MOpRegNum::power_isa_temp_reg().value],
|
[MOpRegNum::power_isa_temp_reg()],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
@ -258,11 +258,11 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
|
||||||
[
|
[
|
||||||
if $ra == 0 {
|
if $ra == 0 {
|
||||||
MOpRegNum::const_zero().value
|
MOpRegNum::const_zero()
|
||||||
} else {
|
} else {
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($ra).value
|
MOpRegNum::power_isa_gpr_reg_imm($ra)
|
||||||
},
|
},
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($rb).value,
|
MOpRegNum::power_isa_gpr_reg_imm($rb),
|
||||||
],
|
],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
OutputIntegerMode.Full64(),
|
OutputIntegerMode.Full64(),
|
||||||
|
|
@ -274,8 +274,8 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
|
||||||
StoreMOp::store(
|
StoreMOp::store(
|
||||||
MOpDestReg::new_sim(&[], &[]),
|
MOpDestReg::new_sim(&[], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($ra).value,
|
MOpRegNum::power_isa_gpr_reg_imm($ra),
|
||||||
MOpRegNum::power_isa_gpr_reg_imm($rs).value,
|
MOpRegNum::power_isa_gpr_reg_imm($rs),
|
||||||
],
|
],
|
||||||
LoadStoreWidth.$width(),
|
LoadStoreWidth.$width(),
|
||||||
LoadStoreConversion.ZeroExt(),
|
LoadStoreConversion.ZeroExt(),
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,9 @@ pub fn test_cases_book_i_3_3_19_move_to_from_system_register(retval: &mut Vec<Te
|
||||||
LogicalFlagsMOp::logical_flags(
|
LogicalFlagsMOp::logical_flags(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
|
||||||
[
|
[
|
||||||
MOpRegNum::power_isa_xer_ca_ca32_reg().value,
|
MOpRegNum::power_isa_xer_ca_ca32_reg(),
|
||||||
MOpRegNum::const_zero().value,
|
MOpRegNum::const_zero(),
|
||||||
MOpRegNum::power_isa_xer_so_ov_ov32_reg().value,
|
MOpRegNum::power_isa_xer_so_ov_ov32_reg(),
|
||||||
],
|
],
|
||||||
mcrxrx_imm(),
|
mcrxrx_imm(),
|
||||||
Lut4::from_fn(|a, b| a | b),
|
Lut4::from_fn(|a, b| a | b),
|
||||||
|
|
@ -48,7 +48,7 @@ pub fn test_cases_book_iii_5_4_4_move_to_from_system_register(retval: &mut Vec<T
|
||||||
None,
|
None,
|
||||||
MoveRegMOp::move_reg(
|
MoveRegMOp::move_reg(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||||
[MOpRegNum::power_isa_lr_reg().value],
|
[MOpRegNum::power_isa_lr_reg()],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
@ -58,7 +58,7 @@ pub fn test_cases_book_iii_5_4_4_move_to_from_system_register(retval: &mut Vec<T
|
||||||
None,
|
None,
|
||||||
MoveRegMOp::move_reg(
|
MoveRegMOp::move_reg(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_LR_REG_NUM], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_LR_REG_NUM], &[]),
|
||||||
[MOpRegNum::power_isa_gpr_reg_imm(3).value],
|
[MOpRegNum::power_isa_gpr_reg_imm(3)],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
@ -68,7 +68,7 @@ pub fn test_cases_book_iii_5_4_4_move_to_from_system_register(retval: &mut Vec<T
|
||||||
None,
|
None,
|
||||||
MoveRegMOp::move_reg(
|
MoveRegMOp::move_reg(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||||
[MOpRegNum::power_isa_ctr_reg().value],
|
[MOpRegNum::power_isa_ctr_reg()],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
@ -78,7 +78,7 @@ pub fn test_cases_book_iii_5_4_4_move_to_from_system_register(retval: &mut Vec<T
|
||||||
None,
|
None,
|
||||||
MoveRegMOp::move_reg(
|
MoveRegMOp::move_reg(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_CTR_REG_NUM], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_CTR_REG_NUM], &[]),
|
||||||
[MOpRegNum::power_isa_gpr_reg_imm(3).value],
|
[MOpRegNum::power_isa_gpr_reg_imm(3)],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
@ -88,7 +88,7 @@ pub fn test_cases_book_iii_5_4_4_move_to_from_system_register(retval: &mut Vec<T
|
||||||
None,
|
None,
|
||||||
MoveRegMOp::move_reg(
|
MoveRegMOp::move_reg(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||||
[MOpRegNum::power_isa_tar_reg().value],
|
[MOpRegNum::power_isa_tar_reg()],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
@ -98,7 +98,7 @@ pub fn test_cases_book_iii_5_4_4_move_to_from_system_register(retval: &mut Vec<T
|
||||||
None,
|
None,
|
||||||
MoveRegMOp::move_reg(
|
MoveRegMOp::move_reg(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TAR_REG_NUM], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TAR_REG_NUM], &[]),
|
||||||
[MOpRegNum::power_isa_gpr_reg_imm(3).value],
|
[MOpRegNum::power_isa_gpr_reg_imm(3)],
|
||||||
0.cast_to_static::<SInt<_>>(),
|
0.cast_to_static::<SInt<_>>(),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
@ -109,7 +109,7 @@ pub fn test_cases_book_iii_5_4_4_move_to_from_system_register(retval: &mut Vec<T
|
||||||
None,
|
None,
|
||||||
ReadSpecialMOp::read_special(
|
ReadSpecialMOp::read_special(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||||
[MOpRegNum::const_zero().value; 0],
|
[MOpRegNum::const_zero(); 0],
|
||||||
ReadSpecialMOpImm.PowerIsaTimeBase(),
|
ReadSpecialMOpImm.PowerIsaTimeBase(),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
@ -120,7 +120,7 @@ pub fn test_cases_book_iii_5_4_4_move_to_from_system_register(retval: &mut Vec<T
|
||||||
None,
|
None,
|
||||||
ReadSpecialMOp::read_special(
|
ReadSpecialMOp::read_special(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||||
[MOpRegNum::const_zero().value; 0],
|
[MOpRegNum::const_zero(); 0],
|
||||||
ReadSpecialMOpImm.PowerIsaTimeBaseU(),
|
ReadSpecialMOpImm.PowerIsaTimeBaseU(),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
@ -131,7 +131,7 @@ pub fn test_cases_book_iii_5_4_4_move_to_from_system_register(retval: &mut Vec<T
|
||||||
None,
|
None,
|
||||||
ReadSpecialMOp::read_special(
|
ReadSpecialMOp::read_special(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||||
[MOpRegNum::const_zero().value; 0],
|
[MOpRegNum::const_zero(); 0],
|
||||||
ReadSpecialMOpImm.PowerIsaTimeBase(),
|
ReadSpecialMOpImm.PowerIsaTimeBase(),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
@ -142,7 +142,7 @@ pub fn test_cases_book_iii_5_4_4_move_to_from_system_register(retval: &mut Vec<T
|
||||||
None,
|
None,
|
||||||
ReadSpecialMOp::read_special(
|
ReadSpecialMOp::read_special(
|
||||||
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
|
||||||
[MOpRegNum::const_zero().value; 0],
|
[MOpRegNum::const_zero(); 0],
|
||||||
ReadSpecialMOpImm.PowerIsaTimeBaseU(),
|
ReadSpecialMOpImm.PowerIsaTimeBaseU(),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue