1use core::convert::From;
4use core::{cmp, fmt, slice};
5
6pub use capstone_sys::ppc_insn_group as PpcInsnGroup;
8pub use capstone_sys::ppc_insn as PpcInsn;
9pub use capstone_sys::ppc_reg as PpcReg;
10pub use capstone_sys::ppc_bc as PpcBc;
11pub use capstone_sys::ppc_bh as PpcBh;
12use capstone_sys::{cs_ppc, cs_ppc_op, ppc_op_mem, ppc_op_crx, ppc_op_type};
13
14pub use crate::arch::arch_builder::ppc::*;
15use crate::arch::DetailsArchInsn;
16use crate::instruction::{RegId, RegIdInt};
17
18pub struct PpcInsnDetail<'a>(pub(crate) &'a cs_ppc);
20
21impl PpcInsnDetail<'_> {
22 pub fn bc(&self) -> PpcBc {
24 self.0.bc
25 }
26
27 pub fn bh(&self) -> PpcBh {
29 self.0.bh
30 }
31
32 pub fn update_cr0(&self) -> PpcBh {
34 self.0.bh
35 }
36}
37
38impl_PartialEq_repr_fields!(PpcInsnDetail<'a> [ 'a ];
39 bc, bh, update_cr0, operands
40);
41
42#[derive(Clone, Debug, Eq, PartialEq)]
44pub enum PpcOperand {
45 Reg(RegId),
47
48 Imm(i64),
50
51 Mem(PpcOpMem),
53
54 Crx(PpcOpCrx),
56
57 Invalid,
59}
60
61impl Default for PpcOperand {
62 fn default() -> Self {
63 PpcOperand::Invalid
64 }
65}
66
67#[derive(Debug, Copy, Clone)]
69pub struct PpcOpMem(pub(crate) ppc_op_mem);
70
71impl PpcOpMem {
72 pub fn base(&self) -> RegId {
74 RegId(self.0.base as RegIdInt)
75 }
76
77 pub fn disp(&self) -> i32 {
79 self.0.disp
80 }
81}
82
83impl_PartialEq_repr_fields!(PpcOpMem;
84 base, disp
85);
86
87impl cmp::Eq for PpcOpMem {}
88
89#[derive(Debug, Copy, Clone)]
91pub struct PpcOpCrx(pub(crate) ppc_op_crx);
92
93impl PpcOpCrx {
94 pub fn scale(&self) -> u32 {
96 self.0.scale as u32
97 }
98
99 pub fn reg(&self) -> RegId {
101 RegId(self.0.reg as RegIdInt)
102 }
103
104 pub fn cond(&self) -> PpcBc {
106 self.0.cond
107 }
108}
109
110impl cmp::PartialEq for PpcOpCrx {
111 fn eq(&self, other: &Self) -> bool {
112 (self.scale(), self.reg(), self.cond()) == (other.scale(), other.reg(), other.cond())
113 }
114}
115
116impl cmp::Eq for PpcOpCrx {}
117
118impl From<&cs_ppc_op> for PpcOperand {
119 fn from(insn: &cs_ppc_op) -> PpcOperand {
120 match insn.type_ {
121 ppc_op_type::PPC_OP_REG => {
122 PpcOperand::Reg(RegId(unsafe { insn.__bindgen_anon_1.reg } as RegIdInt))
123 }
124 ppc_op_type::PPC_OP_IMM => PpcOperand::Imm(unsafe { insn.__bindgen_anon_1.imm }),
125 ppc_op_type::PPC_OP_MEM => {
126 PpcOperand::Mem(PpcOpMem(unsafe { insn.__bindgen_anon_1.mem }))
127 }
128 ppc_op_type::PPC_OP_CRX => {
129 PpcOperand::Crx(PpcOpCrx(unsafe { insn.__bindgen_anon_1.crx }))
130 }
131 ppc_op_type::PPC_OP_INVALID => PpcOperand::Invalid,
132 }
133 }
134}
135
136def_arch_details_struct!(
137 InsnDetail = PpcInsnDetail;
138 Operand = PpcOperand;
139 OperandIterator = PpcOperandIterator;
140 OperandIteratorLife = PpcOperandIterator<'a>;
141 [ pub struct PpcOperandIterator<'a>(slice::Iter<'a, cs_ppc_op>); ]
142 cs_arch_op = cs_ppc_op;
143 cs_arch = cs_ppc;
144);
145
146#[cfg(test)]
147mod test {
148 use super::*;
149
150 #[test]
151 fn test_ppc_op_type() {
152 use capstone_sys::*;
153 use super::ppc_op_type::*;
154 use super::PpcBc::*;
155 use super::PpcReg::*;
156 use self::PpcOperand::*;
157
158 fn t(
159 op: (ppc_op_type, cs_ppc_op__bindgen_ty_1),
160 expected_op: PpcOperand,
161 ) {
162 let op = PpcOperand::from(&cs_ppc_op {
163 type_: op.0,
164 __bindgen_anon_1: op.1
165 });
166 assert_eq!(expected_op, op);
167 }
168
169 t(
170 (PPC_OP_INVALID, cs_ppc_op__bindgen_ty_1 { reg: 0 }),
171 Invalid,
172 );
173 t(
174 (PPC_OP_REG, cs_ppc_op__bindgen_ty_1 { reg: 0 }),
175 Reg(RegId(0)),
176 );
177 t(
178 (PPC_OP_IMM, cs_ppc_op__bindgen_ty_1 { imm: 42 }),
179 Imm(42),
180 );
181
182 let crx = ppc_op_crx { scale: 0, reg: PPC_REG_R0, cond: PPC_BC_LT };
183 t(
184 (PPC_OP_CRX, cs_ppc_op__bindgen_ty_1 { crx }),
185 Crx(PpcOpCrx(crx)),
186 );
187
188 let op_mem = PpcOperand::from(&cs_ppc_op {
189 type_: PPC_OP_MEM,
190 __bindgen_anon_1: cs_ppc_op__bindgen_ty_1 { mem: ppc_op_mem {
191 base: PPC_REG_VS38,
192 disp: -10 }}
193 });
194 if let Mem(op_mem) = op_mem {
195 assert_eq!(
196 (op_mem.base(), op_mem.disp()),
197 (RegId(PPC_REG_VS38 as RegIdInt), -10)
198 );
199 } else {
200 panic!("Did not get expected Mem");
201 }
202 }
203}