* 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:
Mark Alexander 1997-03-22 04:40:03 +00:00
parent 7cad1a894b
commit c81a76b311
3 changed files with 147 additions and 86 deletions

View File

@ -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

View File

@ -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);
} }

View File

@ -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 */
} }