Support for different MIPS IDT processor models.
* mips-tdep.c (mips_processor_type, tmp_mips_processor_type, mips_generic_reg_names, mips_r3041_reg_names, mips_r3051_reg_names, mips_r3081_reg_names, mips_processor_type_table): New globals. (mips_do_registers_info): Don't display register if name is empty. (mips_set_processor_type_command): New command. (mips_show_processor_type_command): New command. (mips_set_processor_type): New function. (mips_read_processor_type): New function. * config/mips/tm-idt.h (DEFAULT_MIPS_TYPE): New macro. * config/mips/tm-mips.h (DEFAULT_MIPS_TYPE): New macro. (NUM_REGS): Increase to account for all CP0 registers. (REGISTER_NAMES): Add empty names for CP0 registers. (FIRST_EMBED_REGNUM, LAST_EMBED_REGNUM): Adjust. (PRID_REGNUM): New macro.
This commit is contained in:
parent
f618f758e9
commit
9f9f94aa09
4 changed files with 300 additions and 80 deletions
|
@ -1,3 +1,22 @@
|
|||
Thu Nov 17 17:51:12 1994 Stan Shebs (shebs@andros.cygnus.com)
|
||||
|
||||
Support for different MIPS IDT processor models.
|
||||
* mips-tdep.c (mips_processor_type, tmp_mips_processor_type,
|
||||
mips_generic_reg_names, mips_r3041_reg_names,
|
||||
mips_r3051_reg_names, mips_r3081_reg_names,
|
||||
mips_processor_type_table): New globals.
|
||||
(mips_do_registers_info): Don't display register if name is empty.
|
||||
(mips_set_processor_type_command): New command.
|
||||
(mips_show_processor_type_command): New command.
|
||||
(mips_set_processor_type): New function.
|
||||
(mips_read_processor_type): New function.
|
||||
* config/mips/tm-idt.h (DEFAULT_MIPS_TYPE): New macro.
|
||||
* config/mips/tm-mips.h (DEFAULT_MIPS_TYPE): New macro.
|
||||
(NUM_REGS): Increase to account for all CP0 registers.
|
||||
(REGISTER_NAMES): Add empty names for CP0 registers.
|
||||
(FIRST_EMBED_REGNUM, LAST_EMBED_REGNUM): Adjust.
|
||||
(PRID_REGNUM): New macro.
|
||||
|
||||
Wed Nov 16 16:41:52 1994 Stan Shebs (shebs@andros.cygnus.com)
|
||||
|
||||
* README: Add warning about termcap in Ultrix and OSF/1.
|
||||
|
|
|
@ -19,3 +19,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||
#define TARGET_BYTE_ORDER_SELECTABLE
|
||||
|
||||
#include "mips/tm-bigmips.h"
|
||||
|
||||
#undef DEFAULT_MIPS_TYPE
|
||||
#define DEFAULT_MIPS_TYPE "r3051"
|
||||
|
|
|
@ -34,13 +34,16 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||
/* Floating point is IEEE compliant */
|
||||
#define IEEE_FLOAT
|
||||
|
||||
extern int mips_processor_id;
|
||||
|
||||
/* Some MIPS boards are provided both with and without a floating
|
||||
point coprocessor; we provide a user settable variable to tell gdb
|
||||
whether there is one or not. */
|
||||
extern int mips_fpu;
|
||||
|
||||
/* The name of the usual type of MIPS processor that is in the target
|
||||
system. */
|
||||
|
||||
#define DEFAULT_MIPS_TYPE "generic"
|
||||
|
||||
/* Offset from address of function to start of its code.
|
||||
Zero on most machines. */
|
||||
|
||||
|
@ -105,7 +108,7 @@ extern int in_sigtramp PARAMS ((CORE_ADDR, char *));
|
|||
|
||||
/* Number of machine registers */
|
||||
|
||||
#define NUM_REGS 80
|
||||
#define NUM_REGS 90
|
||||
|
||||
/* Initializer for an array of names of registers.
|
||||
There should be NUM_REGS strings in this initializer. */
|
||||
|
@ -120,8 +123,9 @@ extern int in_sigtramp PARAMS ((CORE_ADDR, char *));
|
|||
"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
|
||||
"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",\
|
||||
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",\
|
||||
"fsr", "fir", "fp", "inx", "rand", "tlblo","ctxt", "tlbhi",\
|
||||
"epc", "prid"\
|
||||
"fsr", "fir", "fp", "", \
|
||||
"", "", "", "", "", "", "", "", \
|
||||
"", "", "", "", "", "", "", "", \
|
||||
}
|
||||
|
||||
/* Register numbers of various important registers.
|
||||
|
@ -146,8 +150,9 @@ extern int in_sigtramp PARAMS ((CORE_ADDR, char *));
|
|||
#define FCRCS_REGNUM 70 /* FP control/status */
|
||||
#define FCRIR_REGNUM 71 /* FP implementation/revision */
|
||||
#define FP_REGNUM 72 /* Pseudo register that contains true address of executing stack frame */
|
||||
#define FIRST_EMBED_REGNUM 73 /* First supervisor register for embedded use */
|
||||
#define LAST_EMBED_REGNUM 79 /* Last one */
|
||||
#define FIRST_EMBED_REGNUM 74 /* First CP0 register for embedded use */
|
||||
#define PRID_REGNUM 89 /* Processor ID */
|
||||
#define LAST_EMBED_REGNUM 89 /* Last one */
|
||||
|
||||
/* Define DO_REGISTERS_INFO() to do machine-specific formatting
|
||||
of register dumps. */
|
||||
|
@ -156,6 +161,7 @@ extern int in_sigtramp PARAMS ((CORE_ADDR, char *));
|
|||
|
||||
/* Total amount of space needed to store our copies of the machine's
|
||||
register state, the array `registers'. */
|
||||
|
||||
#define REGISTER_BYTES (NUM_REGS*MIPS_REGSIZE)
|
||||
|
||||
/* Index within `registers' of the first byte of the space for
|
||||
|
|
338
gdb/mips-tdep.c
338
gdb/mips-tdep.c
|
@ -43,13 +43,95 @@ extern struct obstack frame_cache_obstack;
|
|||
static int mips_in_lenient_prologue PARAMS ((CORE_ADDR, CORE_ADDR));
|
||||
#endif
|
||||
|
||||
void mips_set_processor_type_command PARAMS ((char *, int));
|
||||
|
||||
static void reinit_frame_cache_sfunc PARAMS ((char *, int,
|
||||
struct cmd_list_element *));
|
||||
|
||||
/* This value is the model of MIPS in use. It is derived from the value
|
||||
of the PrID register. */
|
||||
|
||||
char *mips_processor_type;
|
||||
|
||||
char *tmp_mips_processor_type;
|
||||
|
||||
/* Some MIPS boards don't support floating point, so we permit the
|
||||
user to turn it off. */
|
||||
|
||||
int mips_fpu = 1;
|
||||
|
||||
/* A set of original names, to be used when restoring back to generic
|
||||
registers from a specific set. */
|
||||
|
||||
char *mips_generic_reg_names[] = REGISTER_NAMES;
|
||||
|
||||
/* Names of IDT R3041 registers. */
|
||||
|
||||
char *mips_r3041_reg_names[] = {
|
||||
"zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
|
||||
"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
|
||||
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
|
||||
"t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
|
||||
"sr", "lo", "hi", "bad", "cause","pc",
|
||||
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
|
||||
"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
|
||||
"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
|
||||
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
|
||||
"fsr", "fir", "fp", "",
|
||||
"", "", "bus", "ccfg", "", "", "", "",
|
||||
"", "", "port", "cmp", "", "", "epc", "prid",
|
||||
};
|
||||
|
||||
/* Names of IDT R3051 registers. */
|
||||
|
||||
char *mips_r3051_reg_names[] = {
|
||||
"zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
|
||||
"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
|
||||
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
|
||||
"t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
|
||||
"sr", "lo", "hi", "bad", "cause","pc",
|
||||
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
|
||||
"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
|
||||
"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
|
||||
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
|
||||
"fsr", "fir", "fp", "",
|
||||
"inx", "rand", "elo", "", "ctxt", "", "", "",
|
||||
"", "", "ehi", "", "", "", "epc", "prid",
|
||||
};
|
||||
|
||||
/* Names of IDT R3081 registers. */
|
||||
|
||||
char *mips_r3081_reg_names[] = {
|
||||
"zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
|
||||
"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
|
||||
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
|
||||
"t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
|
||||
"sr", "lo", "hi", "bad", "cause","pc",
|
||||
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
|
||||
"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
|
||||
"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
|
||||
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
|
||||
"fsr", "fir", "fp", "",
|
||||
"inx", "rand", "elo", "cfg", "ctxt", "", "", "",
|
||||
"", "", "ehi", "", "", "", "epc", "prid",
|
||||
};
|
||||
|
||||
struct {
|
||||
char *name;
|
||||
char **regnames;
|
||||
} mips_processor_type_table[] = {
|
||||
{ "generic", mips_generic_reg_names },
|
||||
{ "r3041", mips_r3041_reg_names },
|
||||
{ "r3051", mips_r3051_reg_names },
|
||||
{ "r3071", mips_r3081_reg_names },
|
||||
{ "r3081", mips_r3081_reg_names },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
/* Heuristic_proc_start may hunt through the text section for a long
|
||||
time across a 2400 baud serial line. Allows the user to limit this
|
||||
search. */
|
||||
|
||||
static unsigned int heuristic_fence_post = 0;
|
||||
|
||||
#define PROC_LOW_ADDR(proc) ((proc)->pdr.adr) /* least address */
|
||||
|
@ -78,7 +160,7 @@ struct linked_proc_info
|
|||
|
||||
void
|
||||
mips_find_saved_regs (fci)
|
||||
FRAME fci;
|
||||
struct frame_info *fci;
|
||||
{
|
||||
int ireg;
|
||||
CORE_ADDR reg_position;
|
||||
|
@ -202,7 +284,7 @@ mips_find_saved_regs (fci)
|
|||
|
||||
static int
|
||||
read_next_frame_reg(fi, regno)
|
||||
FRAME fi;
|
||||
struct frame_info *fi;
|
||||
int regno;
|
||||
{
|
||||
/* If it is the frame for sigtramp we have a complete sigcontext
|
||||
|
@ -244,7 +326,7 @@ read_next_frame_reg(fi, regno)
|
|||
|
||||
int
|
||||
mips_frame_saved_pc(frame)
|
||||
FRAME frame;
|
||||
struct frame_info *frame;
|
||||
{
|
||||
mips_extra_func_info_t proc_desc = frame->proc_desc;
|
||||
/* We have to get the saved pc from the sigcontext
|
||||
|
@ -326,7 +408,7 @@ Otherwise, you told GDB there was a function where there isn't one, or\n\
|
|||
static mips_extra_func_info_t
|
||||
heuristic_proc_desc(start_pc, limit_pc, next_frame)
|
||||
CORE_ADDR start_pc, limit_pc;
|
||||
FRAME next_frame;
|
||||
struct frame_info *next_frame;
|
||||
{
|
||||
CORE_ADDR sp = read_next_frame_reg (next_frame, SP_REGNUM);
|
||||
CORE_ADDR cur_pc;
|
||||
|
@ -336,11 +418,12 @@ heuristic_proc_desc(start_pc, limit_pc, next_frame)
|
|||
unsigned long reg_mask = 0;
|
||||
|
||||
if (start_pc == 0) return NULL;
|
||||
memset(&temp_proc_desc, '\0', sizeof(temp_proc_desc));
|
||||
memset(&temp_saved_regs, '\0', sizeof(struct frame_saved_regs));
|
||||
PROC_LOW_ADDR(&temp_proc_desc) = start_pc;
|
||||
memset (&temp_proc_desc, '\0', sizeof(temp_proc_desc));
|
||||
memset (&temp_saved_regs, '\0', sizeof(struct frame_saved_regs));
|
||||
PROC_LOW_ADDR (&temp_proc_desc) = start_pc;
|
||||
|
||||
if (start_pc + 200 < limit_pc) limit_pc = start_pc + 200;
|
||||
if (start_pc + 200 < limit_pc)
|
||||
limit_pc = start_pc + 200;
|
||||
restart:
|
||||
frame_size = 0;
|
||||
for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += 4) {
|
||||
|
@ -399,9 +482,9 @@ heuristic_proc_desc(start_pc, limit_pc, next_frame)
|
|||
}
|
||||
|
||||
static mips_extra_func_info_t
|
||||
find_proc_desc(pc, next_frame)
|
||||
CORE_ADDR pc;
|
||||
FRAME next_frame;
|
||||
find_proc_desc (pc, next_frame)
|
||||
CORE_ADDR pc;
|
||||
struct frame_info *next_frame;
|
||||
{
|
||||
mips_extra_func_info_t proc_desc;
|
||||
struct block *b = block_for_pc(pc);
|
||||
|
@ -431,7 +514,7 @@ find_proc_desc(pc, next_frame)
|
|||
* THEN create a "heuristic" proc_desc (by analyzing
|
||||
* the actual code) to replace the "official" proc_desc.
|
||||
*/
|
||||
proc_desc = (mips_extra_func_info_t)SYMBOL_VALUE(sym);
|
||||
proc_desc = (mips_extra_func_info_t) SYMBOL_VALUE (sym);
|
||||
if (next_frame == NULL) {
|
||||
struct symtab_and_line val;
|
||||
struct symbol *proc_symbol =
|
||||
|
@ -445,9 +528,10 @@ find_proc_desc(pc, next_frame)
|
|||
}
|
||||
if (!proc_symbol || pc < val.pc) {
|
||||
mips_extra_func_info_t found_heuristic =
|
||||
heuristic_proc_desc(PROC_LOW_ADDR(proc_desc),
|
||||
pc, next_frame);
|
||||
if (found_heuristic) proc_desc = found_heuristic;
|
||||
heuristic_proc_desc (PROC_LOW_ADDR (proc_desc),
|
||||
pc, next_frame);
|
||||
if (found_heuristic)
|
||||
proc_desc = found_heuristic;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -459,10 +543,11 @@ find_proc_desc(pc, next_frame)
|
|||
heuristic_proc_desc knows how to create them! */
|
||||
|
||||
register struct linked_proc_info *link;
|
||||
|
||||
for (link = linked_proc_desc_table; link; link = link->next)
|
||||
if (PROC_LOW_ADDR(&link->info) <= pc
|
||||
&& PROC_HIGH_ADDR(&link->info) > pc)
|
||||
return &link->info;
|
||||
if (PROC_LOW_ADDR(&link->info) <= pc
|
||||
&& PROC_HIGH_ADDR(&link->info) > pc)
|
||||
return &link->info;
|
||||
|
||||
if (startaddr == 0)
|
||||
startaddr = heuristic_proc_start (pc);
|
||||
|
@ -475,9 +560,9 @@ find_proc_desc(pc, next_frame)
|
|||
|
||||
mips_extra_func_info_t cached_proc_desc;
|
||||
|
||||
FRAME_ADDR
|
||||
CORE_ADDR
|
||||
mips_frame_chain(frame)
|
||||
FRAME frame;
|
||||
struct frame_info *frame;
|
||||
{
|
||||
mips_extra_func_info_t proc_desc;
|
||||
CORE_ADDR saved_pc = FRAME_SAVED_PC(frame);
|
||||
|
@ -563,10 +648,10 @@ init_extra_frame_info(fci)
|
|||
cache. This allows the rest of info frame to extract the important
|
||||
arguments without difficulty. */
|
||||
|
||||
FRAME
|
||||
struct frame_info *
|
||||
setup_arbitrary_frame (argc, argv)
|
||||
int argc;
|
||||
FRAME_ADDR *argv;
|
||||
CORE_ADDR *argv;
|
||||
{
|
||||
if (argc != 2)
|
||||
error ("MIPS frame specifications require two arguments: sp and pc");
|
||||
|
@ -608,34 +693,33 @@ mips_push_arguments(nargs, args, sp, struct_return, struct_addr)
|
|||
accumulate_size = (accumulate_size + 7) & -8;
|
||||
m_arg->offset = accumulate_size;
|
||||
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;
|
||||
if (! GDB_TARGET_IS_MIPS64)
|
||||
accumulate_size = (accumulate_size + m_arg->len + 3) & -4;
|
||||
else
|
||||
{
|
||||
static char zeroes[8] = { 0 };
|
||||
int len = m_arg->len;
|
||||
|
||||
if (len < 8)
|
||||
if (accumulate_size >= 4 * MIPS_REGSIZE)
|
||||
accumulate_size = (accumulate_size + m_arg->len + 3) &~ 4;
|
||||
else
|
||||
{
|
||||
#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;
|
||||
static char zeroes[8] = { 0 };
|
||||
int len = m_arg->len;
|
||||
|
||||
if (len < 8)
|
||||
{
|
||||
if (TARGET_BYTE_ORDER == BIG_ENDIAN)
|
||||
m_arg->offset += 8 - len;
|
||||
++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;
|
||||
++fake_args;
|
||||
}
|
||||
accumulate_size = (accumulate_size + len + 7) & ~8;
|
||||
}
|
||||
accumulate_size = (accumulate_size + len + 7) & ~8;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
accumulate_size = (accumulate_size + 7) & (-8);
|
||||
if (accumulate_size < 4 * MIPS_REGSIZE)
|
||||
|
@ -759,8 +843,8 @@ void
|
|||
mips_pop_frame()
|
||||
{
|
||||
register int regnum;
|
||||
FRAME frame = get_current_frame ();
|
||||
CORE_ADDR new_sp = frame->frame;
|
||||
struct frame_info *frame = get_current_frame ();
|
||||
CORE_ADDR new_sp = FRAME_FP (frame);
|
||||
|
||||
mips_extra_func_info_t proc_desc = frame->proc_desc;
|
||||
|
||||
|
@ -781,8 +865,6 @@ mips_pop_frame()
|
|||
}
|
||||
write_register (SP_REGNUM, new_sp);
|
||||
flush_cached_frames ();
|
||||
/* We let mips_init_extra_frame_info figure out the frame pointer */
|
||||
set_current_frame (create_new_frame (0, read_pc ()));
|
||||
|
||||
if (proc_desc && PROC_DESC_IS_DUMMY(proc_desc))
|
||||
{
|
||||
|
@ -870,48 +952,66 @@ mips_print_register (regnum, all)
|
|||
}
|
||||
|
||||
/* Replacement for generic do_registers_info. */
|
||||
|
||||
void
|
||||
mips_do_registers_info (regnum, fpregs)
|
||||
int regnum;
|
||||
int fpregs;
|
||||
{
|
||||
if (regnum != -1) {
|
||||
if (regnum != -1)
|
||||
{
|
||||
if (*(reg_names[regnum]) == '\0')
|
||||
error ("Not a valid register for the current processor type");
|
||||
|
||||
mips_print_register (regnum, 0);
|
||||
printf_filtered ("\n");
|
||||
}
|
||||
else {
|
||||
for (regnum = 0; regnum < NUM_REGS; ) {
|
||||
if ((!fpregs) && regnum >= FP0_REGNUM && regnum <= FCRIR_REGNUM) {
|
||||
regnum++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int did_newline;
|
||||
|
||||
for (regnum = 0; regnum < NUM_REGS; )
|
||||
{
|
||||
if (((!fpregs) && regnum >= FP0_REGNUM && regnum <= FCRIR_REGNUM)
|
||||
|| *(reg_names[regnum]) == '\0')
|
||||
{
|
||||
regnum++;
|
||||
continue;
|
||||
}
|
||||
mips_print_register (regnum, 1);
|
||||
regnum++;
|
||||
if ((regnum & 3) == 0 || regnum == NUM_REGS)
|
||||
printf_filtered (";\n");
|
||||
else
|
||||
printf_filtered ("; ");
|
||||
}
|
||||
}
|
||||
printf_filtered ("; ");
|
||||
did_newline = 0;
|
||||
if ((regnum & 3) == 0)
|
||||
{
|
||||
printf_filtered ("\n");
|
||||
did_newline = 1;
|
||||
}
|
||||
}
|
||||
if (!did_newline)
|
||||
printf_filtered ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Return number of args passed to a frame. described by FIP.
|
||||
Can return -1, meaning no way to tell. */
|
||||
|
||||
int
|
||||
mips_frame_num_args(fip)
|
||||
FRAME fip;
|
||||
mips_frame_num_args (frame)
|
||||
struct frame_info *frame;
|
||||
{
|
||||
#if 0
|
||||
struct chain_info_t *p;
|
||||
#if 0 /* FIXME Use or lose this! */
|
||||
struct chain_info_t *p;
|
||||
|
||||
p = mips_find_cached_frame(FRAME_FP(fip));
|
||||
if (p->valid)
|
||||
return p->the_info.numargs;
|
||||
p = mips_find_cached_frame (FRAME_FP (frame));
|
||||
if (p->valid)
|
||||
return p->the_info.numargs;
|
||||
#endif
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Is this a branch with a delay slot? */
|
||||
|
||||
static int is_delayed PARAMS ((unsigned long));
|
||||
|
||||
static int
|
||||
|
@ -1110,11 +1210,90 @@ in_sigtramp (pc, ignore)
|
|||
return (pc >= sigtramp_address && pc < sigtramp_end);
|
||||
}
|
||||
|
||||
static void reinit_frame_cache_sfunc PARAMS ((char *, int,
|
||||
struct cmd_list_element *));
|
||||
/* Command to set the processor type. */
|
||||
|
||||
void
|
||||
mips_set_processor_type_command (args, from_tty)
|
||||
char *args;
|
||||
int from_tty;
|
||||
{
|
||||
int i;
|
||||
|
||||
if (tmp_mips_processor_type == NULL || *tmp_mips_processor_type == '\0')
|
||||
{
|
||||
printf_unfiltered ("The known MIPS processor types are as follows:\n\n");
|
||||
for (i = 0; mips_processor_type_table[i].name != NULL; ++i)
|
||||
printf_unfiltered ("%s\n", mips_processor_type_table[i].name);
|
||||
|
||||
/* Restore the value. */
|
||||
tmp_mips_processor_type = strsave (mips_processor_type);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mips_set_processor_type (tmp_mips_processor_type))
|
||||
{
|
||||
error ("Unknown processor type `%s'.", tmp_mips_processor_type);
|
||||
/* Restore its value. */
|
||||
tmp_mips_processor_type = strsave (mips_processor_type);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mips_show_processor_type_command (args, from_tty)
|
||||
char *args;
|
||||
int from_tty;
|
||||
{
|
||||
}
|
||||
|
||||
/* Modify the actual processor type. */
|
||||
|
||||
int
|
||||
mips_set_processor_type (str)
|
||||
char *str;
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (str == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; mips_processor_type_table[i].name != NULL; ++i)
|
||||
{
|
||||
if (strcasecmp (str, mips_processor_type_table[i].name) == 0)
|
||||
{
|
||||
mips_processor_type = str;
|
||||
|
||||
for (j = 0; j < NUM_REGS; ++j)
|
||||
reg_names[j] = mips_processor_type_table[i].regnames[j];
|
||||
|
||||
return 1;
|
||||
|
||||
/* FIXME tweak fpu flag too */
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Attempt to identify the particular processor model by reading the
|
||||
processor id. */
|
||||
|
||||
char *
|
||||
mips_read_processor_type ()
|
||||
{
|
||||
int prid;
|
||||
|
||||
prid = read_register (PRID_REGNUM);
|
||||
|
||||
if (prid & ~0xf == 0x700)
|
||||
return savestring ("r3041", strlen("r3041"));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Just like reinit_frame_cache, but with the right arguments to be
|
||||
callable as an sfunc. */
|
||||
|
||||
static void
|
||||
reinit_frame_cache_sfunc (args, from_tty, c)
|
||||
char *args;
|
||||
|
@ -1140,6 +1319,19 @@ Turn off to avoid using floating point instructions when calling functions\n\
|
|||
or dealing with return values.", &setlist),
|
||||
&showlist);
|
||||
|
||||
c = add_set_cmd ("processor", class_support, var_string_noescape,
|
||||
(char *) &tmp_mips_processor_type,
|
||||
"Set the type of MIPS processor in use.\n\
|
||||
Set this to be able to access processor-type-specific registers.\n\
|
||||
",
|
||||
&setlist);
|
||||
c->function.cfunc = mips_set_processor_type_command;
|
||||
c = add_show_from_set (c, &showlist);
|
||||
c->function.cfunc = mips_show_processor_type_command;
|
||||
|
||||
tmp_mips_processor_type = strsave (DEFAULT_MIPS_TYPE);
|
||||
mips_set_processor_type_command (strsave (DEFAULT_MIPS_TYPE), 0);
|
||||
|
||||
/* We really would like to have both "0" and "unlimited" work, but
|
||||
command.c doesn't deal with that. So make it a var_zinteger
|
||||
because the user can always use "999999" or some such for unlimited. */
|
||||
|
|
Loading…
Reference in a new issue