random instruction generator, use std::io::Write

This commit is contained in:
Richard Patel 2021-08-14 03:28:16 +02:00
parent 8b8bb66031
commit ecd06bf524
6 changed files with 182 additions and 56 deletions

89
Cargo.lock generated
View File

@ -8,6 +8,23 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "getrandom"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "hermit-abi"
version = "0.1.19"
@ -56,3 +73,75 @@ dependencies = [
"num_cpus",
"ppc750cl",
]
[[package]]
name = "ppc750cl-rand"
version = "0.1.0"
dependencies = [
"ppc750cl",
"rand_core",
"sfmt",
]
[[package]]
name = "ppv-lite86"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom",
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
]
[[package]]
name = "rand_chacha"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [
"getrandom",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
"rand_core",
]
[[package]]
name = "sfmt"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "269239cd28e19133d5dc0179d060b00b0b95ce1224792ea5b7c075241d4ee309"
dependencies = [
"rand",
"rand_core",
]
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"

View File

@ -2,4 +2,5 @@
members = [
"lib",
"fuzz",
"rand",
]

View File

@ -102,11 +102,14 @@ fn disasm(x: u32) {
struct DevNull;
impl std::fmt::Write for DevNull {
fn write_str(&mut self, s: &str) -> std::fmt::Result {
s.as_bytes()
.iter()
.for_each(|b| unsafe { std::ptr::read_volatile(b); });
impl std::io::Write for DevNull {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
buf.iter().for_each(|b| unsafe {
std::ptr::read_volatile(b);
});
Ok(buf.len())
}
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
}

View File

@ -1,6 +1,6 @@
#![allow(clippy::unusual_byte_groupings)]
use std::fmt::Write;
use std::io::Write;
use std::ops::Range;
use num_traits::AsPrimitive;
@ -1298,7 +1298,7 @@ impl Ins {
ins
}
fn write_string_form_reg123<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_reg123<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match self.op {
Opcode::Eciwx => "eciwx",
Opcode::Ecowx => "ecowx",
@ -1329,7 +1329,7 @@ impl Ins {
write!(out, "{} r{}, r{}, r{}", name, self.d(), self.a(), self.b())
}
fn write_string_form_reg123_rc<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_reg123_rc<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name_suffix = if self.rc() != 0 { "." } else { "" };
let name = match self.op {
Opcode::And => "and",
@ -1350,7 +1350,7 @@ impl Ins {
)
}
fn write_string_form_reg123_oe_rc<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_reg123_oe_rc<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name_suffix = match (self.oe() != 0, self.rc() != 0) {
(false, false) => "",
(false, true) => ".",
@ -1380,7 +1380,7 @@ impl Ins {
)
}
fn write_string_noargs<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_noargs<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match self.op {
Opcode::Eieio => "eieio",
Opcode::Isync => "isync",
@ -1393,7 +1393,7 @@ impl Ins {
write!(out, "{}", name)
}
fn write_string_form_reg12_simm<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_reg12_simm<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match self.op {
Opcode::Addi => "addi",
Opcode::Addic => "addic",
@ -1413,7 +1413,7 @@ impl Ins {
)
}
fn write_string_form_reg12_uimm<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_reg12_uimm<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match self.op {
Opcode::Andi_ => "andi.",
Opcode::Andis_ => "andis.",
@ -1433,7 +1433,7 @@ impl Ins {
)
}
fn write_string_form_reg12_offset<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_reg12_offset<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match self.op {
Opcode::Lha => "lha",
Opcode::Lhau => "lhau",
@ -1463,7 +1463,7 @@ impl Ins {
)
}
fn write_string_form_fr1_reg2_offset<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_fr1_reg2_offset<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match self.op {
Opcode::Lfd => "lfd",
Opcode::Lfdu => "lfdu",
@ -1485,7 +1485,7 @@ impl Ins {
)
}
fn write_string_form_fr1_reg23<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_fr1_reg23<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match self.op {
Opcode::Lfdux => "lfdux",
Opcode::Lfdx => "lfdx",
@ -1501,7 +1501,7 @@ impl Ins {
write!(out, "{} fr{}, r{}, r{}", name, self.d(), self.a(), self.b())
}
fn write_string_mtfsf<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_mtfsf<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match self.op {
Opcode::Mtfsf => "mtfsf",
_ => disasm_unreachable!(self.code),
@ -1509,7 +1509,7 @@ impl Ins {
write!(out, "{} {}, fr{}", name, self.fm(), self.b())
}
fn write_string_mtfsfi<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_mtfsfi<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match self.op {
Opcode::Mtfsfi => "mtfsfi",
_ => disasm_unreachable!(self.code),
@ -1523,7 +1523,7 @@ impl Ins {
)
}
fn write_string_form_reg1<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_reg1<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match self.op {
Opcode::Mfcr => "mfcr",
Opcode::Mfmsr => "mfmsr",
@ -1534,7 +1534,7 @@ impl Ins {
write!(out, "{} r{}", name, self.d())
}
fn write_string_form_reg12_oe_rc<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_reg12_oe_rc<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name_suffix = match (self.oe() != 0, self.rc() != 0) {
(false, false) => "",
(false, true) => ".",
@ -1552,7 +1552,7 @@ impl Ins {
write!(out, "{}{} r{}, r{}", name, name_suffix, self.d(), self.a())
}
fn write_string_form_reg13<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_reg13<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match self.op {
Opcode::Mfsrin => "mfsrin",
Opcode::Mtsrin => "mtsrin",
@ -1561,7 +1561,7 @@ impl Ins {
write!(out, "{} r{}, r{}", name, self.d(), self.b())
}
fn write_string_form_reg21_rc<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_reg21_rc<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name_suffix = if self.rc() != 0 { "." } else { "" };
let name = match self.op {
Opcode::Cntlzw => "cntlzw",
@ -1572,7 +1572,7 @@ impl Ins {
write!(out, "{}{} r{}, r{}", name, name_suffix, self.a(), self.s())
}
fn write_string_form_fr1<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_fr1<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match self.op {
Opcode::Mffs => match self.rc() != 0 {
false => "mffs",
@ -1583,7 +1583,7 @@ impl Ins {
write!(out, "{} fr{}", name, self.d())
}
fn write_string_form_fr13<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_fr13<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name_suffix = if self.rc() != 0 { "." } else { "" };
let name = match self.op {
Opcode::Fabs => "fabs",
@ -1613,7 +1613,7 @@ impl Ins {
)
}
fn write_string_form_fr123<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_fr123<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name_suffix = if self.rc() != 0 { "." } else { "" };
let name = match self.op {
Opcode::Fadd => "fadd",
@ -1642,7 +1642,7 @@ impl Ins {
)
}
fn write_string_form_fr1243<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_fr1243<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name_suffix = if self.rc() != 0 { "." } else { "" };
let name = match self.op {
Opcode::Fmadd => "fmadd",
@ -1677,7 +1677,7 @@ impl Ins {
)
}
fn write_string_form_fr124<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_fr124<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name_suffix = if self.rc() != 0 { "." } else { "" };
let name = match self.op {
Opcode::Fmul => "fmul",
@ -1698,7 +1698,7 @@ impl Ins {
)
}
fn write_string_form_condreg1_fr23<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_condreg1_fr23<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match self.op {
Opcode::Fcmpo => "fcmpo",
Opcode::Fcmpu => "fcmpu",
@ -1718,7 +1718,7 @@ impl Ins {
)
}
fn write_string_form_condreg1_fr13_rc<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_condreg1_fr13_rc<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name_suffix = if self.rc() != 0 { "." } else { "" };
let name = match self.op {
Opcode::Fctiw => "fctiw",
@ -1736,7 +1736,7 @@ impl Ins {
)
}
fn write_string_b<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_b<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match (self.aa() != 0, self.lk() != 0) {
(false, false) => "b",
(false, true) => "bl",
@ -1747,7 +1747,7 @@ impl Ins {
write!(out, "{} 0x{:x}", name, self.li())
}
fn write_string_bc<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_bc<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match (self.aa() != 0, self.lk() != 0) {
(false, false) => "bc",
(false, true) => "bcl",
@ -1765,7 +1765,7 @@ impl Ins {
)
}
fn write_string_branch_cond_to_reg<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_branch_cond_to_reg<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match self.op {
Opcode::Bcctr => match self.lk() != 0 {
false => "bcctr",
@ -1786,7 +1786,7 @@ impl Ins {
write!(out, "{} 0x{:x}, 0x{:x}", name, self.bo(), self.bi())
}
fn write_string_cmp<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_cmp<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match self.op {
Opcode::Cmp => "cmp",
Opcode::Cmpl => "cmpl",
@ -1803,7 +1803,7 @@ impl Ins {
)
}
fn write_string_cmp_simm<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_cmp_simm<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = "cmpi";
write!(
out,
@ -1816,7 +1816,7 @@ impl Ins {
)
}
fn write_string_cmp_uimm<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_cmp_uimm<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = "cmpli";
write!(
out,
@ -1829,7 +1829,7 @@ impl Ins {
)
}
fn write_string_form_condreg1<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_condreg1<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match self.op {
Opcode::Mcrxr => "mcrxr",
Opcode::Mtfsb0 => match self.rc() != 0 {
@ -1845,7 +1845,7 @@ impl Ins {
write!(out, "{} crf{}", name, self.crf_d())
}
fn write_string_form_condreg12<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_condreg12<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match self.op {
Opcode::Mcrf => "mcrf",
Opcode::Mcrfs => "mcrfs",
@ -1854,7 +1854,7 @@ impl Ins {
write!(out, "{} crf{}, crf{}", name, self.crf_d(), self.crf_s())
}
fn write_string_form_condreg123<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_condreg123<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match self.op {
Opcode::Crand => "crand",
Opcode::Crandc => "crandc",
@ -1876,7 +1876,7 @@ impl Ins {
)
}
fn write_string_form_reg23<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_reg23<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match self.op {
Opcode::Dcbf => "dcbf",
Opcode::Dcbi => "dcbi",
@ -1891,7 +1891,7 @@ impl Ins {
write!(out, "{} r{}, r{}", name, self.a(), self.b())
}
fn write_string_form_reg213<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_reg213<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name_suffix = if self.rc() != 0 { "." } else { "" };
let name = match self.op {
Opcode::Eqv => "eqv",
@ -1921,7 +1921,7 @@ impl Ins {
)
}
fn write_string_rlw_imm<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_rlw_imm<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name_prefix = if self.rc() != 0 { "." } else { "" };
let name = match self.op {
Opcode::Rlwimi => "rlwimi",
@ -1941,7 +1941,7 @@ impl Ins {
)
}
fn write_string_rlw_reg<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_rlw_reg<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
assert_eq!(self.op, Opcode::Rlwnm);
let name_prefix = if self.rc() != 0 { "." } else { "" };
write!(
@ -1956,7 +1956,7 @@ impl Ins {
)
}
fn write_string_form_reg12_nb<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_reg12_nb<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match self.op {
Opcode::Lswi => "lswi",
Opcode::Stswi => "stswi",
@ -1965,7 +1965,7 @@ impl Ins {
write!(out, "{} r{}, r{}, {}", name, self.d(), self.a(), self.b())
}
fn write_string_form_reg1_spr<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_reg1_spr<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match self.op {
Opcode::Mfspr => match self.spr() {
1 => return write!(out, "mfxer r{}", self.s()),
@ -1979,7 +1979,7 @@ impl Ins {
write!(out, "{} r{}, {}", name, self.d(), self.spr())
}
fn write_string_form_spr_reg1<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_spr_reg1<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match self.op {
Opcode::Mtspr => match self.spr() {
1 => return write!(out, "mtxer r{}", self.s()),
@ -1992,7 +1992,7 @@ impl Ins {
write!(out, "{} {}, r{}", name, self.spr(), self.s())
}
fn write_string_form_reg1_sr<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_reg1_sr<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match self.op {
Opcode::Mfsr => "mfsr",
_ => disasm_unreachable!(self.code),
@ -2000,7 +2000,7 @@ impl Ins {
write!(out, "{} r{}, {}", name, self.d(), self.sr())
}
fn write_string_form_sr_reg1<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_form_sr_reg1<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match self.op {
Opcode::Mtsr => "mtsr",
_ => disasm_unreachable!(self.code),
@ -2008,12 +2008,12 @@ impl Ins {
write!(out, "{} {}, r{}", name, self.sr(), self.s())
}
fn write_string_mtcrf<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_mtcrf<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
assert_eq!(self.op, Opcode::Mtcrf);
write!(out, "mtcrf {} r{}", self.crm(), self.s())
}
fn write_string_srawi<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_srawi<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
assert_eq!(self.op, Opcode::Srawi);
let name_suffix = if self.rc() != 0 { "." } else { "" };
write!(
@ -2026,17 +2026,17 @@ impl Ins {
)
}
fn write_string_tw<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_tw<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
assert_eq!(self.op, Opcode::Tw);
write!(out, "tw {}, r{}, r{}", self.to(), self.a(), self.b())
}
fn write_string_twi<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_twi<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
assert_eq!(self.op, Opcode::Twi);
write!(out, "twi {}, r{}, {}", self.to(), self.a(), self.simm())
}
fn write_string_psq<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_psq<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match self.op {
Opcode::PsqL => "psq_l",
Opcode::PsqLu => "psq_lu",
@ -2056,7 +2056,7 @@ impl Ins {
)
}
fn write_string_psq_x<W: Write>(&self, out: &mut W) -> std::fmt::Result {
fn write_string_psq_x<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
let name = match self.op {
Opcode::PsqLx => "psq_lx",
Opcode::PsqLux => "psq_lux",
@ -2076,7 +2076,7 @@ impl Ins {
)
}
pub fn write_string<W: Write>(&self, out: &mut W) -> std::fmt::Result {
pub fn write_string<W: Write>(&self, out: &mut W) -> std::io::Result<()> {
match self.op {
Opcode::Illegal => write!(out, "<illegal>"),
@ -2308,9 +2308,9 @@ impl Ins {
impl ToString for Ins {
fn to_string(&self) -> String {
let mut s = String::new();
self.write_string(&mut s).unwrap();
s
let mut buf = Vec::<u8>::new();
self.write_string(&mut buf).unwrap();
unsafe { String::from_utf8_unchecked(buf) }
}
}

9
rand/Cargo.toml Normal file
View File

@ -0,0 +1,9 @@
[package]
name = "ppc750cl-rand"
version = "0.1.0"
edition = "2018"
[dependencies]
ppc750cl = { path = "../lib" }
rand_core = "0.5"
sfmt = "0.6"

24
rand/src/main.rs Normal file
View File

@ -0,0 +1,24 @@
use rand_core::{RngCore, SeedableRng};
use sfmt::SFMT;
use ppc750cl::{Ins, Opcode};
use std::io::{BufWriter, Write};
fn main() {
let mut rng = SFMT::seed_from_u64(42);
let stdout = std::io::stdout();
let stdout_lock = stdout.lock();
let mut stream = BufWriter::with_capacity(1_000_000, stdout_lock);
loop {
let ins = Ins::disasm(rng.next_u32());
if ins.op == Opcode::Illegal {
continue;
}
if ins.write_string(&mut stream).is_err() {
return;
}
if stream.write_all("\n".as_ref()).is_err() {
return;
}
}
}