mirror of
https://github.com/avrdudes/avrdude.git
synced 2026-09-24 10:06:25 +03:00
Warn when opcodes have undefined results, eg, ld r26, X+
This commit is contained in:
@@ -312,19 +312,19 @@ const AVR_opcode_data avr_opcodes[164] = {
|
||||
{OP_ID(ld_1), 0xfe0f, 0x900c, 1, OP_AVR2, "1001 000d dddd 1100", OTY_XFRX|OTY_RALL,
|
||||
"ld", "Rd, X", "Load Indirect", "Rd <-- (X)", "--------",
|
||||
{"2", "2", "2", "1/2"}, ""},
|
||||
{OP_ID(ld_2), 0xfe0f, 0x900d, 1, OP_AVR2, "1001 000d dddd 1101", OTY_XFRX|OTY_RALL,
|
||||
{OP_ID(ld_2), 0xfe0f, 0x900d, 1, OP_AVR2, "1001 000d dddd 1101", OTY_XFRX|OTY_RALL|OTY_XWRN,
|
||||
"ld", "Rd, X+", "Load Indirect and Post-Increment", "Rd <-- (X), X <-- X + 1", "--------",
|
||||
{"2", "2", "2", "2/3"}, ""},
|
||||
{OP_ID(ld_3), 0xfe0f, 0x900e, 1, OP_AVR2, "1001 000d dddd 1110", OTY_XFRX|OTY_RALL,
|
||||
{OP_ID(ld_3), 0xfe0f, 0x900e, 1, OP_AVR2, "1001 000d dddd 1110", OTY_XFRX|OTY_RALL|OTY_XWRN,
|
||||
"ld", "Rd, -X", "Load Indirect and Pre-Decrement", "X <-- X - 1, Rd <-- (X)", "--------",
|
||||
{"2", "3", "2", "2/3"}, ""},
|
||||
{OP_ID(ld_4), 0xfe0f, 0x8008, 1, OP_AVR2, "1000 000d dddd 1000", OTY_XFRX|OTY_RALL,
|
||||
"ld", "Rd, Y", "Load Indirect", "Rd <-- (Y) <-- (Y)", "--------",
|
||||
{"2", "2", "2", "1/2"}, "alias for ldd Rd, Y+0"},
|
||||
{OP_ID(ld_5), 0xfe0f, 0x9009, 1, OP_AVR2, "1001 000d dddd 1001", OTY_XFRX|OTY_RALL,
|
||||
{OP_ID(ld_5), 0xfe0f, 0x9009, 1, OP_AVR2, "1001 000d dddd 1001", OTY_XFRX|OTY_RALL|OTY_YWRN,
|
||||
"ld", "Rd, Y+", "Load Indirect and Post-Increment", "Rd <-- (Y), Y <-- Y + 1", "--------",
|
||||
{"2", "2", "2", "2/3"}, ""},
|
||||
{OP_ID(ld_6), 0xfe0f, 0x900a, 1, OP_AVR2, "1001 000d dddd 1010", OTY_XFRX|OTY_RALL,
|
||||
{OP_ID(ld_6), 0xfe0f, 0x900a, 1, OP_AVR2, "1001 000d dddd 1010", OTY_XFRX|OTY_RALL|OTY_YWRN,
|
||||
"ld", "Rd, -Y", "Load Indirect and Pre-Decrement", "Y <-- Y - 1 Rd <-- (Y)", "--------",
|
||||
{"2", "3", "2", "2/3"}, ""},
|
||||
{OP_ID(ldd_1), 0xd208, 0x8008, 1, OP_AVR2nRC, "10q0 qq0d dddd 1qqq", OTY_XFRX|OTY_RALL,
|
||||
@@ -333,10 +333,10 @@ const AVR_opcode_data avr_opcodes[164] = {
|
||||
{OP_ID(ld_7), 0xfe0f, 0x8000, 1, OP_AVR1, "1000 000d dddd 0000", OTY_XFRX|OTY_RALL,
|
||||
"ld", "Rd, Z", "Load Indirect", "Rd <-- (Z)", "--------",
|
||||
{"2", "2", "2", "1/2"}, "alias for ldd Rd, Z+0"},
|
||||
{OP_ID(ld_8), 0xfe0f, 0x9001, 1, OP_AVR1, "1001 000d dddd 0001", OTY_XFRX|OTY_RALL,
|
||||
{OP_ID(ld_8), 0xfe0f, 0x9001, 1, OP_AVR1, "1001 000d dddd 0001", OTY_XFRX|OTY_RALL|OTY_ZWRN,
|
||||
"ld", "Rd, Z+", "Load Indirect and Post-Increment", "Rd <-- (Z), Z <-- Z + 1", "--------",
|
||||
{"2", "2", "2", "2/3"}, ""},
|
||||
{OP_ID(ld_9), 0xfe0f, 0x9002, 1, OP_AVR1, "1001 000d dddd 0010", OTY_XFRX|OTY_RALL,
|
||||
{OP_ID(ld_9), 0xfe0f, 0x9002, 1, OP_AVR1, "1001 000d dddd 0010", OTY_XFRX|OTY_RALL|OTY_ZWRN,
|
||||
"ld", "Rd, -Z", "Load Indirect and Pre-Decrement", "Z <-- Z - 1, Rd <-- (Z)", "--------",
|
||||
{"2", "3", "2", "2/3"}, ""},
|
||||
{OP_ID(ldd_2), 0xd208, 0x8000, 1, OP_AVR2nRC, "10q0 qq0d dddd 0qqq", OTY_XFRX|OTY_RALL,
|
||||
@@ -348,19 +348,19 @@ const AVR_opcode_data avr_opcodes[164] = {
|
||||
{OP_ID(st_1), 0xfe0f, 0x920c, 1, OP_AVR2, "1001 001r rrrr 1100", OTY_XFRX|OTY_RALL,
|
||||
"st", "X, Rr", "Store Indirect", "(X) <-- Rr", "--------",
|
||||
{"2", "1", "1", "1"}, ""},
|
||||
{OP_ID(st_2), 0xfe0f, 0x920d, 1, OP_AVR2, "1001 001r rrrr 1101", OTY_XFRX|OTY_RALL,
|
||||
{OP_ID(st_2), 0xfe0f, 0x920d, 1, OP_AVR2, "1001 001r rrrr 1101", OTY_XFRX|OTY_RALL|OTY_XWRN,
|
||||
"st", "X+, Rr", "Store Indirect and Post-Increment", "(X) <-- Rr, X <-- X + 1", "--------",
|
||||
{"2", "1", "1", "1"}, ""},
|
||||
{OP_ID(st_3), 0xfe0f, 0x920e, 1, OP_AVR2, "1001 001r rrrr 1110", OTY_XFRX|OTY_RALL,
|
||||
{OP_ID(st_3), 0xfe0f, 0x920e, 1, OP_AVR2, "1001 001r rrrr 1110", OTY_XFRX|OTY_RALL|OTY_XWRN,
|
||||
"st", "-X, Rr", "Store Indirect and Pre-Decrement", "X <-- X - 1, (X) <-- Rr", "--------",
|
||||
{"2", "2", "1", "1"}, ""},
|
||||
{OP_ID(st_4), 0xfe0f, 0x8208, 1, OP_AVR2, "1000 001r rrrr 1000", OTY_XFRX|OTY_RALL,
|
||||
"st", "Y, Rr", "Store Indirect", "(Y) <-- Rr", "--------",
|
||||
{"2", "1", "1", "1"}, "alias for std Y+0, Rr"},
|
||||
{OP_ID(st_5), 0xfe0f, 0x9209, 1, OP_AVR2, "1001 001r rrrr 1001", OTY_XFRX|OTY_RALL,
|
||||
{OP_ID(st_5), 0xfe0f, 0x9209, 1, OP_AVR2, "1001 001r rrrr 1001", OTY_XFRX|OTY_RALL|OTY_YWRN,
|
||||
"st", "Y+, Rr", "Store Indirect and Post-Increment", "(Y) <-- Rr, Y <-- Y + 1", "--------",
|
||||
{"2", "1", "1", "1"}, ""},
|
||||
{OP_ID(st_6), 0xfe0f, 0x920a, 1, OP_AVR2, "1001 001r rrrr 1010", OTY_XFRX|OTY_RALL,
|
||||
{OP_ID(st_6), 0xfe0f, 0x920a, 1, OP_AVR2, "1001 001r rrrr 1010", OTY_XFRX|OTY_RALL|OTY_YWRN,
|
||||
"st", "-Y, Rr", "Store Indirect and Pre-Decrement", "Y <-- Y - 1, (Y) <-- Rr", "--------",
|
||||
{"2", "2", "1", "1"}, ""},
|
||||
{OP_ID(std_1), 0xd208, 0x8208, 1, OP_AVR2nRC, "10q0 qq1r rrrr 1qqq", OTY_XFRX|OTY_RALL,
|
||||
@@ -369,10 +369,10 @@ const AVR_opcode_data avr_opcodes[164] = {
|
||||
{OP_ID(st_7), 0xfe0f, 0x8200, 1, OP_AVR1, "1000 001r rrrr 0000", OTY_XFRX|OTY_RALL,
|
||||
"st", "Z, Rr", "Store Indirect", "(Z) <-- Rr", "--------",
|
||||
{"2", "1", "1", "1"}, "alias for std Z+0, Rr"},
|
||||
{OP_ID(st_8), 0xfe0f, 0x9201, 1, OP_AVR1, "1001 001r rrrr 0001", OTY_XFRX|OTY_RALL,
|
||||
{OP_ID(st_8), 0xfe0f, 0x9201, 1, OP_AVR1, "1001 001r rrrr 0001", OTY_XFRX|OTY_RALL|OTY_ZWRN,
|
||||
"st", "Z+, Rr", "Store Indirect and Post-Increment", "(Z) <-- Rr, Z <-- Z + 1", "--------",
|
||||
{"2", "1", "1", "1"}, ""},
|
||||
{OP_ID(st_9), 0xfe0f, 0x9202, 1, OP_AVR1, "1001 001r rrrr 0010", OTY_XFRX|OTY_RALL,
|
||||
{OP_ID(st_9), 0xfe0f, 0x9202, 1, OP_AVR1, "1001 001r rrrr 0010", OTY_XFRX|OTY_RALL|OTY_ZWRN,
|
||||
"st", "-Z, Rr", "Store Indirect and Pre-Decrement", "Z <-- Z - 1, (Z) <-- Rr", "--------",
|
||||
{"2", "2", "1", "1"}, ""},
|
||||
{OP_ID(std_2), 0xd208, 0x8200, 1, OP_AVR2nRC, "10q0 qq1r rrrr 0qqq", OTY_XFRX|OTY_RALL,
|
||||
@@ -384,7 +384,7 @@ const AVR_opcode_data avr_opcodes[164] = {
|
||||
{OP_ID(lpm_2), 0xfe0f, 0x9004, 1, OP_AVR25, "1001 000d dddd 0100", OTY_XFRX|OTY_RALL,
|
||||
"lpm", "Rd, Z", "Load Program Memory", "Rd <-- (Z)", "--------",
|
||||
{"3", "3", "3", "n/a"}, ""},
|
||||
{OP_ID(lpm_3), 0xfe0f, 0x9005, 1, OP_AVR25, "1001 000d dddd 0101", OTY_XFRX|OTY_RALL,
|
||||
{OP_ID(lpm_3), 0xfe0f, 0x9005, 1, OP_AVR25, "1001 000d dddd 0101", OTY_XFRX|OTY_RALL|OTY_ZWRN,
|
||||
"lpm", "Rd, Z+", "Load Program Memory and Post- Increment", "Rd <-- (Z), Z <-- Z + 1", "--------",
|
||||
{"3", "3", "3", "n/a"}, ""},
|
||||
{OP_ID(elpm_1), 0xffff, 0x95d8, 1, OP_AVR_L, "1001 0101 1101 1000", OTY_XFRX,
|
||||
@@ -393,7 +393,7 @@ const AVR_opcode_data avr_opcodes[164] = {
|
||||
{OP_ID(elpm_2), 0xfe0f, 0x9006, 1, OP_AVR_L, "1001 000d dddd 0110", OTY_XFRX|OTY_RALL,
|
||||
"elpm", "Rd, Z", "Extended Load Program Memory", "Rd <-- (RAMPZ:Z)", "--------",
|
||||
{"3", "3", "3", "n/a"}, ""},
|
||||
{OP_ID(elpm_3), 0xfe0f, 0x9007, 1, OP_AVR_L, "1001 000d dddd 0111", OTY_XFRX|OTY_RALL,
|
||||
{OP_ID(elpm_3), 0xfe0f, 0x9007, 1, OP_AVR_L, "1001 000d dddd 0111", OTY_XFRX|OTY_RALL|OTY_ZWRN,
|
||||
"elpm", "Rd, Z+", "Extended Load Program Memory and Post-Increment", "Rd <-- (RAMPZ:Z), Z <-- Z + 1", "--------",
|
||||
{"3", "3", "3", "n/a"}, ""},
|
||||
{OP_ID(spm), 0xffff, 0x95e8, 1, OP_AVR25, "1001 0101 1110 1000", OTY_XFRX,
|
||||
@@ -589,7 +589,7 @@ const AVR_opcode_data avr_opcodes[164] = {
|
||||
{"1-3", "1-3", "1-3", "1/2"}, ""},
|
||||
};
|
||||
|
||||
// Return whether or not the giveb 16-bit opcode has a 16-bit address argument
|
||||
// Return whether or not the given 16-bit opcode has a 16-bit address argument
|
||||
int is_opcode32(int op) {
|
||||
return
|
||||
(op & 0xfe0e) == 0x940e || // call
|
||||
|
||||
34
src/disasm.c
34
src/disasm.c
@@ -152,7 +152,7 @@ void disassemble(const char *buf, int addr, int opcode, AVR_opcode mnemo, Disasm
|
||||
|
||||
// Apply register formula
|
||||
int regword = 0;
|
||||
switch(oc->type & OTY_RMASK) {
|
||||
switch(oc->type & OTY_REG_MASK) {
|
||||
case OTY_REVN: // Even registers r0, r2, ..., r30
|
||||
Rd *= 2, Rr *= 2;
|
||||
regword = 1; // movw
|
||||
@@ -175,6 +175,27 @@ void disassemble(const char *buf, int addr, int opcode, AVR_opcode mnemo, Disasm
|
||||
Ra = (Ra & 0xf) | ((Ra >> 1) & 0x30) | ((Ra & 0x10) << 2) | (((Ra & 0x10) ^ 0x10) << 3);
|
||||
}
|
||||
|
||||
int awd = cx->dis_addrwidth, swd = cx->dis_sramwidth;
|
||||
snprintf(line->code, 256, "%-7s ", oc->opcode);
|
||||
char *c = line->code + strlen(line->code);
|
||||
*line->comment = 0;
|
||||
|
||||
// Check for opcodes with undefined results
|
||||
switch(oc->type & OTY_WARN_MASK) {
|
||||
case OTY_XWRN:
|
||||
if(Rd == 26 || Rd == 27 || Rr == 26 || Rr == 27)
|
||||
add_comment(line, "Warning: the result of this operation is undefined\n");
|
||||
break;
|
||||
case OTY_YWRN:
|
||||
if(Rd == 28 || Rd == 29 || Rr == 28 || Rr == 29)
|
||||
add_comment(line, "Warning: the result of this operation is undefined\n");
|
||||
break;
|
||||
case OTY_ZWRN:
|
||||
if(Rd == 30 || Rd == 31 || Rr == 30 || Rr == 31)
|
||||
add_comment(line, "Warning: the result of this operation is undefined\n");
|
||||
break;
|
||||
}
|
||||
|
||||
int target = 0, offset = 0, is_jumpcall = 0, is_relative = 0;
|
||||
int is_function = !!(oc->type & OTY_EXTERNAL); // call/rcall affects stack memory
|
||||
const char *kmemaddr = NULL, *memaddr, *regname;
|
||||
@@ -207,16 +228,8 @@ void disassemble(const char *buf, int addr, int opcode, AVR_opcode mnemo, Disasm
|
||||
Register_JumpCall(addr, target, mnemo, is_function);
|
||||
is_jumpcall = 1;
|
||||
break;
|
||||
default:
|
||||
pmsg_warning("OPCODE_%s has an unexpected number %d of k bits\n",
|
||||
oc->idname, Nk);
|
||||
}
|
||||
|
||||
int awd = cx->dis_addrwidth, swd = cx->dis_sramwidth;
|
||||
snprintf(line->code, 256, "%-7s ", oc->opcode);
|
||||
char *c = line->code + strlen(line->code);
|
||||
*line->comment = 0;
|
||||
|
||||
for(const char *o = oc->operands; *o && c-line->code < 255; o++) {
|
||||
switch(*o) {
|
||||
case 'R':
|
||||
@@ -370,8 +383,7 @@ int disasm(const char *buf, int buflen, int addr, int leadin, int leadout) {
|
||||
|
||||
Pos += oplen;
|
||||
} else {
|
||||
term_out(".word 0x%02x%02x ; Invalid opcode at 0x%04x\n",
|
||||
buf[Pos + 1] & 0xff, buf[Pos] & 0xff, disasm_wrap(Pos + addr));
|
||||
term_out(".word 0x%02x%02x ; Invalid opcode\n", buf[Pos+1] & 0xff, buf[Pos] & 0xff);
|
||||
Pos += 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1583,30 +1583,38 @@ typedef enum {
|
||||
#define PART_ALL (PART_AVR_XM|OP_AVR_L|OP_AVR_XL) // All but RC (the latter conflicts)
|
||||
|
||||
// Opcode types
|
||||
#define OTY_RMASK 7 // Register formula mask
|
||||
#define OTY_REG_MASK 7 // Register formula mask
|
||||
#define OTY_RNONE 0 // No registers addressed in this opcode
|
||||
#define OTY_RALL 1 // Opcode can use all 32 registers (both Rd, Rr)
|
||||
#define OTY_REVN 2 // Opcode only uses even registers (Rd *= 2, Rr *= 2)
|
||||
#define OTY_RUPP 3 // Opcode only uses upper registers (Rd += 16, Rr += 16)
|
||||
#define OTY_RW24 4 // Opcode only uses r24, r26, r28, r30 (Rd = Rd *2 + 24)
|
||||
|
||||
#define OTY_EXTERNAL 0x010 // Opcode might r/w either I/O region or memory
|
||||
#define OTY_ALBI 0x020 // Arithmetic, logic or bitwise operation
|
||||
#define OTY_ALBX 0x030 // Arithmetic, logic or bitwise operation (external)
|
||||
#define OTY_XFRI 0x040 // Data transfer (only affecting registers)
|
||||
#define OTY_XFRX 0x050 // Data transfer (between external I/O or memory and regs)
|
||||
#define OTY_JMPI 0x080 // Jump to potentially anywhere in flash (jmp, ijmp, eijmp)
|
||||
#define OTY_JMPX 0x090 // Jump to potentially anywhere in flash (calls and ret/i)
|
||||
#define OTY_RJMI 0x100 // Relative jump rjmp, range [-4094, 4096] bytes
|
||||
#define OTY_RJMX 0x110 // Relative call rcall, range [-4094, 4096] bytes
|
||||
#define OTY_BRAI 0x200 // Conditional branch, range [-126, 128] bytes
|
||||
#define OTY_SKPI 0x400 // Conditional skip, range [0, 4] bytes (cpse, sbrc, sbrs)
|
||||
#define OTY_SKPX 0x410 // Conditional skip, range [0, 4] bytes (sbic, sbis)
|
||||
#define OTY_MCUI 0x800 // nop and wdr
|
||||
#define OTY_MCUX 0x810 // sleep and break
|
||||
#define OTY_EXTERNAL 0x008 // Opcode might r/w either I/O region or memory
|
||||
|
||||
#define OTY_ALIAS 0x1000 // Opcode is a strict alias for another one, eg, sbr == ori
|
||||
#define OTY_CONSTRAINT 0x2000 // Opcode has constraints: Rr == Rd (tst, clr, lsl, rol)
|
||||
#define OTY_TYPE_MASK 0x78 // OPCODE type mask
|
||||
#define OTY_ITYPE_MASK 0x70 // OPCODE type mask matching OTY_xxxI types
|
||||
#define OTY_MCUI 0x00 // nop and wdr
|
||||
#define OTY_MCUX 0x08 // sleep and break
|
||||
#define OTY_ALBI 0x10 // Arithmetic, logic or bitwise operation
|
||||
#define OTY_ALBX 0x18 // Arithmetic, logic or bitwise operation (external)
|
||||
#define OTY_XFRI 0x20 // Data transfer (only affecting registers)
|
||||
#define OTY_XFRX 0x28 // Data transfer (between external I/O or memory and regs)
|
||||
#define OTY_JMPI 0x30 // Jump to potentially anywhere in flash (jmp, ijmp, eijmp)
|
||||
#define OTY_JMPX 0x38 // Jump to potentially anywhere in flash (calls and ret/i)
|
||||
#define OTY_RJMI 0x40 // Relative jump rjmp, range [-4094, 4096] bytes
|
||||
#define OTY_RJMX 0x48 // Relative call rcall, range [-4094, 4096] bytes
|
||||
#define OTY_BRAI 0x50 // Conditional branch, range [-126, 128] bytes
|
||||
#define OTY_SKPI 0x60 // Conditional skip, range [0, 4] bytes (cpse, sbrc, sbrs)
|
||||
#define OTY_SKPX 0x68 // Conditional skip, range [0, 4] bytes (sbic, sbis)
|
||||
|
||||
#define OTY_ALIAS 0x100 // Opcode is a strict alias for another one, eg, sbr == ori
|
||||
#define OTY_CONSTRAINT 0x200 // Opcode has constraints: Rr == Rd (tst, clr, lsl, rol)
|
||||
|
||||
#define OTY_WARN_MASK 0xc00 // OPCODE warning mask
|
||||
#define OTY_XWRN 0x400 // Operand register must not be r27/r28
|
||||
#define OTY_YWRN 0x800 // Operand register must not be r29/r30
|
||||
#define OTY_ZWRN 0xc00 // Operand register must not be r29/r30
|
||||
|
||||
typedef struct {
|
||||
AVR_opcode mnemo; // Eg, OPCODE_add
|
||||
|
||||
Reference in New Issue
Block a user