working on adding proc-macro that replaces macro_rules-based instrs! macro
[power-instruction-analyzer.git] / src / main.rs
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 // See Notices.txt for copyright information
3
4 use power_instruction_analyzer::{
5 Instr, InstructionInput, InstructionInputRegister, TestCase, WholeTest,
6 };
7
8 const TEST_VALUES: &[u64] = &[
9 0x0,
10 0x1,
11 0x2,
12 0xFFFF_FFFF_FFFF_FFFF,
13 0xFFFF_FFFF_FFFF_FFFE,
14 0x7FFF_FFFF_FFFF_FFFF,
15 0x8000_0000_0000_0000,
16 0x1234_5678_0000_0000,
17 0x1234_5678_8000_0000,
18 0x1234_5678_FFFF_FFFF,
19 0x1234_5678_7FFF_FFFF,
20 ];
21
22 fn call_with_inputs(
23 mut inputs: InstructionInput,
24 input_registers: &[InstructionInputRegister],
25 f: &mut impl FnMut(InstructionInput),
26 ) {
27 if let Some((&input_register, input_registers)) = input_registers.split_first() {
28 for &i in TEST_VALUES {
29 inputs[input_register] = i;
30 call_with_inputs(inputs, input_registers, f);
31 }
32 } else {
33 f(inputs);
34 }
35 }
36
37 fn main() {
38 let mut test_cases = Vec::new();
39 let mut any_model_mismatch = false;
40 for &instr in Instr::VALUES {
41 call_with_inputs(
42 InstructionInput {
43 ra: 0,
44 rb: 0,
45 rc: 0,
46 },
47 instr.get_used_input_registers(),
48 &mut |inputs| {
49 let model_outputs = instr.get_model_fn()(inputs);
50 #[cfg(feature = "native_instrs")]
51 let native_outputs = Some(instr.get_native_fn()(inputs));
52 #[cfg(not(feature = "native_instrs"))]
53 let native_outputs = None;
54 let model_mismatch = match native_outputs {
55 Some(native_outputs) if native_outputs != model_outputs => true,
56 _ => false,
57 };
58 any_model_mismatch |= model_mismatch;
59 test_cases.push(TestCase {
60 instr,
61 inputs,
62 native_outputs,
63 model_outputs,
64 model_mismatch,
65 });
66 },
67 );
68 }
69 let whole_test = WholeTest {
70 test_cases,
71 any_model_mismatch,
72 };
73 serde_json::to_writer_pretty(std::io::stdout().lock(), &whole_test).unwrap();
74 println!();
75 }