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.h33
1 files changed, 27 insertions, 6 deletions
diff --git a/asm/arm/instruction.h b/asm/arm/instruction.h
index d64679a..862585a 100644
--- a/asm/arm/instruction.h
+++ b/asm/arm/instruction.h
@@ -113,6 +113,7 @@ namespace {
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"); }
+
// reg size 3: arm register 0-7
// reg size 4: arm register 0-15
// reg size 8: arm special registers for insns msr, mrs
@@ -120,7 +121,14 @@ namespace {
std::shared_ptr<Operand> reg(uint8_t size, uint8_t pos, std::optional<uint8_t> reg_list_ref_index = std::nullopt) { 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); }
+
+ // register list: "{" <rN> "," <rM> "," ... "}"
+ // size 8 -> arm regs 0-7
+ // size 9 -> pc + arm regs 0-7
std::shared_ptr<Operand> reg_list(uint8_t size, uint8_t pos) { throw std::runtime_error("Unimplemented: reg_list"); }
+
+ // duplicate same operand (reg) to 2 locations in encoding
+ std::shared_ptr<Operand> duplicate(std::shared_ptr<Operand> op, uint8_t pos) {throw std::runtime_error("Unimplemented: duplicate");}
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"); }
@@ -142,7 +150,7 @@ namespace {
}
std::shared_ptr<Operand> bracketed(Operands operands) { throw std::runtime_error("Unimplemented: bracketed"); };
- std::shared_ptr<Operand> optional(std::shared_ptr<Operand> op) { return op; }
+ std::shared_ptr<Operand> optional(std::shared_ptr<Operand> op) { throw std::runtime_error("Unimplemented: optional");return op; }
// TODO: consistency checks:
// * all bits in an instruction defined
@@ -184,14 +192,18 @@ namespace {
{"ldm", 2, Pattern(0xC800, high_bits(5)), Operands{suffixed(reg(3, 8, 1), "!", ""), reg_list(8, 0)}}, // T1
{"ldmia", 2, Pattern(0xC800, high_bits(5)).alternative_syntax(), Operands{suffixed(reg(3, 8, 1), "!", ""), reg_list(8, 0)}}, // T1
{"ldmfd", 2, Pattern(0xC800, high_bits(5)).alternative_syntax(), Operands{suffixed(reg(3, 8, 1), "!", ""), reg_list(8, 0)}}, // T1
- {"ldr", 2, Pattern(0x6800, high_bits(5)), Operands{reg(3, 0), bracketed(Operands{reg(3, 3), optional(imm(5, 6, 4))})}}, // T1
- {"ldr", 2, Pattern(0x9800, high_bits(5)), Operands{reg(3, 8), bracketed(Operands{reg("sp"), optional(imm(8, 0, 4))})}}, // T2
+ {"ldr", 2, Pattern(0x6800, high_bits(5)), Operands{reg(3, 0), bracketed(Operands{reg(3, 3), imm(5, 6, 4)})}}, // T1
+ {"ldr", 2, Pattern(0x6800, high_bits(5) + (0x1F << 6)).alternative_syntax(), Operands{reg(3, 0), bracketed(Operands{reg(3, 3)})}}, // T1
+ {"ldr", 2, Pattern(0x9800, high_bits(5)), Operands{reg(3, 8), bracketed(Operands{reg("sp"), imm(8, 0, 4)})}}, // T2
+ {"ldr", 2, Pattern(0x9800, high_bits(5) + 0xFF).alternative_syntax(), Operands{reg(3, 8), bracketed(Operands{reg("sp")})}}, // T2
{"ldr", 2, Pattern(0x4800, high_bits(5)), Operands{reg(3, 8), label(8, 0, 4)}}, // T1
{"ldr", 2, Pattern(0x4800, high_bits(5)).alternative_syntax(), Operands{reg(3, 8), bracketed(Operands{reg("pc"), imm(8, 0, 4)})}}, // T1
{"ldr", 2, Pattern(0x5800, high_bits(7)), Operands{reg(3, 0), bracketed(Operands{reg(3, 3), reg(3,6), optional(id("lsl #0"))})}}, // T1
- {"ldrb", 2, Pattern(0x7800, high_bits(5)), Operands{reg(3, 0), bracketed(Operands{reg(3, 3), optional(imm(5, 6, 4))})}}, // T1
+ {"ldrb", 2, Pattern(0x7800, high_bits(5)), Operands{reg(3, 0), bracketed(Operands{reg(3, 3), imm(5, 6, 4)})}}, // T1
+ {"ldrb", 2, Pattern(0x7800, high_bits(5) + (0x1F << 6)).alternative_syntax(), Operands{reg(3, 0), bracketed(Operands{reg(3, 3)})}}, // T1
{"ldrb", 2, Pattern(0x5C00, high_bits(7)), Operands{reg(3, 0), bracketed(Operands{reg(3, 3), reg(3,6), optional(id("lsl #0"))})}}, // T1
- {"ldrh", 2, Pattern(0x8800, high_bits(5)), Operands{reg(3, 0), bracketed(Operands{reg(3, 3), optional(imm(5, 6, 4))})}}, // T1
+ {"ldrh", 2, Pattern(0x8800, high_bits(5)), Operands{reg(3, 0), bracketed(Operands{reg(3, 3), imm(5, 6, 4)})}}, // T1
+ {"ldrh", 2, Pattern(0x8800, high_bits(5) + (0x1F << 6)).alternative_syntax(), Operands{reg(3, 0), bracketed(Operands{reg(3, 3)})}}, // T1
{"ldrh", 2, Pattern(0x5A00, high_bits(7)), Operands{reg(3, 0), bracketed(Operands{reg(3, 3), reg(3,6), optional(id("lsl #0"))})}}, // T1
{"ldrsb", 2, Pattern(0x5600, high_bits(7)), Operands{reg(3, 0), bracketed(Operands{reg(3, 3), reg(3,6), optional(id("lsl #0"))})}}, // T1
{"ldrsh", 2, Pattern(0x5E00, high_bits(7)), Operands{reg(3, 0), bracketed(Operands{reg(3, 3), reg(3,6), optional(id("lsl #0"))})}}, // T1
@@ -211,8 +223,17 @@ namespace {
{"movs", 2, Pattern(0x41C0, high_bits(10)).alternative_syntax(), Operands{reg(3, 0), same_reg(0), prefixed(reg(3, 3), "ror ")}}, // T1
{"mrs", 4, Pattern(0xF3EF8000, high_bits(20)), Operands{reg(4, 8), reg(8, 0)}}, // T1
{"msr", 4, Pattern(0xF3808800, 0xFFF0FF00), Operands{reg(4, 16), reg(8, 0)}}, // T1
+ {"muls", 2, Pattern(0x4340, high_bits(10)), Operands{optional(same_reg(2)), reg(3, 3), reg(3, 0)}}, // T1
+ {"mvns", 2, Pattern(0x43C0, high_bits(10)), Operands{reg(3, 0), reg(3, 3)}}, // T1
+ {"neg", 2, Pattern(0x4240, high_bits(10)).alternative_syntax(), Operands{reg(3, 0), reg(3, 3)}}, // T1
+ {"neg", 2, Pattern(0x4240, high_bits(10)).alternative_syntax(), Operands{duplicate(reg(3, 0), 3)}}, // T1
+ {"nop", 2, Pattern{0xBF00, 0xFFFF}, {}}, // T1
+ {"orrs", 2, Pattern{0x4300, high_bits(10)}, Operands{optional(same_reg(1)), reg(3, 0), reg(3, 3)}}, // T1
+ {"pop", 2, Pattern{0xBC00, high_bits(7)}, Operands{reg_list(9, 0)}}, // T1
{"rors", 2, Pattern(0x41C0, high_bits(10)), Operands{reg(3, 0), same_reg(0), reg(3, 3)}}, // T1
- };
+ {"rsbs", 2, Pattern(0x4240, high_bits(10)), Operands{reg(3, 0), reg(3, 3), id("#0")}}, // T1
+ {"rsbs", 2, Pattern(0x4240, high_bits(10)).alternative_syntax(), Operands{duplicate(reg(3, 0), 3), id("#0")}}, // T1
+ };
};