Add Darwin (Mac OS X kernel) native support.

* config.gcc (powerpc-*-darwin*): Add native bits.
        * config/darwin.c: New file, generic Darwin support functions.
        * config/darwin.h: New file, generic Darwin definitions.
        * config/darwin-protos.h: New file, generic Darwin prototypes.
        * rs6000/darwin.h: New file, Darwin for PowerPC.
        * rs6000/t-darwin: New file, Darwin makefile fragment.
        * rs6000/rs6000.h (OBJECT_MACHO): New macro.
        (TARGET_MACHO): Ditto.
        (rs6000_abi): Add ABI_DARWIN.
        (RS6000_REG_SAVE): Add ABI_DARWIN case.
        (RS6000_SAVE_AREA): Ditto.
        (FP_ARG_MAX_REG): Ditto.
        (RETURN_ADDRESS_OFFSET): Ditto.
        * rs6000/rs6000.c (rs6000_legitimize_address): Add TARGET_MACHO
        cases.
        (rs6000_emit_move): Add ABI_DARWIN cases.
        (print_operand): Ditto.
        (first_reg_to_save): Ditto.
        (rs6000_stack_info): Ditto, also align stack by 16 instead of 8.
        (debug_stack_info): Ditto.
        (rs6000_emit_prologue): Ditto.
        (rs6000_emit_epilogue): Ditto.
        (output_profiler_hook): Ditto.
        (output_function_profiler): Ditto.
        (rs6000_add_gc_roots): Call machopic_add_gc_roots if TARGET_MACHO.
        (output_mi_thunk): Add TARGET_MACHO case.
        (add_compiler_stub): Ditto.
        (output_compiler_stub): Ditto.
        (no_previous_def): Ditto.
        (output_call): Ditto.
        (machopic_output_stub): Ditto.
        (rs6000_machopic_legitimize_pic_address): Ditto.
        (toc_section): Ditto.
        * rs6000/rs6000.md (addsi3_high): New TARGET_MACHO pattern.
        (macho_high): Ditto.
        (macho_low): Ditto.
        (movsi_low): Ditto.
        (load_macho_picbase): Ditto.
        (call): Add TARGET_MACHO case to modify function.
        (call_value): Ditto.
        (call_nonlocal_sysv): Add ABI_DARWIN case.
        (call_value_nonlocal_sysv): Ditto.
        * rs6000/rs6000-protos.h (rs6000_machopic_legitimize_pic_address):
        Add prototype.
        (machopic_output_stub): Ditto.
        * ginclude/stddef.h: Test _BSD_WCHAR_T_DEFINED_.

From-SVN: r41277
This commit is contained in:
Stan Shebs 2001-04-12 02:13:00 +00:00 committed by Stan Shebs
parent 5101b30466
commit ee890fe2a1
12 changed files with 2606 additions and 16 deletions

View file

@ -1,3 +1,53 @@
2001-04-11 Stan Shebs <shebs@apple.com>
Add Darwin (Mac OS X kernel) native support.
* config.gcc (powerpc-*-darwin*): Add native bits.
* config/darwin.c: New file, generic Darwin support functions.
* config/darwin.h: New file, generic Darwin definitions.
* config/darwin-protos.h: New file, generic Darwin prototypes.
* rs6000/darwin.h: New file, Darwin for PowerPC.
* rs6000/t-darwin: New file, Darwin makefile fragment.
* rs6000/rs6000.h (OBJECT_MACHO): New macro.
(TARGET_MACHO): Ditto.
(rs6000_abi): Add ABI_DARWIN.
(RS6000_REG_SAVE): Add ABI_DARWIN case.
(RS6000_SAVE_AREA): Ditto.
(FP_ARG_MAX_REG): Ditto.
(RETURN_ADDRESS_OFFSET): Ditto.
* rs6000/rs6000.c (rs6000_legitimize_address): Add TARGET_MACHO
cases.
(rs6000_emit_move): Add ABI_DARWIN cases.
(print_operand): Ditto.
(first_reg_to_save): Ditto.
(rs6000_stack_info): Ditto, also align stack by 16 instead of 8.
(debug_stack_info): Ditto.
(rs6000_emit_prologue): Ditto.
(rs6000_emit_epilogue): Ditto.
(output_profiler_hook): Ditto.
(output_function_profiler): Ditto.
(rs6000_add_gc_roots): Call machopic_add_gc_roots if TARGET_MACHO.
(output_mi_thunk): Add TARGET_MACHO case.
(add_compiler_stub): Ditto.
(output_compiler_stub): Ditto.
(no_previous_def): Ditto.
(output_call): Ditto.
(machopic_output_stub): Ditto.
(rs6000_machopic_legitimize_pic_address): Ditto.
(toc_section): Ditto.
* rs6000/rs6000.md (addsi3_high): New TARGET_MACHO pattern.
(macho_high): Ditto.
(macho_low): Ditto.
(movsi_low): Ditto.
(load_macho_picbase): Ditto.
(call): Add TARGET_MACHO case to modify function.
(call_value): Ditto.
(call_nonlocal_sysv): Add ABI_DARWIN case.
(call_value_nonlocal_sysv): Ditto.
* rs6000/rs6000-protos.h (rs6000_machopic_legitimize_pic_address):
Add prototype.
(machopic_output_stub): Ditto.
* ginclude/stddef.h: Test _BSD_WCHAR_T_DEFINED_.
2001-04-11 Mark Mitchell <mark@codesourcery.com>
* dwarf2out.c (modified_type_die): Don't create new types here.

View file

@ -2647,8 +2647,15 @@ powerpc-*-beos*)
tmake_file=rs6000/t-beos
;;
powerpc-*-darwin*)
cpu_type=rs6000
tm_file="${tm_file} darwin.h rs6000/darwin.h"
tm_p_file="${tm_p_file} darwin-protos.h"
tmake_file=rs6000/t-darwin
xm_file=rs6000/xm-darwin.h
xmake_file=rs6000/x-darwin
extra_objs="darwin.o"
# Darwin linker does collect2 functionality
use_collect2=no
;;
powerpc-*-sysv*)
tm_file="${tm_file} svr4.h rs6000/sysv4.h"

View file

@ -0,0 +1,57 @@
/* Prototypes.
Copyright (C) 2001 Free Software Foundation, Inc.
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. */
extern int name_needs_quotes PARAMS ((const char *));
extern void machopic_validate_stub_or_non_lazy_ptr PARAMS ((const char *, int));
extern char *machopic_function_base_name PARAMS ((void));
extern char *machopic_non_lazy_ptr_name PARAMS ((const char*));
extern char *machopic_stub_name PARAMS ((const char*));
extern void machopic_add_gc_roots PARAMS ((void));
extern void machopic_picsymbol_stub_section PARAMS ((void));
extern void machopic_symbol_stub_section PARAMS ((void));
extern void machopic_lazy_symbol_ptr_section PARAMS ((void));
extern void machopic_nl_symbol_ptr_section PARAMS ((void));
#ifdef RTX_CODE
extern int machopic_operand_p PARAMS ((rtx));
extern enum machopic_addr_class machopic_classify_name PARAMS ((const char*));
extern rtx machopic_indirect_data_reference PARAMS ((rtx, rtx));
extern rtx machopic_indirect_call_target PARAMS ((rtx));
extern rtx machopic_legitimize_pic_address PARAMS ((rtx, enum machine_mode, rtx));
#endif /* RTX_CODE */
#ifdef TREE_CODE
extern enum machopic_addr_class machopic_classify_ident PARAMS ((tree));
extern void machopic_define_ident PARAMS ((tree));
extern void machopic_define_name PARAMS ((const char*));
extern int machopic_name_defined_p PARAMS ((const char*));
extern int machopic_ident_defined_p PARAMS ((tree));
#endif /* TREE_CODE */
extern void machopic_finish PARAMS ((FILE *));

1002
gcc/config/darwin.c Normal file

File diff suppressed because it is too large Load diff

763
gcc/config/darwin.h Normal file
View file

@ -0,0 +1,763 @@
/* Target definitions for Darwin (Mac OS X) systems.
Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001
Free Software Foundation, Inc.
Contributed by Apple Computer Inc.
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. */
/* The definitions in this file are common to all processor types
running Darwin, which is the kernel for Mac OS X. Darwin is
basically a BSD user layer laid over a Mach kernel, then evolved
for many years (at NeXT) in parallel with other Unix systems. So
while the runtime is a somewhat idiosyncratic Mach-based thing,
other definitions look like they would for a BSD variant. */
/* Although NeXT ran on many different architectures, as of Jan 2001
the only supported Darwin targets are PowerPC and x86. */
/* Make the compiler look here for standard stuff. */
#undef STANDARD_EXEC_PREFIX
#define STANDARD_EXEC_PREFIX "/usr/libexec/"
/* Name of the command that invokes the compiler - used in g++.c. */
#undef GCC_NAME
#define GCC_NAME "cc"
/* Never try linking with -lm - used in g++.c. */
#define NO_MATH_LIBRARY
/* We have atexit. */
#define HAVE_ATEXIT
/* Define an empty body for the function do_global_dtors() in libgcc2.c. */
#define DO_GLOBAL_DTORS_BODY
/* The string value for __SIZE_TYPE__. */
#ifndef SIZE_TYPE
#define SIZE_TYPE "long unsigned int"
#endif
/* Type used for ptrdiff_t, as a string used in a declaration. */
#undef PTRDIFF_TYPE
#define PTRDIFF_TYPE "int"
/* wchar_t is int. */
#undef WCHAR_TYPE
#define WCHAR_TYPE "int"
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 32
/* Don't default to pcc-struct-return, because gcc is the only compiler, and
we want to retain compatibility with older gcc versions. */
#undef DEFAULT_PCC_STRUCT_RETURN
#define DEFAULT_PCC_STRUCT_RETURN 0
/* Don't warn about MacOS-style 'APPL' four-char-constants. */
#undef WARN_FOUR_CHAR_CONSTANTS
#define WARN_FOUR_CHAR_CONSTANTS 0
/* Machine dependent cpp options. */
/* The sequence here allows us to get a more specific version number
glued into __APPLE_CC__. Normally this number would be updated as
part of submitting to a release engineering organization. */
#ifndef APPLE_CC
#define APPLE_CC 999
#endif
#define STRINGIFY_THIS(x) # x
#define REALLY_STRINGIFY(x) STRINGIFY_THIS(x)
#undef CPP_SPEC
#define CPP_SPEC "-D__APPLE_CC__=" REALLY_STRINGIFY(APPLE_CC) " \
%{static:-D__STATIC__}%{!static:-D__DYNAMIC__}"
/* Machine dependent libraries. */
#undef LIB_SPEC
#define LIB_SPEC \
"%{!static:%{!pg:-framework System}%{pg:-framework System,_profile}}"
#undef LIBGCC_SPEC
#define LIBGCC_SPEC "%{!shared:%{static:-lcc} \
%{!static:-lcc_dynamic}}"
/* We specify crt0.o as -lcrt0.o so that ld will search the library path. */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC \
"%{pg:%{static:-lgcrt0.o}%{!static:-lgcrt1.o}} \
%{!pg:%{static:-lcrt0.o}%{!static:-lcrt1.o}}"
#undef DOLLARS_IN_IDENTIFIERS
#define DOLLARS_IN_IDENTIFIERS 2
/* Allow #sccs (but don't do anything). */
#define SCCS_DIRECTIVE
/* We use Dbx symbol format. */
#define DBX_DEBUGGING_INFO
/* When generating stabs debugging, use N_BINCL entries. */
#define DBX_USE_BINCL
/* There is no limit to the length of stabs strings. */
#define DBX_CONTIN_LENGTH 0
/* gdb needs a null N_SO at the end of each file for scattered loading. */
#undef DBX_OUTPUT_MAIN_SOURCE_FILE_END
#define DBX_OUTPUT_MAIN_SOURCE_FILE_END(FILE, FILENAME) \
do { text_section (); \
fprintf (FILE, \
"\t.stabs \"%s\",%d,0,0,Letext\nLetext:\n", "" , N_SO); \
} while (0)
/* Our profiling scheme doesn't LP labels and counter words. */
#define NO_PROFILE_COUNTERS
/* Don't use .gcc_compiled symbols to communicate with GDB;
They interfere with numerically sorted symbol lists. */
#undef ASM_IDENTIFY_GCC
#define ASM_IDENTIFY_GCC(asm_out_file)
#undef INIT_SECTION_ASM_OP
#define INIT_SECTION_ASM_OP
#undef INVOKE__main
#undef ASM_OUTPUT_CONSTRUCTOR
#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \
do { if (flag_pic) \
mod_init_section (); \
else \
constructor_section (); \
ASM_OUTPUT_ALIGN (FILE, 1); \
fprintf (FILE, "\t.long "); \
assemble_name (FILE, NAME); \
fprintf (FILE, "\n"); \
if (!flag_pic) \
fprintf (FILE, ".reference .constructors_used\n"); \
} while (0)
#undef ASM_OUTPUT_DESTRUCTOR
#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \
do { if (flag_pic) \
mod_term_section (); \
else \
destructor_section (); \
ASM_OUTPUT_ALIGN (FILE, 1); \
fprintf (FILE, "\t.long "); \
assemble_name (FILE, NAME); \
fprintf (FILE, "\n"); \
if (!flag_pic) \
fprintf (FILE, ".reference .destructors_used\n"); \
} while (0)
/* Don't output a .file directive. That is only used by the assembler for
error reporting. */
#undef ASM_FILE_START
#define ASM_FILE_START(FILE)
#undef ASM_FILE_END
#define ASM_FILE_END(FILE) \
do { \
extern const char *language_string; \
machopic_finish (asm_out_file); \
if (strcmp (language_string, "GNU C++") == 0) \
{ \
constructor_section (); \
destructor_section (); \
ASM_OUTPUT_ALIGN (FILE, 1); \
} \
} while (0)
/* Give ObjcC methods pretty symbol names. */
#undef OBJC_GEN_METHOD_LABEL
#define OBJC_GEN_METHOD_LABEL(BUF,IS_INST,CLASS_NAME,CAT_NAME,SEL_NAME,NUM) \
do { if (CAT_NAME) \
sprintf (BUF, "%c[%s(%s) %s]", (IS_INST) ? '-' : '+', \
(CLASS_NAME), (CAT_NAME), (SEL_NAME)); \
else \
sprintf (BUF, "%c[%s %s]", (IS_INST) ? '-' : '+', \
(CLASS_NAME), (SEL_NAME)); \
} while (0)
/* The RTTI data (e.g., __ti4name) is common and public (and static),
but it does need to be referenced via indirect PIC data pointers.
The machopic_define_name calls are telling the machopic subsystem
that the name *is* defined in this module, so it doesn't need to
make them indirect. */
#undef ASM_DECLARE_OBJECT_NAME
#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \
do { \
char *xname = NAME; \
if (GET_CODE (XEXP (DECL_RTL (DECL), 0)) != SYMBOL_REF) \
xname = IDENTIFIER_POINTER (DECL_NAME (DECL)); \
if ((TREE_STATIC (DECL) \
&& (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) \
|| DECL_INITIAL (DECL)) \
machopic_define_name (xname); \
ASM_OUTPUT_LABEL (FILE, xname); \
} while (0)
/* Wrap new method names in quotes so the assembler doesn't gag.
Make Objective-C internal symbols local. */
#undef ASM_OUTPUT_LABELREF
#define ASM_OUTPUT_LABELREF(FILE,NAME) \
do { \
if (NAME[0] == '&') \
{ \
int len = strlen (NAME); \
if (len > 6 && !strcmp ("$stub", NAME + len - 5)) \
machopic_validate_stub_or_non_lazy_ptr (NAME, 1); \
else if (len > 7 && !strcmp ("$stub\"", NAME + len - 6)) \
machopic_validate_stub_or_non_lazy_ptr (NAME, 1); \
else if (len > 14 && !strcmp ("$non_lazy_ptr", NAME + len - 13)) \
machopic_validate_stub_or_non_lazy_ptr (NAME, 0); \
fputs (&NAME[1], FILE); \
} \
else if (NAME[0] == '+' || NAME[0] == '-') \
fprintf (FILE, "\"%s\"", NAME); \
else if (!strncmp (NAME, "_OBJC_", 6)) \
fprintf (FILE, "L%s", NAME); \
else if (!strncmp (NAME, ".objc_class_name_", 17)) \
fprintf (FILE, "%s", NAME); \
else \
fprintf (FILE, "_%s", NAME); \
} while (0)
#undef ALIGN_ASM_OP
#define ALIGN_ASM_OP ".align"
#undef ASM_OUTPUT_ALIGN
#define ASM_OUTPUT_ALIGN(FILE,LOG) \
if ((LOG) != 0) \
fprintf (FILE, "\t%s %d\n", ALIGN_ASM_OP, (LOG))
/* Ensure correct alignment of bss data. */
#undef ASM_OUTPUT_ALIGNED_DECL_LOCAL
#define ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN) \
do { \
fputs (".lcomm ", (FILE)); \
assemble_name ((FILE), (NAME)); \
fprintf ((FILE), ",%u,%u\n", (SIZE), floor_log2 ((ALIGN) / BITS_PER_UNIT)); \
if ((DECL) && ((TREE_STATIC (DECL) \
&& (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) \
|| DECL_INITIAL (DECL))) \
machopic_define_name (NAME); \
} while (0)
/* Output nothing for #ident. */
#undef ASM_OUTPUT_IDENT
#define ASM_OUTPUT_IDENT(FILE, NAME)
/* The maximum alignment which the object file format can support.
For Mach-O, this is 2^15. */
#undef MAX_OFILE_ALIGNMENT
#define MAX_OFILE_ALIGNMENT 0x8000
/* Create new Mach-O sections. */
#undef SECTION_FUNCTION
#define SECTION_FUNCTION(FUNCTION, SECTION, DIRECTIVE, WAS_TEXT, OBJC) \
void \
FUNCTION () \
{ \
extern void text_section (); \
extern void objc_section_init (); \
extern int flag_no_mach_text_sections; \
\
if (WAS_TEXT && flag_no_mach_text_sections) \
text_section (); \
else if (in_section != SECTION) \
{ \
if (OBJC) \
objc_section_init (); \
data_section (); \
if (asm_out_file) \
fprintf (asm_out_file, "%s\n", DIRECTIVE); \
in_section = SECTION; \
} \
} \
#define ALIAS_SECTION(enum_value, alias_name) \
do { if (!strcmp (alias_name, name)) \
section_alias[enum_value] = (alias ? get_identifier (alias) : 0); \
} while (0)
/* Darwin uses many types of special sections. */
#undef EXTRA_SECTIONS
#define EXTRA_SECTIONS \
in_const, in_const_data, in_cstring, in_literal4, in_literal8, \
in_constructor, in_destructor, in_mod_init, in_mod_term, \
in_objc_class, in_objc_meta_class, in_objc_category, \
in_objc_class_vars, in_objc_instance_vars, \
in_objc_cls_meth, in_objc_inst_meth, \
in_objc_cat_cls_meth, in_objc_cat_inst_meth, \
in_objc_selector_refs, \
in_objc_selector_fixup, \
in_objc_symbols, in_objc_module_info, \
in_objc_protocol, in_objc_string_object, \
in_objc_constant_string_object, \
in_objc_class_names, in_objc_meth_var_names, \
in_objc_meth_var_types, in_objc_cls_refs, \
in_machopic_nl_symbol_ptr, \
in_machopic_lazy_symbol_ptr, \
in_machopic_symbol_stub, \
in_machopic_picsymbol_stub, \
num_sections
#undef EXTRA_SECTION_FUNCTIONS
#define EXTRA_SECTION_FUNCTIONS \
SECTION_FUNCTION (const_section, \
in_const, \
".const", 1, 0) \
SECTION_FUNCTION (const_data_section, \
in_const_data, \
".const_data", 1, 0) \
SECTION_FUNCTION (cstring_section, \
in_cstring, \
".cstring", 1, 0) \
SECTION_FUNCTION (literal4_section, \
in_literal4, \
".literal4", 1, 0) \
SECTION_FUNCTION (literal8_section, \
in_literal8, \
".literal8", 1, 0) \
SECTION_FUNCTION (constructor_section, \
in_constructor, \
".constructor", 0, 0) \
SECTION_FUNCTION (mod_init_section, \
in_mod_init, \
".mod_init_func", 0, 0) \
SECTION_FUNCTION (mod_term_section, \
in_mod_term, \
".mod_term_func", 0, 0) \
SECTION_FUNCTION (destructor_section, \
in_destructor, \
".destructor", 0, 0) \
SECTION_FUNCTION (objc_class_section, \
in_objc_class, \
".objc_class", 0, 1) \
SECTION_FUNCTION (objc_meta_class_section, \
in_objc_meta_class, \
".objc_meta_class", 0, 1) \
SECTION_FUNCTION (objc_category_section, \
in_objc_category, \
".objc_category", 0, 1) \
SECTION_FUNCTION (objc_class_vars_section, \
in_objc_class_vars, \
".objc_class_vars", 0, 1) \
SECTION_FUNCTION (objc_instance_vars_section, \
in_objc_instance_vars, \
".objc_instance_vars", 0, 1) \
SECTION_FUNCTION (objc_cls_meth_section, \
in_objc_cls_meth, \
".objc_cls_meth", 0, 1) \
SECTION_FUNCTION (objc_inst_meth_section, \
in_objc_inst_meth, \
".objc_inst_meth", 0, 1) \
SECTION_FUNCTION (objc_cat_cls_meth_section, \
in_objc_cat_cls_meth, \
".objc_cat_cls_meth", 0, 1) \
SECTION_FUNCTION (objc_cat_inst_meth_section, \
in_objc_cat_inst_meth, \
".objc_cat_inst_meth", 0, 1) \
SECTION_FUNCTION (objc_selector_refs_section, \
in_objc_selector_refs, \
".objc_message_refs", 0, 1) \
SECTION_FUNCTION (objc_selector_fixup_section, \
in_objc_selector_fixup, \
".section __OBJC, __sel_fixup", 0, 1) \
SECTION_FUNCTION (objc_symbols_section, \
in_objc_symbols, \
".objc_symbols", 0, 1) \
SECTION_FUNCTION (objc_module_info_section, \
in_objc_module_info, \
".objc_module_info", 0, 1) \
SECTION_FUNCTION (objc_protocol_section, \
in_objc_protocol, \
".objc_protocol", 0, 1) \
SECTION_FUNCTION (objc_string_object_section, \
in_objc_string_object, \
".objc_string_object", 0, 1) \
SECTION_FUNCTION (objc_constant_string_object_section, \
in_objc_constant_string_object, \
".section __OBJC, __cstring_object", 0, 1) \
SECTION_FUNCTION (objc_class_names_section, \
in_objc_class_names, \
".objc_class_names", 0, 1) \
SECTION_FUNCTION (objc_meth_var_names_section, \
in_objc_meth_var_names, \
".objc_meth_var_names", 0, 1) \
SECTION_FUNCTION (objc_meth_var_types_section, \
in_objc_meth_var_types, \
".objc_meth_var_types", 0, 1) \
SECTION_FUNCTION (objc_cls_refs_section, \
in_objc_cls_refs, \
".objc_cls_refs", 0, 1) \
\
SECTION_FUNCTION (machopic_lazy_symbol_ptr_section, \
in_machopic_lazy_symbol_ptr, \
".lazy_symbol_pointer", 0, 0) \
SECTION_FUNCTION (machopic_nl_symbol_ptr_section, \
in_machopic_nl_symbol_ptr, \
".non_lazy_symbol_pointer", 0, 0) \
SECTION_FUNCTION (machopic_symbol_stub_section, \
in_machopic_symbol_stub, \
".symbol_stub", 0, 0) \
SECTION_FUNCTION (machopic_picsymbol_stub_section, \
in_machopic_picsymbol_stub, \
".picsymbol_stub", 0, 0) \
\
void \
objc_section_init () \
{ \
static int been_here = 0; \
\
if (been_here == 0) \
{ \
been_here = 1; \
/* written, cold -> hot */ \
objc_cat_cls_meth_section (); \
objc_cat_inst_meth_section (); \
objc_string_object_section (); \
objc_constant_string_object_section (); \
objc_selector_refs_section (); \
objc_selector_fixup_section (); \
objc_cls_refs_section (); \
objc_class_section (); \
objc_meta_class_section (); \
/* shared, hot -> cold */ \
objc_cls_meth_section (); \
objc_inst_meth_section (); \
objc_protocol_section (); \
objc_class_names_section (); \
objc_meth_var_types_section (); \
objc_meth_var_names_section (); \
objc_category_section (); \
objc_class_vars_section (); \
objc_instance_vars_section (); \
objc_module_info_section (); \
objc_symbols_section (); \
} \
} \
static tree section_alias[(int) num_sections]; \
void try_section_alias () \
{ \
if (section_alias[in_section] && asm_out_file) \
fprintf (asm_out_file, "%s\n", \
IDENTIFIER_POINTER (section_alias[in_section])); \
} \
void alias_section (name, alias) \
char *name, *alias; \
{ \
ALIAS_SECTION (in_data, "data"); \
ALIAS_SECTION (in_text, "text"); \
ALIAS_SECTION (in_const, "const"); \
ALIAS_SECTION (in_const_data, "const_data"); \
ALIAS_SECTION (in_cstring, "cstring"); \
ALIAS_SECTION (in_literal4, "literal4"); \
ALIAS_SECTION (in_literal8, "literal8"); \
}
#undef READONLY_DATA_SECTION
#define READONLY_DATA_SECTION const_section
#undef SELECT_SECTION
#define SELECT_SECTION(exp,reloc) \
do \
{ \
if (TREE_CODE (exp) == STRING_CST) \
{ \
if (flag_writable_strings) \
data_section (); \
else if (TREE_STRING_LENGTH (exp) != \
strlen (TREE_STRING_POINTER (exp)) + 1) \
readonly_data_section (); \
else \
cstring_section (); \
} \
else if (TREE_CODE (exp) == INTEGER_CST \
|| TREE_CODE (exp) == REAL_CST) \
{ \
tree size = TYPE_SIZE (TREE_TYPE (exp)); \
\
if (TREE_CODE (size) == INTEGER_CST && \
TREE_INT_CST_LOW (size) == 4 && \
TREE_INT_CST_HIGH (size) == 0) \
literal4_section (); \
else if (TREE_CODE (size) == INTEGER_CST && \
TREE_INT_CST_LOW (size) == 8 && \
TREE_INT_CST_HIGH (size) == 0) \
literal8_section (); \
else \
readonly_data_section (); \
} \
else if (TREE_CODE (exp) == CONSTRUCTOR \
&& TREE_TYPE (exp) \
&& TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE \
&& TYPE_NAME (TREE_TYPE (exp))) \
{ \
tree name = TYPE_NAME (TREE_TYPE (exp)); \
if (TREE_CODE (name) == TYPE_DECL) \
name = DECL_NAME (name); \
if (!strcmp (IDENTIFIER_POINTER (name), "NSConstantString")) \
objc_constant_string_object_section (); \
else if (!strcmp (IDENTIFIER_POINTER (name), "NXConstantString")) \
objc_string_object_section (); \
else if (TREE_READONLY (exp) || TREE_CONSTANT (exp)) \
{ \
if (TREE_SIDE_EFFECTS (exp) || flag_pic && reloc) \
const_data_section (); \
else \
readonly_data_section (); \
} \
else \
data_section (); \
} \
else if (TREE_CODE (exp) == VAR_DECL && \
DECL_NAME (exp) && \
TREE_CODE (DECL_NAME (exp)) == IDENTIFIER_NODE && \
IDENTIFIER_POINTER (DECL_NAME (exp)) && \
!strncmp (IDENTIFIER_POINTER (DECL_NAME (exp)), "_OBJC_", 6)) \
{ \
const char *name = IDENTIFIER_POINTER (DECL_NAME (exp)); \
\
if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20)) \
objc_cls_meth_section (); \
else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23)) \
objc_inst_meth_section (); \
else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20)) \
objc_cat_cls_meth_section (); \
else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23)) \
objc_cat_inst_meth_section (); \
else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22)) \
objc_class_vars_section (); \
else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25)) \
objc_instance_vars_section (); \
else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22)) \
objc_cat_cls_meth_section (); \
else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17)) \
objc_class_names_section (); \
else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20)) \
objc_meth_var_names_section (); \
else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20)) \
objc_meth_var_types_section (); \
else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22)) \
objc_cls_refs_section (); \
else if (!strncmp (name, "_OBJC_CLASS_", 12)) \
objc_class_section (); \
else if (!strncmp (name, "_OBJC_METACLASS_", 16)) \
objc_meta_class_section (); \
else if (!strncmp (name, "_OBJC_CATEGORY_", 15)) \
objc_category_section (); \
else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25)) \
objc_selector_refs_section (); \
else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20)) \
objc_selector_fixup_section (); \
else if (!strncmp (name, "_OBJC_SYMBOLS", 13)) \
objc_symbols_section (); \
else if (!strncmp (name, "_OBJC_MODULES", 13)) \
objc_module_info_section (); \
else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32)) \
objc_cat_inst_meth_section (); \
else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29)) \
objc_cat_cls_meth_section (); \
else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20)) \
objc_cat_cls_meth_section (); \
else if (!strncmp (name, "_OBJC_PROTOCOL_", 15)) \
objc_protocol_section (); \
else if ((TREE_READONLY (exp) || TREE_CONSTANT (exp)) \
&& !TREE_SIDE_EFFECTS (exp)) \
{ if (flag_pic && reloc ) const_data_section (); \
else readonly_data_section (); } \
else \
data_section (); \
} \
else if (TREE_READONLY (exp) || TREE_CONSTANT (exp)) \
{ \
if (TREE_SIDE_EFFECTS (exp) || flag_pic && reloc) \
const_data_section (); \
else \
readonly_data_section (); \
} \
else \
data_section (); \
try_section_alias (); \
} \
while (0)
#undef SELECT_RTX_SECTION
#define SELECT_RTX_SECTION(mode, rtx) \
do \
{ \
if (GET_MODE_SIZE (mode) == 8) \
literal8_section (); \
else if (GET_MODE_SIZE (mode) == 4) \
literal4_section (); \
else \
const_section (); \
} \
while (0)
#define DECLARE_UNRESOLVED_REFERENCE(NAME) \
do { extern FILE* asm_out_file; \
if (asm_out_file) { \
if (flag_pic) \
fprintf (asm_out_file, "\t.lazy_reference "); \
else \
fprintf (asm_out_file, "\t.reference "); \
assemble_name (asm_out_file, NAME); \
fprintf (asm_out_file, "\n"); \
} \
} while (0)
#define DECLARE_CLASS_REFERENCE(NAME) \
do { extern FILE* asm_out_file; \
if (asm_out_file) { \
fprintf (asm_out_file, "\t"); \
assemble_name (asm_out_file, NAME); \
fprintf (asm_out_file, "=0\n"); \
assemble_global (NAME); \
} \
} while (0)
#undef ASM_GLOBALIZE_LABEL
#define ASM_GLOBALIZE_LABEL(FILE,NAME) \
do { const char* _x = (NAME); if (!!strncmp (_x, "_OBJC_", 6)) { \
(fputs (".globl ", FILE), assemble_name (FILE, _x), fputs ("\n", FILE)); \
}} while (0)
#undef ASM_GENERATE_INTERNAL_LABEL
#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
sprintf (LABEL, "*%s%d", PREFIX, NUM)
/* This is how to output an internal numbered label where PREFIX is
the class of label and NUM is the number within the class. */
#undef ASM_OUTPUT_INTERNAL_LABEL
#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
fprintf (FILE, "%s%d:\n", PREFIX, NUM)
/* Since we have a separate readonly data section, define this so that
jump tables end up in text rather than data. */
#ifndef JUMP_TABLES_IN_TEXT_SECTION
#define JUMP_TABLES_IN_TEXT_SECTION 1
#endif
/* Symbolic names for various things we might know about a symbol. */
enum machopic_addr_class {
MACHOPIC_UNDEFINED,
MACHOPIC_DEFINED_DATA,
MACHOPIC_UNDEFINED_DATA,
MACHOPIC_DEFINED_FUNCTION,
MACHOPIC_UNDEFINED_FUNCTION
};
/* Macros defining the various PIC cases. */
#define MACHOPIC_INDIRECT (flag_pic)
#define MACHOPIC_JUST_INDIRECT (flag_pic == 1)
#define MACHOPIC_PURE (flag_pic == 2)
#define GEN_BINDER_NAME_FOR_STUB(BUF,STUB,STUB_LENGTH) \
do { \
const char *stub_ = (STUB); \
char *buffer_ = (BUF); \
strcpy (buffer_, stub_); \
if (stub_[0] == '"') \
{ \
strcpy (buffer_ + (STUB_LENGTH) - 1, "_binder\""); \
} \
else \
{ \
strcpy (buffer_ + (STUB_LENGTH), "_binder"); \
} \
} while (0)
#define GEN_SYMBOL_NAME_FOR_SYMBOL(BUF,SYMBOL,SYMBOL_LENGTH) \
do { \
const char *symbol_ = (SYMBOL); \
char *buffer_ = (BUF); \
if (name_needs_quotes (symbol_) && symbol_[0] != '"') \
{ \
sprintf (buffer_, "\"%s\"", symbol_); \
} \
else \
{ \
strcpy (buffer_, symbol_); \
} \
} while (0)
/* Given a symbol name string, create the lazy pointer version
of the symbol name. */
#define GEN_LAZY_PTR_NAME_FOR_SYMBOL(BUF,SYMBOL,SYMBOL_LENGTH) \
do { \
const char *symbol_ = (SYMBOL); \
char *buffer_ = (BUF); \
if (symbol_[0] == '"') \
{ \
strcpy (buffer_, "\"L"); \
strcpy (buffer_ + 2, symbol_ + 1); \
strcpy (buffer_ + (SYMBOL_LENGTH), "$lazy_ptr\""); \
} \
else if (name_needs_quotes (symbol_)) \
{ \
strcpy (buffer_, "\"L"); \
strcpy (buffer_ + 2, symbol_); \
strcpy (buffer_ + (SYMBOL_LENGTH) + 2, "$lazy_ptr\""); \
} \
else \
{ \
strcpy (buffer_, "L"); \
strcpy (buffer_ + 1, symbol_); \
strcpy (buffer_ + (SYMBOL_LENGTH) + 1, "$lazy_ptr"); \
} \
} while (0)

175
gcc/config/rs6000/darwin.h Normal file
View file

@ -0,0 +1,175 @@
/* Target definitions for PowerPC running Darwin (Mac OS X).
Copyright (C) 1997, 2000, 2001 Free Software Foundation, Inc.
Contributed by Apple Computer Inc.
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. */
/* The "Darwin ABI" is mostly like AIX, but with some key differences. */
#define DEFAULT_ABI ABI_DARWIN
/* The object file format is Mach-O. */
#define TARGET_OBJECT_FORMAT OBJECT_MACHO
/* We're not ever going to do TOCs. */
#define TARGET_TOC 0
#define TARGET_NO_TOC 1
#define CPP_PREDEFINES "-D__ppc__ -D__NATURAL_ALIGNMENT__ -D__MACH__ -D__BIG_ENDIAN__ -D__APPLE__"
/* We want -fPIC by default, unless we're using -static to compile for
the kernel or some such. */
#define CC1_SPEC "%{!static:-fPIC}"
#define FIXED_R13 0
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_POWERPC | MASK_MULTIPLE | MASK_NEW_MNEMONICS \
| MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC)
/* Base register for access to local variables of the function. */
#undef FRAME_POINTER_REGNUM
#define FRAME_POINTER_REGNUM 30
#undef PIC_OFFSET_TABLE_REGNUM
#define PIC_OFFSET_TABLE_REGNUM 31
#undef STACK_BOUNDARY
#define STACK_BOUNDARY 128
/* Pad the outgoing args area to 16 bytes instead of the usual 8. */
#undef STARTING_FRAME_OFFSET
#define STARTING_FRAME_OFFSET \
(RS6000_ALIGN (current_function_outgoing_args_size, 16) \
+ RS6000_VARARGS_AREA \
+ RS6000_SAVE_AREA)
#undef STACK_DYNAMIC_OFFSET
#define STACK_DYNAMIC_OFFSET(FUNDECL) \
(RS6000_ALIGN (current_function_outgoing_args_size, 16) \
+ (STACK_POINTER_OFFSET))
/* Define cutoff for using external functions to save floating point.
Currently on Darwin, always use inline stores. */
#undef FP_SAVE_INLINE
#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 64)
/* Always use the "debug" register names, they're what the assembler
wants to see. */
#undef REGISTER_NAMES
#define REGISTER_NAMES DEBUG_REGISTER_NAMES
/* This outputs NAME to FILE. */
#undef RS6000_OUTPUT_BASENAME
#define RS6000_OUTPUT_BASENAME(FILE, NAME) \
assemble_name (FILE, NAME);
/* Output before instructions. */
/* This is how to output the definition of a user-level label named NAME,
such as the label on a static function or variable NAME. */
#define ASM_OUTPUT_LABEL(FILE,NAME) \
do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0)
/* This is how to output a command to make the user-level label named NAME
defined for reference from other files. */
#undef ASM_GLOBALIZE_LABEL
#define ASM_GLOBALIZE_LABEL(FILE,NAME) \
do { fputs ("\t.globl ", FILE); \
RS6000_OUTPUT_BASENAME (FILE, NAME); putc ('\n', FILE);} while (0)
/* This is how to output an internal label prefix. rs6000.c uses this
when generating traceback tables. */
/* Not really used for Darwin? */
#undef ASM_OUTPUT_INTERNAL_LABEL_PREFIX
#define ASM_OUTPUT_INTERNAL_LABEL_PREFIX(FILE,PREFIX) \
fprintf (FILE, "%s", PREFIX)
#undef TEXT_SECTION_ASM_OP
#define TEXT_SECTION_ASM_OP ".text"
/* Output before writable data. */
#undef DATA_SECTION_ASM_OP
#define DATA_SECTION_ASM_OP ".data"
/* This says how to output an assembler line to define a global common
symbol. */
/* ? */
#undef ASM_OUTPUT_ALIGNED_COMMON
#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
do { fputs (".comm ", (FILE)); \
RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \
fprintf ((FILE), ",%d\n", (SIZE)); } while (0)
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
fprintf (FILE, "\t.space %d\n", SIZE)
/* FP save and restore routines. */
#define SAVE_FP_PREFIX "._savef"
#define SAVE_FP_SUFFIX ""
#define RESTORE_FP_PREFIX "._restf"
#define RESTORE_FP_SUFFIX ""
/* Generate insns to call the profiler. */
#define PROFILE_HOOK(LABEL) output_profile_hook (LABEL)
/* Function name to call to do profiling. */
#define RS6000_MCOUNT "*mcount"
/* Since Darwin doesn't do TOCs, stub this out. */
#define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X, MODE) 0
/* Given an rtx X being reloaded into a reg required to be
in class CLASS, return the class of reg to actually use.
In general this is just CLASS; but on some machines
in some cases it is preferable to use a more restrictive class.
On the RS/6000, we have to return NO_REGS when we want to reload a
floating-point CONST_DOUBLE to force it to be copied to memory.
Don't allow R0 when loading the address of, or otherwise furtling with,
a SYMBOL_REF. */
#undef PREFERRED_RELOAD_CLASS
#define PREFERRED_RELOAD_CLASS(X,CLASS) \
(((GET_CODE (X) == CONST_DOUBLE \
&& GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) \
? NO_REGS \
: (GET_MODE_CLASS (GET_MODE (X)) == MODE_INT \
&& (CLASS) == NON_SPECIAL_REGS) \
? GENERAL_REGS \
: (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == HIGH) \
? BASE_REGS \
: (CLASS)))
/* Fix for emit_group_load (): force large constants to be pushed via regs. */
#define ALWAYS_PUSH_CONSTS_USING_REGS_P 1

View file

@ -108,8 +108,12 @@ extern void rs6000_emit_eh_toc_restore PARAMS ((rtx));
extern void rs6000_emit_move PARAMS ((rtx, rtx, enum machine_mode));
extern rtx rs6000_legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
extern void rs6000_select_rtx_section PARAMS ((enum machine_mode, rtx));
extern rtx rs6000_return_addr PARAMS ((int, rtx));
extern void rs6000_output_symbol_ref PARAMS ((FILE*, rtx));
extern rtx rs6000_machopic_legitimize_pic_address PARAMS ((rtx orig, enum machine_mode mode, rtx reg));
#endif /* RTX_CODE */
#ifdef TREE_CODE
@ -139,6 +143,7 @@ extern void rs6000_unique_section PARAMS ((tree, int));
/* expr.h defines ARGS_SIZE_RTX and `enum direction' */
extern enum direction function_arg_padding PARAMS ((enum machine_mode, tree));
#endif /* ARGS_SIZE_RTX */
#endif /* TREE_CODE */
extern void optimization_options PARAMS ((int, int));
@ -172,3 +177,5 @@ extern void rs6000_emit_load_toc_table PARAMS ((int));
extern void rs6000_aix_emit_builtin_unwind_init PARAMS ((void));
extern void rs6000_emit_epilogue PARAMS ((int));
extern void debug_stack_info PARAMS ((rs6000_stack_t *));
extern void machopic_output_stub PARAMS ((FILE *, const char *, const char *));

View file

@ -1526,6 +1526,19 @@ rs6000_legitimize_address (x, oldx, mode)
emit_insn (gen_elf_high (reg, (x)));
return gen_rtx_LO_SUM (Pmode, reg, (x));
}
else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
&& ! flag_pic
&& GET_CODE (x) != CONST_INT
&& GET_CODE (x) != CONST_DOUBLE
&& CONSTANT_P (x)
&& (TARGET_HARD_FLOAT || mode != DFmode)
&& mode != DImode
&& mode != TImode)
{
rtx reg = gen_reg_rtx (Pmode);
emit_insn (gen_macho_high (reg, (x)));
return gen_rtx_LO_SUM (Pmode, reg, (x));
}
else if (TARGET_TOC
&& CONSTANT_POOL_EXPR_P (x)
&& ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
@ -1644,7 +1657,8 @@ rs6000_emit_move (dest, source, mode)
return;
}
if (TARGET_ELF && TARGET_NO_TOC && ! flag_pic
if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
&& TARGET_NO_TOC && ! flag_pic
&& mode == Pmode
&& CONSTANT_P (operands[1])
&& GET_CODE (operands[1]) != HIGH
@ -1670,6 +1684,13 @@ rs6000_emit_move (dest, source, mode)
operands[1] = new_ref;
}
if (DEFAULT_ABI == ABI_DARWIN)
{
emit_insn (gen_macho_high (target, operands[1]));
emit_insn (gen_macho_low (operands[0], target, operands[1]));
return;
}
emit_insn (gen_elf_high (target, operands[1]));
emit_insn (gen_elf_low (operands[0], target, operands[1]));
return;
@ -1708,6 +1729,21 @@ rs6000_emit_move (dest, source, mode)
if (GET_CODE (operands[1]) != LABEL_REF)
emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
/* Darwin uses a special PIC legitimizer. */
if (DEFAULT_ABI == ABI_DARWIN && flag_pic)
{
rtx temp_reg = ((reload_in_progress || reload_completed)
? operands[0] : NULL);
#if TARGET_MACHO
operands[1] =
rs6000_machopic_legitimize_pic_address (operands[1], mode,
temp_reg);
#endif
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
return;
}
/* If we are to limit the number of things we put in the TOC and
this is a symbol plus a constant we can add in one insn,
just put the symbol in the TOC and add the constant. Don't do
@ -4296,6 +4332,7 @@ print_operand (file, x, code)
case ABI_V4:
case ABI_AIX_NODESC:
case ABI_SOLARIS:
case ABI_DARWIN:
break;
}
}
@ -4655,8 +4692,10 @@ first_reg_to_save ()
if (regs_ever_live[first_reg]
&& (! call_used_regs[first_reg]
|| (first_reg == PIC_OFFSET_TABLE_REGNUM
&& (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
&& flag_pic == 1)))
&& (((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
&& flag_pic == 1)
|| (DEFAULT_ABI == ABI_DARWIN
&& flag_pic)))))
break;
if (profile_flag)
@ -4665,7 +4704,7 @@ first_reg_to_save ()
before/after the .__mcount call plus an additional register
for the static chain, if needed; use registers from 30 down to 22
to do this. */
if (DEFAULT_ABI == ABI_AIX)
if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
{
int last_parm_reg, profile_first_reg;
@ -4683,6 +4722,12 @@ first_reg_to_save ()
Skip reg 31 which may contain the frame pointer. */
profile_first_reg = (33 - last_parm_reg
- (current_function_needs_context ? 1 : 0));
#if TARGET_MACHO
/* Need to skip another reg to account for R31 being PICBASE
(when flag_pic is set) or R30 being used as the frame
pointer (when flag_pic is not set). */
--profile_first_reg;
#endif
/* Do not save frame pointer if no parameters needs to be saved. */
if (profile_first_reg == 31)
profile_first_reg = 32;
@ -4700,6 +4745,12 @@ first_reg_to_save ()
}
}
#if TARGET_MACHO
if (flag_pic && current_function_uses_pic_offset_table &&
(first_reg > PIC_OFFSET_TABLE_REGNUM))
return PIC_OFFSET_TABLE_REGNUM;
#endif
return first_reg;
}
@ -4722,7 +4773,7 @@ first_fp_reg_to_save ()
complicated by having two separate calling sequences, the AIX calling
sequence and the V.4 calling sequence.
AIX stack frames look like:
AIX (and Darwin/Mac OS) stack frames look like:
32-bit 64-bit
SP----> +---------------------------------------+
| back chain to caller | 0 0
@ -4821,8 +4872,10 @@ rs6000_stack_info ()
info_ptr->first_gp_reg_save = first_reg_to_save ();
/* Assume that we will have to save PIC_OFFSET_TABLE_REGNUM,
even if it currently looks like we won't. */
if (flag_pic == 1
&& (abi == ABI_V4 || abi == ABI_SOLARIS)
if (((flag_pic == 1
&& (abi == ABI_V4 || abi == ABI_SOLARIS))
|| (flag_pic &&
abi == ABI_DARWIN))
&& info_ptr->first_gp_reg_save > PIC_OFFSET_TABLE_REGNUM)
info_ptr->gp_size = reg_size * (32 - PIC_OFFSET_TABLE_REGNUM);
else
@ -4845,6 +4898,7 @@ rs6000_stack_info ()
&& !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
|| (abi == ABI_V4 && current_function_calls_alloca)
|| (abi == ABI_SOLARIS && current_function_calls_alloca)
|| (DEFAULT_ABI == ABI_DARWIN && flag_pic && current_function_uses_pic_offset_table)
|| info_ptr->calls_p)
{
info_ptr->lr_save_p = 1;
@ -4886,6 +4940,8 @@ rs6000_stack_info ()
+ info_ptr->cr_size
+ info_ptr->lr_size
+ info_ptr->toc_size, 8);
if (DEFAULT_ABI == ABI_DARWIN)
info_ptr->save_size = RS6000_ALIGN (info_ptr->save_size, 16);
/* Calculate the offsets */
switch (abi)
@ -4896,6 +4952,7 @@ rs6000_stack_info ()
case ABI_AIX:
case ABI_AIX_NODESC:
case ABI_DARWIN:
info_ptr->fp_save_offset = - info_ptr->fp_size;
info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
@ -4942,7 +4999,7 @@ rs6000_stack_info ()
else
info_ptr->push_p = (frame_pointer_needed
|| write_symbols != NO_DEBUG
|| (abi != ABI_DARWIN && write_symbols != NO_DEBUG)
|| ((total_raw_size - info_ptr->fixed_size)
> (TARGET_32BIT ? 220 : 288)));
@ -4985,6 +5042,7 @@ debug_stack_info (info)
case ABI_NONE: abi_string = "NONE"; break;
case ABI_AIX: abi_string = "AIX"; break;
case ABI_AIX_NODESC: abi_string = "AIX"; break;
case ABI_DARWIN: abi_string = "Darwin"; break;
case ABI_V4: abi_string = "V.4"; break;
case ABI_SOLARIS: abi_string = "Solaris"; break;
}
@ -5740,8 +5798,10 @@ rs6000_emit_prologue ()
if ((regs_ever_live[info->first_gp_reg_save+i]
&& ! call_used_regs[info->first_gp_reg_save+i])
|| (i+info->first_gp_reg_save == PIC_OFFSET_TABLE_REGNUM
&& (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
&& flag_pic == 1))
&& (((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
&& flag_pic == 1)
|| (DEFAULT_ABI == ABI_DARWIN
&& flag_pic))))
{
rtx addr, reg, mem;
reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
@ -5858,6 +5918,18 @@ rs6000_emit_prologue ()
emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
gen_rtx_REG (Pmode, 11));
}
if (DEFAULT_ABI == ABI_DARWIN
&& flag_pic && current_function_uses_pic_offset_table)
{
rtx dest = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (dest)));
rs6000_maybe_dead (
emit_move_insn (gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM),
gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)));
}
}
@ -6051,8 +6123,10 @@ rs6000_emit_epilogue (sibcall)
if ((regs_ever_live[info->first_gp_reg_save+i]
&& ! call_used_regs[info->first_gp_reg_save+i])
|| (i+info->first_gp_reg_save == PIC_OFFSET_TABLE_REGNUM
&& (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
&& flag_pic == 1))
&& (((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
&& flag_pic == 1)
|| (DEFAULT_ABI == ABI_DARWIN
&& flag_pic))))
{
rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
GEN_INT (info->gp_save_offset
@ -6626,6 +6700,17 @@ output_mi_thunk (file, thunk_fndecl, delta, function)
if (flag_pic) fputs ("@plt", file);
putc ('\n', file);
break;
#if TARGET_MACHO
case ABI_DARWIN:
fprintf (file, "\tb %s", prefix);
if (flag_pic && !machopic_name_defined_p (fname))
assemble_name (file, machopic_stub_name (fname));
else
assemble_name (file, fname);
putc ('\n', file);
break;
#endif
}
}
}
@ -7226,6 +7311,28 @@ output_profile_hook (labelno)
emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1,
fun, Pmode);
}
else if (DEFAULT_ABI == ABI_DARWIN)
{
char *mcount_name = RS6000_MCOUNT;
int caller_addr_regno = LINK_REGISTER_REGNUM;
/* Be conservative and always set this, at least for now. */
current_function_uses_pic_offset_table = 1;
#if TARGET_MACHO
/* For PIC code, set up a stub and collect the caller's address
from r0, which is where the prologue puts it. */
if (flag_pic)
{
mcount_name = machopic_stub_name (mcount_name);
if (current_function_uses_pic_offset_table)
caller_addr_regno = 0;
}
#endif
emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
0, VOIDmode, 1,
gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
}
}
/* Write function profiler code. */
@ -7296,6 +7403,7 @@ output_function_profiler (file, labelno)
break;
case ABI_AIX:
case ABI_DARWIN:
/* Don't do anything, done in output_profile_hook (). */
break;
@ -7834,4 +7942,325 @@ rs6000_add_gc_roots ()
toc_hash_table = htab_create (1021, toc_hash_function, toc_hash_eq, NULL);
ggc_add_root (&toc_hash_table, 1, sizeof (toc_hash_table),
toc_hash_mark_table);
#if TARGET_MACHO
machopic_add_gc_roots ();
#endif
}
#if TARGET_MACHO
#if 0
/* Returns 1 if OP is either a symbol reference or a sum of a symbol
reference and a constant. */
int
symbolic_operand (op)
register rtx op;
{
switch (GET_CODE (op))
{
case SYMBOL_REF:
case LABEL_REF:
return 1;
case CONST:
op = XEXP (op, 0);
return (GET_CODE (op) == SYMBOL_REF ||
(GET_CODE (XEXP (op, 0)) == SYMBOL_REF
|| GET_CODE (XEXP (op, 0)) == LABEL_REF)
&& GET_CODE (XEXP (op, 1)) == CONST_INT);
default:
return 0;
}
}
#endif
#ifdef RS6000_LONG_BRANCH
static tree stub_list = 0;
/* ADD_COMPILER_STUB adds the compiler generated stub for handling
procedure calls to the linked list. */
void
add_compiler_stub (label_name, function_name, line_number)
tree label_name;
tree function_name;
int line_number;
{
tree stub = build_tree_list (function_name, label_name);
TREE_TYPE (stub) = build_int_2 (line_number, 0);
TREE_CHAIN (stub) = stub_list;
stub_list = stub;
}
#define STUB_LABEL_NAME(STUB) TREE_VALUE (STUB)
#define STUB_FUNCTION_NAME(STUB) TREE_PURPOSE (STUB)
#define STUB_LINE_NUMBER(STUB) TREE_INT_CST_LOW (TREE_TYPE (STUB))
/* OUTPUT_COMPILER_STUB outputs the compiler generated stub for handling
procedure calls from the linked list and initializes the linked list. */
void output_compiler_stub ()
{
char tmp_buf[256];
char label_buf[256];
char *label;
tree tmp_stub, stub;
if (!flag_pic)
for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
{
fprintf (asm_out_file,
"%s:\n", IDENTIFIER_POINTER(STUB_LABEL_NAME(stub)));
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
fprintf (asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER(stub));
#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
if (IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))[0] == '*')
strcpy (label_buf,
IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))+1);
else
{
label_buf[0] = '_';
strcpy (label_buf+1,
IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub)));
}
strcpy (tmp_buf, "lis r12,hi16(");
strcat (tmp_buf, label_buf);
strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
strcat (tmp_buf, label_buf);
strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
output_asm_insn (tmp_buf, 0);
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
fprintf(asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER (stub));
#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
}
stub_list = 0;
}
/* NO_PREVIOUS_DEF checks in the link list whether the function name is
already there or not. */
int no_previous_def (function_name)
tree function_name;
{
tree stub;
for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
if (function_name == STUB_FUNCTION_NAME (stub))
return 0;
return 1;
}
/* GET_PREV_LABEL gets the label name from the previous definition of
the function. */
tree get_prev_label (function_name)
tree function_name;
{
tree stub;
for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
if (function_name == STUB_FUNCTION_NAME (stub))
return STUB_LABEL_NAME (stub);
return 0;
}
/* INSN is either a function call or a millicode call. It may have an
unconditional jump in its delay slot.
CALL_DEST is the routine we are calling. */
char *
output_call (insn, call_dest, operand_number)
rtx insn;
rtx call_dest;
int operand_number;
{
static char buf[256];
if (GET_CODE (call_dest) == SYMBOL_REF && TARGET_LONG_BRANCH && !flag_pic)
{
tree labelname;
tree funname = get_identifier (XSTR (call_dest, 0));
if (no_previous_def (funname))
{
int line_number;
rtx label_rtx = gen_label_rtx ();
char *label_buf, temp_buf[256];
ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
CODE_LABEL_NUMBER (label_rtx));
label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
labelname = get_identifier (label_buf);
for (; insn && GET_CODE (insn) != NOTE; insn = PREV_INSN (insn));
if (insn)
line_number = NOTE_LINE_NUMBER (insn);
add_compiler_stub (labelname, funname, line_number);
}
else
labelname = get_prev_label (funname);
sprintf (buf, "jbsr %%z%d,%.246s",
operand_number, IDENTIFIER_POINTER (labelname));
return buf;
}
else
{
sprintf (buf, "bl %%z%d", operand_number);
return buf;
}
}
#endif /* RS6000_LONG_BRANCH */
#define GEN_LOCAL_LABEL_FOR_SYMBOL(BUF,SYMBOL,LENGTH,N) \
do { \
const char *symbol_ = (SYMBOL); \
char *buffer_ = (BUF); \
if (symbol_[0] == '"') \
{ \
sprintf(buffer_, "\"L%d$%s", (N), symbol_+1); \
} \
else if (name_needs_quotes(symbol_)) \
{ \
sprintf(buffer_, "\"L%d$%s\"", (N), symbol_); \
} \
else \
{ \
sprintf(buffer_, "L%d$%s", (N), symbol_); \
} \
} while (0)
/* Generate PIC and indirect symbol stubs. */
void
machopic_output_stub (file, symb, stub)
FILE *file;
const char *symb, *stub;
{
unsigned int length;
char *binder_name, *symbol_name, *lazy_ptr_name;
char *local_label_0, *local_label_1, *local_label_2;
static int label = 0;
label += 1;
length = strlen (stub);
binder_name = alloca (length + 32);
GEN_BINDER_NAME_FOR_STUB (binder_name, stub, length);
length = strlen (symb);
symbol_name = alloca (length + 32);
GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
lazy_ptr_name = alloca (length + 32);
GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
local_label_0 = alloca (length + 32);
GEN_LOCAL_LABEL_FOR_SYMBOL (local_label_0, symb, length, 0);
local_label_1 = alloca (length + 32);
GEN_LOCAL_LABEL_FOR_SYMBOL (local_label_1, symb, length, 1);
local_label_2 = alloca (length + 32);
GEN_LOCAL_LABEL_FOR_SYMBOL (local_label_2, symb, length, 2);
if (flag_pic == 2)
machopic_picsymbol_stub_section ();
else
machopic_symbol_stub_section ();
fprintf (file, "%s:\n", stub);
fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
if (flag_pic == 2)
{
fprintf (file, "\tmflr r0\n");
fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
lazy_ptr_name, local_label_0);
fprintf (file, "\tmtlr r0\n");
fprintf (file, "\tlwz r12,lo16(%s-%s)(r11)\n",
lazy_ptr_name, local_label_0);
fprintf (file, "\tmtctr r12\n");
fprintf (file, "\taddi r11,r11,lo16(%s-%s)\n",
lazy_ptr_name, local_label_0);
fprintf (file, "\tbctr\n");
}
else
fprintf (file, "non-pure not supported\n");
machopic_lazy_symbol_ptr_section ();
fprintf (file, "%s:\n", lazy_ptr_name);
fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
fprintf (file, "\t.long dyld_stub_binding_helper\n");
}
/* Legitimize PIC addresses. If the address is already
position-independent, we return ORIG. Newly generated
position-independent addresses go into a reg. This is REG if non
zero, otherwise we allocate register(s) as necessary. */
#define SMALL_INT(X) ((unsigned) (INTVAL(X) + 0x4000) < 0x8000)
rtx
rs6000_machopic_legitimize_pic_address (orig, mode, reg)
rtx orig;
enum machine_mode mode;
rtx reg;
{
rtx base, offset;
if (reg == NULL && ! reload_in_progress && ! reload_completed)
reg = gen_reg_rtx (Pmode);
if (GET_CODE (orig) == CONST)
{
if (GET_CODE (XEXP (orig, 0)) == PLUS
&& XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
return orig;
if (GET_CODE (XEXP (orig, 0)) == PLUS)
{
base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
Pmode, reg);
offset = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
Pmode, reg);
}
else
abort ();
if (GET_CODE (offset) == CONST_INT)
{
if (SMALL_INT (offset))
return plus_constant_for_output (base, INTVAL (offset));
else if (! reload_in_progress && ! reload_completed)
offset = force_reg (Pmode, offset);
else
abort ();
}
return gen_rtx (PLUS, Pmode, base, offset);
}
/* Fall back on generic machopic code. */
return machopic_legitimize_pic_address (orig, mode, reg);
}
/* This is just a placeholder to make linking work without having to
add this to the generic Darwin EXTRA_SECTIONS. If -mcall-aix is
ever needed for Darwin (not too likely!) this would have to get a
real definition. */
void
toc_section ()
{
}
#endif /* TARGET_MACHO */

View file

@ -30,10 +30,12 @@ Boston, MA 02111-1307, USA. */
#define OBJECT_XCOFF 1
#define OBJECT_ELF 2
#define OBJECT_PEF 3
#define OBJECT_MACHO 4
#define TARGET_ELF (TARGET_OBJECT_FORMAT == OBJECT_ELF)
#define TARGET_AIX (TARGET_OBJECT_FORMAT == OBJECT_XCOFF)
#define TARGET_MACOS (TARGET_OBJECT_FORMAT == OBJECT_PEF)
#define TARGET_MACHO (TARGET_OBJECT_FORMAT == OBJECT_MACHO)
/* Print subsidiary information on the compiler version in use. */
#define TARGET_VERSION ;
@ -861,6 +863,10 @@ extern int rs6000_debug_arg; /* debug argument handling */
&& flag_pic == 1) \
fixed_regs[PIC_OFFSET_TABLE_REGNUM] \
= call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
if (DEFAULT_ABI == ABI_DARWIN && flag_pic) \
global_regs[PIC_OFFSET_TABLE_REGNUM] \
= fixed_regs[PIC_OFFSET_TABLE_REGNUM] \
= call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
}
/* Specify the registers used for certain standard purposes.
@ -1159,7 +1165,8 @@ enum rs6000_abi {
ABI_AIX, /* IBM's AIX */
ABI_AIX_NODESC, /* AIX calling sequence minus function descriptors */
ABI_V4, /* System V.4/eabi */
ABI_SOLARIS /* Solaris */
ABI_SOLARIS, /* Solaris */
ABI_DARWIN /* Apple's Darwin (OS X kernel) */
};
extern enum rs6000_abi rs6000_current_abi; /* available for use by subtarget */
@ -1210,13 +1217,14 @@ typedef struct rs6000_stack {
/* Size of the outgoing register save area */
#define RS6000_REG_SAVE ((DEFAULT_ABI == ABI_AIX \
|| DEFAULT_ABI == ABI_AIX_NODESC) \
|| DEFAULT_ABI == ABI_AIX_NODESC \
|| DEFAULT_ABI == ABI_DARWIN) \
? (TARGET_64BIT ? 64 : 32) \
: 0)
/* Size of the fixed area on the stack */
#define RS6000_SAVE_AREA \
(((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_AIX_NODESC) ? 24 : 8) \
(((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_DARWIN) ? 24 : 8) \
<< (TARGET_64BIT ? 1 : 0))
/* MEM representing address to save the TOC register */
@ -1351,7 +1359,8 @@ typedef struct rs6000_stack {
#define FP_ARG_AIX_MAX_REG 45
#define FP_ARG_V4_MAX_REG 40
#define FP_ARG_MAX_REG ((DEFAULT_ABI == ABI_AIX \
|| DEFAULT_ABI == ABI_AIX_NODESC) \
|| DEFAULT_ABI == ABI_AIX_NODESC \
|| DEFAULT_ABI == ABI_DARWIN) \
? FP_ARG_AIX_MAX_REG : FP_ARG_V4_MAX_REG)
#define FP_ARG_NUM_REG (FP_ARG_MAX_REG - FP_ARG_MIN_REG + 1)
@ -1645,6 +1654,7 @@ typedef struct rs6000_args
abi's store the return address. */
#define RETURN_ADDRESS_OFFSET \
((DEFAULT_ABI == ABI_AIX \
|| DEFAULT_ABI == ABI_DARWIN \
|| DEFAULT_ABI == ABI_AIX_NODESC) ? (TARGET_32BIT ? 8 : 16) : \
(DEFAULT_ABI == ABI_V4 \
|| DEFAULT_ABI == ABI_SOLARIS) ? (TARGET_32BIT ? 4 : 8) : \

View file

@ -1449,6 +1449,14 @@
{cau|addis} %0,%1,%v2"
[(set_attr "length" "4,4,4,4")])
(define_insn "addsi3_high"
[(set (match_operand:SI 0 "gpc_reg_operand" "=b")
(plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
(high:SI (match_operand 2 "" ""))))]
"TARGET_MACHO && !TARGET_64BIT"
"{cau|addis} %0,%1,ha16(%2)"
[(set_attr "length" "4")])
(define_insn "*addsi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
(compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
@ -7347,6 +7355,22 @@
{cal|la} %0,%2@l(%1)
{ai|addic} %0,%1,%K2")
;; Mach-O PIC trickery.
(define_insn "macho_high"
[(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
(high:SI (match_operand 1 "" "")))]
"TARGET_MACHO && ! TARGET_64BIT"
"{liu|lis} %0,ha16(%1)")
(define_insn "macho_low"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,!*r")
(match_operand 2 "" "")))]
"TARGET_MACHO && ! TARGET_64BIT"
"@
{cal %0,%a2@l(%1)|la %0,lo16(%2)(%1)}
{cal %0,%a2@l(%1)|addic %0,%1,lo16(%2)}")
;; Set up a register with a value from the GOT table
(define_expand "movsi_got"
@ -7406,6 +7430,15 @@
""
"{ rs6000_emit_move (operands[0], operands[1], SImode); DONE; }")
(define_insn "movsi_low"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(mem:SI (lo_sum:SI (match_operand:SI 1 "register_operand" "b")
(match_operand 2 "" ""))))]
"TARGET_MACHO && ! TARGET_64BIT"
"{l|lwz} %0,lo16(%2)(%1)"
[(set_attr "type" "load")
(set_attr "length" "4")])
(define_insn "*movsi_internal1"
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,r,r,r,r,r,*q,*c*l,*h")
(match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,R,*h,r,r,0"))]
@ -9257,6 +9290,21 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
"{l|lwz} %0,%2-%3(%1)"
[(set_attr "type" "load")])
(define_insn "load_macho_picbase"
[(set (match_operand:SI 0 "register_operand" "=l")
(unspec:SI [(const_int 0)] 15))]
"(DEFAULT_ABI == ABI_DARWIN) && flag_pic"
"*
{
#if TARGET_MACHO
char *picbase = machopic_function_base_name ();
operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (picbase, -1));
#endif
return \"bcl 20,31,%1\\n%1:\";
}"
[(set_attr "type" "branch")
(set_attr "length" "4")])
;; If the TOC is shared over a translation unit, as happens with all
;; the kinds of PIC that we support, we need to restore the TOC
;; pointer only when jumping over units of translation.
@ -9376,6 +9424,11 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
""
"
{
#if TARGET_MACHO
if (flag_pic)
operands[0] = machopic_indirect_call_target (operands[0]);
#endif
if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != CONST_INT)
abort ();
@ -9389,6 +9442,7 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
if (DEFAULT_ABI == ABI_V4
|| DEFAULT_ABI == ABI_AIX_NODESC
|| DEFAULT_ABI == ABI_DARWIN
|| DEFAULT_ABI == ABI_SOLARIS)
operands[0] = force_reg (Pmode, operands[0]);
@ -9419,6 +9473,11 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
""
"
{
#if TARGET_MACHO
if (flag_pic)
operands[1] = machopic_indirect_call_target (operands[1]);
#endif
if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != CONST_INT)
abort ();
@ -9432,6 +9491,7 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
if (DEFAULT_ABI == ABI_V4
|| DEFAULT_ABI == ABI_AIX_NODESC
|| DEFAULT_ABI == ABI_DARWIN
|| DEFAULT_ABI == ABI_SOLARIS)
operands[0] = force_reg (Pmode, operands[0]);
@ -9664,6 +9724,7 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
(clobber (match_scratch:SI 3 "=l,l,l,l"))]
"DEFAULT_ABI == ABI_AIX_NODESC
|| DEFAULT_ABI == ABI_V4
|| DEFAULT_ABI == ABI_DARWIN
|| DEFAULT_ABI == ABI_SOLARIS"
"*
{
@ -9696,6 +9757,7 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
(clobber (match_scratch:SI 4 "=l,l,l,l"))]
"DEFAULT_ABI == ABI_AIX_NODESC
|| DEFAULT_ABI == ABI_V4
|| DEFAULT_ABI == ABI_DARWIN
|| DEFAULT_ABI == ABI_SOLARIS"
"*
{

View file

@ -0,0 +1,26 @@
# Do not build libgcc1.
LIBGCC1 =
CROSS_LIBGCC1 =
# We want fine grained libraries, so use the new code to build the
# floating point emulation libraries.
FPBIT = fp-bit.c
DPBIT = dp-bit.c
dp-bit.c: $(srcdir)/config/fp-bit.c
cat $(srcdir)/config/fp-bit.c > dp-bit.c
fp-bit.c: $(srcdir)/config/fp-bit.c
echo '#define FLOAT' > fp-bit.c
cat $(srcdir)/config/fp-bit.c >> fp-bit.c
darwin.o: $(srcdir)/config/darwin.c
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/darwin.c
# Build the libraries for both hard and soft floating point
MULTILIB_OPTIONS = msoft-float
MULTILIB_DIRNAMES = soft-float
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib

View file

@ -234,6 +234,7 @@ typedef long ssize_t;
#ifndef __WCHAR_T
#ifndef _WCHAR_T_
#ifndef _BSD_WCHAR_T_
#ifndef _BSD_WCHAR_T_DEFINED_ /* Darwin */
#ifndef _WCHAR_T_DEFINED_
#ifndef _WCHAR_T_DEFINED
#ifndef _WCHAR_T_H
@ -298,6 +299,7 @@ typedef __WCHAR_TYPE__ wchar_t;
#endif
#endif
#endif
#endif
#endif /* __wchar_t__ */
#undef __need_wchar_t
#endif /* _STDDEF_H or __need_wchar_t. */