1
2use expression::{Expr,EvaluationError,IndirectionMode};
3use location::{Positioned,Span};
4use env::{Names,Env};
5use std::fmt;
6use waterbear_instruction_derive::Instruction;
7
8#[derive(Debug)]
9pub enum EncodingError {
10 NumOutOfRange {
11 span: Span,
12 bits: usize,
13 value: i32
14 },
15 SignedNumOutOfRange {
16 span: Span,
17 bits: usize,
18 value: i32
19 },
20 InvalidAddress {
21 span: Span,
22 value: i32
23 },
24 AddrBitsDontMatch {
25 span: Span,
26 pos: usize,
27 value: i32,
28 pos_top: u8,
29 value_top: u8
30 },
31 EvalError(EvaluationError)
32}
33
34impl EncodingError {
35 pub fn mismatch_top_bits(span: Span, pos: usize, value: i32, pos_top: u8, value_top: u8) -> EncodingError {
36 EncodingError::AddrBitsDontMatch { span, pos, value, pos_top, value_top }
37 }
38
39 pub fn out_of_range(span: Span, bits: usize, value: i32) -> EncodingError {
40 EncodingError::NumOutOfRange { span, bits, value }
41 }
42
43 pub fn signed_out_of_range(span: Span, bits: usize, value: i32) -> EncodingError {
44 EncodingError::SignedNumOutOfRange { span, bits, value }
45 }
46
47 pub fn invalid_addr(span: Span, value: i32) -> EncodingError {
48 EncodingError::InvalidAddress { span, value }
49 }
50}
51
52impl From<EvaluationError> for EncodingError {
53 fn from(error: EvaluationError) -> Self {
54 EncodingError::EvalError(error)
55 }
56}
57
58#[allow(non_camel_case_types)]
59#[derive(Debug,Instruction,Eq,PartialEq,Ord,PartialOrd,Hash,Clone)]
60pub enum Instr<Ex,IM> {
61 #[instr="10000001 [a7][a6][a5][a4][a3][a2][a1][a0]"]
62 Add_i8(Ex),
63 #[instr="1000001[a8] [a7][a6][a5][a4][a3][a2][a1][a0]"]
64 Add_d9(Ex),
65 #[instr="100001[a1][a0]"]
66 Add_Ri(IM),
67
68 #[instr="10010001 [a7][a6][a5][a4][a3][a2][a1][a0]"]
69 Addc_i8(Ex),
70 #[instr="1001001[a8] [a7][a6][a5][a4][a3][a2][a1][a0]"]
71 Addc_d9(Ex),
72 #[instr="100101[a1][a0]"]
73 Addc_Ri(IM),
74
75 #[instr="10100001 [a7][a6][a5][a4][a3][a2][a1][a0]"]
76 Sub_i8(Ex),
77 #[instr="1010001[a8] [a7][a6][a5][a4][a3][a2][a1][a0]"]
78 Sub_d9(Ex),
79 #[instr="101001[a1][a0]"]
80 Sub_Ri(IM),
81
82 #[instr="10110001 [a7][a6][a5][a4][a3][a2][a1][a0]"]
83 Subc_i8(Ex),
84 #[instr="1011001[a8] [a7][a6][a5][a4][a3][a2][a1][a0]"]
85 Subc_d9(Ex),
86 #[instr="101101[a1][a0]"]
87 Subc_Ri(IM),
88
89 #[instr="0110001[a8] [a7][a6][a5][a4][a3][a2][a1][a0]"]
90 Inc_d9(Ex),
91 #[instr="011001[a1][a0]"]
92 Inc_Ri(IM),
93
94 #[instr="0111001[a8] [a7][a6][a5][a4][a3][a2][a1][a0]"]
95 Dec_d9(Ex),
96 #[instr="011101[a1][a0]"]
97 Dec_Ri(IM),
98
99 #[instr="00110000"]
100 Mul,
101 #[instr="01000000"]
102 Div,
103
104 #[instr="11100001 [a7][a6][a5][a4][a3][a2][a1][a0]"]
105 And_i8(Ex),
106 #[instr="1110001[a8] [a7][a6][a5][a4][a3][a2][a1][a0]"]
107 And_d9(Ex),
108 #[instr="111001[a1][a0]"]
109 And_Ri(IM),
110
111 #[instr="11010001 [a7][a6][a5][a4][a3][a2][a1][a0]"]
112 Or_i8(Ex),
113 #[instr="1101001[a8] [a7][a6][a5][a4][a3][a2][a1][a0]"]
114 Or_d9(Ex),
115 #[instr="110101[a1][a0]"]
116 Or_Ri(IM),
117
118 #[instr="11110001 [a7][a6][a5][a4][a3][a2][a1][a0]"]
119 Xor_i8(Ex),
120 #[instr="1111001[a8] [a7][a6][a5][a4][a3][a2][a1][a0]"]
121 Xor_d9(Ex),
122 #[instr="111101[a1][a0]"]
123 Xor_Ri(IM),
124
125 #[instr="11100000"]
126 Rol,
127 #[instr="11110000"]
128 Rolc,
129
130 #[instr="11000000"]
131 Ror,
132 #[instr="11010000"]
133 Rorc,
134
135 #[instr="0000001[a8] [a7][a6][a5][a4][a3][a2][a1][a0]"]
136 Ld_d9(Ex),
137 #[instr="000001[a1][a0]"]
138 Ld_Ri(IM),
139
140 #[instr="0001001[a8] [a7][a6][a5][a4][a3][a2][a1][a0]"]
141 St_d9(Ex),
142 #[instr="000101[a1][a0]"]
143 St_Ri(IM),
144
145 #[instr="0010001[b8] [b7][b6][b5][b4][b3][b2][b1][b0] [a7][a6][a5][a4][a3][a2][a1][a0]"]
146 Mov_d9(Ex, Ex),
147 #[instr="001001[b1][b0] [a7][a6][a5][a4][a3][a2][a1][a0]"]
148 Mov_Rj(Ex, IM),
149
150 #[instr="11000001"]
151 Ldc,
152
153 #[instr="0110000[a8] [a7][a6][a5][a4][a3][a2][a1][a0]"]
154 Push(Ex),
155 #[instr="0111000[a8] [a7][a6][a5][a4][a3][a2][a1][a0]"]
156 Pop(Ex),
157
158 #[instr="1100001[a8] [a7][a6][a5][a4][a3][a2][a1][a0]"]
159 Xch_d9(Ex),
160 #[instr="110001[a1][a0]"]
161 Xch_Ri(IM),
162
163 #[instr="001[a11]1[a10][a9][a8] [a7][a6][a5][a4][a3][a2][a1][a0]"]
164 Jmp(Ex),
165 #[instr="00100001 [a15][a14][a13][a12][a11][a10][a9][a8] [a7][a6][a5][a4][a3][a2][a1][a0]"]
166 Jmpf(Ex),
167
168 #[instr="00000001 [a7][a6][a5][a4][a3][a2][a1][a0]"]
169 Br(Ex),
170 #[instr="00010001 [a7][a6][a5][a4][a3][a2][a1][a0] [a15][a14][a13][a12][a11][a10][a9][a8]"]
171 Brf(Ex),
172 #[instr="10000000 [a7][a6][a5][a4][a3][a2][a1][a0]"]
173 Bz(Ex),
174 #[instr="10010000 [a7][a6][a5][a4][a3][a2][a1][a0]"]
175 Bnz(Ex),
176 #[instr="011[a8]1[b2][b1][b0] [a7][a6][a5][a4][a3][a2][a1][a0] [c7][c6][c5][c4][c3][c2][c1][c0]"]
177 Bp(Ex, Ex, Ex),
178 #[instr="010[a8]1[b2][b1][b0] [a7][a6][a5][a4][a3][a2][a1][a0] [c7][c6][c5][c4][c3][c2][c1][c0]"]
179 Bpc(Ex, Ex, Ex),
180 #[instr="100[a8]1[b2][b1][b0] [a7][a6][a5][a4][a3][a2][a1][a0] [c7][c6][c5][c4][c3][c2][c1][c0]"]
181 Bn(Ex, Ex, Ex),
182 #[instr="0101001[a8] [a7][a6][a5][a4][a3][a2][a1][a0] [b7][b6][b5][b4][b3][b2][b1][b0]"]
183 Dbnz_d9(Ex, Ex),
184 #[instr="010101[a1][a0] [b7][b6][b5][b4][b3][b2][b1][b0]"]
185 Dbnz_Ri(IM, Ex),
186 #[instr="00110001 [a7][a6][a5][a4][a3][a2][a1][a0] [b7][b6][b5][b4][b3][b2][b1][b0]"]
187 Be_i8(Ex, Ex),
188 #[instr="0011001[a8] [a7][a6][a5][a4][a3][a2][a1][a0] [b7][b6][b5][b4][b3][b2][b1][b0]"]
189 Be_d9(Ex, Ex),
190 #[instr="001101[a1][a0] [b7][b6][b5][b4][b3][b2][b1][b0] [c7][c6][c5][c4][c3][c2][c1][c0]"]
191 Be_Rj(IM, Ex, Ex),
192 #[instr="01000001 [a7][a6][a5][a4][a3][a2][a1][a0] [b7][b6][b5][b4][b3][b2][b1][b0]"]
193 Bne_i8(Ex, Ex),
194 #[instr="0100001[a8] [a7][a6][a5][a4][a3][a2][a1][a0] [b7][b6][b5][b4][b3][b2][b1][b0]"]
195 Bne_d9(Ex, Ex),
196 #[instr="010001[a1][a0] [b7][b6][b5][b4][b3][b2][b1][b0] [c7][c6][c5][c4][c3][c2][c1][c0]"]
197 Bne_Rj(IM, Ex, Ex),
198
199 #[instr="000[a11]1[a10][a9][a8] [a7][a6][a5][a4][a3][a2][a1][a0]"]
200 Call(Ex),
201 #[instr="00100000 [a15][a14][a13][a12][a11][a10][a9][a8] [a7][a6][a5][a4][a3][a2][a1][a0]"]
202 Callf(Ex),
203 #[instr="00010000 [a7][a6][a5][a4][a3][a2][a1][a0] [a15][a14][a13][a12][a11][a10][a9][a8]"]
204 Callr(Ex),
205
206 #[instr="10100000"]
207 Ret,
208 #[instr="10110000"]
209 Reti,
210
211 #[instr="110[a8]1[b2][b1][b0] [a7][a6][a5][a4][a3][a2][a1][a0]"]
212 Clr1(Ex, Ex),
213 #[instr="111[a8]1[b2][b1][b0] [a7][a6][a5][a4][a3][a2][a1][a0]"]
214 Set1(Ex, Ex),
215 #[instr="101[a8]1[b2][b1][b0] [a7][a6][a5][a4][a3][a2][a1][a0]"]
216 Not1(Ex, Ex),
217
218 #[instr="00000000"]
219 Nop,
220
221 #[instr="01010000"]
222 Ldf,
223 #[instr="01010001"]
224 Stf
225}
226
227impl Instr<i32,u8> {
228 pub fn decode(bytes: &[u8]) -> Option<Instr<i32,u8>> {
229 Instr::<i32,u8>::decode_raw(bytes).map(|instr| decode_from_raw(instr))
230 }
231}
232
233impl fmt::Display for Instr<Expr,IndirectionMode> {
234 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
235 use instruction::Instr::*;
236 match self {
237 Add_i8(imm) => write!(f, "add #{}", imm),
238 Add_d9(d9) => write!(f, "add {}", d9),
239 Add_Ri(im) => write!(f, "add {}", im),
240
241 Addc_i8(imm) => write!(f, "addc #{}", imm),
242 Addc_d9(d9) => write!(f, "addc {}", d9),
243 Addc_Ri(im) => write!(f, "addc {}", im),
244
245 Sub_i8(imm) => write!(f, "sub #{}", imm),
246 Sub_d9(d9) => write!(f, "sub {}", d9),
247 Sub_Ri(im) => write!(f, "sub {}", im),
248
249 Subc_i8(imm) => write!(f, "subc #{}", imm),
250 Subc_d9(d9) => write!(f, "subc {}", d9),
251 Subc_Ri(im) => write!(f, "subc {}", im),
252
253 Inc_d9(d9) => write!(f, "inc {}", d9),
254 Inc_Ri(im) => write!(f, "inc {}", im),
255
256 Dec_d9(d9) => write!(f, "dec {}", d9),
257 Dec_Ri(im) => write!(f, "dec {}", im),
258
259 Mul => write!(f, "mul"),
260 Div => write!(f, "div"),
261
262 And_i8(imm) => write!(f, "and #{}", imm),
263 And_d9(d9) => write!(f, "and {}", d9),
264 And_Ri(im) => write!(f, "and {}", im),
265
266 Or_i8(imm) => write!(f, "or #{}", imm),
267 Or_d9(d9) => write!(f, "or {}", d9),
268 Or_Ri(im) => write!(f, "or {}", im),
269
270 Xor_i8(imm) => write!(f, "xor #{}", imm),
271 Xor_d9(d9) => write!(f, "xor {}", d9),
272 Xor_Ri(im) => write!(f, "xor {}", im),
273
274 Rol => write!(f, "rol"),
275 Rolc => write!(f, "rolc"),
276
277 Ror => write!(f, "ror"),
278 Rorc => write!(f, "rorc"),
279
280 Ld_d9(d9) => write!(f, "ld {}", d9),
281 Ld_Ri(im) => write!(f, "ld {}", im),
282
283 St_d9(d9) => write!(f, "st {}", d9),
284 St_Ri(im) => write!(f, "st {}", im),
285
286 Mov_d9(imm, d9) => write!(f, "mov #{}, {}", imm, d9),
287 Mov_Rj(imm, im) => write!(f, "mov #{}, {}", imm, im),
288
289 Ldc => write!(f, "ldc"),
290
291 Push(d9) => write!(f, "push {}", d9),
292 Pop(d9) => write!(f, "pop {}", d9),
293
294 Xch_d9(d9) => write!(f, "xch {}", d9),
295 Xch_Ri(ri) => write!(f, "xch {}", ri),
296
297 Jmp(a12) => write!(f, "jmp {}", a12),
298 Jmpf(a16) => write!(f, "jmpf {}", a16),
299
300 Br(r8) => write!(f, "br {}", r8),
301 Brf(r16) => write!(f, "brf {}", r16),
302 Bz(r8) => write!(f, "bz {}", r8),
303 Bnz(r8) => write!(f, "bnz {}", r8),
304 Bp(d9, b3, r8) => write!(f, "bp {}, {}, {}", d9, b3, r8),
305 Bpc(d9, b3, r8) => write!(f, "bpc {}, {}, {}", d9, b3, r8),
306 Bn(d9, b3, r8) => write!(f, "bn {}, {}, {}", d9, b3, r8),
307 Dbnz_d9(d9, r8) => write!(f, "dbnz {}, {}", d9, r8),
308 Dbnz_Ri(im, r8) => write!(f, "dbnz {}, {}", im, r8),
309 Be_i8(imm, r8) => write!(f, "be #{}, {}", imm, r8),
310 Be_d9(d9, r8) => write!(f, "be {}, {}", d9, r8),
311 Be_Rj(im, imm, r8) => write!(f, "be {}, #{}, {}", im, imm, r8),
312 Bne_i8(imm, r8) => write!(f, "bne #{}, {}", imm, r8),
313 Bne_d9(d9, r8) => write!(f, "bne {}, {}", d9, r8),
314 Bne_Rj(im, imm, r8) => write!(f, "bne {}, #{}, {}", im, imm, r8),
315
316 Call(a12) => write!(f, "call {}", a12),
317 Callf(a16) => write!(f, "callf {}", a16),
318 Callr(r16) => write!(f, "callr {}", r16),
319
320 Ret => write!(f, "ret"),
321 Reti => write!(f, "reti"),
322
323 Clr1(d9, b3) => write!(f, "clr1 {}, {}", d9, b3),
324 Set1(d9, b3) => write!(f, "set1 {}, {}", d9, b3),
325 Not1(d9, b3) => write!(f, "not1 {}, {}", d9, b3),
326
327 Nop => write!(f, "nop"),
328
329 Ldf => write!(f, "ldf"),
330 Stf => write!(f, "stf")
331 }
332 }
333}
334
335type EncResult<T> = Result<T,EncodingError>;
336
337fn eval<E: Env<i32>>(expr: &Expr, env: &E, bits: usize) -> EncResult<i32> {
338 let value = expr.eval(env)?;
339 if (value >> bits) != 0 {
340 Err(EncodingError::out_of_range(expr.span(), bits, value))
341 } else {
342 Ok(value)
343 }
344}
345
346fn eval3<E: Env<i32>>(expr: &Expr, env: &E) -> EncResult<i32> {
347 eval(expr, env, 3)
348}
349
350fn eval8<E: Env<i32>>(expr: &Expr, env: &E) -> EncResult<i32> {
351 eval(expr, env, 8)
352}
353
354fn eval9<E: Env<i32>>(expr: &Expr, env: &E) -> EncResult<i32> {
355 eval(expr, env, 9)
356}
357
358fn eval16<E: Env<i32>>(expr: &Expr, env: &E) -> EncResult<i32> {
359 eval(expr, env, 16)
360}
361
362fn rel8<E: Env<i32>>(expr: &Expr, pos: usize, env: &E) -> EncResult<i32> {
363 let address = expr.eval(env)?;
364 if address >= 0 && address <= 65535 {
365 let value = address - (pos as i32);
366 if value >= -128 && value <= 127 {
367 Ok(value)
368 } else {
369 Err(EncodingError::signed_out_of_range(expr.span(), 8, value))
370 }
371 } else {
372 Err(EncodingError::invalid_addr(expr.span(), address))
373 }
374}
375
376fn eval12<E: Env<i32>>(expr: &Expr, pos: usize, env: &E) -> EncResult<i32> {
377 let addr = eval16(expr, env)?;
378 let val_top = (addr as usize) & 0b1111000000000000;
379 let pos_top = pos & 0b1111000000000000;
380 let value = ((addr as usize) & 0b0000111111111111) as i32;
381 if val_top != pos_top {
382 return Err(EncodingError::mismatch_top_bits(
383 expr.span(),
384 pos,
385 addr,
386 ((pos_top >> 12) & 0xFF) as u8,
387 ((val_top >> 12) & 0xFF) as u8
388 ));
389 } else {
390 Ok(value)
391 }
392}
393
394fn rel16<E: Env<i32>>(expr: &Expr, pos: usize, env: &E) -> EncResult<i32> {
395 let address = expr.eval(env)?;
396 if address >= 0 && address <= 65535 {
397 let value = address - (pos as i32) + 1;
398 if value >= -32768 && value <= 32767 {
399 Ok(value)
400 } else {
401 Err(EncodingError::signed_out_of_range(expr.span(), 16, value))
402 }
403 } else {
404 Err(EncodingError::invalid_addr(expr.span(), address))
405 }
406}
407
408type EvalResult = EncResult<Instr<i32,u8>>;
409
410impl Instr<Expr,IndirectionMode> {
411 pub fn eval(&self, pos: usize, label: &str, names: &Names) -> EvalResult {
412 use instruction::Instr::*;
413 let nenv = names.as_env("Name", label);
414 let venv = names.as_env("Variable", label);
415 let lenv = names.as_env("Label", label);
416 let val = match self {
417 Add_i8(imm) => Add_i8(eval8(imm, &nenv)?),
418 Add_d9(dir) => Add_d9(eval9(dir, &venv)?),
419 Add_Ri(ind) => Add_Ri(ind.index()),
420
421 Addc_i8(imm) => Addc_i8(eval8(imm, &nenv)?),
422 Addc_d9(dir) => Addc_d9(eval9(dir, &venv)?),
423 Addc_Ri(ind) => Addc_Ri(ind.index()),
424
425 Sub_i8(imm) => Sub_i8(eval8(imm, &nenv)?),
426 Sub_d9(dir) => Sub_d9(eval9(dir, &venv)?),
427 Sub_Ri(ind) => Sub_Ri(ind.index()),
428
429 Subc_i8(imm) => Subc_i8(eval8(imm, &nenv)?),
430 Subc_d9(dir) => Subc_d9(eval9(dir, &venv)?),
431 Subc_Ri(ind) => Subc_Ri(ind.index()),
432
433 Inc_d9(dir) => Inc_d9(eval9(dir, &venv)?),
434 Inc_Ri(ind) => Inc_Ri(ind.index()),
435
436 Dec_d9(dir) => Dec_d9(eval9(dir, &venv)?),
437 Dec_Ri(ind) => Dec_Ri(ind.index()),
438
439 Mul => Mul,
440 Div => Div,
441
442 And_i8(imm) => And_i8(eval8(imm, &nenv)?),
443 And_d9(dir) => And_d9(eval9(dir, &venv)?),
444 And_Ri(ind) => And_Ri(ind.index()),
445
446 Or_i8(imm) => Or_i8(eval8(imm, &nenv)?),
447 Or_d9(dir) => Or_d9(eval9(dir, &venv)?),
448 Or_Ri(ind) => Or_Ri(ind.index()),
449
450 Xor_i8(imm) => Xor_i8(eval8(imm, &nenv)?),
451 Xor_d9(dir) => Xor_d9(eval9(dir, &venv)?),
452 Xor_Ri(ind) => Xor_Ri(ind.index()),
453
454 Rol => Rol,
455 Rolc => Rolc,
456
457 Ror => Ror,
458 Rorc => Rorc,
459
460 Ld_d9(dir) => Ld_d9(eval9(dir, &venv)?),
461 Ld_Ri(ind) => Ld_Ri(ind.index()),
462
463 St_d9(dir) => St_d9(eval9(dir, &venv)?),
464 St_Ri(ind) => St_Ri(ind.index()),
465
466 Mov_d9(imm, dir) => Mov_d9(eval8(imm, &nenv)?, eval9(dir, &venv)?),
467 Mov_Rj(imm, ind) => Mov_Rj(eval8(imm, &nenv)?, ind.index()),
468
469 Ldc => Ldc,
470
471 Push(dir) => Push(eval9(dir, &venv)?),
472 Pop(dir) => Pop(eval9(dir, &venv)?),
473
474 Xch_d9(dir) => Xch_d9(eval9(dir, &venv)?),
475 Xch_Ri(ind) => Xch_Ri(ind.index()),
476
477 Jmp(abs) => Jmp(eval12(abs, pos, &lenv)?),
478 Jmpf(abs) => Jmpf(eval16(abs, &lenv)?),
479
480 Br(rel) => Br(rel8(rel, pos, &lenv)?),
481 Brf(rel) => Brf(rel16(rel, pos, &lenv)?),
482 Bz(rel) => Bz(rel8(rel, pos, &lenv)?),
483 Bnz(rel) => Bnz(rel8(rel, pos, &lenv)?),
484 Bp(dir, b3, rel) => Bp(
485 eval9(dir, &venv)?,
486 eval3(b3, &nenv)?,
487 rel8(rel, pos, &lenv)?
488 ),
489 Bpc(dir, b3, rel) => Bpc(
490 eval9(dir, &venv)?,
491 eval3(b3, &nenv)?,
492 rel8(rel, pos, &lenv)?
493 ),
494 Bn(dir, b3, rel) => Bn(
495 eval9(dir, &venv)?,
496 eval3(b3, &nenv)?,
497 rel8(rel, pos, &lenv)?
498 ),
499 Dbnz_d9(dir, rel) => Dbnz_d9(
500 eval9(dir, &venv)?,
501 rel8(rel, pos, &lenv)?
502 ),
503 Dbnz_Ri(ind, rel) => Dbnz_Ri(ind.index(), rel8(rel, pos, &lenv)?),
504 Be_i8(imm, rel) => Be_i8(eval8(imm, &nenv)?, rel8(rel, pos, &lenv)?),
505 Be_d9(dir, rel) => Be_d9(eval9(dir, &venv)?, rel8(rel, pos, &lenv)?),
506 Be_Rj(ind, imm, rel) => Be_Rj(
507 ind.index(),
508 eval8(imm, &nenv)?,
509 rel8(rel, pos, &lenv)?
510 ),
511 Bne_i8(imm, rel) => Bne_i8(
512 eval8(imm, &nenv)?,
513 rel8(rel, pos, &lenv)?
514 ),
515 Bne_d9(dir, rel) => Bne_d9(
516 eval9(dir, &venv)?,
517 rel8(rel, pos, &lenv)?
518 ),
519 Bne_Rj(ind, imm, rel) => Bne_Rj(
520 ind.index(),
521 eval8(imm, &nenv)?,
522 rel8(rel, pos, &lenv)?
523 ),
524
525 Call(a12) => Call(eval12(a12, pos, &lenv)?),
526 Callf(a16) => Callf(eval16(a16, &lenv)?),
527 Callr(r16) => Callr(rel16(r16, pos, &lenv)?),
528
529 Ret => Ret,
530 Reti => Reti,
531
532 Clr1(dir, b3) => Clr1(eval9(dir, &venv)?, eval3(b3, &nenv)?),
533 Set1(dir, b3) => Set1(eval9(dir, &venv)?, eval3(b3, &nenv)?),
534 Not1(dir, b3) => Not1(eval9(dir, &venv)?, eval3(b3, &nenv)?),
535
536 Nop => Nop,
537 Ldf => Ldf,
538 Stf => Stf
539 };
540 Ok(val)
541 }
542}
543
544fn decode_from_raw(instr: Instr<i32,u8>) -> Instr<i32,u8> {
545 fn rel16(rel: i32) -> i32 {
546 use std::mem;
547 unsafe {
548 let r16 = mem::transmute::<u16, i16>(rel as u16);
549 r16 as i32
550 }
551 }
552
553 fn rel8(rel: i32) -> i32 {
554 use std::mem;
555 unsafe {
556 let r8 = mem::transmute::<u8, i8>(rel as u8);
557 r8 as i32
558 }
559 }
560 use instruction::Instr::*;
561 match instr {
562 Add_i8(val) => Add_i8(val),
563 Add_d9(val) => Add_d9(val),
564 Add_Ri(val) => Add_Ri(val),
565
566 Addc_i8(val) => Addc_i8(val),
567 Addc_d9(val) => Addc_d9(val),
568 Addc_Ri(val) => Addc_Ri(val),
569
570 Sub_i8(val) => Sub_i8(val),
571 Sub_d9(val) => Sub_d9(val),
572 Sub_Ri(val) => Sub_Ri(val),
573
574 Subc_i8(val) => Subc_i8(val),
575 Subc_d9(val) => Subc_d9(val),
576 Subc_Ri(val) => Subc_Ri(val),
577
578 Inc_d9(val) => Inc_d9(val),
579 Inc_Ri(val) => Inc_Ri(val),
580
581 Dec_d9(val) => Dec_d9(val),
582 Dec_Ri(val) => Dec_Ri(val),
583
584 Mul => Mul,
585 Div => Div,
586
587 And_i8(val) => And_i8(val),
588 And_d9(val) => And_d9(val),
589 And_Ri(val) => And_Ri(val),
590
591 Or_i8(val) => Or_i8(val),
592 Or_d9(val) => Or_d9(val),
593 Or_Ri(val) => Or_Ri(val),
594
595 Xor_i8(val) => Xor_i8(val),
596 Xor_d9(val) => Xor_d9(val),
597 Xor_Ri(val) => Xor_Ri(val),
598
599 Rol => Rol,
600 Rolc => Rolc,
601
602 Ror => Ror,
603 Rorc => Rorc,
604
605 Ld_d9(val) => Ld_d9(val),
606 Ld_Ri(val) => Ld_Ri(val),
607
608 St_d9(val) => St_d9(val),
609 St_Ri(val) => St_Ri(val),
610
611 Mov_d9(val1, val2) => Mov_d9(val1, val2),
612 Mov_Rj(val1, val2) => Mov_Rj(val1, val2),
613
614 Ldc => Ldc,
615
616 Push(val) => Push(val),
617 Pop(val) => Pop(val),
618
619 Xch_d9(val) => Xch_d9(val),
620 Xch_Ri(val) => Xch_Ri(val),
621
622 Jmp(abs) => Jmp(abs),
623 Jmpf(abs) => Jmpf(abs),
624
625 Br(rel) => Br(rel8(rel)),
626 Brf(rel) => Brf(rel16(rel)),
627 Bz(rel) => Bz(rel8(rel)),
628 Bnz(rel) => Bnz(rel8(rel)),
629 Bp(dir, b3, rel) => Bp(dir, b3, rel8(rel)),
630 Bpc(dir, b3, rel) => Bpc(dir, b3, rel8(rel)),
631 Bn(dir, b3, rel) => Bn(dir, b3, rel8(rel)),
632 Dbnz_d9(dir, rel) => Dbnz_d9(dir, rel8(rel)),
633 Dbnz_Ri(ind, rel) => Dbnz_Ri(ind, rel8(rel)),
634 Be_i8(imm, rel) => Be_i8(imm, rel8(rel)),
635 Be_d9(dir, rel) => Be_d9(dir, rel8(rel)),
636 Be_Rj(ind, imm, rel) => Be_Rj(ind, imm, rel8(rel)),
637 Bne_i8(imm, rel) => Bne_i8(imm, rel8(rel)),
638 Bne_d9(dir, rel) => Bne_d9(dir, rel8(rel)),
639 Bne_Rj(ind, imm, rel) => Bne_Rj(ind, imm, rel8(rel)),
640
641 Call(a12) => Call(a12),
642 Callf(a16) => Callf(a16),
643 Callr(r16) => Callr(rel16(r16)),
644
645 Ret => Ret,
646 Reti => Reti,
647
648 Clr1(dir, b3) => Clr1(dir, b3),
649 Set1(dir, b3) => Set1(dir, b3),
650 Not1(dir, b3) => Not1(dir, b3),
651
652 Nop => Nop,
653 Ldf => Ldf,
654 Stf => Stf
655 }
656}
657
658#[cfg(test)]
659mod test {
660 use instruction::Instr;
661
662 #[test]
663 fn test_encode() {
664 test(Instr::Add_i8(0xf3), vec![0x81, 0xf3], "Add_i8");
665 test(Instr::Add_d9(0x1F4), vec![0x83, 0xf4], "Add_d9");
666 }
667
668 fn test(instr: Instr<i32,u8>, bytes: Vec<u8>, message: &str) {
669 assert_eq!(instr.encode(), bytes, "{}", message);
670 }
671
672 #[test]
673 fn test_decode() {
674 let bytes = vec![0x81, 0xf3];
675 let instr = Instr::Add_i8(0xf3);
676 let decoded = Instr::<i32,u8>::decode(&bytes);
677 assert_eq!(decoded.unwrap(),instr);
678 }
679
680 #[test]
681 fn test_decode2() {
682 let a = 0b000011111111 as i32;
683 let bytes = vec![0b00101000, 0b11111111];
684 let instr = Instr::Jmp(a);
685 let decoded = Instr::<i32,u8>::decode(&bytes);
686 assert_eq!(decoded.unwrap(),instr);
687 }
688}