174 lines
5.0 KiB
C
174 lines
5.0 KiB
C
/* Definitions for Linux for S/390.
|
|
Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
|
Contributed by Hartmut Penner (hpenner@de.ibm.com) and
|
|
Ulrich Weigand (uweigand@de.ibm.com).
|
|
|
|
This file is part of GCC.
|
|
|
|
GCC is free software; you can redistribute it and/or modify it under
|
|
the terms of the GNU General Public License as published by the Free
|
|
Software Foundation; either version 2, or (at your option) any later
|
|
version.
|
|
|
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with GCC; see the file COPYING. If not, write to the Free
|
|
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|
02111-1307, USA. */
|
|
|
|
#ifndef _LINUX_H
|
|
#define _LINUX_H
|
|
|
|
/* Target specific version string. */
|
|
|
|
#ifdef DEFAULT_TARGET_64BIT
|
|
#undef TARGET_VERSION
|
|
#define TARGET_VERSION fprintf (stderr, " (Linux for zSeries)");
|
|
#else
|
|
#undef TARGET_VERSION
|
|
#define TARGET_VERSION fprintf (stderr, " (Linux for S/390)");
|
|
#endif
|
|
|
|
|
|
/* Target specific type definitions. */
|
|
|
|
/* ??? Do we really want long as size_t on 31-bit? */
|
|
#undef SIZE_TYPE
|
|
#define SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "long unsigned int")
|
|
#undef PTRDIFF_TYPE
|
|
#define PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int")
|
|
|
|
#undef WCHAR_TYPE
|
|
#define WCHAR_TYPE "int"
|
|
#undef WCHAR_TYPE_SIZE
|
|
#define WCHAR_TYPE_SIZE 32
|
|
|
|
|
|
/* Target specific preprocessor settings. */
|
|
|
|
#define TARGET_OS_CPP_BUILTINS() \
|
|
do \
|
|
{ \
|
|
LINUX_TARGET_OS_CPP_BUILTINS(); \
|
|
if (flag_pic) \
|
|
{ \
|
|
builtin_define ("__PIC__"); \
|
|
builtin_define ("__pic__"); \
|
|
} \
|
|
} \
|
|
while (0)
|
|
|
|
|
|
/* Target specific assembler settings. */
|
|
|
|
#undef ASM_SPEC
|
|
#define ASM_SPEC "%{m31&m64}%{mesa&mzarch}%{march=*}"
|
|
|
|
|
|
/* Target specific linker settings. */
|
|
|
|
#ifdef DEFAULT_TARGET_64BIT
|
|
#define MULTILIB_DEFAULTS { "m64" }
|
|
#else
|
|
#define MULTILIB_DEFAULTS { "m31" }
|
|
#endif
|
|
|
|
#undef LINK_SPEC
|
|
#define LINK_SPEC \
|
|
"%{m31:-m elf_s390}%{m64:-m elf64_s390} \
|
|
%{shared:-shared} \
|
|
%{!shared: \
|
|
%{static:-static} \
|
|
%{!static: \
|
|
%{rdynamic:-export-dynamic} \
|
|
%{!dynamic-linker: \
|
|
%{m31:-dynamic-linker /lib/ld.so.1} \
|
|
%{m64:-dynamic-linker /lib/ld64.so.1}}}}"
|
|
|
|
|
|
#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
|
|
|
|
/* 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)®s_->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)®s_->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)®s_->psw_addr - new_cfa_; \
|
|
(FS)->retaddr_column = 32; \
|
|
\
|
|
goto SUCCESS; \
|
|
} while (0)
|
|
|
|
#endif
|