# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
+[[package]]
+name = "itoa"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e"
+
[[package]]
name = "power-instruction-analyzer"
version = "0.1.0"
+dependencies = [
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1502d12e458c49a4c9cbff560d0fe0060c252bc29799ed94ca2ed4bb665a0101"
+dependencies = [
+ "unicode-xid",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "54a21852a652ad6f610c9510194f398ff6f8692e334fd1145fed931f7fbe44ea"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "ryu"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed3d612bc64430efeb3f7ee6ef26d590dce0c43249217bddc62112540c7941e1"
+
+[[package]]
+name = "serde"
+version = "1.0.110"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "99e7b308464d16b56eba9964e4972a3eee817760ab60d88c3f86e1fecb08204c"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.110"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "818fbf6bfa9a42d3bfcaca148547aa00c7b915bec71d1757aa2d44ca68771984"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.53"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "993948e75b189211a9b31a7528f950c6adc21f9720b6438ff80a7fa2f864cea2"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef781e621ee763a2a40721a8861ec519cb76966aee03bb5d00adb6a31dc1c1de"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-xid",
+]
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
// See Notices.txt for copyright information
#![feature(llvm_asm)]
-use std::fmt;
-#[derive(Copy, Clone, Debug)]
-struct OverflowFlags {
- overflow: bool,
- overflow32: bool,
+mod serde_hex;
+
+use serde::{Deserialize, Serialize};
+
+#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
+pub struct OverflowFlags {
+ pub overflow: bool,
+ pub overflow32: bool,
}
impl OverflowFlags {
- fn from_xer(xer: u64) -> Self {
+ pub fn from_xer(xer: u64) -> Self {
Self {
overflow: (xer & 0x4000_0000) != 0,
overflow32: (xer & 0x8_0000) != 0,
}
}
-impl fmt::Display for OverflowFlags {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- let Self {
- overflow,
- overflow32,
- } = *self;
- write!(
- f,
- "OV:{overflow}, OV32:{overflow32}",
- overflow = overflow as i32,
- overflow32 = overflow32 as i32,
- )
- }
+#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
+pub struct TestDivResult {
+ #[serde(with = "serde_hex::SerdeHex")]
+ pub result: u64,
+ #[serde(default, flatten, skip_serializing_if = "Option::is_none")]
+ pub overflow: Option<OverflowFlags>,
}
-#[derive(Copy, Clone, Debug)]
-struct TestDivResult {
- result: u64,
- overflow: Option<OverflowFlags>,
-}
-
-impl fmt::Display for TestDivResult {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- let Self { result, overflow } = *self;
- write!(f, "{:#X}", result)?;
- if let Some(overflow) = overflow {
- write!(f, ", {}", overflow)?;
- }
- Ok(())
- }
+#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
+pub struct TestDivInput {
+ #[serde(with = "serde_hex::SerdeHex")]
+ pub dividend: u64,
+ #[serde(with = "serde_hex::SerdeHex")]
+ pub divisor: u64,
+ #[serde(with = "serde_hex::SerdeHex")]
+ pub result_prev: u64,
}
-#[derive(Copy, Clone, Debug)]
-struct TestDivInput {
- dividend: u64,
- divisor: u64,
- result_prev: u64,
-}
-
-impl fmt::Display for TestDivInput {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- let Self {
- dividend,
- divisor,
- result_prev,
- } = *self;
- write!(
- f,
- "{:#X} div {:#X} (result_prev:{:#X})",
- dividend, divisor, result_prev,
- )
- }
+#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
+pub struct TestDivCase {
+ pub instr: TestDivInstr,
+ #[serde(flatten)]
+ pub inputs: TestDivInput,
+ #[serde(flatten)]
+ pub outputs: TestDivResult,
}
macro_rules! make_div_functions {
(
#[div]
{
- $($div_name:ident;)+
+ $($div_enum:ident = $div_fn:ident ($div_instr:literal),)+
}
#[rem]
{
- $($rem_name:ident;)+
+ $($rem_enum:ident = $rem_fn:ident ($rem_instr:literal),)+
}
) => {
+ #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)]
+ pub enum TestDivInstr {
+ $(
+ #[serde(rename = $div_instr)]
+ $div_enum,
+ )+
+ $(
+ #[serde(rename = $rem_instr)]
+ $rem_enum,
+ )+
+ }
+
+ impl TestDivInstr {
+ pub fn get_fn(self) -> fn(TestDivInput) -> TestDivResult {
+ match self {
+ $(
+ Self::$div_enum => TestDivInput::$div_fn,
+ )+
+ $(
+ Self::$rem_enum => TestDivInput::$rem_fn,
+ )+
+ }
+ }
+ pub fn name(self) -> &'static str {
+ match self {
+ $(
+ Self::$div_enum => $div_instr,
+ )+
+ $(
+ Self::$rem_enum => $rem_instr,
+ )+
+ }
+ }
+ pub const VALUES: &'static [Self] = &[
+ $(
+ Self::$div_enum,
+ )+
+ $(
+ Self::$rem_enum,
+ )+
+ ];
+ }
+
impl TestDivInput {
$(
- #[inline(never)]
- pub fn $div_name(self) -> TestDivResult {
+ pub fn $div_fn(self) -> TestDivResult {
let Self {
dividend,
divisor,
unsafe {
llvm_asm!(
concat!(
- stringify!($div_name),
+ $div_instr,
" $0, $3, $4\n",
"mfxer $1"
)
}
)+
$(
- #[inline(never)]
- pub fn $rem_name(self) -> TestDivResult {
+ pub fn $rem_fn(self) -> TestDivResult {
let Self {
dividend,
divisor,
unsafe {
llvm_asm!(
concat!(
- stringify!($rem_name),
+ $rem_instr,
" $0, $2, $3"
)
: "=&r"(result)
}
}
)+
- pub const FUNCTIONS: &'static [(fn(TestDivInput) -> TestDivResult, &'static str)] = &[
- $((Self::$div_name, stringify!($div_name)),)+
- $((Self::$rem_name, stringify!($rem_name)),)+
- ];
}
};
}
make_div_functions! {
#[div]
- {divdeo; divdeuo; divdo; divduo; divweo; divweuo; divwo; divwuo;}
+ {
+ DivDE = divde("divdeo"),
+ DivDEU = divdeu("divdeuo"),
+ DivD = divd("divdo"),
+ DivDU = divdu("divduo"),
+ DivWE = divwe("divweo"),
+ DivWEU = divweu("divweuo"),
+ DivW = divw("divwo"),
+ DivWU = divwu("divwuo"),
+ }
#[rem]
- {modsd; modud; modsw; moduw;}
+ {
+ ModSD = modsd("modsd"),
+ ModUD = modud("modud"),
+ ModSW = modsw("modsw"),
+ ModUW = moduw("moduw"),
+ }
}
const TEST_VALUES: &[u64] = &[
];
fn main() {
- for &(f, name) in TestDivInput::FUNCTIONS {
+ let mut cases = Vec::new();
+ for &instr in TestDivInstr::VALUES {
for ÷nd in TEST_VALUES {
for &divisor in TEST_VALUES {
let inputs = TestDivInput {
divisor,
result_prev: 0xFECD_BA98_7654_3210,
};
- let outputs = f(inputs);
- println!("{}: {} -> {}", name, inputs, outputs);
+ let outputs = instr.get_fn()(inputs);
+ cases.push(TestDivCase {
+ instr,
+ inputs,
+ outputs,
+ });
}
}
}
+ serde_json::to_writer_pretty(std::io::stdout().lock(), &cases).unwrap();
}