cambridge_asm/exec/
mov.rs1use super::{Context, RtError::*, RtResult};
7use crate::inst::Op::{self, *};
8
9pub fn ldm(ctx: &mut Context, op: &Op) -> RtResult {
16 match op {
17 MultiOp(ops) => match ops[..] {
18 [ref op, Literal(val)] if op.is_register() => {
19 *ctx.get_mut_register(op) = val;
20 Ok(())
21 }
22 _ => Err(InvalidMultiOp),
23 },
24 &Literal(val) => {
25 ctx.acc = val;
26 Ok(())
27 }
28 Null => Err(NoOperand),
29 _ => Err(InvalidOperand),
30 }
31}
32
33pub fn ldd(ctx: &mut Context, op: &Op) -> RtResult {
40 match op {
41 Addr(addr) => {
42 ctx.acc = ctx.mem.get(addr).copied()?;
43 Ok(())
44 }
45 MultiOp(ops) => match ops[..] {
46 [ref reg, Addr(ref addr)] if reg.is_register() => {
47 *ctx.get_mut_register(reg) = ctx.mem.get(addr).copied()?;
48 Ok(())
49 }
50 _ => Err(InvalidMultiOp),
51 },
52 Null => Err(NoOperand),
53 _ => Err(InvalidOperand),
54 }
55}
56
57pub fn ldi(ctx: &mut Context, op: &Op) -> RtResult {
64 match op {
65 &Addr(addr) => {
66 let addr2 = ctx.mem.get(&addr)?;
67
68 ctx.acc = ctx
69 .mem
70 .get(addr2)
71 .copied()
72 .map_err(|_| InvalidIndirectAddr {
73 src: addr,
74 redirect: *addr2,
75 })?;
76
77 Ok(())
78 }
79 MultiOp(ops) => match ops[..] {
80 [ref reg, Addr(addr)] if reg.is_register() => {
81 let addr2 = ctx.mem.get(&addr)?;
82
83 *ctx.get_mut_register(reg) =
84 ctx.mem
85 .get(addr2)
86 .copied()
87 .map_err(|_| InvalidIndirectAddr {
88 src: addr,
89 redirect: *addr2,
90 })?;
91
92 Ok(())
93 }
94 _ => Err(InvalidMultiOp),
95 },
96 Null => Err(NoOperand),
97 _ => Err(InvalidOperand),
98 }
99}
100
101pub fn ldx(ctx: &mut Context, op: &Op) -> RtResult {
108 match op {
109 &Addr(addr) => {
110 ctx.acc = ctx
111 .mem
112 .get(&(addr + ctx.ix))
113 .copied()
114 .map_err(|_| InvalidIndexedAddr {
115 src: addr,
116 offset: ctx.ix,
117 })?;
118
119 Ok(())
120 }
121 MultiOp(ops) => match ops[..] {
122 [ref reg, Addr(addr)] if reg.is_register() => {
123 *ctx.get_mut_register(reg) =
124 ctx.mem
125 .get(&(addr + ctx.ix))
126 .copied()
127 .map_err(|_| InvalidIndexedAddr {
128 src: addr,
129 offset: ctx.ix,
130 })?;
131
132 Ok(())
133 }
134 _ => Err(InvalidMultiOp),
135 },
136 Null => Err(NoOperand),
137 _ => Err(InvalidOperand),
138 }
139}
140
141pub fn ldr(ctx: &mut Context, op: &Op) -> RtResult {
146 match op {
147 &Literal(val) => ctx.ix = val,
148 Null => return Err(NoOperand),
149 _ => return Err(InvalidOperand),
150 }
151
152 Ok(())
153}
154
155pub fn mov(ctx: &mut Context, op: &Op) -> RtResult {
164 match op {
165 MultiOp(ops) => match ops[..] {
166 [ref dest, ref src] if dest.is_read_write() && src.is_usizeable() => {
167 let src = ctx.read(src)?;
168 ctx.modify(dest, |val| *val = src)?;
169 }
170 _ => return Err(InvalidMultiOp),
171 },
172 reg if reg.is_register() => *ctx.get_mut_register(reg) = ctx.acc,
173 Null => return Err(NoOperand),
174 _ => return Err(InvalidOperand),
175 }
176
177 Ok(())
178}
179
180pub fn sto(ctx: &mut Context, op: &Op) -> RtResult {
185 match op {
186 Addr(x) => {
187 *ctx.mem.get_mut(x)? = ctx.acc;
188
189 Ok(())
190 }
191 Null => Err(NoOperand),
192 _ => Err(InvalidOperand),
193 }
194}