use crate::data::{ literal::DebugMsg, literal::Label, literal::RoutineName, Rd, Wr, }; use crate::instr::Cond; /// A higher level simple opration #[derive(Clone, Debug, Eq, PartialEq)] pub enum HLOp { /// Mark a jump target. Label(Label), /// Jump to a label Jump(Label), /// Jump to a label if a flag is set JumpIf(Cond, Label), /// Low level op L(Op), } /// A low level instruction #[derive(Clone, Debug, Eq, PartialEq)] pub enum Op { /// Do nothing Nop, /// Mark a far jump target (can be jumped to from another routine). /// This label is preserved in optimized code. FarLabel(Label), /// Jump to a label that can be in another function FarJump(Label), /// Call a routine with arguments. /// The arguments are passed as argX. Return values are stored in resX registers. Call(RoutineName, Vec), /// Exit the current routine with return values Ret(Vec), /// Mark a routine entry point (call target). /// Kept in the low level instruction file for position-independent code Routine(RoutineName), /// Skip backward or forward Skip(Rd), /// Skip if a flag is set SkipIf(Cond, Rd), /// Deny jumps, skips and run across this address, producing a run-time fault with a message. Barrier(Option), /// Generate a run-time fault with a debugger message Fault(Option), Move { dst: Wr, src: Rd }, Test { a: Rd }, Compare { a: Rd, b: Rd }, StoreStatus { dst: Wr }, LoadStatus { src: Rd }, Add { dst: Wr, a: Rd, b: Rd }, Sub { dst: Wr, a: Rd, b: Rd }, Mul { dst: Wr, a: Rd, b: Rd }, Div { dst: Wr, rem: Wr, a: Rd, div: Rd }, // "Mod" is functionally equivalent to "Div" with the result discarded, // but status flags are updated by the remainder Mod { dst: Wr, a: Rd, div: Rd }, And { dst: Wr, a: Rd, b: Rd }, Or { dst: Wr, a: Rd, b: Rd }, Xor { dst: Wr, a: Rd, b: Rd }, Cpl { dst: Wr, a: Rd }, Rol { dst: Wr, a: Rd, n: Rd }, // Rotate (with wrap-around) Ror { dst: Wr, a: Rd, n: Rd }, Lsl { dst: Wr, a: Rd, n: Rd }, // Shift Lsr { dst: Wr, a: Rd, n: Rd }, Asr { dst: Wr, a: Rd, n: Rd }, } /// Make "into" work impl From for HLOp { fn from(op: Op) -> Self { HLOp::L(op) } }