diff options
Diffstat (limited to 'src/predicate.rs')
-rw-r--r-- | src/predicate.rs | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/src/predicate.rs b/src/predicate.rs new file mode 100644 index 0000000..737ff7f --- /dev/null +++ b/src/predicate.rs @@ -0,0 +1,101 @@ +/* + Copyright 2021-2023 Gabriel Jensen. + + This file is part of Luma. + + Luma is free software: you can redistribute it + and/or modify it under the terms of the GNU + Affero General Public License as published by + the Free Software Foundation, either version 3 + of the License, or (at your option) any later + version. + + Luma is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU + Affero General Public License along with Luma. + If not, see <https://www.gnu.org/licenses/>. +*/ + +use std::mem::transmute; + +#[derive(Clone, Copy)] +#[repr(u8)] +pub enum Predicate { + Eq = 0b0000, + Ne = 0b0001, + Cs = 0b0010, // Hs + Cc = 0b0011, // Lo + Mi = 0b0100, + Pl = 0b0101, + Vs = 0b0110, + Vc = 0b0111, + Hi = 0b1000, + Ls = 0b1001, + Ge = 0b1010, + Lt = 0b1011, + Gt = 0b1100, + Le = 0b1101, + Al = 0b1110, + Nv = 0b1111, +} + +impl Predicate { + pub fn from_raw(mut raw: u8) -> Self { + raw &= 0b00001111; + return unsafe { transmute(raw) }; + } + + pub fn test(self, cpsr: u32) -> bool { + let v = cpsr & 0b00010000000000000000000000000000 != 0x0; + let c = cpsr & 0b00100000000000000000000000000000 != 0x0; + let z = cpsr & 0b01000000000000000000000000000000 != 0x0; + let n = cpsr & 0b10000000000000000000000000000000 != 0x0; + + use Predicate::*; + return match self { + Eq => z, + Ne => !z, + Cs => c, + Cc => !c, + Mi => n, + Pl => !n, + Vs => v, + Vc => !v, + Hi => c && !z, + Ls => !c && z, + Ge => n == v, + Lt => n != v, + Gt => !z && n == v, + Le => z && n != v, + Al => true, + Nv => false, // Unpredictable in ARMv4. + }; + } + + pub fn code(self) -> &'static str { + use Predicate::*; + return match self { + Eq => "eq", + Ne => "ne", + Cs => "cs", + Cc => "cc", + Mi => "mi", + Pl => "pl", + Vs => "vs", + Vc => "vc", + Hi => "hi", + Ls => "ls", + Ge => "ge", + Lt => "lt", + Gt => "gt", + Le => "le", + Al => "al", + Nv => "nv", + }; + } +} |