cambridge_asm/exec/
cmp.rs1use super::{Context, RtError::*, RtResult};
7use crate::inst::Op::{self, *};
8
9pub fn jmp(ctx: &mut Context, op: &Op) -> RtResult {
15 match op {
16 &Addr(x) => {
17 ctx.override_flow_control();
18 ctx.mar = x;
19 }
20 MultiOp(ops) => match ops[..] {
21 [Addr(eq), Addr(ne)] => {
22 ctx.override_flow_control();
23 if ctx.cmp {
24 ctx.mar = eq;
25 } else {
26 ctx.mar = ne;
27 }
28 }
29 _ => return Err(InvalidMultiOp),
30 },
31 Null => return Err(NoOperand),
32 _ => return Err(InvalidOperand),
33 }
34
35 Ok(())
36}
37
38pub fn cmp(ctx: &mut Context, op: &Op) -> RtResult {
44 match op {
45 MultiOp(ops) => match ops[..] {
46 [ref a, ref b] if a.is_usizeable() && b.is_usizeable() => {
47 ctx.cmp = ctx.read(a)? == ctx.read(b)?;
48 }
49 _ => return Err(InvalidMultiOp),
50 },
51 val if val.is_usizeable() => ctx.cmp = ctx.acc == ctx.read(val)?,
52 Null => return Err(NoOperand),
53 _ => return Err(InvalidOperand),
54 }
55
56 Ok(())
57}
58
59pub fn cmi(ctx: &mut Context, op: &Op) -> RtResult {
65 match op {
66 &Addr(addr) => {
67 let addr2 = ctx.mem.get(&addr)?;
68
69 ctx.cmp = ctx.acc
70 == ctx
71 .mem
72 .get(addr2)
73 .copied()
74 .map_err(|_| InvalidIndirectAddr {
75 src: addr,
76 redirect: *addr2,
77 })?;
78
79 Ok(())
80 }
81 MultiOp(ops) => match ops[..] {
82 [ref dest, Addr(addr)] if dest.is_usizeable() => {
83 let addr2 = ctx.mem.get(&addr)?;
84
85 ctx.cmp = ctx.read(dest)?
86 == ctx
87 .mem
88 .get(addr2)
89 .copied()
90 .map_err(|_| InvalidIndirectAddr {
91 src: addr,
92 redirect: *addr2,
93 })?;
94
95 Ok(())
96 }
97 _ => Err(InvalidMultiOp),
98 },
99 Null => Err(NoOperand),
100 _ => Err(InvalidOperand),
101 }
102}
103
104pub fn jpe(ctx: &mut Context, op: &Op) -> RtResult {
109 match op {
110 &Addr(addr) => {
111 if ctx.cmp {
112 ctx.override_flow_control();
113 ctx.mar = addr;
114 }
115
116 Ok(())
117 }
118 Null => Err(NoOperand),
119 _ => Err(InvalidOperand),
120 }
121}
122
123pub fn jpn(ctx: &mut Context, op: &Op) -> RtResult {
128 match op {
129 &Addr(addr) => {
130 if !ctx.cmp {
131 ctx.override_flow_control();
132 ctx.mar = addr;
133 }
134
135 Ok(())
136 }
137 Null => Err(NoOperand),
138 _ => Err(InvalidOperand),
139 }
140}