From 2bbaf73aa27c5a51181ee8316dea569df22c3f49 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 21 Feb 2024 14:18:41 -0500 Subject: [PATCH] Delete was is now duplicated. --- InstructionSets/ARM/Decoder.hpp | 63 ++-------------- InstructionSets/ARM/Instruction.hpp | 112 +--------------------------- 2 files changed, 8 insertions(+), 167 deletions(-) diff --git a/InstructionSets/ARM/Decoder.hpp b/InstructionSets/ARM/Decoder.hpp index febe92584..e4ffe0e57 100644 --- a/InstructionSets/ARM/Decoder.hpp +++ b/InstructionSets/ARM/Decoder.hpp @@ -123,6 +123,11 @@ struct OperationMapper { template void dispatch(uint32_t instruction, SchedulerT &scheduler) { constexpr auto partial = static_cast(i << 20); + // Cf. the ARM2 datasheet, p.45. Tests below match its ordering + // other than that 'undefined' is the fallthrough case. More specific + // page references are provided were more detailed versions of the + // decoding are depicted. + // Data processing; cf. p.17. if constexpr (((partial >> 26) & 0b11) == 0b00) { constexpr auto operation = Operation(int(Operation::AND) + ((partial >> 21) & 0xf)); @@ -150,47 +155,15 @@ struct OperationMapper { } }; +/// Decodes @c instruction, making an appropriate call into @c scheduler. template void dispatch(uint32_t instruction, SchedulerT &scheduler) { OperationMapper mapper; Reflection::dispatch(mapper, (instruction >> 20) & 0xff, instruction, scheduler); } /* -template -using OperationTable = std::array; -template -constexpr OperationTable operation_table() { - OperationTable result{}; - for(std::size_t c = 0; c < result.size(); c++) { - const auto opcode = static_cast(c << 20); - // Cf. the ARM2 datasheet, p.45. Tests below match its ordering - // other than that 'undefined' is the fallthrough case. More specific - // page references are provided were more detailed versions of the - // decoding are depicted. - - // Data processing; cf. p.17. - if(((opcode >> 26) & 0b11) == 0b00) { - const auto operation = (c >> 21) & 0xf; - if((opcode >> 20) & 1) { - result[c] = Operation(int(Operation::ANDS) + operation); - } else { - result[c] = Operation(int(Operation::AND) + operation); - } - continue; - } - - // Multiply and multiply-accumulate (MUL, MLA); cf. p.23. - if(((opcode >> 22) & 0b111'111) == 0b000'000) { - switch((opcode >> 20) & 3) { - case 0: result[c] = Operation::MUL; break; - case 1: result[c] = Operation::MULS; break; - case 2: result[c] = Operation::MLA; break; - case 3: result[c] = Operation::MLAS; break; - } - continue; - } // Single data transfer (LDR, STR); cf. p.25. if(((opcode >> 26) & 0b11) == 0b01) { @@ -229,30 +202,6 @@ constexpr OperationTable operation_table() { } result[c] = Operation::Undefined; - } - return result; -} - -template -constexpr Operation operation(uint32_t opcode) { - constexpr OperationTable operations = operation_table(); - - const auto op = operations[(opcode >> 21) & 0x7f]; - - // MUL and MLA have an extra constraint that doesn't fit the neat - // 256-entry table format as above. - // - // Hope: most instructions aren't MUL/MLA so relying on the branch predictor - // here is fine. - if( - is_multiply(op) - && ((opcode >> 4) & 0b1111) != 0b1001 - ) { - return Operation::Undefined; - } - - return op; -} */ diff --git a/InstructionSets/ARM/Instruction.hpp b/InstructionSets/ARM/Instruction.hpp index d242f041d..5bcefa5a0 100644 --- a/InstructionSets/ARM/Instruction.hpp +++ b/InstructionSets/ARM/Instruction.hpp @@ -14,104 +14,7 @@ namespace InstructionSet::ARM { -/*enum class ShiftType { - LogicalLeft = 0b00, - LogicalRight = 0b01, - ArithmeticRight = 0b10, - RotateRight = 0b11, -}; - -template -class Instruction { - public: - constexpr Instruction(uint32_t opcode) noexcept : opcode_(opcode) {} - - constexpr Condition condition() const { return Condition(opcode_ >> 28); } - constexpr Operation operation() const { - return InstructionSet::ARM::operation(opcode_); - } - - // - // B and BL. - // - struct Branch { - constexpr Branch(uint32_t opcode) noexcept : opcode_(opcode) {} - - /// Provides a 26-bit offset to add to the program counter for B and BL. - uint32_t offset() const { return (opcode_ & 0xff'ffff) << 2; } - - private: - uint32_t opcode_; - }; - Branch branch() const { return Branch(opcode_); } - - // - // Data processing (i.e. AND to MVN). - // - struct DataProcessing { - constexpr DataProcessing(uint32_t opcode) noexcept : opcode_(opcode) {} - - /// The destination register index. - int destination() const { return (opcode_ >> 12) & 0xf; } - - /// The operand 1 register index. - int operand1() const { return (opcode_ >> 16) & 0xf; } - - /// @returns @c true if operand 2 is defined by the @c rotate() and @c immediate() fields; - /// @c false if it is defined by the @c shift_*() and @c operand2() fields. - bool operand2_is_immediate() const { return opcode_ & (1 << 25); } - - // - // Register values for operand 2. - // - - /// The operand 2 register index if @c operand2_is_immediate() is @c false; meaningless otherwise. - int operand2() const { return opcode_ & 0xf; } - /// The type of shift to apply to operand 2 if @c operand2_is_immediate() is @c false; meaningless otherwise. - ShiftType shift_type() const { return ShiftType((opcode_ >> 5) & 3); } - /// @returns @c true if the amount to shift by should be taken from a register; @c false if it is an immediate value. - bool shift_count_is_register() const { return opcode_ & (1 << 4); } - /// The shift amount register index if @c shift_count_is_register() is @c true; meaningless otherwise. - int shift_register() const { return (opcode_ >> 8) & 0xf; } - /// The amount to shift by if @c shift_count_is_register() is @c false; meaningless otherwise. - int shift_amount() const { return (opcode_ >> 7) & 0x1f; } - - // - // Immediate values for operand 2. - // - - /// An 8-bit value to rotate right @c rotate() places if @c operand2_is_immediate() is @c true; meaningless otherwise. - int immediate() const { return opcode_ & 0xff; } - /// The number of bits to rotate @c immediate() by if @c operand2_is_immediate() is @c true; meaningless otherwise. - int rotate() const { return (opcode_ >> 7) & 0x1e; } - - private: - uint32_t opcode_; - }; - DataProcessing data_processing() const { return DataProcessing(opcode_); } - - // - // MUL and MLA. - // - struct Multiply { - constexpr Multiply(uint32_t opcode) noexcept : opcode_(opcode) {} - - /// The destination register index. i.e. 'Rd'. - int destination() const { return (opcode_ >> 16) & 0xf; } - - /// The accumulator register index for multiply-add. i.e. 'Rn'. - int accumulator() const { return (opcode_ >> 12) & 0xf; } - - /// The multiplicand register index. i.e. 'Rs'. - int multiplicand() const { return (opcode_ >> 8) & 0xf; } - - /// The multiplier register index. i.e. 'Rm'. - int multiplier() const { return opcode_ & 0xf; } - - private: - uint32_t opcode_; - }; - Multiply multiply() const { return Multiply(opcode_); } +/* // // LDR and STR. @@ -132,17 +35,6 @@ class Instruction { int offset() const { return opcode_ & 0xfff; } // TODO: P, U, B, W, L, I. - - private: - uint32_t opcode_; - - }; - - private: - uint32_t opcode_; -};*/ - -// TODO: do MUL and MLA really transpose Rd and Rn as per the data sheet? -// ARM: Assembly Language Programming by Cockerell thinks not. +*/ }