Skip to main content

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