diff options
Diffstat (limited to 'opcodes/avr-dis.c')
-rw-r--r-- | opcodes/avr-dis.c | 359 |
1 files changed, 0 insertions, 359 deletions
diff --git a/opcodes/avr-dis.c b/opcodes/avr-dis.c deleted file mode 100644 index 4598cab4145..00000000000 --- a/opcodes/avr-dis.c +++ /dev/null @@ -1,359 +0,0 @@ -/* Disassemble AVR instructions. - Copyright 1999, 2000 Free Software Foundation, Inc. - - Contributed by Denis Chertykov <denisc@overta.ru> - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include <assert.h> -#include "sysdep.h" -#include "dis-asm.h" -#include "opintl.h" - - -struct avr_opcodes_s -{ - char *name; - char *constraints; - char *opcode; - int insn_size; /* in words */ - int isa; - unsigned int bin_opcode; - unsigned int bin_mask; -}; - -#define AVR_INSN(NAME, CONSTR, OPCODE, SIZE, ISA, BIN) \ -{#NAME, CONSTR, OPCODE, SIZE, ISA, BIN, 0}, - -struct avr_opcodes_s avr_opcodes[] = -{ - #include "opcode/avr.h" - {NULL, NULL, NULL, 0, 0, 0, 0} -}; - -static int avr_operand PARAMS ((unsigned int, unsigned int, - unsigned int, int, char *, char *, int)); - -static int -avr_operand (insn, insn2, pc, constraint, buf, comment, regs) - unsigned int insn; - unsigned int insn2; - unsigned int pc; - int constraint; - char *buf; - char *comment; - int regs; -{ - int ok = 1; - - switch (constraint) - { - /* Any register operand. */ - case 'r': - if (regs) - insn = (insn & 0xf) | ((insn & 0x0200) >> 5); /* source register */ - else - insn = (insn & 0x01f0) >> 4; /* destination register */ - - sprintf (buf, "r%d", insn); - break; - - case 'd': - if (regs) - sprintf (buf, "r%d", 16 + (insn & 0xf)); - else - sprintf (buf, "r%d", 16 + ((insn & 0xf0) >> 4)); - break; - - case 'w': - sprintf (buf, "r%d", 24 + ((insn & 0x30) >> 3)); - break; - - case 'a': - if (regs) - sprintf (buf, "r%d", 16 + (insn & 7)); - else - sprintf (buf, "r%d", 16 + ((insn >> 4) & 7)); - break; - - case 'v': - if (regs) - sprintf (buf, "r%d", (insn & 0xf) * 2); - else - sprintf (buf, "r%d", ((insn & 0xf0) >> 3)); - break; - - case 'e': - { - char *xyz; - - switch (insn & 0x100f) - { - case 0x0000: xyz = "Z"; break; - case 0x1001: xyz = "Z+"; break; - case 0x1002: xyz = "-Z"; break; - case 0x0008: xyz = "Y"; break; - case 0x1009: xyz = "Y+"; break; - case 0x100a: xyz = "-Y"; break; - case 0x100c: xyz = "X"; break; - case 0x100d: xyz = "X+"; break; - case 0x100e: xyz = "-X"; break; - default: xyz = "??"; ok = 0; - } - sprintf (buf, xyz); - - if (AVR_UNDEF_P (insn)) - sprintf (comment, _("undefined")); - } - break; - - case 'z': - *buf++ = 'Z'; - if (insn & 0x1) - *buf++ = '+'; - *buf = '\0'; - if (AVR_UNDEF_P (insn)) - sprintf (comment, _("undefined")); - break; - - case 'b': - { - unsigned int x; - - x = (insn & 7); - x |= (insn >> 7) & (3 << 3); - x |= (insn >> 8) & (1 << 5); - - if (insn & 0x8) - *buf++ = 'Y'; - else - *buf++ = 'Z'; - sprintf (buf, "+%d", x); - sprintf (comment, "0x%02x", x); - } - break; - - case 'h': - sprintf (buf, "0x%x", - ((((insn & 1) | ((insn & 0x1f0) >> 3)) << 16) | insn2) * 2); - break; - - case 'L': - { - int rel_addr = (((insn & 0xfff) ^ 0x800) - 0x800) * 2; - sprintf (buf, ".%+-8d", rel_addr); - sprintf (comment, "0x%x", pc + 2 + rel_addr); - } - break; - - case 'l': - { - int rel_addr = ((((insn >> 3) & 0x7f) ^ 0x40) - 0x40) * 2; - sprintf (buf, ".%+-8d", rel_addr); - sprintf (comment, "0x%x", pc + 2 + rel_addr); - } - break; - - case 'i': - sprintf (buf, "0x%04X", insn2); - break; - - case 'M': - sprintf (buf, "0x%02X", ((insn & 0xf00) >> 4) | (insn & 0xf)); - sprintf (comment, "%d", ((insn & 0xf00) >> 4) | (insn & 0xf)); - break; - - case 'n': - sprintf (buf, "??"); - fprintf (stderr, _("Internal disassembler error")); - ok = 0; - break; - - case 'K': - { - unsigned int x; - - x = (insn & 0xf) | ((insn >> 2) & 0x30); - sprintf (buf, "0x%02x", x); - sprintf (comment, "%d", x); - } - break; - - case 's': - sprintf (buf, "%d", insn & 7); - break; - - case 'S': - sprintf (buf, "%d", (insn >> 4) & 7); - break; - - case 'P': - { - unsigned int x; - x = (insn & 0xf); - x |= (insn >> 5) & 0x30; - sprintf (buf, "0x%02x", x); - sprintf (comment, "%d", x); - } - break; - - case 'p': - { - unsigned int x; - - x = (insn >> 3) & 0x1f; - sprintf (buf, "0x%02x", x); - sprintf (comment, "%d", x); - } - break; - - case '?': - *buf = '\0'; - break; - - default: - sprintf (buf, "??"); - fprintf (stderr, _("unknown constraint `%c'"), constraint); - ok = 0; - } - - return ok; -} - -static unsigned short avrdis_opcode PARAMS ((bfd_vma, disassemble_info *)); - -static unsigned short -avrdis_opcode (addr, info) - bfd_vma addr; - disassemble_info *info; -{ - bfd_byte buffer[2]; - int status; - status = info->read_memory_func(addr, buffer, 2, info); - if (status != 0) - { - info->memory_error_func(status, addr, info); - return -1; - } - return bfd_getl16 (buffer); -} - - -int -print_insn_avr(addr, info) - bfd_vma addr; - disassemble_info *info; -{ - unsigned int insn, insn2; - struct avr_opcodes_s *opcode; - void *stream = info->stream; - fprintf_ftype prin = info->fprintf_func; - static int initialized; - int cmd_len = 2; - int ok = 0; - char op1[20], op2[20], comment1[40], comment2[40]; - - if (!initialized) - { - initialized = 1; - - for (opcode = avr_opcodes; opcode->name; opcode++) - { - char * s; - unsigned int bin = 0; - unsigned int mask = 0; - - for (s = opcode->opcode; *s; ++s) - { - bin <<= 1; - mask <<= 1; - bin |= (*s == '1'); - mask |= (*s == '1' || *s == '0'); - } - assert (s - opcode->opcode == 16); - assert (opcode->bin_opcode == bin); - opcode->bin_mask = mask; - } - } - - insn = avrdis_opcode (addr, info); - - for (opcode = avr_opcodes; opcode->name; opcode++) - { - if ((insn & opcode->bin_mask) == opcode->bin_opcode) - break; - } - - /* Special case: disassemble `ldd r,b+0' as `ld r,b', and - `std b+0,r' as `st b,r' (next entry in the table). */ - - if (AVR_DISP0_P (insn)) - opcode++; - - op1[0] = 0; - op2[0] = 0; - comment1[0] = 0; - comment2[0] = 0; - - if (opcode->name) - { - char *op = opcode->constraints; - - insn2 = 0; - ok = 1; - - if (opcode->insn_size > 1) - { - insn2 = avrdis_opcode (addr + 2, info); - cmd_len = 4; - } - - if (*op && *op != '?') - { - int regs = REGISTER_P (*op); - - ok = avr_operand (insn, insn2, addr, *op, op1, comment1, 0); - - if (ok && *(++op) == ',') - ok = avr_operand (insn, insn2, addr, *(++op), op2, - *comment1 ? comment2 : comment1, regs); - } - } - - if (!ok) - { - /* Unknown opcode, or invalid combination of operands. */ - sprintf (op1, "0x%04x", insn); - op2[0] = 0; - sprintf (comment1, "????"); - comment2[0] = 0; - } - - (*prin) (stream, "%s", ok ? opcode->name : ".word"); - - if (*op1) - (*prin) (stream, "\t%s", op1); - - if (*op2) - (*prin) (stream, ", %s", op2); - - if (*comment1) - (*prin) (stream, "\t; %s", comment1); - - if (*comment2) - (*prin) (stream, " %s", comment2); - - return cmd_len; -} |