* mips-tdep.c (mips_push_arguments): On non-EABI architectures,
copy first two floating point arguments to general registers, so that MIPS16 functions will receive the arguments correctly. (mips_print_register): Print double registers correctly on little-endian hosts. (mips_extract_return_value): Return double values correctly on little-endian hosts. * mdebugread.c (parse_procedure): Adjust address of procedure relative to address in file descriptor record; this accounts for constant strings that may precede functions in the text section. Remove now-useless lowest_pdr_addr from argument list and all calls.
This commit is contained in:
parent
7cad1a894b
commit
c81a76b311
3 changed files with 147 additions and 86 deletions
|
@ -1,3 +1,18 @@
|
||||||
|
Fri Mar 21 19:10:05 1997 Mark Alexander <marka@cygnus.com>
|
||||||
|
|
||||||
|
* mips-tdep.c (mips_push_arguments): On non-EABI architectures,
|
||||||
|
copy first two floating point arguments to general registers, so that
|
||||||
|
MIPS16 functions will receive the arguments correctly.
|
||||||
|
(mips_print_register): Print double registers correctly on
|
||||||
|
little-endian hosts.
|
||||||
|
(mips_extract_return_value): Return double values correctly
|
||||||
|
on little-endian hosts.
|
||||||
|
|
||||||
|
* mdebugread.c (parse_procedure): Adjust address of procedure relative
|
||||||
|
to address in file descriptor record; this accounts for constant
|
||||||
|
strings that may precede functions in the text section. Remove
|
||||||
|
now-useless lowest_pdr_addr from argument list and all calls.
|
||||||
|
|
||||||
Fri Mar 21 15:36:25 1997 Michael Meissner <meissner@cygnus.com>
|
Fri Mar 21 15:36:25 1997 Michael Meissner <meissner@cygnus.com>
|
||||||
|
|
||||||
* configure.tgt (powerpc*-{eabi,linux,sysv,elf}*): Determine
|
* configure.tgt (powerpc*-{eabi,linux,sysv,elf}*): Determine
|
||||||
|
|
|
@ -1893,14 +1893,13 @@ upgrade_type (fd, tpp, tq, ax, bigend, sym_name)
|
||||||
to look for the function which contains the MIPS_EFI_SYMBOL_NAME symbol
|
to look for the function which contains the MIPS_EFI_SYMBOL_NAME symbol
|
||||||
in question, or NULL to use top_stack->cur_block. */
|
in question, or NULL to use top_stack->cur_block. */
|
||||||
|
|
||||||
static void parse_procedure PARAMS ((PDR *, struct symtab *, CORE_ADDR,
|
static void parse_procedure PARAMS ((PDR *, struct symtab *,
|
||||||
struct partial_symtab *));
|
struct partial_symtab *));
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parse_procedure (pr, search_symtab, lowest_pdr_addr, pst)
|
parse_procedure (pr, search_symtab, pst)
|
||||||
PDR *pr;
|
PDR *pr;
|
||||||
struct symtab *search_symtab;
|
struct symtab *search_symtab;
|
||||||
CORE_ADDR lowest_pdr_addr;
|
|
||||||
struct partial_symtab *pst;
|
struct partial_symtab *pst;
|
||||||
{
|
{
|
||||||
struct symbol *s, *i;
|
struct symbol *s, *i;
|
||||||
|
@ -2006,7 +2005,7 @@ parse_procedure (pr, search_symtab, lowest_pdr_addr, pst)
|
||||||
e = (struct mips_extra_func_info *) SYMBOL_VALUE (i);
|
e = (struct mips_extra_func_info *) SYMBOL_VALUE (i);
|
||||||
e->pdr = *pr;
|
e->pdr = *pr;
|
||||||
e->pdr.isym = (long) s;
|
e->pdr.isym = (long) s;
|
||||||
e->pdr.adr += pst->textlow - lowest_pdr_addr;
|
e->pdr.adr += cur_fdr->adr; /* PDR address is relative to FDR address */
|
||||||
|
|
||||||
/* Correct incorrect setjmp procedure descriptor from the library
|
/* Correct incorrect setjmp procedure descriptor from the library
|
||||||
to make backtrace through setjmp work. */
|
to make backtrace through setjmp work. */
|
||||||
|
@ -3372,7 +3371,7 @@ psymtab_to_symtab_1 (pst, filename)
|
||||||
pdr_in = pr_block;
|
pdr_in = pr_block;
|
||||||
pdr_in_end = pdr_in + fh->cpd;
|
pdr_in_end = pdr_in + fh->cpd;
|
||||||
for (; pdr_in < pdr_in_end; pdr_in++)
|
for (; pdr_in < pdr_in_end; pdr_in++)
|
||||||
parse_procedure (pdr_in, st, lowest_pdr_addr, pst);
|
parse_procedure (pdr_in, st, pst);
|
||||||
|
|
||||||
do_cleanups (old_chain);
|
do_cleanups (old_chain);
|
||||||
}
|
}
|
||||||
|
@ -3486,7 +3485,7 @@ psymtab_to_symtab_1 (pst, filename)
|
||||||
pdr_in = pr_block;
|
pdr_in = pr_block;
|
||||||
pdr_in_end = pdr_in + fh->cpd;
|
pdr_in_end = pdr_in + fh->cpd;
|
||||||
for (; pdr_in < pdr_in_end; pdr_in++)
|
for (; pdr_in < pdr_in_end; pdr_in++)
|
||||||
parse_procedure (pdr_in, 0, lowest_pdr_addr, pst);
|
parse_procedure (pdr_in, 0, pst);
|
||||||
|
|
||||||
do_cleanups (old_chain);
|
do_cleanups (old_chain);
|
||||||
}
|
}
|
||||||
|
|
207
gdb/mips-tdep.c
207
gdb/mips-tdep.c
|
@ -316,6 +316,32 @@ mips16_decode_reg_save (inst, gen_mask)
|
||||||
*gen_mask |= (1 << 31);
|
*gen_mask |= (1 << 31);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Fetch and return instruction from the specified location. If the PC
|
||||||
|
is odd, assume it's a MIPS16 instruction; otherwise MIPS32. */
|
||||||
|
|
||||||
|
static t_inst
|
||||||
|
mips_fetch_instruction (addr)
|
||||||
|
CORE_ADDR addr;
|
||||||
|
{
|
||||||
|
char buf[MIPS_INSTLEN];
|
||||||
|
int instlen;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if (IS_MIPS16_ADDR (addr))
|
||||||
|
{
|
||||||
|
instlen = MIPS16_INSTLEN;
|
||||||
|
addr = UNMAKE_MIPS16_ADDR (addr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
instlen = MIPS_INSTLEN;
|
||||||
|
status = read_memory_nobpt (addr, buf, instlen);
|
||||||
|
if (status)
|
||||||
|
memory_error (status, addr);
|
||||||
|
return extract_unsigned_integer (buf, instlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Guaranteed to set fci->saved_regs to some values (it never leaves it
|
/* Guaranteed to set fci->saved_regs to some values (it never leaves it
|
||||||
NULL). */
|
NULL). */
|
||||||
|
|
||||||
|
@ -330,6 +356,7 @@ mips_find_saved_regs (fci)
|
||||||
/* What registers have been saved? Bitmasks. */
|
/* What registers have been saved? Bitmasks. */
|
||||||
unsigned long gen_mask, float_mask;
|
unsigned long gen_mask, float_mask;
|
||||||
mips_extra_func_info_t proc_desc;
|
mips_extra_func_info_t proc_desc;
|
||||||
|
t_inst inst;
|
||||||
|
|
||||||
fci->saved_regs = (struct frame_saved_regs *)
|
fci->saved_regs = (struct frame_saved_regs *)
|
||||||
obstack_alloc (&frame_cache_obstack, sizeof(struct frame_saved_regs));
|
obstack_alloc (&frame_cache_obstack, sizeof(struct frame_saved_regs));
|
||||||
|
@ -406,34 +433,22 @@ mips_find_saved_regs (fci)
|
||||||
claims are saved have been saved yet. */
|
claims are saved have been saved yet. */
|
||||||
|
|
||||||
CORE_ADDR addr;
|
CORE_ADDR addr;
|
||||||
int status;
|
|
||||||
char buf[MIPS_INSTLEN];
|
|
||||||
t_inst inst;
|
|
||||||
int instlen;
|
|
||||||
|
|
||||||
/* Bitmasks; set if we have found a save for the register. */
|
/* Bitmasks; set if we have found a save for the register. */
|
||||||
unsigned long gen_save_found = 0;
|
unsigned long gen_save_found = 0;
|
||||||
unsigned long float_save_found = 0;
|
unsigned long float_save_found = 0;
|
||||||
|
int instlen;
|
||||||
|
|
||||||
/* If the address is odd, assume this is MIPS16 code. */
|
/* If the address is odd, assume this is MIPS16 code. */
|
||||||
addr = PROC_LOW_ADDR (proc_desc);
|
addr = PROC_LOW_ADDR (proc_desc);
|
||||||
if (IS_MIPS16_ADDR (addr))
|
instlen = IS_MIPS16_ADDR (addr) ? MIPS16_INSTLEN : MIPS_INSTLEN;
|
||||||
{
|
|
||||||
instlen = MIPS16_INSTLEN;
|
|
||||||
addr = UNMAKE_MIPS16_ADDR (addr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
instlen = MIPS_INSTLEN;
|
|
||||||
|
|
||||||
/* Scan through this function's instructions preceding the current
|
/* Scan through this function's instructions preceding the current
|
||||||
PC, and look for those that save registers. */
|
PC, and look for those that save registers. */
|
||||||
while (addr < fci->pc)
|
while (addr < fci->pc)
|
||||||
{
|
{
|
||||||
status = read_memory_nobpt (addr, buf, instlen);
|
inst = mips_fetch_instruction (addr);
|
||||||
if (status)
|
if (IS_MIPS16_ADDR (addr))
|
||||||
memory_error (status, addr);
|
|
||||||
inst = extract_unsigned_integer (buf, instlen);
|
|
||||||
if (instlen == MIPS16_INSTLEN)
|
|
||||||
mips16_decode_reg_save (inst, &gen_save_found);
|
mips16_decode_reg_save (inst, &gen_save_found);
|
||||||
else
|
else
|
||||||
mips32_decode_reg_save (inst, &gen_save_found, &float_save_found);
|
mips32_decode_reg_save (inst, &gen_save_found, &float_save_found);
|
||||||
|
@ -452,6 +467,33 @@ mips_find_saved_regs (fci)
|
||||||
fci->saved_regs->regs[ireg] = reg_position;
|
fci->saved_regs->regs[ireg] = reg_position;
|
||||||
reg_position -= MIPS_REGSIZE;
|
reg_position -= MIPS_REGSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The MIPS16 entry instruction saves $s0 and $s1 in the reverse order
|
||||||
|
of that normally used by gcc. Therefore, we have to fetch the first
|
||||||
|
instruction of the function, and if it's an entry instruction that
|
||||||
|
saves $s0 or $s1, correct their saved addresses. */
|
||||||
|
if (IS_MIPS16_ADDR (PROC_LOW_ADDR (proc_desc)))
|
||||||
|
{
|
||||||
|
inst = mips_fetch_instruction (PROC_LOW_ADDR (proc_desc));
|
||||||
|
if ((inst & 0xf81f) == 0xe809 && (inst & 0x700) != 0x700) /* entry */
|
||||||
|
{
|
||||||
|
int reg;
|
||||||
|
int sreg_count = (inst >> 6) & 3;
|
||||||
|
|
||||||
|
/* Check if the ra register was pushed on the stack. */
|
||||||
|
reg_position = fci->frame + PROC_REG_OFFSET (proc_desc);
|
||||||
|
if (inst & 0x20)
|
||||||
|
reg_position -= MIPS_REGSIZE;
|
||||||
|
|
||||||
|
/* Check if the s0 and s1 registers were pushed on the stack. */
|
||||||
|
for (reg = 16; reg < sreg_count+16; reg++)
|
||||||
|
{
|
||||||
|
fci->saved_regs->regs[reg] = reg_position;
|
||||||
|
reg_position -= MIPS_REGSIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Fill in the offsets for the registers which float_mask says
|
/* Fill in the offsets for the registers which float_mask says
|
||||||
were saved. */
|
were saved. */
|
||||||
reg_position = fci->frame + PROC_FREG_OFFSET (proc_desc);
|
reg_position = fci->frame + PROC_FREG_OFFSET (proc_desc);
|
||||||
|
@ -459,7 +501,7 @@ mips_find_saved_regs (fci)
|
||||||
/* The freg_offset points to where the first *double* register
|
/* The freg_offset points to where the first *double* register
|
||||||
is saved. So skip to the high-order word. */
|
is saved. So skip to the high-order word. */
|
||||||
if (! GDB_TARGET_IS_MIPS64)
|
if (! GDB_TARGET_IS_MIPS64)
|
||||||
reg_position += 4;
|
reg_position += MIPS_REGSIZE;
|
||||||
|
|
||||||
/* Fill in the offsets for the float registers which float_mask says
|
/* Fill in the offsets for the float registers which float_mask says
|
||||||
were saved. */
|
were saved. */
|
||||||
|
@ -621,7 +663,7 @@ Otherwise, you told GDB there was a function where there isn't one, or\n\
|
||||||
addiu sp,-n
|
addiu sp,-n
|
||||||
daddiu sp,-n
|
daddiu sp,-n
|
||||||
extend -n followed by 'addiu sp,+n' or 'daddiu sp,+n' */
|
extend -n followed by 'addiu sp,+n' or 'daddiu sp,+n' */
|
||||||
inst = read_memory_integer (UNMAKE_MIPS16_ADDR (start_pc), 2);
|
inst = mips_fetch_instruction (start_pc);
|
||||||
if (((inst & 0xf81f) == 0xe809 && (inst & 0x700) != 0x700) /* entry */
|
if (((inst & 0xf81f) == 0xe809 && (inst & 0x700) != 0x700) /* entry */
|
||||||
|| (inst & 0xff80) == 0x6380 /* addiu sp,-n */
|
|| (inst & 0xff80) == 0x6380 /* addiu sp,-n */
|
||||||
|| (inst & 0xff80) == 0xfb80 /* daddiu sp,-n */
|
|| (inst & 0xff80) == 0xfb80 /* daddiu sp,-n */
|
||||||
|
@ -647,7 +689,7 @@ Otherwise, you told GDB there was a function where there isn't one, or\n\
|
||||||
return start_pc;
|
return start_pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fetch the immediate value from the current instruction.
|
/* Fetch the immediate value from a MIPS16 instruction.
|
||||||
If the previous instruction was an EXTEND, use it to extend
|
If the previous instruction was an EXTEND, use it to extend
|
||||||
the upper bits of the immediate value. This is a helper function
|
the upper bits of the immediate value. This is a helper function
|
||||||
for mips16_heuristic_proc_desc. */
|
for mips16_heuristic_proc_desc. */
|
||||||
|
@ -701,19 +743,14 @@ mips16_heuristic_proc_desc(start_pc, limit_pc, next_frame, sp)
|
||||||
|
|
||||||
for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += MIPS16_INSTLEN)
|
for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += MIPS16_INSTLEN)
|
||||||
{
|
{
|
||||||
char buf[MIPS16_INSTLEN];
|
int reg, offset;
|
||||||
int status, reg, offset;
|
|
||||||
|
|
||||||
/* Save the previous instruction. If it's an EXTEND, we'll extract
|
/* Save the previous instruction. If it's an EXTEND, we'll extract
|
||||||
the immediate offset extension from it in mips16_get_imm. */
|
the immediate offset extension from it in mips16_get_imm. */
|
||||||
prev_inst = inst;
|
prev_inst = inst;
|
||||||
|
|
||||||
/* Fetch the instruction. */
|
/* Fetch and decode the instruction. */
|
||||||
status = read_memory_nobpt (UNMAKE_MIPS16_ADDR (cur_pc), buf,
|
inst = (unsigned short) mips_fetch_instruction (cur_pc);
|
||||||
MIPS16_INSTLEN);
|
|
||||||
if (status) memory_error (status, cur_pc);
|
|
||||||
inst = (unsigned short) extract_unsigned_integer (buf, MIPS16_INSTLEN);
|
|
||||||
|
|
||||||
if ((inst & 0xff00) == 0x6300 /* addiu sp */
|
if ((inst & 0xff00) == 0x6300 /* addiu sp */
|
||||||
|| (inst & 0xff00) == 0xfb00) /* daddiu sp */
|
|| (inst & 0xff00) == 0xfb00) /* daddiu sp */
|
||||||
{
|
{
|
||||||
|
@ -786,10 +823,11 @@ mips16_heuristic_proc_desc(start_pc, limit_pc, next_frame, sp)
|
||||||
PROC_FRAME_OFFSET(&temp_proc_desc) += 32;
|
PROC_FRAME_OFFSET(&temp_proc_desc) += 32;
|
||||||
|
|
||||||
/* Check if a0-a3 were saved in the caller's argument save area. */
|
/* Check if a0-a3 were saved in the caller's argument save area. */
|
||||||
for (reg = 4, offset = 32; reg < areg_count+4; reg++, offset += 4)
|
for (reg = 4, offset = 32; reg < areg_count+4; reg++)
|
||||||
{
|
{
|
||||||
PROC_REG_MASK(&temp_proc_desc) |= 1 << reg;
|
PROC_REG_MASK(&temp_proc_desc) |= 1 << reg;
|
||||||
temp_saved_regs.regs[reg] = sp + offset;
|
temp_saved_regs.regs[reg] = sp + offset;
|
||||||
|
offset -= MIPS_REGSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the ra register was pushed on the stack. */
|
/* Check if the ra register was pushed on the stack. */
|
||||||
|
@ -798,14 +836,15 @@ mips16_heuristic_proc_desc(start_pc, limit_pc, next_frame, sp)
|
||||||
{
|
{
|
||||||
PROC_REG_MASK(&temp_proc_desc) |= 1 << 31;
|
PROC_REG_MASK(&temp_proc_desc) |= 1 << 31;
|
||||||
temp_saved_regs.regs[31] = sp + offset;
|
temp_saved_regs.regs[31] = sp + offset;
|
||||||
offset -= 4;
|
offset -= MIPS_REGSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the s0 and s1 registers were pushed on the stack. */
|
/* Check if the s0 and s1 registers were pushed on the stack. */
|
||||||
for (reg = 16; reg < sreg_count+16; reg++, offset -= 4)
|
for (reg = 16; reg < sreg_count+16; reg++)
|
||||||
{
|
{
|
||||||
PROC_REG_MASK(&temp_proc_desc) |= 1 << reg;
|
PROC_REG_MASK(&temp_proc_desc) |= 1 << reg;
|
||||||
temp_saved_regs.regs[reg] = sp + offset;
|
temp_saved_regs.regs[reg] = sp + offset;
|
||||||
|
offset -= MIPS_REGSIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((inst & 0xf800) == 0x1800) /* jal(x) */
|
else if ((inst & 0xf800) == 0x1800) /* jal(x) */
|
||||||
|
@ -825,14 +864,11 @@ restart:
|
||||||
PROC_FRAME_OFFSET(&temp_proc_desc) = 0;
|
PROC_FRAME_OFFSET(&temp_proc_desc) = 0;
|
||||||
for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += MIPS_INSTLEN)
|
for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += MIPS_INSTLEN)
|
||||||
{
|
{
|
||||||
char buf[MIPS_INSTLEN];
|
|
||||||
unsigned long inst, high_word, low_word;
|
unsigned long inst, high_word, low_word;
|
||||||
int status, reg;
|
int reg;
|
||||||
|
|
||||||
/* Fetch the instruction. */
|
/* Fetch the instruction. */
|
||||||
status = (unsigned long) read_memory_nobpt (cur_pc, buf, MIPS_INSTLEN);
|
inst = (unsigned long) mips_fetch_instruction (cur_pc);
|
||||||
if (status) memory_error (status, cur_pc);
|
|
||||||
inst = (unsigned long) extract_unsigned_integer (buf, MIPS_INSTLEN);
|
|
||||||
|
|
||||||
/* Save some code by pre-extracting some useful fields. */
|
/* Save some code by pre-extracting some useful fields. */
|
||||||
high_word = (inst >> 16) & 0xffff;
|
high_word = (inst >> 16) & 0xffff;
|
||||||
|
@ -1246,7 +1282,12 @@ mips_push_arguments(nargs, args, sp, struct_return, struct_addr)
|
||||||
/* Floating point arguments passed in registers have to be
|
/* Floating point arguments passed in registers have to be
|
||||||
treated specially. On 32-bit architectures, doubles
|
treated specially. On 32-bit architectures, doubles
|
||||||
are passed in register pairs; the even register gets
|
are passed in register pairs; the even register gets
|
||||||
the low word, and the odd register gets the high word. */
|
the low word, and the odd register gets the high word.
|
||||||
|
On non-EABI processors, the first two floating point arguments are
|
||||||
|
also copied to general registers, because MIPS16 functions
|
||||||
|
don't use float registers for arguments. This duplication of
|
||||||
|
arguments in general registers can't hurt non-MIPS16 functions
|
||||||
|
because those registers are normally skipped. */
|
||||||
if (typecode == TYPE_CODE_FLT
|
if (typecode == TYPE_CODE_FLT
|
||||||
&& float_argreg <= MIPS_LAST_FP_ARG_REGNUM
|
&& float_argreg <= MIPS_LAST_FP_ARG_REGNUM
|
||||||
&& mips_fpu != MIPS_FPU_NONE)
|
&& mips_fpu != MIPS_FPU_NONE)
|
||||||
|
@ -1256,21 +1297,34 @@ mips_push_arguments(nargs, args, sp, struct_return, struct_addr)
|
||||||
int low_offset = TARGET_BYTE_ORDER == BIG_ENDIAN ? 4 : 0;
|
int low_offset = TARGET_BYTE_ORDER == BIG_ENDIAN ? 4 : 0;
|
||||||
unsigned long regval;
|
unsigned long regval;
|
||||||
|
|
||||||
|
/* Write the low word of the double to the even register(s). */
|
||||||
regval = extract_unsigned_integer (val+low_offset, 4);
|
regval = extract_unsigned_integer (val+low_offset, 4);
|
||||||
write_register (float_argreg++, regval); /* low word */
|
write_register (float_argreg++, regval);
|
||||||
|
if (!MIPS_EABI)
|
||||||
|
write_register (argreg+1, regval);
|
||||||
|
|
||||||
|
/* Write the high word of the double to the odd register(s). */
|
||||||
regval = extract_unsigned_integer (val+4-low_offset, 4);
|
regval = extract_unsigned_integer (val+4-low_offset, 4);
|
||||||
write_register (float_argreg++, regval); /* high word */
|
write_register (float_argreg++, regval);
|
||||||
|
if (!MIPS_EABI)
|
||||||
|
{
|
||||||
|
write_register (argreg, regval);
|
||||||
|
argreg += 2;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* This is a floating point value that fits entirely
|
||||||
|
in a single register. */
|
||||||
CORE_ADDR regval = extract_address (val, len);
|
CORE_ADDR regval = extract_address (val, len);
|
||||||
write_register (float_argreg++, regval);
|
write_register (float_argreg++, regval);
|
||||||
|
if (!MIPS_EABI)
|
||||||
|
{
|
||||||
|
write_register (argreg, regval);
|
||||||
|
argreg += GDB_TARGET_IS_MIPS64 ? 1 : 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this is the old ABI, skip one or two general registers. */
|
|
||||||
if (!MIPS_EABI)
|
|
||||||
argreg += GDB_TARGET_IS_MIPS64 ? 1 : 2;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1325,7 +1379,7 @@ mips_push_arguments(nargs, args, sp, struct_return, struct_addr)
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
mips_push_register(CORE_ADDR *sp, int regno)
|
mips_push_register(CORE_ADDR *sp, int regno)
|
||||||
{
|
{
|
||||||
char buffer[MAX_REGISTER_RAW_SIZE];
|
char buffer[MAX_REGISTER_RAW_SIZE];
|
||||||
|
@ -1488,11 +1542,11 @@ mips_print_register (regnum, all)
|
||||||
{
|
{
|
||||||
char dbuffer[MAX_REGISTER_RAW_SIZE];
|
char dbuffer[MAX_REGISTER_RAW_SIZE];
|
||||||
|
|
||||||
read_relative_register_raw_bytes (regnum, dbuffer);
|
/* MIPS doubles are stored in a register pair with the least
|
||||||
read_relative_register_raw_bytes (regnum+1, dbuffer+4); /* FIXME!! */
|
signficant register in the lower-numbered register. */
|
||||||
#ifdef REGISTER_CONVERT_TO_TYPE
|
read_relative_register_raw_bytes (regnum+1, dbuffer);
|
||||||
REGISTER_CONVERT_TO_TYPE(regnum, builtin_type_double, dbuffer);
|
read_relative_register_raw_bytes (regnum, dbuffer+MIPS_REGSIZE);
|
||||||
#endif
|
|
||||||
printf_filtered ("(d%d: ", regnum-FP0_REGNUM);
|
printf_filtered ("(d%d: ", regnum-FP0_REGNUM);
|
||||||
val_print (builtin_type_double, dbuffer, 0,
|
val_print (builtin_type_double, dbuffer, 0,
|
||||||
gdb_stdout, 0, 1, 0, Val_pretty_default);
|
gdb_stdout, 0, 1, 0, Val_pretty_default);
|
||||||
|
@ -1632,14 +1686,9 @@ mips32_skip_prologue (pc, lenient)
|
||||||
or in the gcc frame. */
|
or in the gcc frame. */
|
||||||
for (end_pc = pc + 100; pc < end_pc; pc += MIPS_INSTLEN)
|
for (end_pc = pc + 100; pc < end_pc; pc += MIPS_INSTLEN)
|
||||||
{
|
{
|
||||||
char buf[MIPS_INSTLEN];
|
|
||||||
int status;
|
|
||||||
unsigned long high_word;
|
unsigned long high_word;
|
||||||
|
|
||||||
status = read_memory_nobpt (pc, buf, MIPS_INSTLEN);
|
inst = mips_fetch_instruction (pc);
|
||||||
if (status)
|
|
||||||
memory_error (status, pc);
|
|
||||||
inst = (unsigned long)extract_unsigned_integer (buf, MIPS_INSTLEN);
|
|
||||||
high_word = (inst >> 16) & 0xffff;
|
high_word = (inst >> 16) & 0xffff;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -1724,6 +1773,8 @@ mips16_skip_prologue (pc, lenient)
|
||||||
int lenient;
|
int lenient;
|
||||||
{
|
{
|
||||||
CORE_ADDR end_pc;
|
CORE_ADDR end_pc;
|
||||||
|
int extend_bytes = 0;
|
||||||
|
int prev_extend_bytes;
|
||||||
|
|
||||||
/* Table of instructions likely to be found in a function prologue. */
|
/* Table of instructions likely to be found in a function prologue. */
|
||||||
static struct
|
static struct
|
||||||
|
@ -1751,23 +1802,10 @@ mips16_skip_prologue (pc, lenient)
|
||||||
or in the gcc frame. */
|
or in the gcc frame. */
|
||||||
for (end_pc = pc + 100; pc < end_pc; pc += MIPS16_INSTLEN)
|
for (end_pc = pc + 100; pc < end_pc; pc += MIPS16_INSTLEN)
|
||||||
{
|
{
|
||||||
char buf[MIPS16_INSTLEN];
|
|
||||||
int status;
|
|
||||||
unsigned short inst;
|
unsigned short inst;
|
||||||
int extend_bytes = 0;
|
|
||||||
int prev_extend_bytes;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
status = read_memory_nobpt (UNMAKE_MIPS16_ADDR (pc), buf,
|
inst = mips_fetch_instruction (pc);
|
||||||
MIPS16_INSTLEN);
|
|
||||||
if (status)
|
|
||||||
memory_error (status, pc);
|
|
||||||
inst = (unsigned long)extract_unsigned_integer (buf, MIPS16_INSTLEN);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (lenient && is_delayed (inst))
|
|
||||||
continue;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Normally we ignore an extend instruction. However, if it is
|
/* Normally we ignore an extend instruction. However, if it is
|
||||||
not followed by a valid prologue instruction, we must adjust
|
not followed by a valid prologue instruction, we must adjust
|
||||||
|
@ -1857,23 +1895,32 @@ mips_extract_return_value (valtype, regbuf, valbuf)
|
||||||
{
|
{
|
||||||
int regnum;
|
int regnum;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
int len = TYPE_LENGTH (valtype);
|
||||||
|
|
||||||
regnum = 2;
|
regnum = 2;
|
||||||
if (TYPE_CODE (valtype) == TYPE_CODE_FLT
|
if (TYPE_CODE (valtype) == TYPE_CODE_FLT
|
||||||
&& (mips_fpu == MIPS_FPU_DOUBLE
|
&& (mips_fpu == MIPS_FPU_DOUBLE
|
||||||
|| (mips_fpu == MIPS_FPU_SINGLE && TYPE_LENGTH (valtype) <= 4))) /* FIXME!! */
|
|| (mips_fpu == MIPS_FPU_SINGLE && len <= MIPS_REGSIZE)))
|
||||||
regnum = FP0_REGNUM;
|
{
|
||||||
|
regnum = FP0_REGNUM;
|
||||||
|
|
||||||
|
/* If this is a double, the odd-numbered register (FP1) contains the
|
||||||
|
high word of the result. Copy that to the buffer before
|
||||||
|
copying the low word in FP0. */
|
||||||
|
if (len > MIPS_REGSIZE)
|
||||||
|
{
|
||||||
|
memcpy (valbuf, regbuf + REGISTER_BYTE (regnum+1), MIPS_REGSIZE);
|
||||||
|
len -= MIPS_REGSIZE;
|
||||||
|
valbuf += MIPS_REGSIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (TARGET_BYTE_ORDER == BIG_ENDIAN
|
if (TARGET_BYTE_ORDER == BIG_ENDIAN
|
||||||
&& TYPE_CODE (valtype) != TYPE_CODE_FLT
|
&& TYPE_CODE (valtype) != TYPE_CODE_FLT
|
||||||
&& TYPE_LENGTH (valtype) < REGISTER_RAW_SIZE (regnum))
|
&& len < REGISTER_RAW_SIZE (regnum))
|
||||||
offset = REGISTER_RAW_SIZE (regnum) - TYPE_LENGTH (valtype);
|
offset = REGISTER_RAW_SIZE (regnum) - len;
|
||||||
|
|
||||||
memcpy (valbuf, regbuf + REGISTER_BYTE (regnum) + offset,
|
memcpy (valbuf, regbuf + REGISTER_BYTE (regnum) + offset, len);
|
||||||
TYPE_LENGTH (valtype));
|
|
||||||
#ifdef REGISTER_CONVERT_TO_TYPE
|
|
||||||
REGISTER_CONVERT_TO_TYPE(regnum, valtype, valbuf);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Given a return value in `regbuf' with a type `valtype',
|
/* Given a return value in `regbuf' with a type `valtype',
|
||||||
|
@ -2162,9 +2209,9 @@ mips_about_to_return (pc)
|
||||||
as $a3), then a "jr" using that register. This second case
|
as $a3), then a "jr" using that register. This second case
|
||||||
is almost impossible to distinguish from an indirect jump
|
is almost impossible to distinguish from an indirect jump
|
||||||
used for switch statements, so we don't even try. */
|
used for switch statements, so we don't even try. */
|
||||||
return read_memory_integer (UNMAKE_MIPS16_ADDR (pc), 2) == 0xe820; /* jr $ra */
|
return mips_fetch_instruction (pc) == 0xe820; /* jr $ra */
|
||||||
else
|
else
|
||||||
return read_memory_integer (pc, 4) == 0x3e00008; /* jr $ra */
|
return mips_fetch_instruction (pc) == 0x3e00008; /* jr $ra */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue