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.h44
1 files changed, 36 insertions, 8 deletions
diff --git a/asm/arm/instruction.h b/asm/arm/instruction.h
index 4262ee9..54cc8ca 100644
--- a/asm/arm/instruction.h
+++ b/asm/arm/instruction.h
@@ -31,7 +31,7 @@ uint32_t high_bits(uint8_t number)
class Pattern
{
public:
- Pattern(uint32_t bits, uint32_t mask): _bits{bits}, _mask{mask} {}
+ Pattern(uint32_t bits, uint32_t mask, bool is_alternative_syntax = false): _bits{bits}, _mask{mask} {}
template<typename T>
T encode()
@@ -104,29 +104,57 @@ private:
namespace {
// factory functions
- std::shared_ptr<Operand> imm(uint8_t size, uint8_t pos){ return std::make_shared<Immediate>(size, pos); }
+ std::shared_ptr<Operand> imm(uint8_t size, uint8_t pos, uint8_t factor = 1, uint32_t code0_is_value = 0, const std::vector<uint32_t>& invalid_values = {}){ return std::make_shared<Immediate>(size, pos); }
+ std::shared_ptr<Operand> label(uint8_t size, uint8_t pos, uint8_t factor = 1, bool is_signed = false){ return std::make_shared<Immediate>(size, pos); }
+ std::shared_ptr<Operand> label(uint8_t size, const std::vector<uint8_t>& bits, uint32_t flip_mask, uint8_t factor = 1, bool is_signed = false){ throw std::runtime_error("Unimplemented: label w/ flipmask"); }
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> id(const std::string& name) { throw std::runtime_error("Unimplemented: id"); }
std::shared_ptr<Operand> same_reg(uint8_t index) { return std::make_shared<SameRegister>(index); }
+ std::shared_ptr<Operand> cond(uint8_t pos) { throw std::runtime_error("Unimplemented: cond"); }
std::shared_ptr<Operand> optional(std::shared_ptr<Operand> op) { return op; }
// TODO: consistency checks:
- // * all bits defined
- // * unambiguous
+ // * all bits in an instruction defined
+ // * unambiguous patterns
+ // - except: alternative syntax, which needs to be same as other pattern
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(0xA800, high_bits(5)), Operands{reg(3, 8), imm(8, 0, 4)}}, // T1
+ {"add", 2, Pattern(0xB000, high_bits(9)), Operands{optional(reg("sp")), reg("sp"), imm(7, 0, 4)}}, // 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)}}
+ {"adr", 2, Pattern(0xA000, high_bits(5)), Operands{reg(3, 8), label(8, 0, 4)}}, // T1
+ {"add", 2, Pattern(0xA000, high_bits(5), true), Operands{reg(3, 8), imm(8, 0, 4)}}, // T1, alternative syntax
+ {"ands", 2, Pattern(0x4000, high_bits(10)), Operands{optional(same_reg(1)), reg(3, 0), reg(3, 3)}}, // T1
+ {"asrs", 2, Pattern(0x1000, high_bits(5)), Operands{reg(3, 0), reg(3, 3), imm(5, 6, 1, 32)}}, // T1
+ {"asrs", 2, Pattern(0x4100, high_bits(10)), Operands{same_reg(1), reg(3, 0), reg(3, 3)}}, // T1
+ {"b<c>", 2, Pattern(0xD000, high_bits(4)), Operands{cond(8), label(8, 0, 2, true)}}, // T1
+ {"b", 2, Pattern(0xE000, high_bits(5)), Operands{label(11, 0, 2, true)}}, // T2
+ {"bal", 2, Pattern(0xE000, high_bits(5), true), Operands{label(11, 0, 2, true)}}, // T2
+ {"bics", 2, Pattern(0x4380, high_bits(10)), Operands{optional(same_reg(1)), reg(3, 0), reg(3, 3)}}, // T1
+ {"bkpt", 2, Pattern(0xBE00, high_bits(8)), Operands{imm(8, 0)}}, // T1
+ {"bl", 4, Pattern(0xF000D000, 0xF800D000), Operands{label(24, {11, 0, 10, 16, 1, 11, 1, 13, 1, 26}, 0x00002800, 2, true)}}, // T1
+ {"blx", 2, Pattern(0x4780, 0xFF87), Operands{reg(4, 3)}}, // T1
+ {"bx", 2, Pattern(0x4700, 0xFF87), Operands{reg(4, 3)}}, // T1
+ {"cmn", 2, Pattern(0x42C0, high_bits(10)), Operands{reg(3, 0), reg(3, 3)}}, // T1
+ {"cmp", 2, Pattern(0x2800, high_bits(5)), Operands{reg(3, 8), imm(8, 0)}}, // T1
+ {"cmp", 2, Pattern(0x4280, high_bits(10)), Operands{reg(3, 0), reg(3, 3)}}, // T1
+ {"cmp", 2, Pattern(0x4500, high_bits(8)), Operands{reg(0x87), reg(4, 3)}}, // T2
+ {"cps", 2, Pattern(0xB662, 0xFFEF), Operands{imm(1, 4)}}, // T1
+ {"cpy", 2, Pattern(0x4600, high_bits(8), true), Operands{reg(0x87), reg(4, 3)}}, // T1
+ {"dmb", 4, Pattern(0xF3BF8F5F, high_bits(32)), Operands{id("sy")}}, // T1
+ {"dsb", 4, Pattern(0xF3BF8F4F, high_bits(32)), Operands{id("sy")}}, // T1
+
+ {"lsls", 2, Pattern(0x0000, high_bits(5)), Operands{reg(3, 0), reg(3, 3), imm(5, 6, 1, 0, {0})}},
+ {"mov", 2, Pattern(0x4600, high_bits(8)), Operands{reg(0x87), reg(4, 3)}}, // T1
+ {"movs", 2, Pattern(0x0000, high_bits(10)), Operands{reg(3, 0), reg(3, 3)}}, // T2
};
};