From 00c0f13d3df170d336a806cc5ef1e464b42d04e9 Mon Sep 17 00:00:00 2001 From: Cassie Jones Date: Sat, 11 Jan 2020 06:57:34 -0500 Subject: [PATCH] Add parser and encoder tests, fix a parser bug We test the parser by parsing an instruction, and then encoding it back to binary, printed nicely. The test cases are generated by looking at the spec table. The parser was incorrectly parsing LD2U as ST2U. Fixed. --- toolchain/src/inst/parse.rs | 2 +- toolchain/src/inst/test.rs | 213 ++++++++++++++++++++++++++++++++++-- 2 files changed, 206 insertions(+), 9 deletions(-) diff --git a/toolchain/src/inst/parse.rs b/toolchain/src/inst/parse.rs index 74533cf..f6899ec 100644 --- a/toolchain/src/inst/parse.rs +++ b/toolchain/src/inst/parse.rs @@ -69,7 +69,7 @@ fn inst<'s>() -> impl Fn(&'s str) -> IResult<&'s str, Inst> { box_alt(( with_reg_bang("LD1U", |r, b| Inst::LdD(Data::D1, r, b)), with_reg_bang("ST1U", |r, b| Inst::StD(Data::D1, r, b)), - with_reg_bang("LD2U", |r, b| Inst::StD(Data::D2, r, b)), + with_reg_bang("LD2U", |r, b| Inst::LdD(Data::D2, r, b)), with_reg_bang("ST2U", |r, b| Inst::StD(Data::D2, r, b)), )), box_alt(( diff --git a/toolchain/src/inst/test.rs b/toolchain/src/inst/test.rs index 9086637..58a8697 100644 --- a/toolchain/src/inst/test.rs +++ b/toolchain/src/inst/test.rs @@ -2,7 +2,6 @@ use super::{parse, encode::Encode}; use std::io::Cursor; fn display(buf: &[u8]) -> String { - println!("{}", buf.len()); match buf.len() { 1 => format!("{:04b}_{:04b}", buf[0] >> 4, buf[0] & 0xf), 2 => format!("{:04b}_{:04b} {:04b}_{:04b}", buf[0] >> 4, buf[0] & 0xf, buf[1] >> 4, buf[1] & 0xf), @@ -10,15 +9,28 @@ fn display(buf: &[u8]) -> String { } } +macro_rules! case { + ($txt:expr => !) => { + assert!( + parse::parse_inst($txt).is_none(), + "expect to not parse {:?}", + $txt, + ); + }; + ($txt:expr => $res:expr) => { + let mut buf = [0, 0]; + let mut cursor = Cursor::new(&mut buf[..]); + let parsed = parse::parse_inst($txt).expect(&format!("to parse {:?}", $txt)); + parsed.encode(&mut cursor).expect(&format!("to encode {:?}", parsed)); + let pos = cursor.position() as usize; + assert_eq!($res, &display(&buf[..pos]), "While parsing {:?}", $txt); + }; +} + macro_rules! test_parse { - ($($txt:expr => $res:expr),* $(,)?) => { + ($($txt:expr => $res:tt),* $(,)?) => { $( - let mut buf = [0, 0]; - let mut cursor = Cursor::new(&mut buf[..]); - let parsed = parse::parse_inst($txt).expect(&format!("parsed {:?}", $txt)); - parsed.encode(&mut cursor).expect(&format!("encoded {:x?}", parsed)); - let pos = cursor.position() as usize; - assert_eq!($res, &display(&buf[..pos])); + case!($txt => $res); )* } } @@ -41,3 +53,188 @@ fn jump_call() { } } +#[test] +fn swap() { + test_parse! { + "swap r0" => "0000_1000", + "SWAP r1" => "0000_1001", + "Swap\tr2" => "0000_1010", + "SWAP\t\tr3" => "0000_1011", + "SWAP r4" => "0000_1100", + "SWAP r5" => "0000_1101", + "SWAP r6" => "0000_1110", + "SWAP r7" => "0000_1111", + "SWAP r8" => !, + "swapr0" => !, + "swap 0" => !, + "swap g0" => !, + "swap" => !, + } +} + +#[test] +fn getr_setr() { + test_parse! { + "getr r3" => "0001_0011", + "GETR r7" => "0001_0111", + "GETR r9" => !, + + "SETR r0" => "0001_1000", + "SETR r7" => "0001_1111", + } +} + +#[test] +fn get_set_special() { + test_parse! { + "GET1" => "0010_0000", + "GET2" => "0010_0001", + "GETC" => "0010_0010", + + "SET1" => "0010_1000", + "SET2" => "0010_1001", + "SETC" => "0010_1010", + } +} + +#[test] +fn alu1() { + test_parse! { + "zero" => "0011_0000", + "lsl1" => "0011_0001", + "lsr1" => "0011_0010", + "asr1" => "0011_0011", + "incr" => "0011_0100", + "decr" => "0011_0101", + "comp" => "0011_0110", + "negt" => "0011_0111", + } +} + +#[test] +fn islt() { + test_parse! { + "islt r0" => "0011_1000", + "islt r7" => "0011_1111", + "islt r8" => !, + "islt" => !, + } +} + +#[test] +fn alu_r() { + test_parse! { + "addr r0" => "0100_0000", + "addr r4" => "0100_0100", + "subr r1" => "0100_1001", + "subr r5" => "0100_1101", + "andr r2" => "0101_0010", + "andr r6" => "0101_0110", + "iorr r3" => "0101_1011", + "iorr r7" => "0101_1111", + "xorr r0" => "0110_0000", + "xorr r4" => "0110_0100", + "lslr r1" => "0110_1001", + "lslr r5" => "0110_1101", + "lsrr r2" => "0111_0010", + "lsrr r6" => "0111_0110", + "asrr r3" => "0111_1011", + "asrr r7" => "0111_1111", + } +} + +#[test] +fn ldst() { + test_parse! { + "ld1u r0" => "1000_0000", + "ld1u r3!" => "1001_0011", + "ld2u r2!" => "1011_0010", + "ld2u r4" => "1010_0100", + + "st1u r1" => "1000_1001", + "st1u r7!" => "1001_1111", + "st2u r7!" => "1011_1111", + "st2u r7" => "1010_1111", + } +} + +#[test] +fn alu_i() { + test_parse! { + "andi #00" => "1111_0000 0000_0000", + "andi #0000" => "1111_0000 0000_0000", + "andi #10" => "1111_0000 0000_1010", + "andi #255" => "1111_0000 1111_1111", + "andi #-1" => !, + "andi #-23" => !, + "andi #256" => !, + + "iori #00" => "1111_0001 0000_0000", + "iori #32" => "1111_0001 0010_0000", + "iori #01" => "1111_0001 0000_0001", + "iori #-1" => !, + + "xori #00" => "1111_0010 0000_0000", + "xori #07" => "1111_0010 0000_0111", + "xori #255" => "1111_0010 1111_1111", + "xori #300" => !, + + "addi #0" => "1111_0011 0000_0000", + "addi #1" => "1111_0011 0000_0001", + "addi #127" => "1111_0011 0111_1111", + "addi #128" => !, + "addi #250" => !, + "addi #-1" => "1111_0011 1111_1111", + "addi #-10" => "1111_0011 1111_0110", + "addi #-64" => "1111_0011 1100_0000", + "addi #-65" => !, + "addi #-100" => !, + } +} + +#[test] +fn alu_compact() { + test_parse! { + "roli #0" => "1111_0011 1000_0000", + "roli #7" => "1111_0011 1000_0111", + "roli #-1" => !, + "roli #8" => !, + + "lsli #0" => "1111_0011 1000_1000", + "lsli #7" => "1111_0011 1000_1111", + "lsri #0" => "1111_0011 1001_0000", + "lsri #7" => "1111_0011 1001_0111", + "asri #0" => "1111_0011 1001_1000", + "asri #7" => "1111_0011 1001_1111", + + "clri #0" => "1111_0011 1010_0000", + "clri #7" => "1111_0011 1010_0111", + "seti #0" => "1111_0011 1010_1000", + "seti #7" => "1111_0011 1010_1111", + "togi #0" => "1111_0011 1011_0000", + "togi #7" => "1111_0011 1011_0111", + "exti #0" => "1111_0011 1011_1000", + "exti #7" => "1111_0011 1011_1111", + } +} + +#[test] +fn branch() { + test_parse! { + "bezi #0" => "1111_0100 0000_0000", + "bezi #1" => "1111_0100 0000_0001", + "bezi #-1" => "1111_0100 1111_1111", + "bezi #-128" => "1111_0100 1000_0000", + "bezi #127" => "1111_0100 0111_1111", + "bezi #-129" => !, + "bezi #128" => !, + + "jofi #0" => "1111_0110 0000_0000", + "jofi #1" => "1111_0110 0000_0001", + "jofi #-1" => "1111_0110 1111_1111", + + "cofi #0" => "1111_0111 0000_0000", + "cofi #1" => "1111_0111 0000_0001", + "cofi #-1" => "1111_0111 1111_1111", + } +} -- 2.47.0