diff options
Diffstat (limited to 'src/test/arm32')
-rw-r--r-- | src/test/arm32/arm_encode.rs | 72 | ||||
-rw-r--r-- | src/test/arm32/instruction_display.rs | 114 | ||||
-rw-r--r-- | src/test/arm32/mod.rs | 25 | ||||
-rw-r--r-- | src/test/arm32/thumb_decode.rs | 57 | ||||
-rw-r--r-- | src/test/arm32/thumb_encode.rs | 74 |
5 files changed, 342 insertions, 0 deletions
diff --git a/src/test/arm32/arm_encode.rs b/src/test/arm32/arm_encode.rs new file mode 100644 index 0000000..c16a93f --- /dev/null +++ b/src/test/arm32/arm_encode.rs @@ -0,0 +1,72 @@ +// Copyright 2024 Gabriel Bjørnager Jensen. +// +// This file is part of Pollex. +// +// Pollex is free software: you can redistribute it +// and/or modify it under the terms of the GNU Af- +// fero General Public License as published by the +// Free Software Foundation, either version 3 of +// the License, or (at your option) any later ver- +// sion. +// +// Pollex is distributed in the hope that it will +// be useful, but WITHOUT ANY WARRANTY; without +// even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Af- +// fero General Public License along with Pollex. +// If not, see <https://www.gnu.org/licenses/>. + +use crate::arm32::{ + Sflag, + Instruction, + InstructionCodec, + Predicate, + Register, + Shifter, +}; + +use alloc::vec::Vec; + +#[test] +fn test_arm_encode() { + let tree = [ + Instruction::BranchLink { + predicate: Predicate::HigherOrSame, + source: 0x1F, + }, + + Instruction::Breakpoint { + immediate: 0x45, + }, + + Instruction::SoftwareInterrupt { + predicate: Predicate::Always, + immediate: 0x54, + }, + + Instruction::Move { + predicate: Predicate::Plus, + destination: Register::Pc, + source: Shifter::ArithmeticShiftRightImmediate { source: Register::R3, shift: 0x20 }, + s: Sflag::On, + }, + ]; + + let mut codec = InstructionCodec::new_at(0x08000000); + + let mut opcodes = Vec::new(); + for instruction in tree { opcodes.push(codec.encode_arm(instruction).unwrap()) } + + assert_eq!( + opcodes, + [ + 0b00101010_00000000_00000000_00000000, + 0b11100001_00100000_00000100_01110101, + 0b11101111_00000000_00000000_01010100, + 0b01010001_10110000_11110000_01000011, + ], + ) +} diff --git a/src/test/arm32/instruction_display.rs b/src/test/arm32/instruction_display.rs new file mode 100644 index 0000000..4f834ef --- /dev/null +++ b/src/test/arm32/instruction_display.rs @@ -0,0 +1,114 @@ +// Copyright 2024 Gabriel Bjørnager Jensen. +// +// This file is part of Pollex. +// +// Pollex is free software: you can redistribute it +// and/or modify it under the terms of the GNU Af- +// fero General Public License as published by the +// Free Software Foundation, either version 3 of +// the License, or (at your option) any later ver- +// sion. +// +// Pollex is distributed in the hope that it will +// be useful, but WITHOUT ANY WARRANTY; without +// even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Af- +// fero General Public License along with Pollex. +// If not, see <https://www.gnu.org/licenses/>. + +use crate::arm32::{ + Predicate, + Sflag, + Instruction, + Register, + Shifter, +}; + +use alloc::string::ToString; +use alloc::vec::Vec; + +#[test] +fn test_instruction_display() { + let tree = [ + Instruction::Add { + predicate: Predicate::GreaterThanOrEqual, + destination: Register::R1, + base: Register::R2, + source: Shifter::RotateRightImmediate { source: Register::R3, shift: 0x2 }, + s: Sflag::Off, + }, + + Instruction::SaturatingSubtract { + predicate: Predicate::LessThan, + destination: Register::R4, + base: Register::R5, + source: Register::R6, + }, + + Instruction::InclusiveOr { + predicate: Predicate::Always, + destination: Register::R7, + base: Register::R8, + source: Shifter::LogicalShiftLeftImmediate { source: Register::R9, shift: 0x0 }, + s: Sflag::On, + }, + + Instruction::MultiplyAccumulate { + predicate: Predicate::Equal, + destination: Register::R0, + base: Register::Pc, + source: Register::Pc, + shift: Register::Lr, + s: Sflag::Off, + }, + + Instruction::Move { + predicate: Predicate::NotEqual, + destination: Register::R0, + source: Shifter::LogicalShiftLeftImmediate { source: Register::Pc, shift: 0x0 }, + s: Sflag::Off, + }, + + Instruction::ReverseSubtract { + predicate: Predicate::Always, + destination: Register::R0, + base: Register::R0, + source: Shifter::Immediate(0x0), + s: Sflag::On, + }, + + Instruction::Move { + predicate: Predicate::GreaterThan, + destination: Register::R0, + source: Shifter::LogicalShiftRightImmediate { source: Register::R7, shift: 0x20 }, + s: Sflag::On, + }, + + Instruction::Move { + predicate: Predicate::Always, + destination: Register::R0, + source: Shifter::LogicalShiftLeftImmediate { source: Register::R0, shift: 0x0 }, + s: Sflag::On, + }, + ]; + + let mut displays = Vec::with_capacity(tree.len()); + for instruction in tree { displays.push(instruction.to_string()) } + + assert_eq!( + displays, + [ + "ADDGE r1, r2, r3, ROR #2", + "QSUBLT r4, r5, r6", + "ORRS r7, r8, r9", + "MLAEQ r0, pc, pc, lr", + "CPYNE r0, pc", + "NEGS r0, r0", + "LSRGTS r0, r7, #32", + "MOVS r0, r0", + ], + ); +} diff --git a/src/test/arm32/mod.rs b/src/test/arm32/mod.rs new file mode 100644 index 0000000..f7270a9 --- /dev/null +++ b/src/test/arm32/mod.rs @@ -0,0 +1,25 @@ +// Copyright 2024 Gabriel Bjørnager Jensen. +// +// This file is part of Pollex. +// +// Pollex is free software: you can redistribute it +// and/or modify it under the terms of the GNU Af- +// fero General Public License as published by the +// Free Software Foundation, either version 3 of +// the License, or (at your option) any later ver- +// sion. +// +// Pollex is distributed in the hope that it will +// be useful, but WITHOUT ANY WARRANTY; without +// even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Af- +// fero General Public License along with Pollex. +// If not, see <https://www.gnu.org/licenses/>. + +mod arm_encode; +mod instruction_display; +mod thumb_decode; +mod thumb_encode;
\ No newline at end of file diff --git a/src/test/arm32/thumb_decode.rs b/src/test/arm32/thumb_decode.rs new file mode 100644 index 0000000..eff61d2 --- /dev/null +++ b/src/test/arm32/thumb_decode.rs @@ -0,0 +1,57 @@ +// Copyright 2024 Gabriel Bjørnager Jensen. +// +// This file is part of Pollex. +// +// Pollex is free software: you can redistribute it +// and/or modify it under the terms of the GNU Af- +// fero General Public License as published by the +// Free Software Foundation, either version 3 of +// the License, or (at your option) any later ver- +// sion. +// +// Pollex is distributed in the hope that it will +// be useful, but WITHOUT ANY WARRANTY; without +// even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Af- +// fero General Public License along with Pollex. +// If not, see <https://www.gnu.org/licenses/>. + +use crate::arm32::{ + Instruction, + InstructionCodec, + Predicate, + Register, +}; + +use alloc::vec::Vec; + +#[test] +fn test_thumb_decode() { + let binary = [ + 0b11011111_10101010, + 0b01000111_01110000, + ]; + + let mut codec = InstructionCodec::new(); + + let mut programme = Vec::new(); + for opcode in binary { programme.push(codec.decode_thumb(opcode.into()).unwrap()) } + + assert_eq!( + programme, + [ + Instruction::SoftwareInterrupt { + predicate: Predicate::Always, + immediate: 0b10101010, + }, + + Instruction::BranchExchange { + predicate: Predicate::Always, + source: Register::Lr, + }, + ], + ) +} diff --git a/src/test/arm32/thumb_encode.rs b/src/test/arm32/thumb_encode.rs new file mode 100644 index 0000000..178b938 --- /dev/null +++ b/src/test/arm32/thumb_encode.rs @@ -0,0 +1,74 @@ +// Copyright 2024 Gabriel Bjørnager Jensen. +// +// This file is part of Pollex. +// +// Pollex is free software: you can redistribute it +// and/or modify it under the terms of the GNU Af- +// fero General Public License as published by the +// Free Software Foundation, either version 3 of +// the License, or (at your option) any later ver- +// sion. +// +// Pollex is distributed in the hope that it will +// be useful, but WITHOUT ANY WARRANTY; without +// even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Af- +// fero General Public License along with Pollex. +// If not, see <https://www.gnu.org/licenses/>. + +use crate::arm32::{ + Instruction, + InstructionCodec, + Predicate, + Register, + Sflag, + Shifter, +}; + +use alloc::vec::Vec; + +#[test] +fn test_thumb_encode() { + let programme = [ + Instruction::BranchLink { + predicate: Predicate::Always, + source: 0x08000044, + }, + + Instruction::And { + predicate: Predicate::Always, + destination: Register::R0, + base: Register::R0, + source: Shifter::LogicalShiftLeftImmediate { source: Register::R7, shift: 0x0 }, + s: Sflag::On, + }, + + Instruction::Branch { + predicate: Predicate::Always, + immediate: 0x08000008, + }, + ]; + + let mut codec = InstructionCodec::new_at(0x08000000); + + let mut opcodes = Vec::new(); + for instruction in programme { + let opcode = codec.encode_thumb(instruction).unwrap(); + + opcodes.push(opcode.0); + if let Some(opcode) = opcode.1 { opcodes.push(opcode) }; + } + + assert_eq!( + opcodes, + [ + 0b11110000_00000000, + 0b11111000_00100000, + 0b01000000_00111000, + 0b11100000_00000000, + ], + ) +} |