2002-12-04 15:42:16 +00:00
|
|
|
/* 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 GNU CC.
|
|
|
|
|
|
|
|
GNU CC 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.
|
|
|
|
|
|
|
|
GNU CC 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 GNU CC; 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. */
|
|
|
|
|
2003-07-11 03:40:53 +00:00
|
|
|
#define TARGET_OS_CPP_BUILTINS() \
|
|
|
|
do \
|
|
|
|
{ \
|
|
|
|
builtin_define_std ("linux"); \
|
|
|
|
builtin_define_std ("unix"); \
|
|
|
|
builtin_assert ("system=linux"); \
|
|
|
|
builtin_assert ("system=unix"); \
|
|
|
|
builtin_define ("__ELF__"); \
|
|
|
|
builtin_define ("__gnu_linux__"); \
|
|
|
|
if (flag_pic) \
|
|
|
|
{ \
|
|
|
|
builtin_define ("__PIC__"); \
|
|
|
|
builtin_define ("__pic__"); \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
while (0)
|
2002-12-04 15:42:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* Target specific assembler settings. */
|
|
|
|
|
|
|
|
#ifdef DEFAULT_TARGET_64BIT
|
|
|
|
#undef ASM_SPEC
|
|
|
|
#define ASM_SPEC "%{m31:-m31 -Aesa}"
|
|
|
|
#else
|
|
|
|
#undef ASM_SPEC
|
|
|
|
#define ASM_SPEC "%{m64:-m64 -Aesame}"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/* Target specific linker settings. */
|
|
|
|
|
2003-07-11 03:40:53 +00:00
|
|
|
#ifdef DEFAULT_TARGET_64BIT
|
|
|
|
#define MULTILIB_DEFAULTS { "m64" }
|
|
|
|
#else
|
|
|
|
#define MULTILIB_DEFAULTS { "m31" }
|
|
|
|
#endif
|
|
|
|
|
2002-12-04 15:42:16 +00:00
|
|
|
#define LINK_ARCH31_SPEC \
|
|
|
|
"-m elf_s390 \
|
|
|
|
%{shared:-shared} \
|
|
|
|
%{!shared: \
|
|
|
|
%{static:-static} \
|
|
|
|
%{!static: \
|
|
|
|
%{rdynamic:-export-dynamic} \
|
|
|
|
%{!dynamic-linker:-dynamic-linker /lib/ld.so.1}}}"
|
|
|
|
|
|
|
|
#define LINK_ARCH64_SPEC \
|
|
|
|
"-m elf64_s390 \
|
|
|
|
%{shared:-shared} \
|
|
|
|
%{!shared: \
|
|
|
|
%{static:-static} \
|
|
|
|
%{!static: \
|
|
|
|
%{rdynamic:-export-dynamic} \
|
|
|
|
%{!dynamic-linker:-dynamic-linker /lib/ld64.so.1}}}"
|
|
|
|
|
|
|
|
#ifdef DEFAULT_TARGET_64BIT
|
|
|
|
#undef LINK_SPEC
|
|
|
|
#define LINK_SPEC "%{m31:%(link_arch31)} %{!m31:%(link_arch64)}"
|
|
|
|
#else
|
|
|
|
#undef LINK_SPEC
|
|
|
|
#define LINK_SPEC "%{m64:%(link_arch64)} %{!m64:%(link_arch31)}"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/* This macro defines names of additional specifications to put in the specs
|
|
|
|
that can be used in various specifications like CC1_SPEC. Its definition
|
|
|
|
is an initializer with a subgrouping for each command option. */
|
|
|
|
|
|
|
|
#define EXTRA_SPECS \
|
|
|
|
{ "link_arch31", LINK_ARCH31_SPEC }, \
|
|
|
|
{ "link_arch64", LINK_ARCH64_SPEC }, \
|
|
|
|
|
|
|
|
|
2003-07-11 03:40:53 +00:00
|
|
|
/* 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)
|
2002-12-04 15:42:16 +00:00
|
|
|
|
|
|
|
#endif
|