Index: sparc-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/sparc-tdep.c,v retrieving revision 1.157 diff -u -p -r1.157 sparc-tdep.c --- sparc-tdep.c 23 Nov 2004 18:59:13 -0000 1.157 +++ sparc-tdep.c 26 Nov 2004 22:12:15 -0000 @@ -80,6 +80,7 @@ struct regset; #define X_OP2(i) (((i) >> 22) & 0x7) #define X_IMM22(i) ((i) & 0x3fffff) #define X_OP3(i) (((i) >> 19) & 0x3f) +#define X_RS1(i) (((i) >> 14) & 0x1f) #define X_I(i) (((i) >> 13) & 1) /* Sign extension macros. */ #define X_DISP22(i) ((X_IMM22 (i) ^ 0x200000) - 0x200000) @@ -575,7 +576,59 @@ sparc_analyze_prologue (CORE_ADDR pc, CO if (X_OP (insn) == 2 && X_OP3 (insn) == 0x3c) { cache->frameless_p = 0; - return pc + offset + 4; + offset += 4; + + insn = sparc_fetch_instruction (pc + offset); + + while (1) + { + /* Recognize stores into the frame from the input registers. + This recognizes all non alternate stores of an input register, + into a location offset from the frame pointer between + +68 and +92. */ + + /* The above will fail for arguments that are promoted + (eg. shorts to ints or floats to doubles), because the compiler + will pass them in positive-offset frame space, but the prologue + will save them (after conversion) in negative frame space at an + unpredictable offset. Therefore I am going to remove the + restriction on the target-address of the save, on the theory + that any unbroken sequence of saves from input registers must + be part of the prologue. In un-optimized code (at least), I'm + fairly sure that the compiler would emit SOME other instruction + (eg. a move or add) before emitting another save that is actually + a part of the function body. + + Besides, the reserved stack space is different for SPARC64 anyway. + + MVS 4/23/2000 */ + + if (X_OP (insn) == 3 + && (X_OP3 (insn) & 0x3c) == 4 /* Store, non-alternate. */ + && (X_RD (insn) & 0x18) == 0x18 /* Input register. */ + && X_I (insn) /* Immediate mode. */ + && X_RS1 (insn) == 30) /* Off of frame pointer. */ + ; /* empty statement -- fall thru to end of loop */ + else if ((gdbarch_ptr_bit (current_gdbarch) == 64) + && X_OP (insn) == 3 + && (X_OP3 (insn) & 0x3c) == 12 /* store, extended (64-bit) */ + && (X_RD (insn) & 0x18) == 0x18 /* input register */ + && X_I (insn) /* immediate mode */ + && X_RS1 (insn) == 30) /* off of frame pointer */ + ; /* empty statement -- fall thru to end of loop */ + else if (X_OP (insn) == 3 + && (X_OP3 (insn) & 0x3c) == 36 /* store, floating-point */ + && X_I (insn) /* immediate mode */ + && X_RS1 (insn) == 30) /* off of frame pointer */ + ; /* empty statement -- fall thru to end of loop */ + else + break; + + offset += 4; + insn = sparc_fetch_instruction (pc + offset); + } + + return pc + offset; } return pc;