1use std::fmt::{Display, Formatter};
2
3use crate::value::{LocalValueId, insn::mnemonic::MnemonicKind};
4use smallvec::smallvec;
5
6use super::mnemonic::Args;
7
8#[non_exhaustive]
9#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
10pub enum Unop {
11 IntNegate,
12 IntNot,
13 FloatNegate,
14 FloatAbs,
15 FloatSqrt,
16 FloatCeil,
17 FloatFloor,
18 FloatRound,
19}
20
21impl Unop {
22 pub fn eval_int(&self, value: u128, size: usize) -> Option<u128> {
27 use super::bits::mask_for_size;
28 let mask = mask_for_size(size);
29 let v = value & mask;
30 match self {
31 Unop::IntNegate => Some(v.wrapping_neg() & mask),
32 Unop::IntNot => Some(!v & mask),
33 _ => None,
34 }
35 }
36}
37
38impl Display for Unop {
39 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
40 let s = match self {
41 Unop::IntNegate => "-",
42 Unop::IntNot => "~",
43 Unop::FloatNegate => "f-",
44 Unop::FloatAbs => "abs",
45 Unop::FloatSqrt => "sqrt",
46 Unop::FloatCeil => "ceil",
47 Unop::FloatFloor => "floor",
48 Unop::FloatRound => "round",
49 };
50
51 write!(f, "{}", s)
52 }
53}
54
55#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
56pub struct Unary {
57 pub op: Unop,
58 pub src: LocalValueId,
59}
60
61impl MnemonicKind for Unary {
62 fn opcode(&self) -> &'static str {
63 "unop"
64 }
65
66 fn args(&self) -> Args {
67 smallvec![self.src]
68 }
69}
70
71