[[package]]
name = "inventory"
-version = "0.1.7"
+version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "621b50c176968fd3b0bd71f821a28a0ea98db2b5aea966b2fbb8bd1b7d310328"
+checksum = "49c68da9c8b1bda33dc6f55b2a9b4f44eca5ba2b2a1a308eab40db9fb7e200cb"
dependencies = [
"ctor",
"ghost",
[[package]]
name = "inventory-impl"
-version = "0.1.7"
+version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f99a4111304bade76468d05beab3487c226e4fe4c4de1c4e8f006e815762db73"
+checksum = "4143007b389ae51577282e3c95cf5a7ae0c9e06cafa927508300ceedcbc0354c"
dependencies = [
"proc-macro2",
"quote",
[[package]]
name = "itoa"
-version = "0.4.5"
+version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e"
+checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
[[package]]
name = "libc"
-version = "0.2.71"
+version = "0.2.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49"
+checksum = "755456fae044e6fa1ebbbd1b3e902ae19e73097ed4ed87bb79934a867c007bc3"
[[package]]
name = "lock_api"
"pyo3",
"serde",
"serde_json",
+ "serde_plain",
]
[[package]]
name = "proc-macro-hack"
-version = "0.5.16"
+version = "0.5.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4"
+checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598"
[[package]]
name = "proc-macro2"
-version = "1.0.17"
+version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1502d12e458c49a4c9cbff560d0fe0060c252bc29799ed94ca2ed4bb665a0101"
+checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
-version = "1.0.6"
+version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "54a21852a652ad6f610c9510194f398ff6f8692e334fd1145fed931f7fbe44ea"
+checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_syscall"
-version = "0.1.56"
+version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
+checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "ryu"
-version = "1.0.4"
+version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed3d612bc64430efeb3f7ee6ef26d590dce0c43249217bddc62112540c7941e1"
+checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
[[package]]
name = "scopeguard"
[[package]]
name = "serde"
-version = "1.0.110"
+version = "1.0.115"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99e7b308464d16b56eba9964e4972a3eee817760ab60d88c3f86e1fecb08204c"
+checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.110"
+version = "1.0.115"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "818fbf6bfa9a42d3bfcaca148547aa00c7b915bec71d1757aa2d44ca68771984"
+checksum = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48"
dependencies = [
"proc-macro2",
"quote",
[[package]]
name = "serde_json"
-version = "1.0.53"
+version = "1.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "993948e75b189211a9b31a7528f950c6adc21f9720b6438ff80a7fa2f864cea2"
+checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c"
dependencies = [
"itoa",
"ryu",
"serde",
]
+[[package]]
+name = "serde_plain"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "625fb0da2b006092b426a94acc1611bec52f2ec27bb27b266a9f93c29ee38eda"
+dependencies = [
+ "serde",
+]
+
[[package]]
name = "smallvec"
-version = "1.4.0"
+version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7cb5678e1615754284ec264d9bb5b4c27d2018577fd90ac0ceb578591ed5ee4"
+checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252"
[[package]]
name = "syn"
-version = "1.0.27"
+version = "1.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef781e621ee763a2a40721a8861ec519cb76966aee03bb5d00adb6a31dc1c1de"
+checksum = "891d8d6567fe7c7f8835a3a98af4208f3846fba258c1bc3c31d6e506239f11f9"
dependencies = [
"proc-macro2",
"quote",
[[package]]
name = "unicode-xid"
-version = "0.2.0"
+version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
+checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "unindent"
[[package]]
name = "winapi"
-version = "0.3.8"
+version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
use serde::{Deserialize, Serialize};
use std::{
cmp::Ordering,
+ fmt,
ops::{Index, IndexMut},
};
+use serde_plain::forward_display_to_serde;
-#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
-pub struct OverflowFlags {
- pub so: bool,
- pub ov: bool,
- pub ov32: bool,
+fn is_default<T: Default + PartialEq>(v: &T) -> bool {
+ T::default() == *v
}
-impl OverflowFlags {
- pub const fn from_xer(xer: u64) -> Self {
- Self {
- so: (xer & 0x8000_0000) != 0,
- ov: (xer & 0x4000_0000) != 0,
- ov32: (xer & 0x8_0000) != 0,
+// powerpc bit numbers count from MSB to LSB
+const fn get_xer_bit_mask(powerpc_bit_num: usize) -> u64 {
+ (1 << 63) >> powerpc_bit_num
+}
+
+macro_rules! xer_subset {
+ (
+ $struct_vis:vis struct $struct_name:ident {
+ $(
+ #[bit($powerpc_bit_num:expr, $mask_name:ident)]
+ $field_vis:vis $field_name:ident: bool,
+ )+
}
+ ) => {
+ #[derive(Default, Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
+ $struct_vis struct $struct_name {
+ $(
+ $field_vis $field_name: bool,
+ )+
+ }
+
+ impl $struct_name {
+ $(
+ $field_vis const $mask_name: u64 = get_xer_bit_mask($powerpc_bit_num);
+ )+
+ pub const fn from_xer(xer: u64) -> Self {
+ Self {
+ $(
+ $field_name: (xer & Self::$mask_name) != 0,
+ )+
+ }
+ }
+ pub const fn to_xer(self) -> u64 {
+ let mut retval = 0u64;
+ $(
+ if self.$field_name {
+ retval |= Self::$mask_name;
+ }
+ )+
+ retval
+ }
+ }
+ };
+}
+
+xer_subset! {
+ pub struct OverflowFlags {
+ #[bit(32, XER_SO_MASK)]
+ pub so: bool,
+ #[bit(33, XER_OV_MASK)]
+ pub ov: bool,
+ #[bit(44, XER_OV32_MASK)]
+ pub ov32: bool,
}
+}
+
+impl OverflowFlags {
pub const fn from_overflow(overflow: bool) -> Self {
Self {
so: overflow,
}
}
+xer_subset! {
+ pub struct CarryFlags {
+ #[bit(34, XER_CA_MASK)]
+ pub ca: bool,
+ #[bit(45, XER_CA32_MASK)]
+ pub ca32: bool,
+ }
+}
+
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct ConditionRegister {
pub lt: bool,
pub rt: Option<u64>,
#[serde(default, flatten, skip_serializing_if = "Option::is_none")]
pub overflow: Option<OverflowFlags>,
+ #[serde(default, flatten, skip_serializing_if = "Option::is_none")]
+ pub carry: Option<CarryFlags>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cr0: Option<ConditionRegister>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cr7: Option<ConditionRegister>,
}
+#[derive(Debug)]
+pub struct MissingInstructionInput {
+ pub input: InstructionInputRegister,
+}
+
+impl fmt::Display for MissingInstructionInput {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "missing instruction input: {}", self.input)
+ }
+}
+
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)]
pub enum InstructionInputRegister {
#[serde(rename = "ra")]
Rb,
#[serde(rename = "rc")]
Rc,
+ #[serde(rename = "ca")]
+ Carry,
}
+forward_display_to_serde!(InstructionInputRegister);
+
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
pub struct InstructionInput {
#[serde(with = "serde_hex::SerdeHex")]
pub ra: u64,
- #[serde(with = "serde_hex::SerdeHex")]
- pub rb: u64,
- #[serde(with = "serde_hex::SerdeHex")]
- pub rc: u64,
-}
-
-impl Index<InstructionInputRegister> for InstructionInput {
- type Output = u64;
- fn index(&self, index: InstructionInputRegister) -> &Self::Output {
- match index {
- InstructionInputRegister::Ra => &self.ra,
- InstructionInputRegister::Rb => &self.rb,
- InstructionInputRegister::Rc => &self.rc,
- }
- }
-}
-
-impl IndexMut<InstructionInputRegister> for InstructionInput {
- fn index_mut(&mut self, index: InstructionInputRegister) -> &mut Self::Output {
- match index {
- InstructionInputRegister::Ra => &mut self.ra,
- InstructionInputRegister::Rb => &mut self.rb,
- InstructionInputRegister::Rc => &mut self.rc,
- }
- }
+ #[serde(
+ default,
+ skip_serializing_if = "Option::is_none",
+ with = "serde_hex::SerdeHex"
+ )]
+ pub rb: Option<u64>,
+ #[serde(
+ default,
+ skip_serializing_if = "Option::is_none",
+ with = "serde_hex::SerdeHex"
+ )]
+ pub rc: Option<u64>,
+ #[serde(default, skip_serializing_if = "Option::is_none", flatten)]
+ pub carry: Option<CarryFlags>,
}
fn is_false(v: &bool) -> bool {
// must be after instrs macro call since it uses a macro definition
mod python;
+}
+
+// must be after instrs macro call since it uses a macro definition
+mod python;
#![cfg(feature = "python")]
-use crate::{ConditionRegister, Instr, InstructionInput, InstructionResult, OverflowFlags};
+use crate::{
+ CarryFlags, ConditionRegister, Instr, InstructionInput, InstructionResult, OverflowFlags,
+};
use pyo3::{prelude::*, wrap_pyfunction, PyObjectProtocol};
use std::{borrow::Cow, cell::RefCell, fmt};
}
}
+ wrap_type! {
+ #[pymodule(m)]
+ #[pyclass(name = CarryFlags)]
+ #[wrapped(value: CarryFlags)]
+ #[args(ca, ca32)]
+ #[text_signature = "(ca, ca32)"]
+ struct PyCarryFlags {
+ #[set = set_ca]
+ ca: bool,
+ #[set = set_ca32]
+ ca32: bool,
+ }
+ }
+
wrap_type! {
#[pymodule(m)]
#[pyclass(name = ConditionRegister)]
#[pymodule(m)]
#[pyclass(name = InstructionInput)]
#[wrapped(value: InstructionInput)]
- #[args(ra, rb, rc)]
- #[text_signature = "(ra, rb, rc)"]
+ #[args(ra, rb="None", rc="None", carry="None")]
+ #[text_signature = "(ra, rb, rc, carry)"]
struct PyInstructionInput {
#[set = set_ra]
ra: u64,
#[set = set_rb]
- rb: u64,
+ rb: Option<u64>,
#[set = set_rc]
- rc: u64,
+ rc: Option<u64>,
+ #[set = set_carry]
+ carry: Option<CarryFlags>,
}
}