aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Weigand <uweigand@de.ibm.com>2002-05-29 13:45:45 +0000
committerUlrich Weigand <uweigand@gcc.gnu.org>2002-05-29 13:45:45 +0000
commitabd6ddecb5724117c0ea2108a5cd42ab405ab288 (patch)
tree09e37972de4dabcaa3497b63004bcce501519d54
parentda06d85a2ba1ea0484730e25975667ed452a2077 (diff)
downloadgcc-abd6ddecb5724117c0ea2108a5cd42ab405ab288.zip
gcc-abd6ddecb5724117c0ea2108a5cd42ab405ab288.tar.gz
gcc-abd6ddecb5724117c0ea2108a5cd42ab405ab288.tar.bz2
* config/s390/linux.h (MD_FALLBACK_FRAME_STATE_FOR): New.
From-SVN: r53993
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/config/s390/linux.h78
2 files changed, 82 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d3dc945..df4027f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,9 @@
2002-05-29 Ulrich Weigand <uweigand@de.ibm.com>
+ * config/s390/linux.h (MD_FALLBACK_FRAME_STATE_FOR): New.
+
+2002-05-29 Ulrich Weigand <uweigand@de.ibm.com>
+
* config/s390/s390.c (legitimate_pic_operand_p): Do not
accept symbolic LARL operands.
(s390_emit_epilogue): Do not set FRAME_RELATED_P on
diff --git a/gcc/config/s390/linux.h b/gcc/config/s390/linux.h
index 7747e3c..f49e8b5 100644
--- a/gcc/config/s390/linux.h
+++ b/gcc/config/s390/linux.h
@@ -288,4 +288,82 @@ do { \
} \
} while (0)
+/* Do code reading to identify a signal frame, and set the frame
+ state data appropriately. See unwind-dw2.c for the structs. */
+
+#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
+ do { \
+ unsigned char *pc_ = (CONTEXT)->ra; \
+ long new_cfa_; \
+ int i_; \
+ \
+ typedef struct \
+ { \
+ unsigned long psw_mask; \
+ unsigned long psw_addr; \
+ unsigned long gprs[16]; \
+ unsigned int acrs[16]; \
+ unsigned int fpc; \
+ unsigned int __pad; \
+ double fprs[16]; \
+ } __attribute__ ((__aligned__ (8))) sigregs_; \
+ \
+ sigregs_ *regs_; \
+ \
+ /* svc $__NR_sigreturn or svc $__NR_rt_sigreturn */ \
+ if (pc_[0] != 0x0a || (pc_[1] != 119 && pc_[1] != 173)) \
+ break; \
+ \
+ /* New-style RT frame: \
+ retcode + alignment (8 bytes) \
+ siginfo (128 bytes) \
+ ucontext (contains sigregs) */ \
+ if ((CONTEXT)->ra == (CONTEXT)->cfa) \
+ { \
+ struct ucontext_ \
+ { \
+ unsigned long uc_flags; \
+ struct ucontext_ *uc_link; \
+ unsigned long uc_stack[3]; \
+ sigregs_ uc_mcontext; \
+ } *uc_ = (CONTEXT)->cfa + 8 + 128; \
+ \
+ regs_ = &uc_->uc_mcontext; \
+ } \
+ \
+ /* Old-style RT frame and all non-RT frames: \
+ old signal mask (8 bytes) \
+ pointer to sigregs */ \
+ else \
+ { \
+ regs_ = *(sigregs_ **)((CONTEXT)->cfa + 8); \
+ } \
+ \
+ new_cfa_ = regs_->gprs[15] + 16*sizeof(long) + 32; \
+ (FS)->cfa_how = CFA_REG_OFFSET; \
+ (FS)->cfa_reg = 15; \
+ (FS)->cfa_offset = \
+ new_cfa_ - (long) (CONTEXT)->cfa + 16*sizeof(long) + 32; \
+ \
+ for (i_ = 0; i_ < 16; i_++) \
+ { \
+ (FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[i_].loc.offset = \
+ (long)&regs_->gprs[i_] - new_cfa_; \
+ } \
+ for (i_ = 0; i_ < 16; i_++) \
+ { \
+ (FS)->regs.reg[16+i_].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[16+i_].loc.offset = \
+ (long)&regs_->fprs[i_] - new_cfa_; \
+ } \
+ \
+ /* Load return addr from PSW into dummy register 32. */ \
+ (FS)->regs.reg[32].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[32].loc.offset = (long)&regs_->psw_addr - new_cfa_; \
+ (FS)->retaddr_column = 32; \
+ \
+ goto SUCCESS; \
+ } while (0)
+
#endif