1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
//! Contains sparc-specific types

use core::convert::From;
use core::{cmp, fmt, slice};

// XXX todo(tmfink): create rusty versions
pub use capstone_sys::sparc_insn_group as SparcInsnGroup;
pub use capstone_sys::sparc_insn as SparcInsn;
pub use capstone_sys::sparc_reg as SparcReg;
pub use capstone_sys::sparc_cc as SparcCC;
pub use capstone_sys::sparc_hint as SparcHint;
use capstone_sys::{cs_sparc, cs_sparc_op, sparc_op_mem, sparc_op_type};

pub use crate::arch::arch_builder::sparc::*;
use crate::arch::DetailsArchInsn;
use crate::instruction::{RegId, RegIdInt};


/// Contains SPARC-specific details for an instruction
pub struct SparcInsnDetail<'a>(pub(crate) &'a cs_sparc);

/// SPARC operand
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum SparcOperand {
    /// Register
    Reg(RegId),

    /// Immediate
    Imm(i64),

    /// Memory
    Mem(SparcOpMem),

    /// Invalid
    Invalid,
}

impl<'a> SparcInsnDetail<'a> {
    /// Condition codes
    pub fn cc(&self) -> SparcCC {
        self.0.cc
    }

    /// Branch hint
    pub fn hint(&self) -> SparcHint {
        self.0.hint
    }
}

impl_PartialEq_repr_fields!(SparcInsnDetail<'a> [ 'a ];
    cc, hint, operands
);

impl Default for SparcOperand {
    fn default() -> Self {
        SparcOperand::Invalid
    }
}

/// SPARC memory operand
#[derive(Debug, Copy, Clone)]
pub struct SparcOpMem(pub(crate) sparc_op_mem);

impl SparcOpMem {
    /// Base register
    pub fn base(&self) -> RegId {
        RegId(RegIdInt::from(self.0.base))
    }

    /// Index register
    pub fn index(&self) -> RegId {
        RegId(RegIdInt::from(self.0.index))
    }

    /// Disp value
    pub fn disp(&self) -> i32 {
        self.0.disp
    }
}

impl_PartialEq_repr_fields!(SparcOpMem;
    base, index, disp
);

impl cmp::Eq for SparcOpMem {}

impl<'a> From<&'a cs_sparc_op> for SparcOperand {
    fn from(insn: &cs_sparc_op) -> SparcOperand {
        match insn.type_ {
            sparc_op_type::SPARC_OP_REG => {
                SparcOperand::Reg(RegId(unsafe { insn.__bindgen_anon_1.reg } as RegIdInt))
            }
            sparc_op_type::SPARC_OP_IMM => SparcOperand::Imm(unsafe { insn.__bindgen_anon_1.imm }),
            sparc_op_type::SPARC_OP_MEM => {
                SparcOperand::Mem(SparcOpMem(unsafe { insn.__bindgen_anon_1.mem }))
            }
            sparc_op_type::SPARC_OP_INVALID => SparcOperand::Invalid,
        }
    }
}

def_arch_details_struct!(
    InsnDetail = SparcInsnDetail;
    Operand = SparcOperand;
    OperandIterator = SparcOperandIterator;
    OperandIteratorLife = SparcOperandIterator<'a>;
    [ pub struct SparcOperandIterator<'a>(slice::Iter<'a, cs_sparc_op>); ]
    cs_arch_op = cs_sparc_op;
    cs_arch = cs_sparc;
);