/* Target-dependent code for Morpho mt processor, for GDB.
- Copyright (C) 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2005-2015 Free Software Foundation, Inc.
This file is part of GDB.
#include "dis-asm.h"
#include "arch-utils.h"
#include "gdbtypes.h"
-#include "gdb_string.h"
#include "regcache.h"
#include "reggroups.h"
#include "gdbcore.h"
#include "inferior.h"
#include "dwarf2-frame.h"
#include "infcall.h"
-#include "gdb_assert.h"
#include "language.h"
#include "valprint.h"
* MT_COPRO_PSEUDOREG_DIM_2)
};
+/* The tdep structure. */
+struct gdbarch_tdep
+{
+ /* ISA-specific types. */
+ struct type *copro_type;
+};
+
+
/* Return name of register number specified by REGNUM. */
static const char *
case MT_QCHANNEL_REGNUM:
case MT_ISCRAMB_REGNUM:
case MT_QSCRAMB_REGNUM:
- return builtin_type_int32;
+ return builtin_type (arch)->builtin_int32;
case MT_BYPA_REGNUM:
case MT_BYPB_REGNUM:
case MT_BYPC_REGNUM:
case MT_OUT_REGNUM:
case MT_ZI2_REGNUM:
case MT_ZQ2_REGNUM:
- return builtin_type_int16;
+ return builtin_type (arch)->builtin_int16;
case MT_EXMAC_REGNUM:
case MT_MAC_REGNUM:
- return builtin_type_uint32;
+ return builtin_type (arch)->builtin_uint32;
case MT_CONTEXT_REGNUM:
return builtin_type (arch)->builtin_long_long;
case MT_FLAG_REGNUM:
return builtin_type (arch)->builtin_unsigned_char;
default:
if (regnum >= MT_CPR0_REGNUM && regnum <= MT_CPR15_REGNUM)
- return builtin_type_int16;
+ return builtin_type (arch)->builtin_int16;
else if (regnum == MT_CPR0_REGNUM + MT_COPRO_PSEUDOREG_MAC_REGNUM)
{
if (gdbarch_bfd_arch_info (arch)->mach == bfd_mach_mrisc2
|| gdbarch_bfd_arch_info (arch)->mach == bfd_mach_ms2)
- return builtin_type_uint64;
+ return builtin_type (arch)->builtin_uint64;
else
- return builtin_type_uint32;
+ return builtin_type (arch)->builtin_uint32;
}
else
- return builtin_type_uint32;
+ return builtin_type (arch)->builtin_uint32;
}
}
static struct type *
mt_register_type (struct gdbarch *arch, int regnum)
{
- static struct type *copro_type = NULL;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
if (regnum >= 0 && regnum < MT_NUM_REGS + MT_NUM_PSEUDO_REGS)
{
- if (copro_type == NULL)
- {
- struct type *temp;
- temp = create_range_type (NULL, builtin_type_int32, 0, 1);
- copro_type = create_array_type (NULL, builtin_type_int16, temp);
- }
switch (regnum)
{
case MT_PC_REGNUM:
return builtin_type (arch)->builtin_data_ptr;
case MT_COPRO_REGNUM:
case MT_COPRO_PSEUDOREG_REGNUM:
- return copro_type;
+ if (tdep->copro_type == NULL)
+ {
+ struct type *elt = builtin_type (arch)->builtin_int16;
+ tdep->copro_type = lookup_array_range_type (elt, 0, 1);
+ }
+ return tdep->copro_type;
case MT_MAC_PSEUDOREG_REGNUM:
return mt_copro_register_type (arch,
MT_CPR0_REGNUM
+ MT_COPRO_PSEUDOREG_MAC_REGNUM);
default:
if (regnum >= MT_R0_REGNUM && regnum <= MT_R15_REGNUM)
- return builtin_type_int32;
+ return builtin_type (arch)->builtin_int32;
else if (regnum < MT_COPRO_PSEUDOREG_ARRAY)
return mt_copro_register_type (arch, regnum);
else
values. */
static enum return_value_convention
-mt_return_value (struct gdbarch *gdbarch, struct type *func_type,
+mt_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+
if (TYPE_LENGTH (type) > 4)
{
/* Return values > 4 bytes are returned in memory,
/* Return values of <= 4 bytes are returned in R11. */
regcache_cooked_read_unsigned (regcache, MT_R11_REGNUM, &temp);
- store_unsigned_integer (readbuf, TYPE_LENGTH (type), temp);
+ store_unsigned_integer (readbuf, TYPE_LENGTH (type),
+ byte_order, temp);
}
if (writebuf)
static CORE_ADDR
mt_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR func_addr = 0, func_end = 0;
- char *func_name;
+ const char *func_name;
unsigned long instr;
if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
struct symbol *sym;
/* Found a function. */
- sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL);
+ sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL).symbol;
if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
{
/* Don't use this trick for assembly source files. */
/* No function symbol, or no line symbol. Use prologue scanning method. */
for (;; pc += 4)
{
- instr = read_memory_unsigned_integer (pc, 4);
+ instr = read_memory_unsigned_integer (pc, 4, byte_order);
if (instr == 0x12000000) /* nop */
continue;
if (instr == 0x12ddc000) /* copy sp into fp */
instruction in the instruction set.
The BP for ms1 is defined as 0x68000000 (BREAK).
- The BP for ms2 is defined as 0x69000000 (illegal) */
+ The BP for ms2 is defined as 0x69000000 (illegal). */
static const gdb_byte *
mt_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr,
mt_select_coprocessor (struct gdbarch *gdbarch,
struct regcache *regcache, int regno)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
unsigned index, base;
gdb_byte copro[4];
- /* Get the copro pseudo regnum. */
+ /* Get the copro pseudo regnum. */
regcache_raw_read (regcache, MT_COPRO_REGNUM, copro);
- base = (extract_signed_integer (&copro[0], 2) * MT_COPRO_PSEUDOREG_DIM_2
- + extract_signed_integer (&copro[2], 2));
+ base = ((extract_signed_integer (&copro[0], 2, byte_order)
+ * MT_COPRO_PSEUDOREG_DIM_2)
+ + extract_signed_integer (&copro[2], 2, byte_order));
regno -= MT_COPRO_PSEUDOREG_ARRAY;
index = regno % MT_COPRO_PSEUDOREG_REGS;
coprocessor register cache. */
unsigned ix;
- store_signed_integer (&copro[0], 2, regno / MT_COPRO_PSEUDOREG_DIM_2);
- store_signed_integer (&copro[2], 2, regno % MT_COPRO_PSEUDOREG_DIM_2);
+ store_signed_integer (&copro[0], 2, byte_order,
+ regno / MT_COPRO_PSEUDOREG_DIM_2);
+ store_signed_integer (&copro[2], 2, byte_order,
+ regno % MT_COPRO_PSEUDOREG_DIM_2);
regcache_raw_write (regcache, MT_COPRO_REGNUM, copro);
/* We must flush the cache, as it is now invalid. */
Additionally there is an array of coprocessor registers which track
the coprocessor registers for each coprocessor. */
-static void
+static enum register_status
mt_pseudo_register_read (struct gdbarch *gdbarch,
- struct regcache *regcache, int regno, gdb_byte *buf)
+ struct regcache *regcache, int regno, gdb_byte *buf)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+
switch (regno)
{
case MT_COPRO_REGNUM:
case MT_COPRO_PSEUDOREG_REGNUM:
- regcache_raw_read (regcache, MT_COPRO_REGNUM, buf);
- break;
+ return regcache_raw_read (regcache, MT_COPRO_REGNUM, buf);
case MT_MAC_REGNUM:
case MT_MAC_PSEUDOREG_REGNUM:
if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_mrisc2
|| gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_ms2)
{
+ enum register_status status;
ULONGEST oldmac = 0, ext_mac = 0;
ULONGEST newmac;
- regcache_cooked_read_unsigned (regcache, MT_MAC_REGNUM, &oldmac);
+ status = regcache_cooked_read_unsigned (regcache, MT_MAC_REGNUM, &oldmac);
+ if (status != REG_VALID)
+ return status;
+
regcache_cooked_read_unsigned (regcache, MT_EXMAC_REGNUM, &ext_mac);
+ if (status != REG_VALID)
+ return status;
+
newmac =
(oldmac & 0xffffffff) | ((long long) (ext_mac & 0xff) << 32);
- store_signed_integer (buf, 8, newmac);
+ store_signed_integer (buf, 8, byte_order, newmac);
+
+ return REG_VALID;
}
else
- regcache_raw_read (regcache, MT_MAC_REGNUM, buf);
+ return regcache_raw_read (regcache, MT_MAC_REGNUM, buf);
break;
default:
{
unsigned index = mt_select_coprocessor (gdbarch, regcache, regno);
if (index == MT_COPRO_PSEUDOREG_MAC_REGNUM)
- mt_pseudo_register_read (gdbarch, regcache,
- MT_MAC_PSEUDOREG_REGNUM, buf);
+ return mt_pseudo_register_read (gdbarch, regcache,
+ MT_MAC_PSEUDOREG_REGNUM, buf);
else if (index < MT_NUM_REGS - MT_CPR0_REGNUM)
- regcache_raw_read (regcache, index + MT_CPR0_REGNUM, buf);
+ return regcache_raw_read (regcache, index + MT_CPR0_REGNUM, buf);
+ else
+ /* ??? */
+ return REG_VALID;
}
break;
}
struct regcache *regcache,
int regno, const gdb_byte *buf)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int i;
switch (regno)
unsigned int oldmac, ext_mac;
ULONGEST newmac;
- newmac = extract_unsigned_integer (buf, 8);
+ newmac = extract_unsigned_integer (buf, 8, byte_order);
oldmac = newmac & 0xffffffff;
ext_mac = (newmac >> 32) & 0xff;
regcache_cooked_write_unsigned (regcache, MT_MAC_REGNUM, oldmac);
struct ui_file *file,
struct frame_info *frame, int regnum, int all)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+
if (regnum == -1)
{
int lim;
regsize = register_size (gdbarch, regnum);
buff = alloca (regsize);
- bytes = alloca (regsize * sizeof (*bytes));
+ bytes = XALLOCAVEC (unsigned int, regsize);
- frame_register_read (frame, regnum, buff);
+ deprecated_frame_register_read (frame, regnum, buff);
fputs_filtered (gdbarch_register_name
(gdbarch, regnum), file);
for (i = 0; i < regsize; i++)
fprintf_filtered (file, "%02x", (unsigned int)
- extract_unsigned_integer (buff + i, 1));
+ extract_unsigned_integer (buff + i, 1, byte_order));
fputs_filtered ("\t", file);
print_longest (file, 'd', 0,
- extract_unsigned_integer (buff, regsize));
+ extract_unsigned_integer (buff, regsize, byte_order));
fputs_filtered ("\n", file);
}
else if (regnum == MT_COPRO_REGNUM
struct value_print_options opts;
buf = alloca (register_size (gdbarch, MT_COPRO_REGNUM));
- frame_register_read (frame, MT_COPRO_REGNUM, buf);
+ deprecated_frame_register_read (frame, MT_COPRO_REGNUM, buf);
/* And print. */
regnum = MT_COPRO_PSEUDOREG_REGNUM;
fputs_filtered (gdbarch_register_name (gdbarch, regnum),
print_spaces_filtered (15 - strlen (gdbarch_register_name
(gdbarch, regnum)),
file);
- get_raw_print_options (&opts);
+ get_no_prettyformat_print_options (&opts);
opts.deref_ref = 1;
val_print (register_type (gdbarch, regnum), buf,
- 0, 0, file, 0, &opts,
- current_language);
+ 0, 0, file, 0, NULL,
+ &opts, current_language);
fputs_filtered ("\n", file);
}
else if (regnum == MT_MAC_REGNUM || regnum == MT_MAC_PSEUDOREG_REGNUM)
gdb_byte buf[3 * sizeof (LONGEST)];
/* Get the two "real" mac registers. */
- frame_register_read (frame, MT_MAC_REGNUM, buf);
+ deprecated_frame_register_read (frame, MT_MAC_REGNUM, buf);
oldmac = extract_unsigned_integer
- (buf, register_size (gdbarch, MT_MAC_REGNUM));
+ (buf, register_size (gdbarch, MT_MAC_REGNUM), byte_order);
if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_mrisc2
|| gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_ms2)
{
- frame_register_read (frame, MT_EXMAC_REGNUM, buf);
+ deprecated_frame_register_read (frame, MT_EXMAC_REGNUM, buf);
ext_mac = extract_unsigned_integer
- (buf, register_size (gdbarch, MT_EXMAC_REGNUM));
+ (buf, register_size (gdbarch, MT_EXMAC_REGNUM), byte_order);
}
else
ext_mac = 0;
int struct_return, CORE_ADDR struct_addr)
{
#define wordsize 4
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
gdb_byte buf[MT_MAX_STRUCT_SIZE];
int argreg = MT_1ST_ARGREG;
int split_param_len = 0;
regcache_cooked_write_unsigned (regcache, argreg++,
extract_unsigned_integer
(value_contents (args[i]),
- wordsize));
+ wordsize, byte_order));
break;
case 8:
case 12:
/* This word of the argument is passed in a register. */
regcache_cooked_write_unsigned (regcache, argreg++,
extract_unsigned_integer
- (val, wordsize));
+ (val, wordsize, byte_order));
typelen -= wordsize;
val += wordsize;
}
for (j = nargs - 1; j >= i; j--)
{
gdb_byte *val;
+ struct cleanup *back_to;
+ const gdb_byte *contents = value_contents (args[j]);
/* Right-justify the value in an aligned-length buffer. */
typelen = TYPE_LENGTH (value_type (args[j]));
slacklen = (wordsize - (typelen % wordsize)) % wordsize;
- val = alloca (typelen + slacklen);
- memcpy (val, value_contents (args[j]), typelen);
+ val = xmalloc (typelen + slacklen);
+ back_to = make_cleanup (xfree, val);
+ memcpy (val, contents, typelen);
memset (val + typelen, 0, slacklen);
/* Now write this data to the stack. */
stack_dest -= typelen + slacklen;
write_memory (stack_dest, val, typelen + slacklen);
+ do_cleanups (back_to);
}
/* Finally, if a param needs to be split between registers and stack,
struct mt_unwind_cache
{
- /* The previous frame's inner most stack address.
+ /* The previous frame's inner most stack address.
Used as this frame ID's stack_addr. */
CORE_ADDR prev_sp;
CORE_ADDR frame_base;
info->frameless_p = 1;
info->saved_regs = trad_frame_alloc_saved_regs (this_frame);
- /* Grab the frame-relative values of SP and FP, needed below.
+ /* Grab the frame-relative values of SP and FP, needed below.
The frame_saved_register function will find them on the
stack or in the registers as appropriate. */
sp = get_frame_register_unsigned (this_frame, MT_SP_REGNUM);
return info;
end_addr = get_frame_pc (this_frame);
- prologue_end_addr = skip_prologue_using_sal (start_addr);
+ prologue_end_addr = skip_prologue_using_sal (gdbarch, start_addr);
if (end_addr == 0)
for (next_addr = start_addr; next_addr < end_addr; next_addr += 4)
{
instr = get_frame_memory_unsigned (this_frame, next_addr, 4);
- if (delayed_store) /* previous instr was a push */
+ if (delayed_store) /* Previous instr was a push. */
{
upper_half = delayed_store >> 16;
regnum = upper_half & 0xf;
offset = delayed_store & 0xffff;
switch (upper_half & 0xfff0)
{
- case 0x43c0: /* push using frame pointer */
+ case 0x43c0: /* push using frame pointer. */
info->saved_regs[regnum].addr = offset;
break;
- case 0x43d0: /* push using stack pointer */
+ case 0x43d0: /* push using stack pointer. */
info->saved_regs[regnum].addr = offset;
break;
default: /* lint */
case 0x12000000: /* NO-OP */
continue;
case 0x12ddc000: /* copy sp into fp */
- info->frameless_p = 0; /* Record that the frame pointer is in use. */
+ info->frameless_p = 0; /* Record that the frame
+ pointer is in use. */
continue;
default:
upper_half = instr >> 16;
keep scanning until we reach it (or we reach end_addr). */
if (prologue_end_addr && (prologue_end_addr > (next_addr + 4)))
- continue; /* Keep scanning, recording saved_regs etc. */
+ continue; /* Keep scanning, recording saved_regs etc. */
else
- break; /* Quit scanning: breakpoint can be set here. */
+ break; /* Quit scanning: breakpoint can be set here. */
}
}
static const struct frame_unwind mt_frame_unwind = {
NORMAL_FRAME,
+ default_frame_unwind_stop_reason,
mt_frame_this_id,
mt_frame_prev_register,
NULL,
mt_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
struct gdbarch *gdbarch;
+ struct gdbarch_tdep *tdep;
/* Find a candidate among the list of pre-declared architectures. */
arches = gdbarch_list_lookup_by_info (arches, &info);
/* None found, create a new architecture from the information
provided. */
- gdbarch = gdbarch_alloc (&info, NULL);
+ tdep = XCNEW (struct gdbarch_tdep);
+ gdbarch = gdbarch_alloc (&info, tdep);
set_gdbarch_float_format (gdbarch, floatformats_ieee_single);
set_gdbarch_double_format (gdbarch, floatformats_ieee_double);
set_gdbarch_unwind_pc (gdbarch, mt_unwind_pc);
set_gdbarch_unwind_sp (gdbarch, mt_unwind_sp);
- /* Methods for saving / extracting a dummy frame's ID.
+ /* Methods for saving / extracting a dummy frame's ID.
The ID's stack address must match the SP value returned by
PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos. */
set_gdbarch_dummy_id (gdbarch, mt_dummy_id);