1use crate::instruction::fphead::CompactInstructionHeader;
2use crate::instruction::register::Register;
3use std::any::Any;
4use std::fmt::Display;
5use std::io::{Error, ErrorKind, Result};
6
7pub mod branching;
8pub mod fphead;
9pub mod invalid;
10pub mod memory;
11pub mod moving;
12pub mod nop;
13pub mod parser;
14pub mod register;
15
16pub trait AsAny {
17 fn as_any(&self) -> &dyn Any;
18 fn as_any_mut(&mut self) -> &mut dyn Any;
19}
20
21impl<T: Any> AsAny for T {
22 fn as_any(&self) -> &dyn Any {
23 self
24 }
25
26 fn as_any_mut(&mut self) -> &mut dyn Any {
27 self
28 }
29}
30
31pub trait C6000Instruction: AsAny {
32 fn new(_input: &InstructionInput) -> Result<Self>
33 where
34 Self: Sized,
35 {
36 Err(Error::new(ErrorKind::Unsupported, "Instruction not 32-bit"))
37 }
38 fn new_compact(_input: &InstructionInput) -> Result<Self>
39 where
40 Self: Sized,
41 {
42 Err(Error::new(
43 ErrorKind::Unsupported,
44 "Instruction not compact (16-bit)",
45 ))
46 }
47 fn instruction(&self) -> String;
48 fn instruction_clean(&self) -> String {
49 self.instruction()
50 }
51 fn operands(&self) -> String {
52 String::from("")
53 }
54 fn instruction_data(&self) -> &InstructionData;
55 fn instruction_data_mut(&mut self) -> &mut InstructionData;
56 fn opcode(&self) -> u32 {
57 self.instruction_data().opcode
58 }
59 fn is_compact(&self) -> bool {
60 self.instruction_data().compact
61 }
62 fn is_parallel(&self) -> bool {
63 self.instruction_data().parallel
64 }
65 fn get_p_bit(&self) -> bool {
66 self.instruction_data().p_bit
67 }
68 fn set_parallel(&mut self, parallel: bool) {
69 self.instruction_data_mut().parallel = parallel;
70 }
71 fn conditional_operation(&self) -> Option<ConditionalOperation> {
72 self.instruction_data().conditional_operation
73 }
74}
75
76pub struct InstructionInput {
77 pub opcode: u32,
78 pub fphead: Option<CompactInstructionHeader>,
79 pub pce1_address: u32,
80}
81
82#[derive(Clone)]
83pub struct InstructionData {
84 pub opcode: u32,
85 pub compact: bool,
86 pub parallel: bool,
87 pub p_bit: bool,
89 pub conditional_operation: Option<ConditionalOperation>,
90}
91
92impl Default for InstructionData {
93 fn default() -> Self {
94 Self {
95 opcode: 0,
96 compact: false,
97 parallel: false,
98 p_bit: false,
99 conditional_operation: None,
100 }
101 }
102}
103
104#[derive(PartialEq, Eq, Clone, Copy)]
105pub enum DataSize {
106 Byte,
107 ByteUnsigned,
108 HalfWord,
109 HalfWordUnsigned,
110 Word,
111 NonAlignedWord,
112 DoubleWord,
113 NonAlignedDoubleWord,
114}
115
116impl DataSize {
117 fn to_short_string(&self) -> String {
118 match self {
119 Self::Byte => String::from("B"),
120 Self::ByteUnsigned => String::from("BU"),
121 Self::HalfWord => String::from("H"),
122 Self::HalfWordUnsigned => String::from("HU"),
123 Self::Word => String::from("W"),
124 Self::NonAlignedWord => String::from("NW"),
125 Self::DoubleWord => String::from("DW"),
126 Self::NonAlignedDoubleWord => String::from("NDW"),
127 }
128 }
129}
130
131impl Display for DataSize {
132 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
133 match self {
134 Self::Byte => write!(f, "Byte"),
135 Self::ByteUnsigned => write!(f, "ByteUnsigned"),
136 Self::HalfWord => write!(f, "HalfWord"),
137 Self::HalfWordUnsigned => write!(f, "HalfWordUnsigned"),
138 Self::Word => write!(f, "Word"),
139 Self::NonAlignedWord => write!(f, "NonAlignedWord"),
140 Self::DoubleWord => write!(f, "DoubleWord"),
141 Self::NonAlignedDoubleWord => write!(f, "NonAlignedDoubleWord"),
142 }
143 }
144}
145
146#[derive(PartialEq, Eq, Clone, Copy)]
147pub enum Unit {
148 L,
149 S,
150 M,
151 D,
152}
153
154impl Unit {
155 pub fn to_sided_string(&self, side: bool) -> String {
156 let mut value = self.to_string();
157 if side == false {
158 value += "1";
159 } else {
160 value += "2";
161 }
162 value
163 }
164}
165
166impl Display for Unit {
167 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
168 match self {
169 Self::L => write!(f, "L"),
170 Self::S => write!(f, "S"),
171 Self::M => write!(f, "M"),
172 Self::D => write!(f, "D"),
173 }
174 }
175}
176
177#[derive(PartialEq, Eq, Clone, Copy)]
178pub enum ConditionalOperation {
179 ReservedLow,
180 ReservedHigh,
181 Zero(Register),
182 NonZero(Register),
183}
184
185impl ConditionalOperation {
186 pub fn from(creg: u8, z: bool) -> Option<Self> {
187 if creg == 0 && z == true {
188 return Some(ConditionalOperation::ReservedLow);
189 } else if creg == 0b111 {
190 return Some(ConditionalOperation::ReservedHigh);
191 }
192 let register_option = {
193 if creg & 0b100 == 0b100 {
194 match creg & 0b11 {
195 0b00 => Some(Register::A(1)),
196 0b01 => Some(Register::A(2)),
197 0b10 => Some(Register::A(0)),
198 _ => None,
199 }
200 } else {
201 match creg & 0b11 {
202 0b01 => Some(Register::B(0)),
203 0b10 => Some(Register::B(1)),
204 0b11 => Some(Register::B(2)),
205 _ => None,
206 }
207 }
208 };
209
210 if let Some(register) = register_option {
211 if z {
212 Some(ConditionalOperation::Zero(register))
213 } else {
214 Some(ConditionalOperation::NonZero(register))
215 }
216 } else {
217 None
218 }
219 }
220}
221
222impl Display for ConditionalOperation {
223 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
224 match self {
225 ConditionalOperation::NonZero(register) => write!(f, "{register}"),
226 ConditionalOperation::Zero(register) => write!(f, "!{register}"),
227 ConditionalOperation::ReservedLow | ConditionalOperation::ReservedHigh => write!(f, ""),
228 }
229 }
230}