1use crate::deserialise::Error;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4#[derive(serde::Deserialize, serde::Serialize)]
5#[repr(u16)]
6pub enum Opcode {
7 Copy,
8 Load,
9 Store,
10 Branch,
11 CBranch,
12 IBranch,
13 Call,
14 ICall,
15 CallOther,
16 Return,
17 IntEq,
18 IntNotEq,
19 IntSLess,
20 IntSLessEq,
21 IntLess,
22 IntLessEq,
23 IntZExt,
24 IntSExt,
25 IntNeg,
26 IntNot,
27 IntAdd,
28 IntSub,
29 IntMul,
30 IntDiv,
31 IntSDiv,
32 IntRem,
33 IntSRem,
34 IntCarry,
35 IntSCarry,
36 IntSBorrow,
37 IntAnd,
38 IntOr,
39 IntXor,
40 IntLShift,
41 IntRShift,
42 IntSRShift,
43 BoolNot,
44 BoolAnd,
45 BoolOr,
46 BoolXor,
47 FloatEq,
48 FloatNotEq,
49 FloatLess,
50 FloatLessEq,
51 FloatIsNaN,
52 FloatAdd,
53 FloatSub,
54 FloatMul,
55 FloatDiv,
56 FloatNeg,
57 FloatAbs,
58 FloatSqrt,
59 FloatOfInt,
60 FloatOfFloat,
61 FloatTruncate,
62 FloatCeiling,
63 FloatFloor,
64 FloatRound,
65 Build,
66 DelaySlot,
67 Piece,
68 Subpiece,
69 Cast,
70 Label,
71 CrossBuild,
72 SegmentOp,
73 CPoolRef,
74 New,
75 Insert,
76 Extract,
77 PopCount,
78}
79
80impl Opcode {
81 pub fn from_str(input: &str) -> Result<Self, Error> {
82 Ok(match input {
83 "COPY" => Self::Copy,
84 "LOAD" => Self::Load,
85 "STORE" => Self::Store,
86 "BRANCH" => Self::Branch,
87 "CBRANCH" => Self::CBranch,
88 "BRANCHIND" => Self::IBranch,
89 "CALL" => Self::Call,
90 "CALLIND" => Self::ICall,
91 "CALLOTHER" => Self::CallOther,
92 "RETURN" => Self::Return,
93 "INT_EQUAL" => Self::IntEq,
94 "INT_NOTEQUAL" => Self::IntNotEq,
95 "INT_SLESS" => Self::IntSLess,
96 "INT_SLESSEQUAL" => Self::IntSLessEq,
97 "INT_LESS" => Self::IntLess,
98 "INT_LESSEQUAL" => Self::IntLessEq,
99 "INT_ZEXT" => Self::IntZExt,
100 "INT_SEXT" => Self::IntSExt,
101 "INT_ADD" => Self::IntAdd,
102 "INT_SUB" => Self::IntSub,
103 "INT_CARRY" => Self::IntCarry,
104 "INT_SCARRY" => Self::IntSCarry,
105 "INT_SBORROW" => Self::IntSBorrow,
106 "INT_2COMP" => Self::IntNeg,
107 "INT_NEGATE" => Self::IntNot,
108 "INT_XOR" => Self::IntXor,
109 "INT_AND" => Self::IntAnd,
110 "INT_OR" => Self::IntOr,
111 "INT_LEFT" => Self::IntLShift,
112 "INT_RIGHT" => Self::IntRShift,
113 "INT_SRIGHT" => Self::IntSRShift,
114 "INT_MULT" => Self::IntMul,
115 "INT_DIV" => Self::IntDiv,
116 "INT_SDIV" => Self::IntSDiv,
117 "INT_REM" => Self::IntRem,
118 "INT_SREM" => Self::IntSRem,
119 "BOOL_NEGATE" => Self::BoolNot,
120 "BOOL_XOR" => Self::BoolXor,
121 "BOOL_AND" => Self::BoolAnd,
122 "BOOL_OR" => Self::BoolOr,
123 "FLOAT_EQUAL" => Self::FloatEq,
124 "FLOAT_NOTEQUAL" => Self::FloatNotEq,
125 "FLOAT_LESS" => Self::FloatLess,
126 "FLOAT_LESSEQUAL" => Self::FloatLessEq,
127 "FLOAT_NAN" => Self::FloatIsNaN,
128 "FLOAT_ADD" => Self::FloatAdd,
129 "FLOAT_DIV" => Self::FloatDiv,
130 "FLOAT_MULT" => Self::FloatMul,
131 "FLOAT_SUB" => Self::FloatSub,
132 "FLOAT_NEG" => Self::FloatNeg,
133 "FLOAT_ABS" => Self::FloatAbs,
134 "FLOAT_SQRT" => Self::FloatSqrt,
135 "INT2FLOAT" => Self::FloatOfInt,
136 "FLOAT2FLOAT" => Self::FloatOfFloat,
137 "TRUNC" => Self::FloatTruncate,
138 "CEIL" => Self::FloatCeiling,
139 "FLOOR" => Self::FloatFloor,
140 "ROUND" => Self::FloatRound,
141 "BUILD" => Self::Build,
142 "DELAY_SLOT" => Self::DelaySlot,
143 "PIECE" => Self::Piece,
144 "SUBPIECE" => Self::Subpiece,
145 "CAST" => Self::Cast,
146 "LABEL" => Self::Label,
147 "CROSSBUILD" => Self::CrossBuild,
148 "SEGMENTOP" => Self::SegmentOp,
149 "CPOOLREF" => Self::CPoolRef,
150 "NEW" => Self::New,
151 "INSERT" => Self::Insert,
152 "EXTRACT" => Self::Extract,
153 "POPCOUNT" => Self::PopCount,
154 _ => return Err(Error::Invariant("invalid opcode name")),
155 })
156 }
157}