summaryrefslogtreecommitdiffhomepage
path: root/asm/arm/instruction.h
diff options
context:
space:
mode:
Diffstat (limited to 'asm/arm/instruction.h')
-rw-r--r--asm/arm/instruction.h38
1 files changed, 31 insertions, 7 deletions
diff --git a/asm/arm/instruction.h b/asm/arm/instruction.h
index 224cc6e..4262ee9 100644
--- a/asm/arm/instruction.h
+++ b/asm/arm/instruction.h
@@ -56,13 +56,21 @@ private:
class Register: public Operand
{
public:
- Register(uint8_t pos): Operand{pos} {};
+ Register(uint8_t size, uint8_t pos): Operand{pos} {}
+ Register(uint32_t mask): Operand{0} { throw std::runtime_error("Unimplemented"); }
+ Register(const std::string& name): Operand{0} { throw std::runtime_error("Unimplemented"); }
+};
+
+class SameRegister: public Operand
+{
+public:
+ SameRegister(uint8_t index): Operand{index} {};
};
class Immediate: public Operand
{
public:
- Immediate(uint8_t pos, uint8_t bits): Operand{pos}, _bits{bits} {}
+ Immediate(uint8_t size, uint8_t pos): Operand{pos}, _bits{size} {}
private:
uint8_t _bits;
};
@@ -96,13 +104,29 @@ private:
namespace {
// factory functions
- std::shared_ptr<Operand> imm(uint8_t pos, uint8_t size){ return std::make_shared<Immediate>(pos, size); };
- std::shared_ptr<Operand> reg(uint8_t pos) { return std::make_shared<Register>(pos); };
+ std::shared_ptr<Operand> imm(uint8_t size, uint8_t pos){ return std::make_shared<Immediate>(size, pos); }
+ std::shared_ptr<Operand> reg(uint8_t size, uint8_t pos) { return std::make_shared<Register>(size, pos); }
+ std::shared_ptr<Operand> reg(uint32_t mask) { return std::make_shared<Register>(mask); }
+ std::shared_ptr<Operand> reg(const std::string& name) { return std::make_shared<Register>(name); }
+ std::shared_ptr<Operand> same_reg(uint8_t index) { return std::make_shared<SameRegister>(index); }
- std::vector<Instruction> insns{
- {"adcs", 2, Pattern(0x4140, high_bits(10)), Operands{reg(0), reg(3)}},
+ std::shared_ptr<Operand> optional(std::shared_ptr<Operand> op) { return op; }
- {"lsls", 2, Pattern(0x0000, high_bits(5)), Operands{reg(0), reg(3), imm(6, 5)}}
+ // TODO: consistency checks:
+ // * all bits defined
+ // * unambiguous
+ std::vector<Instruction> insns{
+ {"adcs", 2, Pattern(0x4140, high_bits(10)), Operands{optional(same_reg(1)), reg(3, 0), reg(3, 3)}}, // T1
+ {"adds", 2, Pattern(0x1C00, high_bits(8)), Operands{reg(3, 0), reg(3, 3), imm(3, 6)}}, // T1
+ {"adds", 2, Pattern(0x3000, high_bits(5)), Operands{optional(same_reg(1)), reg(3, 8), imm(8, 0)}}, // T2
+ {"adds", 2, Pattern(0x1800, high_bits(7)), Operands{reg(3, 0), reg(3, 3), reg(6, 6)}}, // T1
+ {"add", 2, Pattern(0x4400, high_bits(8)), Operands{reg(0b10000111), reg(4, 3)}}, // T2
+ {"add", 2, Pattern(0xA800, high_bits(5)), Operands{reg(3, 8), imm(8, 0)}}, // T1
+ {"add", 2, Pattern(0xB000, high_bits(9)), Operands{optional(reg("sp")), reg("sp"), imm(7, 0)}}, // T2
+ {"add", 2, Pattern(0x4468, 0xFF78), Operands{same_reg(2), reg("sp"), reg(0b10000111)}}, // T1
+ {"add", 2, Pattern(0x4485, 0xFF87), Operands{reg("sp"), reg(4, 3)}}, // T2
+
+ {"lsls", 2, Pattern(0x0000, high_bits(5)), Operands{reg(3, 0), reg(3, 3), imm(5, 6)}}
};
};