|
| 1 | +//! Implements STREXB (Store Register Exclusive Byte) instruction. |
| 2 | +
|
| 3 | +use super::{Encoding::T1, Pattern}; |
| 4 | +use crate::{ |
| 5 | + core::{ |
| 6 | + ArmVersion::{V7EM, V7M, V8M}, |
| 7 | + Effect, ItState, Processor, RunError, |
| 8 | + }, |
| 9 | + decoder::DecodeError, |
| 10 | + instructions::{unpredictable, DecodeHelper, Encoding, Instruction}, |
| 11 | + registers::RegisterIndex, |
| 12 | +}; |
| 13 | + |
| 14 | +/// STREXB instruction. |
| 15 | +/// |
| 16 | +/// Store Register Exclusive Byte. |
| 17 | +pub struct Strexb { |
| 18 | + /// Destination register for the returned status value. |
| 19 | + rd: RegisterIndex, |
| 20 | + /// Source register. |
| 21 | + rt: RegisterIndex, |
| 22 | + /// Base register. |
| 23 | + rn: RegisterIndex, |
| 24 | +} |
| 25 | + |
| 26 | +impl Instruction for Strexb { |
| 27 | + fn patterns() -> &'static [Pattern] { |
| 28 | + &[Pattern { |
| 29 | + encoding: T1, |
| 30 | + versions: &[V7M, V7EM, V8M], |
| 31 | + expression: "111010001100xxxxxxxx(1)(1)(1)(1)0100xxxx", |
| 32 | + }] |
| 33 | + } |
| 34 | + |
| 35 | + fn try_decode(encoding: Encoding, ins: u32, _state: ItState) -> Result<Self, DecodeError> { |
| 36 | + debug_assert_eq!(encoding, T1); |
| 37 | + let rd = ins.reg4(0); |
| 38 | + let rt = ins.reg4(12); |
| 39 | + let rn = ins.reg4(16); |
| 40 | + unpredictable(rd.is_sp_or_pc() || rt.is_sp_or_pc() || rn.is_pc())?; |
| 41 | + unpredictable(rd == rn || rd == rt)?; |
| 42 | + Ok(Self { rd, rt, rn }) |
| 43 | + } |
| 44 | + |
| 45 | + fn execute(&self, proc: &mut Processor) -> Result<Effect, RunError> { |
| 46 | + let address = proc[self.rn]; |
| 47 | + if proc.exclusive_monitors_pass(address, 1)? { |
| 48 | + let value = proc[self.rt] as u8; |
| 49 | + proc.write_u8(address, value)?; |
| 50 | + proc.set(self.rd, 0); |
| 51 | + } else { |
| 52 | + proc.set(self.rd, 1); |
| 53 | + } |
| 54 | + Ok(Effect::None) |
| 55 | + } |
| 56 | + |
| 57 | + fn name(&self) -> String { |
| 58 | + "strexb".into() |
| 59 | + } |
| 60 | + |
| 61 | + fn args(&self, _pc: u32) -> String { |
| 62 | + format!("{}, {}, [{}]", self.rd, self.rt, self.rn) |
| 63 | + } |
| 64 | +} |
0 commit comments