waterbear/
instruction.rs

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}