charm/core/a64/instructions/abs.rs
1//! # ABS
2//!
3//! This instruction calculates the absolute value of the signed integer value in the source register, and writes the result to the destination register.
4
5#![allow(non_snake_case)]
6#![allow(unused)]
7use crate::error::Result;
8use crate::utils::*;
9use super::super::formatter::*;
10use super::super::instruction::*;
11use super::super::operand::*;
12use super::super::consts::*;
13use super::super::config::*;
14use super::super::decoder::*;
15
16// ---------------------------------------------------------------------------
17// Iclass IclassAbs32Dp1src
18// ---------------------------------------------------------------------------
19
20/// Type that represents the IclassAbs32Dp1src instruction class.
21pub(crate) struct IclassAbs32Dp1src;
22
23impl IclassAbs32Dp1src {
24 /// Tries to decode the instruction in `data`.
25 pub(crate) fn decode(data: u32, decoder: &mut Decoder) -> Result<Instruction> {
26 let opcode = (data >> 10) & 63;
27 let opcode_post = opcode;
28 let S = (data >> 29) & 1;
29 let S_post = S;
30 let opcode2 = (data >> 16) & 31;
31 let opcode2_post = opcode2;
32 let Rn = (data >> 5) & 31;
33 let Rn_post = Rn;
34 let sf = (data >> 31) & 1;
35 let sf_post = sf;
36 let field_28 = (data >> 21) & 255;
37 let field_28_post = field_28;
38 let Rd = (data >> 0) & 31;
39 let Rd_post = Rd;
40 let field_30 = (data >> 30) & 1;
41 let field_30_post = field_30;
42
43
44 if (sf_post == 0) {
45 return Abs32Dp1src::decode(data as u32, decoder);
46 }
47
48 if (sf_post == 1) {
49 return Abs64Dp1src::decode(data as u32, decoder);
50 }
51
52 unreachable!()
53 }
54}
55
56/// 32-bit encoding.
57///
58/// # Encoding
59///
60/// <table style="font-family: courier, monospace">
61/// <tr>
62/// <td style="border: none">31</td>
63/// <td style="border: none">30</td>
64/// <td style="border: none">29</td>
65/// <td style="border: none">28</td>
66/// <td style="border: none">27</td>
67/// <td style="border: none">26</td>
68/// <td style="border: none">25</td>
69/// <td style="border: none">24</td>
70/// <td style="border: none">23</td>
71/// <td style="border: none">22</td>
72/// <td style="border: none">21</td>
73/// <td style="border: none">20</td>
74/// <td style="border: none">19</td>
75/// <td style="border: none">18</td>
76/// <td style="border: none">17</td>
77/// <td style="border: none">16</td>
78/// <td style="border: none">15</td>
79/// <td style="border: none">14</td>
80/// <td style="border: none">13</td>
81/// <td style="border: none">12</td>
82/// <td style="border: none">11</td>
83/// <td style="border: none">10</td>
84/// <td style="border: none">9</td>
85/// <td style="border: none">8</td>
86/// <td style="border: none">7</td>
87/// <td style="border: none">6</td>
88/// <td style="border: none">5</td>
89/// <td style="border: none">4</td>
90/// <td style="border: none">3</td>
91/// <td style="border: none">2</td>
92/// <td style="border: none">1</td>
93/// <td style="border: none">0</td>
94/// </tr>
95/// <tr>
96/// <td style="text-align: center" colspan="1">sf</td>
97/// <td style="text-align: center; border-right: none" colspan="1">1</td>
98/// <td style="text-align: center; border-right: none" colspan="1">0</td>
99/// <td style="text-align: center; border-right: none" colspan="1">1</td>
100/// <td style="text-align: center; border-left: none; border-right: none" colspan="1">1</td>
101/// <td style="text-align: center; border-left: none; border-right: none" colspan="1">0</td>
102/// <td style="text-align: center; border-left: none; border-right: none" colspan="1">1</td>
103/// <td style="text-align: center; border-left: none; border-right: none" colspan="1">0</td>
104/// <td style="text-align: center; border-left: none; border-right: none" colspan="1">1</td>
105/// <td style="text-align: center; border-left: none; border-right: none" colspan="1">1</td>
106/// <td style="text-align: center; border-left: none" colspan="1">0</td>
107/// <td style="text-align: center; border-right: none" colspan="1">0</td>
108/// <td style="text-align: center; border-left: none; border-right: none" colspan="1">0</td>
109/// <td style="text-align: center; border-left: none; border-right: none" colspan="1">0</td>
110/// <td style="text-align: center; border-left: none; border-right: none" colspan="1">0</td>
111/// <td style="text-align: center; border-left: none" colspan="1">0</td>
112/// <td style="text-align: center; border-right: none" colspan="1">0</td>
113/// <td style="text-align: center; border-left: none; border-right: none" colspan="1">0</td>
114/// <td style="text-align: center; border-left: none; border-right: none" colspan="1">1</td>
115/// <td style="text-align: center; border-left: none; border-right: none" colspan="1">0</td>
116/// <td style="text-align: center; border-left: none; border-right: none" colspan="1">0</td>
117/// <td style="text-align: center; border-left: none" colspan="1">0</td>
118/// <td style="text-align: center" colspan="5">Rn</td>
119/// <td style="text-align: center" colspan="5">Rd</td>
120/// </tr>
121/// <tr>
122/// <td style="text-align: center; border: none" colspan="1"></td>
123/// <td style="text-align: center; border: none" colspan="1"></td>
124/// <td style="text-align: center; border: none" colspan="1">S</td>
125/// <td style="text-align: center; border: none" colspan="8"></td>
126/// <td style="text-align: center; border: none" colspan="5">opcode2</td>
127/// <td style="text-align: center; border: none" colspan="6">opcode</td>
128/// <td style="text-align: center; border: none" colspan="5"></td>
129/// <td style="text-align: center; border: none" colspan="5"></td>
130/// </tr>
131/// </table>
132pub struct Abs32Dp1src;
133
134impl Abs32Dp1src {
135 /// Returns the instruction mnemonic.
136 pub fn mnemonic(_instr: &Instruction) -> Mnemonic {
137 Mnemonic::ABS
138 }
139
140 /// Returns the instruction size.
141 pub fn size(_instr: &Instruction) -> usize {
142 4
143 }
144
145 /// Decodes the instruction in `data`.
146 pub fn decode(data: u32, decoder: &mut Decoder) -> Result<Instruction> {
147 // Fields are extracted from the input value.
148 let Rn = (data >> 5) & 31;
149 let Rn_post = Rn;
150 let Rd = (data >> 0) & 31;
151 let Rd_post = Rd;
152
153
154 // Operand values are computed from the base fields.
155 let Rd_post = Rd;
156 let op_0 = Register::aarch32(Rd_post, false)?;
157 let Rn_post = Rn;
158 let op_1 = Register::aarch32(Rn_post, false)?;
159
160 // Instruction creation from the operands.
161 let mut instr = Instruction::builder(Code::ABS_32_dp_1src)
162 .operand(0, op_0)?
163 .operand(1, op_1)?
164 .build();
165
166 Ok(instr)
167 }
168
169 /// Encodes the instruction into `buf`.
170 pub fn encode(instr: &Instruction, buf: &mut Vec<u8>) -> Result<usize> {
171 // Retrieve all operand values.
172 let Rd_pre = instr.op0().as_register()?.encode();
173 let Rn_pre = instr.op1().as_register()?.encode();
174
175 // Compute all instruction fields from the operand values.
176 let Rd = (Rd_pre & 31);
177 let Rn = (Rn_pre & 31);
178
179 // Add all fields to the base instruction encoding.
180 let mut instr: u32 = 0b01011010110000000010000000000000;
181 instr |= (Rd & 31) << 0;
182 instr |= (Rn & 31) << 5;
183
184 let bytes = instr.to_le_bytes();
185 let len = bytes.len();
186 buf.extend(bytes);
187 Ok(len)
188 }
189
190 /// Encode an instruction part of an instruction block into `buf`.
191 pub fn encode_block(instr: &mut Instruction, buf: &mut Vec<u8>, labels: &std::collections::HashMap<u64, u64>) -> Result<usize> {
192 Self::encode(instr, buf)
193 }
194
195 /// Verifies that operand #0 is valid.
196 pub fn check_op0(instr: &Instruction, op: &Operand) -> Result<()> {
197 if let Operand::Register(r) = op {
198 if !r.is_aarch32() {
199 todo!()
200 }
201 if *r == Register::WSP {
202 todo!()
203 }
204 return Ok(())
205 }
206 todo!()
207 }
208
209 /// Verifies that operand #1 is valid.
210 pub fn check_op1(instr: &Instruction, op: &Operand) -> Result<()> {
211 if let Operand::Register(r) = op {
212 if !r.is_aarch32() {
213 todo!()
214 }
215 if *r == Register::WSP {
216 todo!()
217 }
218 return Ok(())
219 }
220 todo!()
221 }
222
223 /// Verifies that operand #2 is valid.
224 pub fn check_op2(instr: &Instruction, op: &Operand) -> Result<()> {
225 todo!()
226 }
227
228 /// Verifies that operand #3 is valid.
229 pub fn check_op3(instr: &Instruction, op: &Operand) -> Result<()> {
230 todo!()
231 }
232
233 /// Verifies that operand #4 is valid.
234 pub fn check_op4(instr: &Instruction, op: &Operand) -> Result<()> {
235 todo!()
236 }
237
238 /// Verifies that operand #5 is valid.
239 pub fn check_op5(instr: &Instruction, op: &Operand) -> Result<()> {
240 todo!()
241 }
242
243 /// Verifies that operand #6 is valid.
244 pub fn check_op6(instr: &Instruction, op: &Operand) -> Result<()> {
245 todo!()
246 }
247
248 /// Formats the instruction.
249 pub fn format(instr: &Instruction, fmt: &mut impl Formatter, output: &mut impl FormatterOutput, config: &Config) -> Result<()> {
250 fmt.format_mnemonic(output, &config.global, &config.instructions.abs_32_dp_1src, instr)?;
251 fmt.format_punctuation(output, &config.global, &config.instructions.abs_32_dp_1src, instr, FormatterTextKind::Space)?;
252 fmt.format_operand(output, &config.global, &config.instructions.abs_32_dp_1src, instr, 0)?;
253 fmt.format_punctuation(output, &config.global, &config.instructions.abs_32_dp_1src, instr, FormatterTextKind::Comma)?;
254 fmt.format_operand(output, &config.global, &config.instructions.abs_32_dp_1src, instr, 1)?;
255 Ok(())
256 }
257}
258
259/// Type that represents alias identifiers for [`Abs32Dp1src`].
260#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
261pub enum Abs32Dp1srcAliases {
262 None,
263}
264
265/// 64-bit encoding.
266///
267/// # Encoding
268///
269/// <table style="font-family: courier, monospace">
270/// <tr>
271/// <td style="border: none">31</td>
272/// <td style="border: none">30</td>
273/// <td style="border: none">29</td>
274/// <td style="border: none">28</td>
275/// <td style="border: none">27</td>
276/// <td style="border: none">26</td>
277/// <td style="border: none">25</td>
278/// <td style="border: none">24</td>
279/// <td style="border: none">23</td>
280/// <td style="border: none">22</td>
281/// <td style="border: none">21</td>
282/// <td style="border: none">20</td>
283/// <td style="border: none">19</td>
284/// <td style="border: none">18</td>
285/// <td style="border: none">17</td>
286/// <td style="border: none">16</td>
287/// <td style="border: none">15</td>
288/// <td style="border: none">14</td>
289/// <td style="border: none">13</td>
290/// <td style="border: none">12</td>
291/// <td style="border: none">11</td>
292/// <td style="border: none">10</td>
293/// <td style="border: none">9</td>
294/// <td style="border: none">8</td>
295/// <td style="border: none">7</td>
296/// <td style="border: none">6</td>
297/// <td style="border: none">5</td>
298/// <td style="border: none">4</td>
299/// <td style="border: none">3</td>
300/// <td style="border: none">2</td>
301/// <td style="border: none">1</td>
302/// <td style="border: none">0</td>
303/// </tr>
304/// <tr>
305/// <td style="text-align: center" colspan="1">sf</td>
306/// <td style="text-align: center; border-right: none" colspan="1">1</td>
307/// <td style="text-align: center; border-right: none" colspan="1">0</td>
308/// <td style="text-align: center; border-right: none" colspan="1">1</td>
309/// <td style="text-align: center; border-left: none; border-right: none" colspan="1">1</td>
310/// <td style="text-align: center; border-left: none; border-right: none" colspan="1">0</td>
311/// <td style="text-align: center; border-left: none; border-right: none" colspan="1">1</td>
312/// <td style="text-align: center; border-left: none; border-right: none" colspan="1">0</td>
313/// <td style="text-align: center; border-left: none; border-right: none" colspan="1">1</td>
314/// <td style="text-align: center; border-left: none; border-right: none" colspan="1">1</td>
315/// <td style="text-align: center; border-left: none" colspan="1">0</td>
316/// <td style="text-align: center; border-right: none" colspan="1">0</td>
317/// <td style="text-align: center; border-left: none; border-right: none" colspan="1">0</td>
318/// <td style="text-align: center; border-left: none; border-right: none" colspan="1">0</td>
319/// <td style="text-align: center; border-left: none; border-right: none" colspan="1">0</td>
320/// <td style="text-align: center; border-left: none" colspan="1">0</td>
321/// <td style="text-align: center; border-right: none" colspan="1">0</td>
322/// <td style="text-align: center; border-left: none; border-right: none" colspan="1">0</td>
323/// <td style="text-align: center; border-left: none; border-right: none" colspan="1">1</td>
324/// <td style="text-align: center; border-left: none; border-right: none" colspan="1">0</td>
325/// <td style="text-align: center; border-left: none; border-right: none" colspan="1">0</td>
326/// <td style="text-align: center; border-left: none" colspan="1">0</td>
327/// <td style="text-align: center" colspan="5">Rn</td>
328/// <td style="text-align: center" colspan="5">Rd</td>
329/// </tr>
330/// <tr>
331/// <td style="text-align: center; border: none" colspan="1"></td>
332/// <td style="text-align: center; border: none" colspan="1"></td>
333/// <td style="text-align: center; border: none" colspan="1">S</td>
334/// <td style="text-align: center; border: none" colspan="8"></td>
335/// <td style="text-align: center; border: none" colspan="5">opcode2</td>
336/// <td style="text-align: center; border: none" colspan="6">opcode</td>
337/// <td style="text-align: center; border: none" colspan="5"></td>
338/// <td style="text-align: center; border: none" colspan="5"></td>
339/// </tr>
340/// </table>
341pub struct Abs64Dp1src;
342
343impl Abs64Dp1src {
344 /// Returns the instruction mnemonic.
345 pub fn mnemonic(_instr: &Instruction) -> Mnemonic {
346 Mnemonic::ABS
347 }
348
349 /// Returns the instruction size.
350 pub fn size(_instr: &Instruction) -> usize {
351 4
352 }
353
354 /// Decodes the instruction in `data`.
355 pub fn decode(data: u32, decoder: &mut Decoder) -> Result<Instruction> {
356 // Fields are extracted from the input value.
357 let Rn = (data >> 5) & 31;
358 let Rn_post = Rn;
359 let Rd = (data >> 0) & 31;
360 let Rd_post = Rd;
361
362
363 // Operand values are computed from the base fields.
364 let Rd_post = Rd;
365 let op_0 = Register::aarch64(Rd_post, false)?;
366 let Rn_post = Rn;
367 let op_1 = Register::aarch64(Rn_post, false)?;
368
369 // Instruction creation from the operands.
370 let mut instr = Instruction::builder(Code::ABS_64_dp_1src)
371 .operand(0, op_0)?
372 .operand(1, op_1)?
373 .build();
374
375 Ok(instr)
376 }
377
378 /// Encodes the instruction into `buf`.
379 pub fn encode(instr: &Instruction, buf: &mut Vec<u8>) -> Result<usize> {
380 // Retrieve all operand values.
381 let Rd_pre = instr.op0().as_register()?.encode();
382 let Rn_pre = instr.op1().as_register()?.encode();
383
384 // Compute all instruction fields from the operand values.
385 let Rd = (Rd_pre & 31);
386 let Rn = (Rn_pre & 31);
387
388 // Add all fields to the base instruction encoding.
389 let mut instr: u32 = 0b11011010110000000010000000000000;
390 instr |= (Rd & 31) << 0;
391 instr |= (Rn & 31) << 5;
392
393 let bytes = instr.to_le_bytes();
394 let len = bytes.len();
395 buf.extend(bytes);
396 Ok(len)
397 }
398
399 /// Encode an instruction part of an instruction block into `buf`.
400 pub fn encode_block(instr: &mut Instruction, buf: &mut Vec<u8>, labels: &std::collections::HashMap<u64, u64>) -> Result<usize> {
401 Self::encode(instr, buf)
402 }
403
404 /// Verifies that operand #0 is valid.
405 pub fn check_op0(instr: &Instruction, op: &Operand) -> Result<()> {
406 if let Operand::Register(r) = op {
407 if !r.is_aarch64() {
408 todo!()
409 }
410
411 if *r == Register::SP {
412 todo!()
413 }
414 return Ok(())
415 }
416 todo!()
417 }
418
419 /// Verifies that operand #1 is valid.
420 pub fn check_op1(instr: &Instruction, op: &Operand) -> Result<()> {
421 if let Operand::Register(r) = op {
422 if !r.is_aarch64() {
423 todo!()
424 }
425
426 if *r == Register::SP {
427 todo!()
428 }
429 return Ok(())
430 }
431 todo!()
432 }
433
434 /// Verifies that operand #2 is valid.
435 pub fn check_op2(instr: &Instruction, op: &Operand) -> Result<()> {
436 todo!()
437 }
438
439 /// Verifies that operand #3 is valid.
440 pub fn check_op3(instr: &Instruction, op: &Operand) -> Result<()> {
441 todo!()
442 }
443
444 /// Verifies that operand #4 is valid.
445 pub fn check_op4(instr: &Instruction, op: &Operand) -> Result<()> {
446 todo!()
447 }
448
449 /// Verifies that operand #5 is valid.
450 pub fn check_op5(instr: &Instruction, op: &Operand) -> Result<()> {
451 todo!()
452 }
453
454 /// Verifies that operand #6 is valid.
455 pub fn check_op6(instr: &Instruction, op: &Operand) -> Result<()> {
456 todo!()
457 }
458
459 /// Formats the instruction.
460 pub fn format(instr: &Instruction, fmt: &mut impl Formatter, output: &mut impl FormatterOutput, config: &Config) -> Result<()> {
461 fmt.format_mnemonic(output, &config.global, &config.instructions.abs_64_dp_1src, instr)?;
462 fmt.format_punctuation(output, &config.global, &config.instructions.abs_64_dp_1src, instr, FormatterTextKind::Space)?;
463 fmt.format_operand(output, &config.global, &config.instructions.abs_64_dp_1src, instr, 0)?;
464 fmt.format_punctuation(output, &config.global, &config.instructions.abs_64_dp_1src, instr, FormatterTextKind::Comma)?;
465 fmt.format_operand(output, &config.global, &config.instructions.abs_64_dp_1src, instr, 1)?;
466 Ok(())
467 }
468}
469
470/// Type that represents alias identifiers for [`Abs64Dp1src`].
471#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
472pub enum Abs64Dp1srcAliases {
473 None,
474}
475