diff options
author | Andrew Cagney <cagney@redhat.com> | 2003-06-21 18:02:54 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 2003-06-21 18:02:54 +0000 |
commit | c57bb9fa3e53d81d05b3f263797d4a68d6c9272f (patch) | |
tree | 7dd97762270911e683217bd2e2f188b8d68ec9a4 /gdb/mips-tdep.c | |
parent | 6e51443a2a52062e54da687f7a70127a727335be (diff) | |
download | gdb-c57bb9fa3e53d81d05b3f263797d4a68d6c9272f.zip gdb-c57bb9fa3e53d81d05b3f263797d4a68d6c9272f.tar.gz gdb-c57bb9fa3e53d81d05b3f263797d4a68d6c9272f.tar.bz2 |
2003-06-21 Andrew Cagney <cagney@redhat.com>
* mips-tdep.c (mips_find_saved_regs): Rewrite mdebug code handling
32 bit floating-point register saves.
Diffstat (limited to 'gdb/mips-tdep.c')
-rw-r--r-- | gdb/mips-tdep.c | 50 |
1 files changed, 33 insertions, 17 deletions
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index 538714c..c5dccc9 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -1607,28 +1607,44 @@ mips_find_saved_regs (struct frame_info *fci) CORE_ADDR reg_position = (get_frame_base (fci) + PROC_FREG_OFFSET (proc_desc)); - /* Apparently, the freg_offset gives the offset to the first 64 - bit saved. - - When the ABI specifies 64 bit saved registers, the FREG_OFFSET - designates the first saved 64 bit register. - - When the ABI specifies 32 bit saved registers, the ``64 bit - saved DOUBLE'' consists of two adjacent 32 bit registers, Hence - FREG_OFFSET, designates the address of the lower register of - the register pair. Adjust the offset so that it designates the - upper register of the pair -- i.e., the address of the first - saved 32 bit register. */ - - if (MIPS_SAVED_REGSIZE == 4) - reg_position += MIPS_SAVED_REGSIZE; - /* Fill in the offsets for the float registers which float_mask says were saved. */ for (ireg = MIPS_NUMREGS - 1; float_mask; --ireg, float_mask <<= 1) if (float_mask & 0x80000000) { - set_reg_offset (saved_regs, FP0_REGNUM + ireg, reg_position); + if (MIPS_SAVED_REGSIZE == 4 && TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + { + /* On a big endian 32 bit ABI, floating point registers + are paired to form doubles such that the most + significant part is in $f[N+1] and the least + significant in $f[N] vis: $f[N+1] ||| $f[N]. The + registers are also spilled as a pair and stored as a + double. + + When little-endian the least significant part is + stored first leading to the memory order $f[N] and + then $f[N+1]. + + Unfortunatly, when big-endian the most significant + part of the double is stored first, and the least + significant is stored second. This leads to the + registers being ordered in memory as firt $f[N+1] and + then $f[N]. + + For the big-endian case make certain that the + addresses point at the correct (swapped) locations + $f[N] and $f[N+1] pair (keep in mind that + reg_position is decremented each time through the + loop). */ + if ((ireg & 1)) + set_reg_offset (saved_regs, FP0_REGNUM + ireg, + reg_position - MIPS_SAVED_REGSIZE); + else + set_reg_offset (saved_regs, FP0_REGNUM + ireg, + reg_position + MIPS_SAVED_REGSIZE); + } + else + set_reg_offset (saved_regs, FP0_REGNUM + ireg, reg_position); reg_position -= MIPS_SAVED_REGSIZE; } |