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.h47
1 files changed, 40 insertions, 7 deletions
diff --git a/asm/arm/instruction.h b/asm/arm/instruction.h
index 862585a..9350cc8 100644
--- a/asm/arm/instruction.h
+++ b/asm/arm/instruction.h
@@ -125,7 +125,8 @@ namespace {
// 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"); }
+ std::vector<std::string> default_regs{"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7"};
+ std::shared_ptr<Operand> reg_list(uint8_t size, uint8_t pos, const std::vector<std::string>& regs = default_regs) { 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");}
@@ -158,7 +159,7 @@ namespace {
// - except: alternative syntax, which needs to be same as exactly 1 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(0x1C00, high_bits(7)), 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
@@ -199,10 +200,10 @@ namespace {
{"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), imm(5, 6, 4)})}}, // T1
+ {"ldrb", 2, Pattern(0x7800, high_bits(5)), Operands{reg(3, 0), bracketed(Operands{reg(3, 3), imm(5, 6)})}}, // 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), imm(5, 6, 4)})}}, // T1
+ {"ldrh", 2, Pattern(0x8800, high_bits(5)), Operands{reg(3, 0), bracketed(Operands{reg(3, 3), imm(5, 6, 2)})}}, // 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
@@ -229,11 +230,43 @@ namespace {
{"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
-
+ {"pop", 2, Pattern{0xBC00, high_bits(7)}, Operands{reg_list(9, 0, {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "pc"})}}, // T1
+ {"push", 2, Pattern{0xB400, high_bits(7)}, Operands{reg_list(9, 0, {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "lr"})}}, // T1
+ {"rev", 2, Pattern{0xBA00, high_bits(10)}, Operands{reg(3, 0), reg(3, 3)}}, // T1
+ {"rev16", 2, Pattern{0xBA40, high_bits(10)}, Operands{reg(3, 0), reg(3, 3)}}, // T1
+ {"revsh", 2, Pattern{0xBAC0, high_bits(10)}, Operands{reg(3, 0), reg(3, 3)}}, // 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
- };
+ {"sbcs", 2, Pattern(0x4180, high_bits(10)), Operands{optional(same_reg(1)), reg(3, 0), reg(3, 3)}}, // T1
+ {"sev", 2, Pattern(0xBF40, 0xFFFF), {}}, // T1
+ {"stm", 2, Pattern(0xC000, high_bits(5)), Operands{suffixed(reg(3, 8), "!"), reg_list(8, 0)}}, // T1
+ {"str", 2, Pattern(0x6000, high_bits(5)), Operands{reg(3, 0), bracketed(Operands{reg(3, 3), imm(5, 6, 4)})}}, // T1
+ {"str", 2, Pattern(0x6000, high_bits(5) + (0x1F << 6)).alternative_syntax(), Operands{reg(3, 0), bracketed(Operands{reg(3, 3)})}}, // T1
+ {"str", 2, Pattern(0x9000, high_bits(5)), Operands{reg(3, 8), bracketed(Operands{reg("sp"), imm(8, 0, 4)})}}, // T2
+ {"str", 2, Pattern(0x9000, high_bits(5) + 0xFF).alternative_syntax(), Operands{reg(3, 8), bracketed(Operands{reg("sp")})}}, // T2
+ {"str", 2, Pattern(0x5000, high_bits(7)), Operands{reg(3, 0), bracketed(Operands{reg(3, 3), reg(3,6), optional(id("lsl #0"))})}}, // T1
+ {"strb", 2, Pattern(0x7000, high_bits(5)), Operands{reg(3, 0), bracketed(Operands{reg(3, 3), imm(5, 6)})}}, // T1
+ {"strb", 2, Pattern(0x7000, high_bits(5) + (0x1F << 6)).alternative_syntax(), Operands{reg(3, 0), bracketed(Operands{reg(3, 3)})}}, // T1
+ {"strb", 2, Pattern(0x5400, high_bits(7)), Operands{reg(3, 0), bracketed(Operands{reg(3, 3), reg(3,6), optional(id("lsl #0"))})}}, // T1
+ {"strh", 2, Pattern(0x8000, high_bits(5)), Operands{reg(3, 0), bracketed(Operands{reg(3, 3), imm(5, 6, 2)})}}, // T1
+ {"strh", 2, Pattern(0x8000, high_bits(5) + (0x1F << 6)).alternative_syntax(), Operands{reg(3, 0), bracketed(Operands{reg(3, 3)})}}, // T1
+ {"strh", 2, Pattern(0x5200, high_bits(7)), Operands{reg(3, 0), bracketed(Operands{reg(3, 3), reg(3,6), optional(id("lsl #0"))})}}, // T1
+ {"subs", 2, Pattern(0x1E00, high_bits(7)), Operands{reg(3, 0), reg(3, 3), imm(3, 6)}}, // T1
+ {"subs", 2, Pattern(0x3800, high_bits(5)), Operands{optional(same_reg(1)), reg(3, 8), imm(8, 0)}}, // T2
+ {"subs", 2, Pattern(0x1A00, high_bits(7)), Operands{reg(3, 0), reg(3, 3), reg(6, 6)}}, // T1
+ {"subs", 2, Pattern(0x1A00, high_bits(7)).alternative_syntax(), Operands{duplicate(reg(3, 0), 3), reg(6, 6)}}, // T1
+ {"sub", 2, Pattern(0xB080, high_bits(9)), Operands{optional(reg("sp")), reg("sp"), imm(7, 0, 4)}}, // T1
+ {"svc", 2, Pattern(0xDF00, high_bits(8)), Operands{imm(8, 0)}}, // T1
+ {"sxtb", 2, Pattern(0xB240, high_bits(10)), Operands{reg(3, 0), reg(3, 3)}}, // T1
+ {"sxth", 2, Pattern(0xB200, high_bits(10)), Operands{reg(3, 0), reg(3, 3)}}, // T1
+ {"tst", 2, Pattern(0x4200, high_bits(10)), Operands{reg(3, 0), reg(3, 3)}}, // T1
+ {"udf", 2, Pattern(0xDE00, high_bits(8)), Operands{imm(8, 0)}}, // T1
+ {"uxtb", 2, Pattern(0xB2C0, high_bits(10)), Operands{reg(3, 0), reg(3, 3)}}, // T1
+ {"uxth", 2, Pattern(0xB280, high_bits(10)), Operands{reg(3, 0), reg(3, 3)}}, // T1
+ {"wfe", 2, Pattern(0xBF20, 0xFFFF), {}}, // T1
+ {"wfi", 2, Pattern(0xBF30, 0xFFFF), {}}, // T1
+ {"yield", 2, Pattern(0xBF10, 0xFFFF), {}}, // T1
+ };
};