1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
use yaxpeax_arch::Decoder;
use yaxpeax_power::{InstDecoder, IsaVersion, Instruction};
use yaxpeax_arch::InstructionAlias;
// run the test function `f` on approximately all of the Power opcodes. this is, in practice,
// around 64M instructions rather than 2^32 words; 0..64 of major opcodes and 0..2^10 of extension
// ops.
fn sample_opcs(f: impl Fn(u32)) {
for opc in 0..64 {
for xo in 0..1 << 10 {
let word = (opc << 26) | (xo << 1);
f(word);
}
}
}
fn sample_instrs(decoder: &InstDecoder, f: impl Fn(&Instruction)) {
sample_opcs(|word| {
let bytes = word.to_be_bytes();
let mut reader = yaxpeax_arch::U8Reader::new(&bytes);
if let Ok(res) = decoder.decode(&mut reader) {
f(&res);
};
});
}
#[test]
fn aliases_sampled() {
let rios2 = InstDecoder::for_cpu(IsaVersion::RIOS2).with_be(true);
let ppc = InstDecoder::for_cpu(IsaVersion::PowerPC).with_be(true);
let gekko = InstDecoder::for_cpu(IsaVersion::Gekko).with_be(true);
let cell = InstDecoder::for_cpu(IsaVersion::Cell).with_be(true);
let xenon = InstDecoder::for_cpu(IsaVersion::Xenon).with_be(true);
let p202 = InstDecoder::for_cpu(IsaVersion::V2_02).with_be(true);
let all = InstDecoder::default().with_be(true);
for decoder in [rios2, ppc, gekko, cell, xenon, p202, all] {
sample_instrs(&decoder, |instr| {
let alias = instr.compute_alias();
let dealias = alias.dealias();
assert_eq!(instr, &dealias);
});
}
}
#[test]
#[ignore] // unignored for some tests
fn aliases_exhaustive_slow() {
let all = InstDecoder::default().with_be(true);
for word in 0..u32::MAX {
let bytes = word.to_be_bytes();
let mut reader = yaxpeax_arch::U8Reader::new(&bytes);
if let Ok(instr) = all.decode(&mut reader) {
let alias = instr.compute_alias();
let dealias = alias.dealias();
assert_eq!(instr, dealias);
}
}
}
#[test]
#[ignore] // unignored for some tests
fn aliases_exhaustive_fmt_slow() {
let all = InstDecoder::default().with_be(true);
for word in 0..u32::MAX {
let bytes = word.to_be_bytes();
let mut reader = yaxpeax_arch::U8Reader::new(&bytes);
if let Ok(instr) = all.decode(&mut reader) {
let alias = instr.compute_alias();
let dealias = alias.dealias();
assert_eq!(instr.to_string(), dealias.to_string());
}
}
}
#[test]
#[ignore] // unignored for some tests
fn aliases_exhaustive_fmt_versions_slow() {
let cell = InstDecoder::for_cpu(IsaVersion::Cell).with_be(true);
let xenon = InstDecoder::for_cpu(IsaVersion::Xenon).with_be(true);
let gekko = InstDecoder::for_cpu(IsaVersion::Gekko).with_be(true);
for word in 0..u32::MAX {
let bytes = word.to_be_bytes();
let mut reader = yaxpeax_arch::U8Reader::new(&bytes);
if let Ok(instr) = cell.decode(&mut reader) {
let alias = instr.compute_alias();
let dealias = alias.dealias();
assert_eq!(instr.to_string(), dealias.to_string());
}
let mut reader = yaxpeax_arch::U8Reader::new(&bytes);
if let Ok(instr) = xenon.decode(&mut reader) {
let alias = instr.compute_alias();
let dealias = alias.dealias();
assert_eq!(instr.to_string(), dealias.to_string());
}
let mut reader = yaxpeax_arch::U8Reader::new(&bytes);
if let Ok(instr) = gekko.decode(&mut reader) {
let alias = instr.compute_alias();
let dealias = alias.dealias();
assert_eq!(instr.to_string(), dealias.to_string());
}
}
}
|