Skip to content

Commit 5bae064

Browse files
committed
assembler: add named trap tests, add macro to run single-instruction tests individually
1 parent 8347a2d commit 5bae064

File tree

1 file changed

+111
-109
lines changed

1 file changed

+111
-109
lines changed

assembler/tests/integ.rs

+111-109
Original file line numberDiff line numberDiff line change
@@ -63,111 +63,124 @@ fn pseudo_ops() {
6363
);
6464
}
6565

66-
#[test]
67-
fn add() {
68-
single_instruction_tests(&[
69-
("ADD R0 R0 R0", 0x1000),
70-
("ADD R1 R2 R3", 0x1283),
71-
("ADD R4 R5 R6", 0x1946),
72-
("ADD R7 R7 #0", 0x1FE0),
73-
("ADD R7 R7 #1", 0x1FE1),
74-
("ADD R7 R7 #15", 0x1FEF),
75-
("ADD R7 R7 #-1", 0x1FFF),
76-
]);
77-
}
66+
mod single_instruction {
67+
use super::*;
7868

79-
#[test]
80-
fn and() {
81-
single_instruction_tests(&[
82-
("AND R0 R0 R0", 0x5000),
83-
("AND R1 R2 R3", 0x5283),
84-
("AND R4 R5 R6", 0x5946),
85-
("AND R7 R7 #0", 0x5FE0),
86-
("AND R7 R7 #1", 0x5FE1),
87-
("AND R7 R7 #15", 0x5FEF),
88-
("AND R7 R7 #-1", 0x5FFF),
89-
]);
90-
}
69+
fn single_instruction_test(input: &str, expected: Word) {
70+
let input = format!(".ORIG x3000\n{}\n.END", input);
71+
test(input.as_str(), 0x3000, &[expected]);
72+
}
9173

92-
#[test]
93-
fn jmp() {
94-
single_instruction_tests(&[
95-
("JMP R0", 0xC000),
96-
("JMP R1", 0xC040),
97-
("JMP R2", 0xC080),
98-
("JMP R3", 0xC0C0),
99-
("JMP R4", 0xC100),
100-
("JMP R5", 0xC140),
101-
("JMP R6", 0xC180),
102-
("JMP R7", 0xC1C0),
103-
])
104-
}
74+
macro_rules! single_instruction_tests {
75+
($tests_name:ident
76+
$(
77+
$test_name:ident: $instruction:expr => $expected:expr
78+
),+
79+
$(,)*
80+
) => {
81+
mod $tests_name {
82+
use super::*;
83+
84+
$(
85+
#[test]
86+
fn $test_name() {
87+
single_instruction_test($instruction, $expected);
88+
}
89+
)+
90+
}
91+
};
92+
}
10593

106-
#[test]
107-
fn jsrr() {
108-
single_instruction_tests(&[
109-
("JSRR R0", 0x4000),
110-
("JSRR R1", 0x4040),
111-
("JSRR R2", 0x4080),
112-
("JSRR R3", 0x40C0),
113-
("JSRR R4", 0x4100),
114-
("JSRR R5", 0x4140),
115-
("JSRR R6", 0x4180),
116-
("JSRR R7", 0x41C0),
117-
])
118-
}
94+
single_instruction_tests! { add
95+
minimal: "ADD R0 R0 R0" => 0x1000,
96+
r1_2_3: "ADD R1 R2 R3" => 0x1283,
97+
r4_5_6: "ADD R4 R5 R6" => 0x1946,
98+
r7_imm: "ADD R7 R7 #0" => 0x1FE0,
99+
nonzero_imm: "ADD R7 R7 #1" => 0x1FE1,
100+
max_imm: "ADD R7 R7 #15" => 0x1FEF,
101+
neg_imm: "ADD R7 R7 #-1" => 0x1FFF,
102+
}
119103

120-
#[test]
121-
fn rti() {
122-
single_instruction_test("RTI", 0x8000);
123-
}
104+
single_instruction_tests! { and
105+
minimal: "AND R0 R0 R0" => 0x5000,
106+
r1_2_3: "AND R1 R2 R3" => 0x5283,
107+
r4_5_6: "AND R4 R5 R6" => 0x5946,
108+
r7_imm: "AND R7 R7 #0" => 0x5FE0,
109+
nonzero_imm: "AND R7 R7 #1" => 0x5FE1,
110+
max_imm: "AND R7 R7 #15" => 0x5FEF,
111+
neg_imm: "AND R7 R7 #-1" => 0x5FFF,
112+
}
124113

125-
#[test]
126-
fn ret() {
127-
single_instruction_test("RET", 0xC1C0);
128-
}
114+
single_instruction_tests! { jmp
115+
r0: "JMP R0" => 0xC000,
116+
r1: "JMP R1" => 0xC040,
117+
r2: "JMP R2" => 0xC080,
118+
r3: "JMP R3" => 0xC0C0,
119+
r4: "JMP R4" => 0xC100,
120+
r5: "JMP R5" => 0xC140,
121+
r6: "JMP R6" => 0xC180,
122+
r7: "JMP R7" => 0xC1C0,
123+
}
129124

130-
#[test]
131-
fn ldr() {
132-
single_instruction_tests(&[
133-
("LDR R0 R0 #0", 0x6000),
134-
("LDR R1 R2 #3", 0x6283),
135-
("LDR R3 R4 #31", 0x671F),
136-
("LDR R5 R6 #-1", 0x6BBF),
137-
("LDR R7 R7 #-32", 0x6FE0),
138-
])
139-
}
125+
single_instruction_tests! { jsrr
126+
r0: "JSRR R0" => 0x4000,
127+
r1: "JSRR R1" => 0x4040,
128+
r2: "JSRR R2" => 0x4080,
129+
r3: "JSRR R3" => 0x40C0,
130+
r4: "JSRR R4" => 0x4100,
131+
r5: "JSRR R5" => 0x4140,
132+
r6: "JSRR R6" => 0x4180,
133+
r7: "JSRR R7" => 0x41C0,
134+
}
140135

141-
#[test]
142-
fn not() {
143-
single_instruction_tests(&[
144-
("NOT R0 R1", 0x907F),
145-
("NOT R2 R3", 0x94FF),
146-
("NOT R4 R5", 0x997F),
147-
("NOT R6 R7", 0x9DFF),
148-
])
149-
}
136+
#[test]
137+
fn rti() {
138+
single_instruction_test("RTI", 0x8000);
139+
}
150140

151-
#[test]
152-
fn str() {
153-
single_instruction_tests(&[
154-
("STR R0 R0 #0", 0x7000),
155-
("STR R1 R2 #3", 0x7283),
156-
("STR R3 R4 #31", 0x771F),
157-
("STR R5 R6 #-1", 0x7BBF),
158-
("STR R7 R7 #-32", 0x7FE0),
159-
])
160-
}
141+
#[test]
142+
fn ret() {
143+
single_instruction_test("RET", 0xC1C0);
144+
}
161145

162-
#[test]
163-
fn trap() {
164-
single_instruction_tests(&[
165-
("TRAP x00", 0xF000),
166-
("TRAP x25", 0xF025),
167-
("TRAP xFF", 0xF0FF),
168-
("TRAP #37", 0xF025),
169-
])
170-
}
146+
single_instruction_tests! { ldr
147+
minimal: "LDR R0 R0 #0" => 0x6000,
148+
r1_2: "LDR R1 R2 #3" => 0x6283,
149+
max_imm: "LDR R3 R4 #31" => 0x671F,
150+
neg_imm: "LDR R5 R6 #-1" => 0x6BBF,
151+
min_imm: "LDR R7 R7 #-32" => 0x6FE0,
152+
}
153+
154+
single_instruction_tests! { not
155+
r0_1: "NOT R0 R1" => 0x907F,
156+
r2_3: "NOT R2 R3" => 0x94FF,
157+
r4_5: "NOT R4 R5" => 0x997F,
158+
r6_7: "NOT R6 R7" => 0x9DFF,
159+
}
160+
161+
single_instruction_tests! { str
162+
minimal: "STR R0 R0 #0" => 0x7000,
163+
r1_2: "STR R1 R2 #3" => 0x7283,
164+
max_imm: "STR R3 R4 #31" => 0x771F,
165+
neg_imm: "STR R5 R6 #-1" => 0x7BBF,
166+
min_imm: "STR R7 R7 #-32" => 0x7FE0,
167+
}
168+
169+
single_instruction_tests! { trap
170+
minimal: "TRAP x00" => 0xF000,
171+
halt: "TRAP x25" => 0xF025,
172+
max: "TRAP xFF" => 0xF0FF,
173+
decimal: "TRAP #37" => 0xF025,
174+
}
175+
176+
single_instruction_tests! { named_traps
177+
getc: "GETC" => 0xF020,
178+
out: "OUT" => 0xF021,
179+
puts: "PUTS" => 0xF022,
180+
in_: "IN" => 0xF023,
181+
putsp: "PUTSP" => 0xF024,
182+
halt: "HALT" => 0xF025,
183+
}
171184

172185
// TODO: BR
173186
// TODO: JSR
@@ -176,9 +189,10 @@ fn trap() {
176189
// TODO: ST
177190
// TODO: STI
178191
// TODO: LEA
179-
// TODO: Named TRAPs
180192
// TODO: Pseudo-ops
181193

194+
}
195+
182196
fn test(input: &str, orig: usize, expected_mem: &[Word]) {
183197
let lexer = Lexer::new(input);
184198
let cst = parse(lexer, Lenient);
@@ -195,18 +209,6 @@ fn test(input: &str, orig: usize, expected_mem: &[Word]) {
195209
}
196210
}
197211

198-
fn single_instruction_tests(tests: &[(&str, Word)]) {
199-
for (input, expected) in tests {
200-
single_instruction_test(input, *expected);
201-
}
202-
}
203-
204-
fn single_instruction_test(input: &str, expected: Word) {
205-
let input = format!(".ORIG x3000\n{}\n.END", input);
206-
test(input.as_str(), 0x3000, &[expected]);
207-
}
208-
209-
210212
fn assert_mem(mem: &MemoryDump, location: usize, expected: Word) {
211213
let actual = mem[location];
212214
assert_eq!(expected, actual, "differed at {:#x}: expected {:#x}, was {:#x}", location, expected, actual);

0 commit comments

Comments
 (0)