/* Target-dependent code for the Toshiba MeP for GDB, the GNU debugger.
- Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
- Free Software Foundation, Inc.
+ Copyright (C) 2001-2015 Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
#include "gdbtypes.h"
#include "gdbcmd.h"
#include "gdbcore.h"
-#include "gdb_string.h"
#include "value.h"
#include "inferior.h"
#include "dis-asm.h"
#include "elf-bfd.h"
#include "elf/mep.h"
#include "prologue-value.h"
-#include "opcode/cgen-bitset.h"
+#include "cgen/bitset.h"
#include "infcall.h"
-#include "gdb_assert.h"
-
/* Get the user's customized MeP coprocessor register names from
libopcodes. */
#include "opcodes/mep-desc.h"
mask contains any of the me_module's coprocessor ISAs,
specifically excluding the generic coprocessor register sets. */
- CGEN_CPU_DESC desc = gdbarch_tdep (target_gdbarch)->cpu_desc;
+ CGEN_CPU_DESC desc = gdbarch_tdep (target_gdbarch ())->cpu_desc;
const CGEN_HW_ENTRY *hw;
if (me_module == CONFIG_NONE)
mep_debug_reg_to_regnum (struct gdbarch *gdbarch, int debug_reg)
{
/* The debug info uses the raw register numbers. */
- return mep_raw_to_pseudo[debug_reg];
+ if (debug_reg >= 0 && debug_reg < ARRAY_SIZE (mep_raw_to_pseudo))
+ return mep_raw_to_pseudo[debug_reg];
+ return -1;
}
|| IS_FP_CR64_REGNUM (pseudo))
return 64;
else
- gdb_assert (0);
+ gdb_assert_not_reached ("unexpected coprocessor pseudo register");
}
else if (IS_FP_CR64_REGNUM (pseudo))
return pseudo - MEP_FIRST_FP_CR64_REGNUM;
else
- gdb_assert (0);
+ gdb_assert_not_reached ("unexpected coprocessor pseudo register");
}
from the ELF header's e_flags field of the current executable
file. */
static CONFIG_ATTR
-current_me_module ()
+current_me_module (void)
{
if (target_has_registers)
{
ULONGEST regval;
regcache_cooked_read_unsigned (get_current_regcache (),
MEP_MODULE_REGNUM, ®val);
- return regval;
+ return (CONFIG_ATTR) regval;
}
else
- return gdbarch_tdep (target_gdbarch)->me_module;
+ return gdbarch_tdep (target_gdbarch ())->me_module;
}
then use the 'module_opt' field we computed when we build the
gdbarch object for this module. */
static unsigned int
-current_options ()
+current_options (void)
{
if (target_has_registers)
{
/* Return the width of the current me_module's coprocessor data bus,
in bits. This is either 32 or 64. */
static int
-current_cop_data_bus_width ()
+current_cop_data_bus_width (void)
{
return me_module_cop_data_bus_width (current_me_module ());
}
/* Return the keyword table of coprocessor general-purpose register
names appropriate for the me_module we're dealing with. */
static CGEN_KEYWORD *
-current_cr_names ()
+current_cr_names (void)
{
const CGEN_HW_ENTRY *hw
= me_module_register_set (current_me_module (), "h-cr-", HW_H_CR);
/* Return non-zero if the coprocessor general-purpose registers are
floating-point values, zero otherwise. */
static int
-current_cr_is_float ()
+current_cr_is_float (void)
{
const CGEN_HW_ENTRY *hw
= me_module_register_set (current_me_module (), "h-cr-", HW_H_CR);
/* Return the keyword table of coprocessor control register names
appropriate for the me_module we're dealing with. */
static CGEN_KEYWORD *
-current_ccr_names ()
+current_ccr_names (void)
{
const CGEN_HW_ENTRY *hw
= me_module_register_set (current_me_module (), "h-ccr-", HW_H_CCR);
keep the 'g' packet format fixed), and the pseudoregisters vary
in length. */
if (IS_RAW_CR_REGNUM (reg_nr))
- return builtin_type_uint64;
+ return builtin_type (gdbarch)->builtin_uint64;
/* Since GDB doesn't allow registers to change type, we have two
banks of pseudoregisters for the coprocessor general-purpose
if (size == 32)
{
if (mep_pseudo_cr_is_float (reg_nr))
- return builtin_type_float;
+ return builtin_type (gdbarch)->builtin_float;
else
- return builtin_type_uint32;
+ return builtin_type (gdbarch)->builtin_uint32;
}
else if (size == 64)
{
if (mep_pseudo_cr_is_float (reg_nr))
- return builtin_type_double;
+ return builtin_type (gdbarch)->builtin_double;
else
- return builtin_type_uint64;
+ return builtin_type (gdbarch)->builtin_uint64;
}
else
- gdb_assert (0);
+ gdb_assert_not_reached ("unexpected cr size");
}
/* All other registers are 32 bits long. */
else
- return builtin_type_uint32;
+ return builtin_type (gdbarch)->builtin_uint32;
}
return pc;
}
-static void
-mep_write_pc (struct regcache *regcache, CORE_ADDR pc)
-{
- regcache_cooked_write_unsigned (regcache, MEP_PC_REGNUM, pc);
-}
-
-
-static void
+static enum register_status
mep_pseudo_cr32_read (struct gdbarch *gdbarch,
struct regcache *regcache,
int cookednum,
- void *buf)
+ gdb_byte *buf)
{
+ enum register_status status;
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
/* Read the raw register into a 64-bit buffer, and then return the
appropriate end of that buffer. */
int rawnum = mep_pseudo_to_raw[cookednum];
- char buf64[8];
+ gdb_byte buf64[8];
gdb_assert (TYPE_LENGTH (register_type (gdbarch, rawnum)) == sizeof (buf64));
gdb_assert (TYPE_LENGTH (register_type (gdbarch, cookednum)) == 4);
- regcache_raw_read (regcache, rawnum, buf64);
- /* Slow, but legible. */
- store_unsigned_integer (buf, 4, extract_unsigned_integer (buf64, 8));
+ status = regcache_raw_read (regcache, rawnum, buf64);
+ if (status == REG_VALID)
+ {
+ /* Slow, but legible. */
+ store_unsigned_integer (buf, 4, byte_order,
+ extract_unsigned_integer (buf64, 8, byte_order));
+ }
+ return status;
}
-static void
+static enum register_status
mep_pseudo_cr64_read (struct gdbarch *gdbarch,
struct regcache *regcache,
int cookednum,
- void *buf)
+ gdb_byte *buf)
{
- regcache_raw_read (regcache, mep_pseudo_to_raw[cookednum], buf);
+ return regcache_raw_read (regcache, mep_pseudo_to_raw[cookednum], buf);
}
-static void
+static enum register_status
mep_pseudo_register_read (struct gdbarch *gdbarch,
struct regcache *regcache,
int cookednum,
{
if (IS_CSR_REGNUM (cookednum)
|| IS_CCR_REGNUM (cookednum))
- regcache_raw_read (regcache, mep_pseudo_to_raw[cookednum], buf);
+ return regcache_raw_read (regcache, mep_pseudo_to_raw[cookednum], buf);
else if (IS_CR32_REGNUM (cookednum)
|| IS_FP_CR32_REGNUM (cookednum))
- mep_pseudo_cr32_read (gdbarch, regcache, cookednum, buf);
+ return mep_pseudo_cr32_read (gdbarch, regcache, cookednum, buf);
else if (IS_CR64_REGNUM (cookednum)
|| IS_FP_CR64_REGNUM (cookednum))
- mep_pseudo_cr64_read (gdbarch, regcache, cookednum, buf);
+ return mep_pseudo_cr64_read (gdbarch, regcache, cookednum, buf);
else
- gdb_assert (0);
+ gdb_assert_not_reached ("unexpected pseudo register");
}
mep_pseudo_csr_write (struct gdbarch *gdbarch,
struct regcache *regcache,
int cookednum,
- const void *buf)
+ const gdb_byte *buf)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int size = register_size (gdbarch, cookednum);
struct mep_csr_register *r
= &mep_csr_registers[cookednum - MEP_FIRST_CSR_REGNUM];
ULONGEST mixed_bits;
regcache_raw_read_unsigned (regcache, r->raw, &old_bits);
- new_bits = extract_unsigned_integer (buf, size);
+ new_bits = extract_unsigned_integer (buf, size, byte_order);
mixed_bits = ((r->writeable_bits & new_bits)
| (~r->writeable_bits & old_bits));
regcache_raw_write_unsigned (regcache, r->raw, mixed_bits);
mep_pseudo_cr32_write (struct gdbarch *gdbarch,
struct regcache *regcache,
int cookednum,
- const void *buf)
+ const gdb_byte *buf)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
/* Expand the 32-bit value into a 64-bit value, and write that to
the pseudoregister. */
int rawnum = mep_pseudo_to_raw[cookednum];
- char buf64[8];
+ gdb_byte buf64[8];
gdb_assert (TYPE_LENGTH (register_type (gdbarch, rawnum)) == sizeof (buf64));
gdb_assert (TYPE_LENGTH (register_type (gdbarch, cookednum)) == 4);
/* Slow, but legible. */
- store_unsigned_integer (buf64, 8, extract_unsigned_integer (buf, 4));
+ store_unsigned_integer (buf64, 8, byte_order,
+ extract_unsigned_integer (buf, 4, byte_order));
regcache_raw_write (regcache, rawnum, buf64);
}
mep_pseudo_cr64_write (struct gdbarch *gdbarch,
struct regcache *regcache,
int cookednum,
- const void *buf)
+ const gdb_byte *buf)
{
regcache_raw_write (regcache, mep_pseudo_to_raw[cookednum], buf);
}
else if (IS_CCR_REGNUM (cookednum))
regcache_raw_write (regcache, mep_pseudo_to_raw[cookednum], buf);
else
- gdb_assert (0);
+ gdb_assert_not_reached ("unexpected pseudo register");
}
/* Disassembly. */
/* The mep disassembler needs to know about the section in order to
- work correctly. */
-int
+ work correctly. */
+static int
mep_gdb_print_insn (bfd_vma pc, disassemble_info * info)
{
struct obj_section * s = find_pc_section (pc);
Every bundle is four bytes long, and naturally aligned, and can hold
one or two instructions:
- 16-bit core instruction; 16-bit coprocessor instruction
- These execute in parallel.
+ These execute in parallel.
- 32-bit core instruction
- 32-bit coprocessor instruction
Every bundle is eight bytes long, and naturally aligned, and can hold
one or two instructions:
- 16-bit core instruction; 48-bit (!) coprocessor instruction
- These execute in parallel.
+ These execute in parallel.
- 32-bit core instruction; 32-bit coprocessor instruction
- These execute in parallel.
+ These execute in parallel.
- 64-bit coprocessor instruction
Now, the MeP manual doesn't define any 48- or 64-bit coprocessor
anyway. */
static CORE_ADDR
-mep_get_insn (CORE_ADDR pc, long *insn)
+mep_get_insn (struct gdbarch *gdbarch, CORE_ADDR pc, unsigned long *insn)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int pc_in_vliw_section;
int vliw_mode;
int insn_len;
- char buf[2];
+ gdb_byte buf[2];
*insn = 0;
vliw_mode = 0;
read_memory (pc, buf, sizeof (buf));
- *insn = extract_unsigned_integer (buf, 2) << 16;
+ *insn = extract_unsigned_integer (buf, 2, byte_order) << 16;
/* The major opcode --- the top four bits of the first 16-bit
part --- indicates whether this instruction is 16 or 32 bits
{
/* Fetch the second 16-bit part of the instruction. */
read_memory (pc + 2, buf, sizeof (buf));
- *insn = *insn | extract_unsigned_integer (buf, 2);
+ *insn = *insn | extract_unsigned_integer (buf, 2, byte_order);
}
/* If we're in VLIW code, then the VLIW width determines the address
/* We'd better be in either core, 32-bit VLIW, or 64-bit VLIW mode. */
else
- gdb_assert (0);
+ gdb_assert_not_reached ("unexpected vliw mode");
}
/* Otherwise, the top two bits of the major opcode are (again) what
result->reg_offset[rn] = 1;
}
- stack = make_pv_area (MEP_SP_REGNUM);
+ stack = make_pv_area (MEP_SP_REGNUM, gdbarch_addr_bit (gdbarch));
back_to = make_cleanup_free_pv_area (stack);
pc = start_pc;
CORE_ADDR next_pc;
pv_t pre_insn_fp, pre_insn_sp;
- next_pc = mep_get_insn (pc, &insn);
+ next_pc = mep_get_insn (gdbarch, pc, &insn);
/* A zero return from mep_get_insn means that either we weren't
able to read the instruction from memory, or that we don't
int disp = SWBH_32_OFFSET (insn);
int size = (IS_SB (insn) ? 1
: IS_SH (insn) ? 2
- : IS_SW (insn) ? 4
- : (gdb_assert (0), 1));
+ : (gdb_assert (IS_SW (insn)), 4));
pv_t addr = pv_add_constant (reg[rm], disp);
if (pv_area_store_would_trash (stack, addr))
body, gcc 4.x will use a BRA instruction to branch to the
loop condition checking code. This BRA instruction is
marked as part of the prologue. We therefore set next_pc
- to this branch target and also stop the prologue scan.
+ to this branch target and also stop the prologue scan.
The instructions at and beyond the branch target should
no longer be associated with the prologue.
static CORE_ADDR
mep_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
- char *name;
+ const char *name;
CORE_ADDR func_addr, func_end;
struct mep_prologue p;
stop_addr = func_start;
mep_analyze_prologue (get_frame_arch (this_frame),
- func_start, stop_addr, *this_prologue_cache);
+ func_start, stop_addr,
+ (struct mep_prologue *) *this_prologue_cache);
}
- return *this_prologue_cache;
+ return (struct mep_prologue *) *this_prologue_cache;
}
static const struct frame_unwind mep_frame_unwind = {
NORMAL_FRAME,
+ default_frame_unwind_stop_reason,
mep_frame_this_id,
mep_frame_prev_register,
NULL,
else
offset = 0;
- /* Return values that do fit in a single register are returned in R0. */
+ /* Return values that do fit in a single register are returned in R0. */
regcache_cooked_read_part (regcache, MEP_R0_REGNUM,
offset, TYPE_LENGTH (type),
valbuf);
/* Return values larger than a single register are returned in
memory, pointed to by R0. Unfortunately, we can't count on R0
- pointing to the return buffer, so we raise an error here. */
+ pointing to the return buffer, so we raise an error here. */
else
- error ("GDB cannot set return values larger than four bytes; "
- "the Media Processor's\n"
- "calling conventions do not provide enough information "
- "to do this.\n"
- "Try using the 'return' command with no argument.");
+ error (_("\
+GDB cannot set return values larger than four bytes; the Media Processor's\n\
+calling conventions do not provide enough information to do this.\n\
+Try using the 'return' command with no argument."));
}
-enum return_value_convention
-mep_return_value (struct gdbarch *gdbarch, struct type *func_type,
+static enum return_value_convention
+mep_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf)
{
{
/* Return values larger than a single register are returned in
memory, pointed to by R0. Unfortunately, we can't count on R0
- pointing to the return buffer, so we raise an error here. */
- error ("GDB cannot set return values larger than four bytes; "
- "the Media Processor's\n"
- "calling conventions do not provide enough information "
- "to do this.\n"
- "Try using the 'return' command with no argument.");
+ pointing to the return buffer, so we raise an error here. */
+ error (_("\
+GDB cannot set return values larger than four bytes; the Media Processor's\n\
+calling conventions do not provide enough information to do this.\n\
+Try using the 'return' command with no argument."));
}
return RETURN_VALUE_ABI_RETURNS_ADDRESS;
}
4.2.1 Core register conventions
- Parameters should be evaluated from left to right, and they
- should be held in $1,$2,$3,$4 in order. The fifth parameter or
- after should be held in the stack. If the size is larger than 4
+ should be held in $1,$2,$3,$4 in order. The fifth parameter or
+ after should be held in the stack. If the size is larger than 4
bytes in the first four parameters, the pointer should be held in
- the registers instead. If the size is larger than 4 bytes in the
+ the registers instead. If the size is larger than 4 bytes in the
fifth parameter or after, the pointer should be held in the stack.
- - Return value of a function should be held in register $0. If the
+ - Return value of a function should be held in register $0. If the
size of return value is larger than 4 bytes, $1 should hold the
- pointer pointing memory that would hold the return value. In this
+ pointer pointing memory that would hold the return value. In this
case, the first parameter should be held in $2, the second one in
$3, and the third one in $4, and the forth parameter or after
should be held in the stack.
int struct_return,
CORE_ADDR struct_addr)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR *copy = (CORE_ADDR *) alloca (argc * sizeof (copy[0]));
CORE_ADDR func_addr = find_function_addr (function, NULL);
int i;
for (i = 0; i < argc; i++)
{
- unsigned arg_size = TYPE_LENGTH (value_type (argv[i]));
ULONGEST value;
/* Arguments that fit in a GPR get expanded to fill the GPR. */
- if (arg_size <= MEP_GPR_SIZE)
+ if (TYPE_LENGTH (value_type (argv[i])) <= MEP_GPR_SIZE)
value = extract_unsigned_integer (value_contents (argv[i]),
- TYPE_LENGTH (value_type (argv[i])));
+ TYPE_LENGTH (value_type (argv[i])),
+ byte_order);
/* Arguments too large to fit in a GPR get copied to the stack,
and we pass a pointer to the copy. */
}
else
{
- char buf[MEP_GPR_SIZE];
- store_unsigned_integer (buf, MEP_GPR_SIZE, value);
+ gdb_byte buf[MEP_GPR_SIZE];
+ store_unsigned_integer (buf, MEP_GPR_SIZE, byte_order, value);
write_memory (arg_stack, buf, MEP_GPR_SIZE);
arg_stack += MEP_GPR_SIZE;
}
/* The way to get the me_module code depends on the object file
format. At the moment, we only know how to handle ELF. */
if (bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
- me_module = elf_elfheader (info.abfd)->e_flags & EF_MEP_INDEX_MASK;
+ {
+ int flag = elf_elfheader (info.abfd)->e_flags & EF_MEP_INDEX_MASK;
+ me_module = (CONFIG_ATTR) flag;
+ }
else
me_module = CONFIG_NONE;
}
fputc_unfiltered ('\n', gdb_stderr);
if (module_name)
- warning ("the MeP module '%s' is %s-endian, but the executable\n"
- "%s is %s-endian.",
+ warning (_("the MeP module '%s' is %s-endian, but the executable\n"
+ "%s is %s-endian."),
module_name, module_endianness,
file_name, file_endianness);
else
- warning ("the selected MeP module is %s-endian, but the "
- "executable\n"
- "%s is %s-endian.",
+ warning (_("the selected MeP module is %s-endian, but the "
+ "executable\n"
+ "%s is %s-endian."),
module_endianness, file_name, file_endianness);
}
}
if (gdbarch_tdep (arches->gdbarch)->me_module == me_module)
return arches->gdbarch;
- tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
+ tdep = XNEW (struct gdbarch_tdep);
gdbarch = gdbarch_alloc (&info, tdep);
/* Get a CGEN CPU descriptor for this architecture. */
/* Register set. */
set_gdbarch_read_pc (gdbarch, mep_read_pc);
- set_gdbarch_write_pc (gdbarch, mep_write_pc);
set_gdbarch_num_regs (gdbarch, MEP_NUM_RAW_REGS);
+ set_gdbarch_pc_regnum (gdbarch, MEP_PC_REGNUM);
set_gdbarch_sp_regnum (gdbarch, MEP_SP_REGNUM);
set_gdbarch_register_name (gdbarch, mep_register_name);
set_gdbarch_register_type (gdbarch, mep_register_type);
return gdbarch;
}
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern initialize_file_ftype _initialize_mep_tdep;
void
_initialize_mep_tdep (void)