+ sparc_record_save_insn (cache);
+ offset += 4;
+ return pc + offset;
+ }
+
+ /* Check for an arithmetic operation on %sp. */
+ if (X_OP (insn) == 2
+ && (X_OP3 (insn) == 0 || X_OP3 (insn) == 0x4)
+ && X_RS1 (insn) == SPARC_SP_REGNUM
+ && X_RD (insn) == SPARC_SP_REGNUM)
+ {
+ if (X_I (insn))
+ {
+ cache->frame_offset = X_SIMM13 (insn);
+ if (X_OP3 (insn) == 0)
+ cache->frame_offset = -cache->frame_offset;
+ }
+ offset += 4;
+
+ insn = sparc_fetch_instruction (pc + offset);
+
+ /* Check for an arithmetic operation that sets up the frame. */
+ if (X_OP (insn) == 2
+ && (X_OP3 (insn) == 0 || X_OP3 (insn) == 0x4)
+ && X_RS1 (insn) == SPARC_SP_REGNUM
+ && X_RD (insn) == SPARC_FP_REGNUM)
+ {
+ cache->frameless_p = 0;
+ cache->frame_offset = 0;
+ /* We could check that the amount subtracted to %sp above is the
+ same as the one added here, but this seems superfluous. */
+ cache->copied_regs_mask |= 0x40;
+ offset += 4;
+
+ insn = sparc_fetch_instruction (pc + offset);
+ }
+
+ /* Check for a move (or) operation that copies the return register. */
+ if (X_OP (insn) == 2
+ && X_OP3 (insn) == 0x2
+ && !X_I (insn)
+ && X_RS1 (insn) == SPARC_G0_REGNUM
+ && X_RS2 (insn) == SPARC_O7_REGNUM
+ && X_RD (insn) == SPARC_I7_REGNUM)
+ {
+ cache->copied_regs_mask |= 0x80;
+ offset += 4;
+ }
+
+ return pc + offset;