X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=opcodes%2Frl78-dis.c;h=ef7d9490169e23d3673f5af99714014048488c43;hb=5d2e1193286fe6278ee70c2137b3726994f2e28b;hp=a2298ce4d7e517b63680b211608c45bd86f2a061;hpb=90092e730582d024f621c78c6b5b1e6f2348e77d;p=deliverable%2Fbinutils-gdb.git diff --git a/opcodes/rl78-dis.c b/opcodes/rl78-dis.c index a2298ce4d7..ef7d949016 100644 --- a/opcodes/rl78-dis.c +++ b/opcodes/rl78-dis.c @@ -1,5 +1,5 @@ /* Disassembler code for Renesas RL78. - Copyright (C) 2011-2015 Free Software Foundation, Inc. + Copyright (C) 2011-2020 Free Software Foundation, Inc. Contributed by Red Hat. Written by DJ Delorie. @@ -24,8 +24,12 @@ #include #include "bfd.h" -#include "dis-asm.h" +#include "elf-bfd.h" +#include "disassemble.h" #include "opcode/rl78.h" +#include "elf/rl78.h" + +#include #define DEBUG_SEMANTICS 0 @@ -35,16 +39,30 @@ typedef struct disassemble_info * dis; } RL78_Data; +struct private +{ + OPCODES_SIGJMP_BUF bailout; +}; + static int rl78_get_byte (void * vdata) { bfd_byte buf[1]; RL78_Data *rl78_data = (RL78_Data *) vdata; + int status; - rl78_data->dis->read_memory_func (rl78_data->pc, - buf, - 1, - rl78_data->dis); + status = rl78_data->dis->read_memory_func (rl78_data->pc, + buf, + 1, + rl78_data->dis); + if (status != 0) + { + struct private *priv = (struct private *) rl78_data->dis->private_data; + + rl78_data->dis->memory_error_func (status, rl78_data->pc, + rl78_data->dis); + OPCODES_SIGLONGJMP (priv->bailout, 1); + } rl78_data->pc ++; return buf[0]; @@ -80,8 +98,8 @@ indirect_type (int t) } } -int -print_insn_rl78 (bfd_vma addr, disassemble_info * dis) +static int +print_insn_rl78_common (bfd_vma addr, disassemble_info * dis, RL78_Dis_Isa isa) { int rv; RL78_Data rl78_data; @@ -90,11 +108,19 @@ print_insn_rl78 (bfd_vma addr, disassemble_info * dis) #if DEBUG_SEMANTICS static char buf[200]; #endif + struct private priv; + dis->private_data = (PTR) &priv; rl78_data.pc = addr; rl78_data.dis = dis; - rv = rl78_decode_opcode (addr, &opcode, rl78_get_byte, &rl78_data); + if (OPCODES_SIGSETJMP (priv.bailout) != 0) + { + /* Error return. */ + return -1; + } + + rv = rl78_decode_opcode (addr, &opcode, rl78_get_byte, &rl78_data, isa); dis->bytes_per_line = 10; @@ -202,7 +228,7 @@ print_insn_rl78 (bfd_vma addr, disassemble_info * dis) { char *comma = ""; PR (PS, " \033[35m"); - + if (opcode.flags & RL78_PSW_Z) { PR (PS, "Z"); comma = ","; } if (opcode.flags & RL78_PSW_AC) @@ -225,7 +251,18 @@ print_insn_rl78 (bfd_vma addr, disassemble_info * dis) } if (do_bang) - PC ('!'); + { + /* If we are going to display SP by name, we must omit the bang. */ + if ((oper->type == RL78_Operand_Indirect + || oper->type == RL78_Operand_BitIndirect) + && oper->reg == RL78_Reg_None + && do_sfr + && ((oper->addend == 0xffff8 && opcode.size == RL78_Word) + || (oper->addend == 0x0fff8 && do_es && opcode.size == RL78_Word))) + ; + else + PC ('!'); + } if (do_cond) { @@ -263,6 +300,20 @@ print_insn_rl78 (bfd_vma addr, disassemble_info * dis) PR (PS, "psw"); else if (oper->addend == 0xffff8 && do_sfr && opcode.size == RL78_Word) PR (PS, "sp"); + else if (oper->addend == 0x0fff8 && do_sfr && do_es && opcode.size == RL78_Word) + PR (PS, "sp"); + else if (oper->addend == 0xffff8 && do_sfr && opcode.size == RL78_Byte) + PR (PS, "spl"); + else if (oper->addend == 0xffff9 && do_sfr && opcode.size == RL78_Byte) + PR (PS, "sph"); + else if (oper->addend == 0xffffc && do_sfr && opcode.size == RL78_Byte) + PR (PS, "cs"); + else if (oper->addend == 0xffffd && do_sfr && opcode.size == RL78_Byte) + PR (PS, "es"); + else if (oper->addend == 0xffffe && do_sfr && opcode.size == RL78_Byte) + PR (PS, "pmc"); + else if (oper->addend == 0xfffff && do_sfr && opcode.size == RL78_Byte) + PR (PS, "mem"); else if (oper->addend >= 0xffe20) PR (PS, "%#x", oper->addend); else @@ -288,7 +339,7 @@ print_insn_rl78 (bfd_vma addr, disassemble_info * dis) PR (PS, "+%d", oper->addend); PC (']'); break; - + } if (oper->type == RL78_Operand_BitIndirect) PR (PS, ".%d", oper->bit_number); @@ -327,3 +378,48 @@ print_insn_rl78 (bfd_vma addr, disassemble_info * dis) return rv; } + +int +print_insn_rl78 (bfd_vma addr, disassemble_info * dis) +{ + return print_insn_rl78_common (addr, dis, RL78_ISA_DEFAULT); +} + +int +print_insn_rl78_g10 (bfd_vma addr, disassemble_info * dis) +{ + return print_insn_rl78_common (addr, dis, RL78_ISA_G10); +} + +int +print_insn_rl78_g13 (bfd_vma addr, disassemble_info * dis) +{ + return print_insn_rl78_common (addr, dis, RL78_ISA_G13); +} + +int +print_insn_rl78_g14 (bfd_vma addr, disassemble_info * dis) +{ + return print_insn_rl78_common (addr, dis, RL78_ISA_G14); +} + +disassembler_ftype +rl78_get_disassembler (bfd *abfd) +{ + int cpu = E_FLAG_RL78_ANY_CPU; + + if (abfd != NULL) + cpu = abfd->tdata.elf_obj_data->elf_header->e_flags & E_FLAG_RL78_CPU_MASK; + + switch (cpu) + { + case E_FLAG_RL78_G10: + return print_insn_rl78_g10; + case E_FLAG_RL78_G13: + return print_insn_rl78_g13; + case E_FLAG_RL78_G14: + return print_insn_rl78_g14; + default: + return print_insn_rl78; + } +}