Modified Files:

ChangeLog configure.in defs.h mips-tdep.c

        * configure.in: add mips64-*-elf, mips64-*-ecoff, mips64el-*-elf,
        mips64el-*-ecoff and mips64-big-*.
        * defs.h: get rid of FORCE_LONG_LONG.
        * mips-tdep.c (mips_find_saved_regs): add sd and sdc1 instruction
        parsing. Change register size to be MIPS_REGSIZE.
This commit is contained in:
Kung Hsu 1994-02-18 01:38:08 +00:00
parent 4fbce2fdd2
commit 70126bf94e
4 changed files with 212 additions and 124 deletions

View file

@ -1,3 +1,11 @@
Thu Feb 17 17:25:47 1994 Kung Hsu (kung@mexican.cygnus.com)
* configure.in: add mips64-*-elf, mips64-*-ecoff, mips64el-*-elf,
mips64el-*-ecoff and mips64-big-*.
* defs.h: get rid of FORCE_LONG_LONG.
* mips-tdep.c (mips_find_saved_regs): add sd and sdc1 instruction
parsing. Change register size to be MIPS_REGSIZE.
Thu Feb 17 09:30:22 1994 David J. Mackenzie (djm@thepub.cygnus.com) Thu Feb 17 09:30:22 1994 David J. Mackenzie (djm@thepub.cygnus.com)
* corelow.c, exec.c, irix5-nat.c, mipsread.c, objfiles.c, * corelow.c, exec.c, irix5-nat.c, mipsread.c, objfiles.c,

View file

@ -256,8 +256,13 @@ m88*-motorola-sysv4*) gdb_target=delta88v4 ;;
m88*-motorola-*) gdb_target=delta88 ;; m88*-motorola-*) gdb_target=delta88 ;;
m88*-*-*) gdb_target=m88k ;; m88*-*-*) gdb_target=m88k ;;
mips64*-big-*) gdb_target=bigmips64 ;;
mips*-big-*) gdb_target=bigmips ;; mips*-big-*) gdb_target=bigmips ;;
mips*-dec-*) gdb_target=decstation ;; mips*-dec-*) gdb_target=decstation ;;
mips64*el-*-ecoff*) gdb_target=idtl64 ;;
mips64*-idt-ecoff*) gdb_target=idt64 ;;
mips64*el-*-elf*) gdb_target=idtl64 ;;
mips64*-*-elf*) gdb_target=idt64 ;;
mips*el-*-ecoff*) gdb_target=idtl ;; mips*el-*-ecoff*) gdb_target=idtl ;;
mips*-idt-ecoff*) gdb_target=idt ;; mips*-idt-ecoff*) gdb_target=idt ;;
mips*el-*-elf*) gdb_target=idtl ;; mips*el-*-elf*) gdb_target=idtl ;;

View file

@ -516,7 +516,7 @@ enum val_prettyprint
/* This is to make sure that LONGEST is at least as big as CORE_ADDR. */ /* This is to make sure that LONGEST is at least as big as CORE_ADDR. */
#define LONGEST BFD_HOST_64_TYPE #define LONGEST BFD_HOST_64_BIT
#else /* No BFD64 */ #else /* No BFD64 */
@ -533,7 +533,7 @@ enum val_prettyprint
will select "long long" use for testing purposes. -fnf */ will select "long long" use for testing purposes. -fnf */
#ifndef CC_HAS_LONG_LONG #ifndef CC_HAS_LONG_LONG
# if defined (__GNUC__) && defined (FORCE_LONG_LONG) /* See FIXME above */ # if defined (__GNUC__) /*&& defined (FORCE_LONG_LONG)*/ /* See FIXME above */
# define CC_HAS_LONG_LONG 1 # define CC_HAS_LONG_LONG 1
# endif # endif
#endif #endif

View file

@ -34,6 +34,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "opcode/mips.h" #include "opcode/mips.h"
#define VM_MIN_ADDRESS (unsigned)0x400000 #define VM_MIN_ADDRESS (unsigned)0x400000
/* FIXME: Put this declaration in frame.h. */
extern struct obstack frame_cache_obstack;
#if 0 #if 0
static int mips_in_lenient_prologue PARAMS ((CORE_ADDR, CORE_ADDR)); static int mips_in_lenient_prologue PARAMS ((CORE_ADDR, CORE_ADDR));
@ -69,7 +72,132 @@ struct linked_proc_info
} *linked_proc_desc_table = NULL; } *linked_proc_desc_table = NULL;
#define READ_FRAME_REG(fi, regno) read_next_frame_reg((fi)->next, regno) /* Guaranteed to set fci->saved_regs to some values (it never leaves it
NULL). */
void
mips_find_saved_regs (fci)
FRAME fci;
{
int ireg;
CORE_ADDR reg_position;
/* r0 bit means kernel trap */
int kernel_trap;
/* What registers have been saved? Bitmasks. */
unsigned long gen_mask, float_mask;
mips_extra_func_info_t proc_desc;
fci->saved_regs = (struct frame_saved_regs *)
obstack_alloc (&frame_cache_obstack, sizeof(struct frame_saved_regs));
memset (fci->saved_regs, 0, sizeof (struct frame_saved_regs));
proc_desc = fci->proc_desc;
if (proc_desc == NULL)
/* I'm not sure how/whether this can happen. Normally when we can't
find a proc_desc, we "synthesize" one using heuristic_proc_desc
and set the saved_regs right away. */
return;
kernel_trap = PROC_REG_MASK(proc_desc) & 1;
gen_mask = kernel_trap ? 0xFFFFFFFF : PROC_REG_MASK(proc_desc);
float_mask = kernel_trap ? 0xFFFFFFFF : PROC_FREG_MASK(proc_desc);
if (/* In any frame other than the innermost, we assume that all
registers have been saved. This assumes that all register
saves in a function happen before the first function
call. */
fci->next == NULL
/* In a dummy frame we know exactly where things are saved. */
&& !PROC_DESC_IS_DUMMY (proc_desc)
/* Not sure exactly what kernel_trap means, but if it means
the kernel saves the registers without a prologue doing it,
we better not examine the prologue to see whether registers
have been saved yet. */
&& !kernel_trap)
{
/* We need to figure out whether the registers that the proc_desc
claims are saved have been saved yet. */
CORE_ADDR addr;
int status;
char buf[4];
unsigned long inst;
/* Bitmasks; set if we have found a save for the register. */
unsigned long gen_save_found = 0;
unsigned long float_save_found = 0;
for (addr = PROC_LOW_ADDR (proc_desc);
addr < fci->pc /*&& (gen_mask != gen_save_found
|| float_mask != float_save_found)*/;
addr += 4)
{
status = read_memory_nobpt (addr, buf, 4);
if (status)
memory_error (status, addr);
inst = extract_unsigned_integer (buf, 4);
if (/* sw reg,n($sp) */
(inst & 0xffe00000) == 0xafa00000
/* sw reg,n($r30) */
|| (inst & 0xffe00000) == 0xafc00000
/* sd reg,n($sp) */
|| (inst & 0xffe00000) == 0xffa00000)
{
/* It might be possible to use the instruction to
find the offset, rather than the code below which
is based on things being in a certain order in the
frame, but figuring out what the instruction's offset
is relative to might be a little tricky. */
int reg = (inst & 0x001f0000) >> 16;
gen_save_found |= (1 << reg);
}
else if (/* swc1 freg,n($sp) */
(inst & 0xffe00000) == 0xe7a00000
/* swc1 freg,n($r30) */
|| (inst & 0xffe00000) == 0xe7c00000
/* sdc1 freg,n($sp) */
|| (inst & 0xffe00000) == 0xf7a00000)
{
int reg = ((inst & 0x001f0000) >> 16);
float_save_found |= (1 << reg);
}
}
gen_mask = gen_save_found;
float_mask = float_save_found;
}
/* Fill in the offsets for the registers which gen_mask says
were saved. */
reg_position = fci->frame + PROC_REG_OFFSET (proc_desc);
for (ireg= 31; gen_mask; --ireg, gen_mask <<= 1)
if (gen_mask & 0x80000000)
{
fci->saved_regs->regs[ireg] = reg_position;
reg_position -= MIPS_REGSIZE;
}
/* Fill in the offsets for the registers which float_mask says
were saved. */
reg_position = fci->frame + PROC_FREG_OFFSET (proc_desc);
/* The freg_offset points to where the first *double* register
is saved. So skip to the high-order word. */
reg_position += 4;
for (ireg = 31; float_mask; --ireg, float_mask <<= 1)
if (float_mask & 0x80000000)
{
fci->saved_regs->regs[FP0_REGNUM+ireg] = reg_position;
reg_position -= MIPS_REGSIZE;
}
fci->saved_regs->regs[PC_REGNUM] = fci->saved_regs->regs[RA_REGNUM];
}
static int static int
read_next_frame_reg(fi, regno) read_next_frame_reg(fi, regno)
@ -91,18 +219,26 @@ read_next_frame_reg(fi, regno)
#define SIGFRAME_REG_SIZE 4 #define SIGFRAME_REG_SIZE 4
#endif #endif
for (; fi; fi = fi->next) for (; fi; fi = fi->next)
if (fi->signal_handler_caller) { {
if (fi->signal_handler_caller)
{
int offset; int offset;
if (regno == PC_REGNUM) offset = SIGFRAME_PC_OFF; if (regno == PC_REGNUM) offset = SIGFRAME_PC_OFF;
else if (regno < 32) offset = (SIGFRAME_REGSAVE_OFF else if (regno < 32) offset = (SIGFRAME_REGSAVE_OFF
+ regno * SIGFRAME_REG_SIZE); + regno * SIGFRAME_REG_SIZE);
else return 0; else return 0;
return read_memory_integer(fi->frame + offset, 4); return read_memory_integer(fi->frame + offset, MIPS_REGSIZE);
} }
else if (regno == SP_REGNUM) return fi->frame; else if (regno == SP_REGNUM) return fi->frame;
else if (fi->saved_regs->regs[regno]) else
return read_memory_integer(fi->saved_regs->regs[regno], 4); {
return read_register(regno); if (fi->saved_regs == NULL)
mips_find_saved_regs (fi);
if (fi->saved_regs->regs[regno])
return read_memory_integer(fi->saved_regs->regs[regno], MIPS_REGSIZE);
}
}
return read_register (regno);
} }
int int
@ -372,129 +508,34 @@ void
init_extra_frame_info(fci) init_extra_frame_info(fci)
struct frame_info *fci; struct frame_info *fci;
{ {
extern struct obstack frame_cache_obstack;
/* Use proc_desc calculated in frame_chain */ /* Use proc_desc calculated in frame_chain */
mips_extra_func_info_t proc_desc = mips_extra_func_info_t proc_desc =
fci->next ? cached_proc_desc : find_proc_desc(fci->pc, fci->next); fci->next ? cached_proc_desc : find_proc_desc(fci->pc, fci->next);
fci->saved_regs = (struct frame_saved_regs*) fci->saved_regs = NULL;
obstack_alloc (&frame_cache_obstack, sizeof(struct frame_saved_regs));
memset (fci->saved_regs, 0, sizeof (struct frame_saved_regs));
fci->proc_desc = fci->proc_desc =
proc_desc == &temp_proc_desc ? 0 : proc_desc; proc_desc == &temp_proc_desc ? 0 : proc_desc;
if (proc_desc) if (proc_desc)
{ {
int ireg;
CORE_ADDR reg_position;
/* r0 bit means kernel trap */
int kernel_trap = PROC_REG_MASK(proc_desc) & 1;
/* Fixup frame-pointer - only needed for top frame */ /* Fixup frame-pointer - only needed for top frame */
/* This may not be quite right, if proc has a real frame register. /* This may not be quite right, if proc has a real frame register.
Get the value of the frame relative sp, procedure might have been Get the value of the frame relative sp, procedure might have been
interrupted by a signal at it's very start. */ interrupted by a signal at it's very start. */
if (fci->pc == PROC_LOW_ADDR(proc_desc) && !PROC_DESC_IS_DUMMY(proc_desc)) if (fci->pc == PROC_LOW_ADDR (proc_desc)
fci->frame = READ_FRAME_REG(fci, SP_REGNUM); && !PROC_DESC_IS_DUMMY (proc_desc))
fci->frame = read_next_frame_reg (fci->next, SP_REGNUM);
else else
fci->frame = READ_FRAME_REG(fci, PROC_FRAME_REG(proc_desc)) fci->frame =
+ PROC_FRAME_OFFSET(proc_desc); read_next_frame_reg (fci->next, PROC_FRAME_REG (proc_desc))
+ PROC_FRAME_OFFSET (proc_desc);
if (proc_desc == &temp_proc_desc) if (proc_desc == &temp_proc_desc)
*fci->saved_regs = temp_saved_regs;
else
{ {
/* What registers have been saved? Bitmasks. */ fci->saved_regs = (struct frame_saved_regs*)
unsigned long gen_mask, float_mask; obstack_alloc (&frame_cache_obstack,
sizeof (struct frame_saved_regs));
gen_mask = kernel_trap ? 0xFFFFFFFF : PROC_REG_MASK(proc_desc); *fci->saved_regs = temp_saved_regs;
float_mask = kernel_trap ? 0xFFFFFFFF : PROC_FREG_MASK(proc_desc); fci->saved_regs->regs[PC_REGNUM] = fci->saved_regs->regs[RA_REGNUM];
if (/* In any frame other than the innermost, we assume that all
registers have been saved. This assumes that all register
saves in a function happen before the first function
call. */
fci->next == NULL
/* In a dummy frame we know exactly where things are saved. */
&& !PROC_DESC_IS_DUMMY (proc_desc)
/* Not sure exactly what kernel_trap means, but if it means
the kernel saves the registers without a prologue doing it,
we better not examine the prologue to see whether registers
have been saved yet. */
&& !kernel_trap)
{
/* We need to figure out whether the registers that the proc_desc
claims are saved have been saved yet. */
CORE_ADDR addr;
int status;
char buf[4];
unsigned long inst;
/* Bitmasks; set if we have found a save for the register. */
unsigned long gen_save_found = 0;
unsigned long float_save_found = 0;
for (addr = PROC_LOW_ADDR (proc_desc);
addr < fci->pc && (gen_mask != gen_save_found
|| float_mask != float_save_found);
addr += 4)
{
status = read_memory_nobpt (addr, buf, 4);
if (status)
memory_error (status, addr);
inst = extract_unsigned_integer (buf, 4);
if (/* sw reg,n($sp) */
(inst & 0xffe00000) == 0xafa00000
/* sw reg,n($r30) */
|| (inst & 0xffe00000) == 0xafc00000)
{
/* It might be possible to use the instruction to
find the offset, rather than the code below which
is based on things being in a certain order in the
frame, but figuring out what the instruction's offset
is relative to might be a little tricky. */
int reg = (inst & 0x001f0000) >> 16;
gen_save_found |= (1 << reg);
}
else if (/* swc1 freg,n($sp) */
(inst & 0xffe00000) == 0xe7a00000
/* swc1 freg,n($r30) */
|| (inst & 0xffe00000) == 0xe7c00000)
{
int reg = ((inst & 0x001f0000) >> 16);
float_save_found |= (1 << reg);
}
}
gen_mask = gen_save_found;
float_mask = float_save_found;
}
/* Fill in the offsets for the registers which gen_mask says
were saved. */
reg_position = fci->frame + PROC_REG_OFFSET (proc_desc);
for (ireg= 31; gen_mask; --ireg, gen_mask <<= 1)
if (gen_mask & 0x80000000)
{
fci->saved_regs->regs[ireg] = reg_position;
reg_position -= 4;
}
/* Fill in the offsets for the registers which float_mask says
were saved. */
reg_position = fci->frame + PROC_FREG_OFFSET (proc_desc);
/* The freg_offset points to where the first *double* register
is saved. So skip to the high-order word. */
reg_position += 4;
for (ireg = 31; float_mask; --ireg, float_mask <<= 1)
if (float_mask & 0x80000000)
{
fci->saved_regs->regs[FP0_REGNUM+ireg] = reg_position;
reg_position -= 4;
}
} }
/* hack: if argument regs are saved, guess these contain args */ /* hack: if argument regs are saved, guess these contain args */
@ -503,8 +544,6 @@ init_extra_frame_info(fci)
else if ((PROC_REG_MASK(proc_desc) & 0x40) == 0) fci->num_args = 3; else if ((PROC_REG_MASK(proc_desc) & 0x40) == 0) fci->num_args = 3;
else if ((PROC_REG_MASK(proc_desc) & 0x20) == 0) fci->num_args = 2; else if ((PROC_REG_MASK(proc_desc) & 0x20) == 0) fci->num_args = 2;
else if ((PROC_REG_MASK(proc_desc) & 0x10) == 0) fci->num_args = 1; else if ((PROC_REG_MASK(proc_desc) & 0x10) == 0) fci->num_args = 1;
fci->saved_regs->regs[PC_REGNUM] = fci->saved_regs->regs[RA_REGNUM];
} }
} }
@ -544,11 +583,13 @@ mips_push_arguments(nargs, args, sp, struct_return, struct_addr)
CORE_ADDR struct_addr; CORE_ADDR struct_addr;
{ {
register i; register i;
int accumulate_size = struct_return ? 4 : 0; int accumulate_size = struct_return ? MIPS_REGSIZE : 0;
struct mips_arg { char *contents; int len; int offset; }; struct mips_arg { char *contents; int len; int offset; };
struct mips_arg *mips_args = struct mips_arg *mips_args =
(struct mips_arg*)alloca(nargs * sizeof(struct mips_arg)); (struct mips_arg*)alloca((nargs + 4) * sizeof(struct mips_arg));
register struct mips_arg *m_arg; register struct mips_arg *m_arg;
int fake_args = 0;
for (i = 0, m_arg = mips_args; i < nargs; i++, m_arg++) { for (i = 0, m_arg = mips_args; i < nargs; i++, m_arg++) {
extern value value_arg_coerce(); extern value value_arg_coerce();
value arg = value_arg_coerce (args[i]); value arg = value_arg_coerce (args[i]);
@ -559,16 +600,48 @@ mips_push_arguments(nargs, args, sp, struct_return, struct_addr)
* breaks their varargs implementation...). A correct solution * breaks their varargs implementation...). A correct solution
* requires an simulation of gcc's 'alignof' (and use of 'alignof' * requires an simulation of gcc's 'alignof' (and use of 'alignof'
* in stdarg.h/varargs.h). * in stdarg.h/varargs.h).
* On the 64 bit r4000 we always pass the first four arguments
* using eight bytes each, so that we can load them up correctly
* in CALL_DUMMY.
*/ */
if (m_arg->len > 4) accumulate_size = (accumulate_size + 7) & -8; if (m_arg->len > 4)
accumulate_size = (accumulate_size + 7) & -8;
m_arg->offset = accumulate_size; m_arg->offset = accumulate_size;
accumulate_size = (accumulate_size + m_arg->len + 3) & -4;
m_arg->contents = VALUE_CONTENTS(arg); m_arg->contents = VALUE_CONTENTS(arg);
#ifndef GDB_TARGET_IS_MIPS64
accumulate_size = (accumulate_size + m_arg->len + 3) & -4;
#else
if (accumulate_size >= 4 * MIPS_REGSIZE)
accumulate_size = (accumulate_size + m_arg->len + 3) &~ 4;
else
{
static char zeroes[8] = { 0 };
int len = m_arg->len;
if (len < 8)
{
#if TARGET_BYTE_ORDER == BIG_ENDIAN
m_arg->offset += 8 - len;
#endif
++m_arg;
m_arg->len = 8 - len;
m_arg->contents = zeroes;
#if TARGET_BYTE_ORDER == BIG_ENDIAN
m_arg->offset = accumulate_size;
#else
m_arg->offset = accumulate_size + len;
#endif
++fake_args;
}
accumulate_size = (accumulate_size + len + 7) & ~8;
}
#endif
} }
accumulate_size = (accumulate_size + 7) & (-8); accumulate_size = (accumulate_size + 7) & (-8);
if (accumulate_size < 16) accumulate_size = 16; if (accumulate_size < 4 * MIPS_REGSIZE)
accumulate_size = 4 * MIPS_REGSIZE;
sp -= accumulate_size; sp -= accumulate_size;
for (i = nargs; m_arg--, --i >= 0; ) for (i = nargs + fake_args; m_arg--, --i >= 0; )
write_memory(sp + m_arg->offset, m_arg->contents, m_arg->len); write_memory(sp + m_arg->offset, m_arg->contents, m_arg->len);
if (struct_return) if (struct_return)
{ {
@ -684,6 +757,8 @@ mips_pop_frame()
mips_extra_func_info_t proc_desc = frame->proc_desc; mips_extra_func_info_t proc_desc = frame->proc_desc;
write_register (PC_REGNUM, FRAME_SAVED_PC(frame)); write_register (PC_REGNUM, FRAME_SAVED_PC(frame));
if (frame->saved_regs == NULL)
mips_find_saved_regs (frame);
if (proc_desc) if (proc_desc)
{ {
for (regnum = 32; --regnum >= 0; ) for (regnum = 32; --regnum >= 0; )