linux.h revision 122180
1/* Definitions of target machine for GNU compiler, 2 for PowerPC machines running Linux. 3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 4 Free Software Foundation, Inc. 5 Contributed by Michael Meissner (meissner@cygnus.com). 6 7This file is part of GNU CC. 8 9GNU CC is free software; you can redistribute it and/or modify 10it under the terms of the GNU General Public License as published by 11the Free Software Foundation; either version 2, or (at your option) 12any later version. 13 14GNU CC is distributed in the hope that it will be useful, 15but WITHOUT ANY WARRANTY; without even the implied warranty of 16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17GNU General Public License for more details. 18 19You should have received a copy of the GNU General Public License 20along with GNU CC; see the file COPYING. If not, write to 21the Free Software Foundation, 59 Temple Place - Suite 330, 22Boston, MA 02111-1307, USA. */ 23 24#undef MD_EXEC_PREFIX 25#undef MD_STARTFILE_PREFIX 26 27#undef TARGET_OS_CPP_BUILTINS 28#define TARGET_OS_CPP_BUILTINS() \ 29 do \ 30 { \ 31 builtin_define_std ("PPC"); \ 32 builtin_define ("__ELF__"); \ 33 builtin_define_std ("powerpc"); \ 34 builtin_assert ("cpu=powerpc"); \ 35 builtin_assert ("machine=powerpc"); \ 36 } \ 37 while (0) 38 39#undef CPP_OS_DEFAULT_SPEC 40#define CPP_OS_DEFAULT_SPEC "%(cpp_os_linux)" 41 42/* The GNU C++ standard library currently requires _GNU_SOURCE being 43 defined on glibc-based systems. This temporary hack accomplishes this, 44 it should go away as soon as libstdc++-v3 has a real fix. */ 45#undef CPLUSPLUS_CPP_SPEC 46#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)" 47 48#undef LINK_SHLIB_SPEC 49#define LINK_SHLIB_SPEC "%{shared:-shared} %{!shared: %{static:-static}}" 50 51#define LINK_GCC_C_SEQUENCE_SPEC \ 52 "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}" 53 54#undef LIB_DEFAULT_SPEC 55#define LIB_DEFAULT_SPEC "%(lib_linux)" 56 57#undef STARTFILE_DEFAULT_SPEC 58#define STARTFILE_DEFAULT_SPEC "%(startfile_linux)" 59 60#undef ENDFILE_DEFAULT_SPEC 61#define ENDFILE_DEFAULT_SPEC "%(endfile_linux)" 62 63#undef LINK_START_DEFAULT_SPEC 64#define LINK_START_DEFAULT_SPEC "%(link_start_linux)" 65 66#undef LINK_OS_DEFAULT_SPEC 67#define LINK_OS_DEFAULT_SPEC "%(link_os_linux)" 68 69#undef TARGET_VERSION 70#define TARGET_VERSION fprintf (stderr, " (PowerPC GNU/Linux)"); 71 72/* Override rs6000.h definition. */ 73#undef ASM_APP_ON 74#define ASM_APP_ON "#APP\n" 75 76/* Override rs6000.h definition. */ 77#undef ASM_APP_OFF 78#define ASM_APP_OFF "#NO_APP\n" 79 80/* For backward compatibility, we must continue to use the AIX 81 structure return convention. */ 82#undef DRAFT_V4_STRUCT_RET 83#define DRAFT_V4_STRUCT_RET 1 84 85/* Do code reading to identify a signal frame, and set the frame 86 state data appropriately. See unwind-dw2.c for the structs. */ 87 88#ifdef IN_LIBGCC2 89#include <signal.h> 90 91/* During the 2.5 kernel series the kernel ucontext was changed, but 92 the new layout is compatible with the old one, so we just define 93 and use the old one here for simplicity and compatibility. */ 94 95struct kernel_old_ucontext { 96 unsigned long uc_flags; 97 struct ucontext *uc_link; 98 stack_t uc_stack; 99 struct sigcontext_struct uc_mcontext; 100 sigset_t uc_sigmask; 101}; 102 103enum { SIGNAL_FRAMESIZE = 64 }; 104#endif 105 106#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \ 107 do { \ 108 unsigned char *pc_ = (CONTEXT)->ra; \ 109 struct sigcontext *sc_; \ 110 long new_cfa_; \ 111 int i_; \ 112 \ 113 /* li r0, 0x7777; sc (sigreturn old) */ \ 114 /* li r0, 0x0077; sc (sigreturn new) */ \ 115 /* li r0, 0x6666; sc (rt_sigreturn old) */ \ 116 /* li r0, 0x00AC; sc (rt_sigreturn new) */ \ 117 if (*(unsigned int *) (pc_+4) != 0x44000002) \ 118 break; \ 119 if (*(unsigned int *) (pc_+0) == 0x38007777 \ 120 || *(unsigned int *) (pc_+0) == 0x38000077) \ 121 { \ 122 struct sigframe { \ 123 char gap[SIGNAL_FRAMESIZE]; \ 124 struct sigcontext sigctx; \ 125 } *rt_ = (CONTEXT)->cfa; \ 126 sc_ = &rt_->sigctx; \ 127 } \ 128 else if (*(unsigned int *) (pc_+0) == 0x38006666 \ 129 || *(unsigned int *) (pc_+0) == 0x380000AC) \ 130 { \ 131 struct rt_sigframe { \ 132 char gap[SIGNAL_FRAMESIZE]; \ 133 unsigned long _unused[2]; \ 134 struct siginfo *pinfo; \ 135 void *puc; \ 136 struct siginfo info; \ 137 struct kernel_old_ucontext uc; \ 138 } *rt_ = (CONTEXT)->cfa; \ 139 sc_ = &rt_->uc.uc_mcontext; \ 140 } \ 141 else \ 142 break; \ 143 \ 144 new_cfa_ = sc_->regs->gpr[STACK_POINTER_REGNUM]; \ 145 (FS)->cfa_how = CFA_REG_OFFSET; \ 146 (FS)->cfa_reg = STACK_POINTER_REGNUM; \ 147 (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \ 148 \ 149 for (i_ = 0; i_ < 32; i_++) \ 150 if (i_ != STACK_POINTER_REGNUM) \ 151 { \ 152 (FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \ 153 (FS)->regs.reg[i_].loc.offset \ 154 = (long)&(sc_->regs->gpr[i_]) - new_cfa_; \ 155 } \ 156 \ 157 (FS)->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET; \ 158 (FS)->regs.reg[LINK_REGISTER_REGNUM].loc.offset \ 159 = (long)&(sc_->regs->link) - new_cfa_; \ 160 \ 161 (FS)->regs.reg[CR0_REGNO].how = REG_SAVED_OFFSET; \ 162 (FS)->regs.reg[CR0_REGNO].loc.offset \ 163 = (long)&(sc_->regs->nip) - new_cfa_; \ 164 (FS)->retaddr_column = CR0_REGNO; \ 165 goto SUCCESS; \ 166 } while (0) 167 168