00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "config.h"
00025 #include "system.h"
00026 #include "coretypes.h"
00027 #include "tm.h"
00028 #include "rtl.h"
00029 #include "regs.h"
00030 #include "hard-reg-set.h"
00031 #include "real.h"
00032 #include "insn-config.h"
00033 #include "conditions.h"
00034 #include "insn-flags.h"
00035 #include "output.h"
00036 #include "insn-attr.h"
00037 #include "flags.h"
00038 #include "tree.h"
00039 #include "expr.h"
00040 #include "reload.h"
00041 #include "function.h"
00042 #include "ggc.h"
00043 #include "langhooks.h"
00044 #include "target.h"
00045 #include "tm_p.h"
00046 #include "toplev.h"
00047 #include "hashtab.h"
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 section * darwin_sections[NUM_DARWIN_SECTIONS];
00081
00082
00083 int darwin_ms_struct = false;
00084
00085
00086
00087
00088 static void
00089 output_objc_section_asm_op (const void *directive)
00090 {
00091 static bool been_here = false;
00092
00093 if (! been_here)
00094 {
00095 static const enum darwin_section_enum tomark[] =
00096 {
00097
00098 objc_cat_cls_meth_section,
00099 objc_cat_inst_meth_section,
00100 objc_string_object_section,
00101 objc_constant_string_object_section,
00102 objc_selector_refs_section,
00103 objc_selector_fixup_section,
00104 objc_cls_refs_section,
00105 objc_class_section,
00106 objc_meta_class_section,
00107
00108 objc_cls_meth_section,
00109 objc_inst_meth_section,
00110 objc_protocol_section,
00111 objc_class_names_section,
00112 objc_meth_var_types_section,
00113 objc_meth_var_names_section,
00114 objc_category_section,
00115 objc_class_vars_section,
00116 objc_instance_vars_section,
00117 objc_module_info_section,
00118 objc_symbols_section
00119 };
00120 size_t i;
00121
00122 been_here = true;
00123 for (i = 0; i < ARRAY_SIZE (tomark); i++)
00124 switch_to_section (darwin_sections[tomark[i]]);
00125 }
00126 output_section_asm_op (directive);
00127 }
00128
00129
00130
00131 void
00132 darwin_init_sections (void)
00133 {
00134 #define DEF_SECTION(NAME, FLAGS, DIRECTIVE, OBJC) \
00135 darwin_sections[NAME] = \
00136 get_unnamed_section (FLAGS, (OBJC \
00137 ? output_objc_section_asm_op \
00138 : output_section_asm_op), \
00139 "\t" DIRECTIVE);
00140 #include "config/darwin-sections.def"
00141 #undef DEF_SECTION
00142
00143 readonly_data_section = darwin_sections[const_section];
00144 exception_section = darwin_sections[darwin_exception_section];
00145 eh_frame_section = darwin_sections[darwin_eh_frame_section];
00146 }
00147
00148 int
00149 name_needs_quotes (const char *name)
00150 {
00151 int c;
00152 while ((c = *name++) != '\0')
00153 if (! ISIDNUM (c) && c != '.' && c != '$')
00154 return 1;
00155 return 0;
00156 }
00157
00158
00159 static int
00160 machopic_symbol_defined_p (rtx sym_ref)
00161 {
00162 if (SYMBOL_REF_FLAGS (sym_ref) & MACHO_SYMBOL_FLAG_DEFINED)
00163 return true;
00164
00165
00166
00167 if (SYMBOL_REF_LOCAL_P (sym_ref) && ! SYMBOL_REF_EXTERNAL_P (sym_ref))
00168 {
00169
00170
00171 if (SYMBOL_REF_FLAGS (sym_ref) & MACHO_SYMBOL_FLAG_VARIABLE)
00172 {
00173 tree decl = SYMBOL_REF_DECL (sym_ref);
00174 if (!decl)
00175 return true;
00176 if (DECL_COMMON (decl))
00177 return false;
00178 }
00179 return true;
00180 }
00181 return false;
00182 }
00183
00184
00185
00186
00187 enum machopic_addr_class
00188 machopic_classify_symbol (rtx sym_ref)
00189 {
00190 int flags;
00191 bool function_p;
00192
00193 flags = SYMBOL_REF_FLAGS (sym_ref);
00194 function_p = SYMBOL_REF_FUNCTION_P (sym_ref);
00195 if (machopic_symbol_defined_p (sym_ref))
00196 return (function_p
00197 ? MACHOPIC_DEFINED_FUNCTION : MACHOPIC_DEFINED_DATA);
00198 else
00199 return (function_p
00200 ? MACHOPIC_UNDEFINED_FUNCTION : MACHOPIC_UNDEFINED_DATA);
00201 }
00202
00203 #ifndef TARGET_FIX_AND_CONTINUE
00204 #define TARGET_FIX_AND_CONTINUE 0
00205 #endif
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 static int
00218 indirect_data (rtx sym_ref)
00219 {
00220 int lprefix;
00221 const char *name;
00222
00223
00224 if (TARGET_FIX_AND_CONTINUE == 0)
00225 return 0;
00226
00227
00228
00229
00230
00231
00232 name = XSTR (sym_ref, 0);
00233
00234 lprefix = (((name[0] == '*' || name[0] == '&')
00235 && (name[1] == 'L' || (name[1] == '"' && name[2] == 'L')))
00236 || (strncmp (name, "_OBJC_", 6) == 0));
00237
00238 return ! lprefix;
00239 }
00240
00241
00242 static int
00243 machopic_data_defined_p (rtx sym_ref)
00244 {
00245 if (indirect_data (sym_ref))
00246 return 0;
00247
00248 switch (machopic_classify_symbol (sym_ref))
00249 {
00250 case MACHOPIC_DEFINED_DATA:
00251 case MACHOPIC_DEFINED_FUNCTION:
00252 return 1;
00253 default:
00254 return 0;
00255 }
00256 }
00257
00258 void
00259 machopic_define_symbol (rtx mem)
00260 {
00261 rtx sym_ref;
00262
00263 gcc_assert (GET_CODE (mem) == MEM);
00264 sym_ref = XEXP (mem, 0);
00265 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
00266 }
00267
00268 static GTY(()) char * function_base;
00269
00270 const char *
00271 machopic_function_base_name (void)
00272 {
00273
00274 gcc_assert (!MACHO_DYNAMIC_NO_PIC_P);
00275
00276 if (function_base == NULL)
00277 function_base =
00278 (char *) ggc_alloc_string ("<pic base>", sizeof ("<pic base>"));
00279
00280 current_function_uses_pic_offset_table = 1;
00281
00282 return function_base;
00283 }
00284
00285
00286
00287 rtx
00288 machopic_function_base_sym (void)
00289 {
00290 rtx sym_ref;
00291
00292 sym_ref = gen_rtx_SYMBOL_REF (Pmode, machopic_function_base_name ());
00293 SYMBOL_REF_FLAGS (sym_ref)
00294 |= (MACHO_SYMBOL_FLAG_VARIABLE | MACHO_SYMBOL_FLAG_DEFINED);
00295 return sym_ref;
00296 }
00297
00298
00299
00300 static inline rtx
00301 gen_pic_offset (rtx orig, rtx pic_base)
00302 {
00303 if (!pic_base)
00304 return orig;
00305 else
00306 return gen_rtx_CONST (Pmode, gen_rtx_MINUS (Pmode, orig, pic_base));
00307 }
00308
00309 static GTY(()) const char * function_base_func_name;
00310 static GTY(()) int current_pic_label_num;
00311
00312 void
00313 machopic_output_function_base_name (FILE *file)
00314 {
00315 const char *current_name;
00316
00317
00318 gcc_assert (!MACHO_DYNAMIC_NO_PIC_P);
00319 current_name =
00320 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
00321 if (function_base_func_name != current_name)
00322 {
00323 ++current_pic_label_num;
00324 function_base_func_name = current_name;
00325 }
00326 fprintf (file, "\"L%011d$pb\"", current_pic_label_num);
00327 }
00328
00329
00330 #define NON_LAZY_POINTER_SUFFIX "$non_lazy_ptr"
00331
00332 #define STUB_SUFFIX "$stub"
00333
00334 typedef struct machopic_indirection GTY (())
00335 {
00336
00337 rtx symbol;
00338
00339 const char * ptr_name;
00340
00341
00342 bool stub_p;
00343
00344 bool used;
00345 } machopic_indirection;
00346
00347
00348
00349
00350 static GTY ((param_is (struct machopic_indirection))) htab_t
00351 machopic_indirections;
00352
00353
00354
00355 static hashval_t
00356 machopic_indirection_hash (const void *slot)
00357 {
00358 const machopic_indirection *p = (const machopic_indirection *) slot;
00359 return htab_hash_string (p->ptr_name);
00360 }
00361
00362
00363
00364
00365 static int
00366 machopic_indirection_eq (const void *slot, const void *key)
00367 {
00368 return strcmp (((const machopic_indirection *) slot)->ptr_name, key) == 0;
00369 }
00370
00371
00372
00373
00374 const char *
00375 machopic_indirection_name (rtx sym_ref, bool stub_p)
00376 {
00377 char *buffer;
00378 const char *name = XSTR (sym_ref, 0);
00379 size_t namelen = strlen (name);
00380 machopic_indirection *p;
00381 void ** slot;
00382 bool saw_star = false;
00383 bool needs_quotes;
00384 const char *suffix;
00385 const char *prefix = user_label_prefix;
00386 const char *quote = "";
00387 tree id;
00388
00389 id = maybe_get_identifier (name);
00390 if (id)
00391 {
00392 tree id_orig = id;
00393
00394 while (IDENTIFIER_TRANSPARENT_ALIAS (id))
00395 id = TREE_CHAIN (id);
00396 if (id != id_orig)
00397 {
00398 name = IDENTIFIER_POINTER (id);
00399 namelen = strlen (name);
00400 }
00401 }
00402
00403 if (name[0] == '*')
00404 {
00405 saw_star = true;
00406 prefix = "";
00407 ++name;
00408 --namelen;
00409 }
00410
00411 needs_quotes = name_needs_quotes (name);
00412 if (needs_quotes)
00413 {
00414 quote = "\"";
00415 }
00416
00417 if (stub_p)
00418 suffix = STUB_SUFFIX;
00419 else
00420 suffix = NON_LAZY_POINTER_SUFFIX;
00421
00422 buffer = alloca (strlen ("&L")
00423 + strlen (prefix)
00424 + namelen
00425 + strlen (suffix)
00426 + 2 * strlen (quote)
00427 + 1 );
00428
00429
00430 sprintf (buffer, "&%sL%s%s%s%s", quote, prefix, name, suffix, quote);
00431
00432 if (!machopic_indirections)
00433 machopic_indirections = htab_create_ggc (37,
00434 machopic_indirection_hash,
00435 machopic_indirection_eq,
00436 NULL);
00437
00438 slot = htab_find_slot_with_hash (machopic_indirections, buffer,
00439 htab_hash_string (buffer), INSERT);
00440 if (*slot)
00441 {
00442 p = (machopic_indirection *) *slot;
00443 }
00444 else
00445 {
00446 p = (machopic_indirection *) ggc_alloc (sizeof (machopic_indirection));
00447 p->symbol = sym_ref;
00448 p->ptr_name = xstrdup (buffer);
00449 p->stub_p = stub_p;
00450 p->used = false;
00451 *slot = p;
00452 }
00453
00454 return p->ptr_name;
00455 }
00456
00457
00458
00459 const char*
00460 machopic_mcount_stub_name (void)
00461 {
00462 rtx symbol = gen_rtx_SYMBOL_REF (Pmode, "*mcount");
00463 return machopic_indirection_name (symbol, true);
00464 }
00465
00466
00467
00468
00469
00470
00471 void
00472 machopic_validate_stub_or_non_lazy_ptr (const char *name)
00473 {
00474 machopic_indirection *p;
00475
00476 p = ((machopic_indirection *)
00477 (htab_find_with_hash (machopic_indirections, name,
00478 htab_hash_string (name))));
00479 if (p && ! p->used)
00480 {
00481 const char *real_name;
00482 tree id;
00483
00484 p->used = true;
00485
00486
00487 if (SYMBOL_REF_DECL (p->symbol))
00488 mark_decl_referenced (SYMBOL_REF_DECL (p->symbol));
00489
00490 real_name = targetm.strip_name_encoding (XSTR (p->symbol, 0));
00491
00492 id = maybe_get_identifier (real_name);
00493 if (id)
00494 mark_referenced (id);
00495 }
00496 }
00497
00498
00499
00500
00501 rtx
00502 machopic_indirect_data_reference (rtx orig, rtx reg)
00503 {
00504 rtx ptr_ref = orig;
00505
00506 if (! MACHOPIC_INDIRECT)
00507 return orig;
00508
00509 if (GET_CODE (orig) == SYMBOL_REF)
00510 {
00511 int defined = machopic_data_defined_p (orig);
00512
00513 if (defined && MACHO_DYNAMIC_NO_PIC_P)
00514 {
00515 #if defined (TARGET_TOC)
00516
00517 rtx hi_reg = (no_new_pseudos ? reg : gen_reg_rtx (Pmode));
00518 emit_insn (gen_macho_high (hi_reg, orig));
00519 emit_insn (gen_macho_low (reg, hi_reg, orig));
00520 #else
00521
00522 gcc_unreachable ();
00523 #endif
00524 return reg;
00525 }
00526 else if (defined)
00527 {
00528 #if defined (TARGET_TOC) || defined (HAVE_lo_sum)
00529 rtx pic_base = machopic_function_base_sym ();
00530 rtx offset = gen_pic_offset (orig, pic_base);
00531 #endif
00532
00533 #if defined (TARGET_TOC)
00534 rtx hi_sum_reg = (no_new_pseudos ? reg : gen_reg_rtx (Pmode));
00535
00536 gcc_assert (reg);
00537
00538 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
00539 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
00540 gen_rtx_HIGH (Pmode, offset))));
00541 emit_insn (gen_rtx_SET (Pmode, reg,
00542 gen_rtx_LO_SUM (Pmode, hi_sum_reg, offset)));
00543
00544 orig = reg;
00545 #else
00546 #if defined (HAVE_lo_sum)
00547 gcc_assert (reg);
00548
00549 emit_insn (gen_rtx_SET (VOIDmode, reg,
00550 gen_rtx_HIGH (Pmode, offset)));
00551 emit_insn (gen_rtx_SET (VOIDmode, reg,
00552 gen_rtx_LO_SUM (Pmode, reg, offset)));
00553 emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
00554
00555 orig = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, reg);
00556 #endif
00557 #endif
00558 return orig;
00559 }
00560
00561 ptr_ref = (gen_rtx_SYMBOL_REF
00562 (Pmode,
00563 machopic_indirection_name (orig, false)));
00564
00565 SYMBOL_REF_DATA (ptr_ref) = SYMBOL_REF_DATA (orig);
00566
00567 ptr_ref = gen_const_mem (Pmode, ptr_ref);
00568 machopic_define_symbol (ptr_ref);
00569
00570 return ptr_ref;
00571 }
00572 else if (GET_CODE (orig) == CONST)
00573 {
00574 rtx base, result;
00575
00576
00577 if (GET_CODE (XEXP (orig, 0)) == PLUS)
00578 {
00579 base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0),
00580 reg);
00581 orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
00582 (base == reg ? 0 : reg));
00583 }
00584 else
00585 return orig;
00586
00587 if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
00588 result = plus_constant (base, INTVAL (orig));
00589 else
00590 result = gen_rtx_PLUS (Pmode, base, orig);
00591
00592 if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
00593 {
00594 if (reg)
00595 {
00596 emit_move_insn (reg, result);
00597 result = reg;
00598 }
00599 else
00600 {
00601 result = force_reg (GET_MODE (result), result);
00602 }
00603 }
00604
00605 return result;
00606
00607 }
00608 else if (GET_CODE (orig) == MEM)
00609 XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
00610
00611
00612
00613
00614 else if (GET_CODE (orig) == PLUS
00615 && GET_CODE (XEXP (orig, 0)) == REG
00616 && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
00617 #ifdef I386
00618
00619
00620 && GET_CODE (XEXP (orig, 1)) == CONST
00621 #endif
00622 && reg)
00623 {
00624 emit_move_insn (reg, XEXP (orig, 0));
00625 XEXP (ptr_ref, 0) = reg;
00626 }
00627 return ptr_ref;
00628 }
00629
00630
00631
00632
00633 rtx
00634 machopic_indirect_call_target (rtx target)
00635 {
00636 if (GET_CODE (target) != MEM)
00637 return target;
00638
00639 if (MACHOPIC_INDIRECT
00640 && GET_CODE (XEXP (target, 0)) == SYMBOL_REF
00641 && !(SYMBOL_REF_FLAGS (XEXP (target, 0))
00642 & MACHO_SYMBOL_FLAG_DEFINED))
00643 {
00644 rtx sym_ref = XEXP (target, 0);
00645 const char *stub_name = machopic_indirection_name (sym_ref,
00646 true);
00647 enum machine_mode mode = GET_MODE (sym_ref);
00648
00649 XEXP (target, 0) = gen_rtx_SYMBOL_REF (mode, stub_name);
00650 SYMBOL_REF_DATA (XEXP (target, 0)) = SYMBOL_REF_DATA (sym_ref);
00651 MEM_READONLY_P (target) = 1;
00652 MEM_NOTRAP_P (target) = 1;
00653 }
00654
00655 return target;
00656 }
00657
00658 rtx
00659 machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
00660 {
00661 rtx pic_ref = orig;
00662
00663 if (! MACHOPIC_INDIRECT)
00664 return orig;
00665
00666
00667 if (GET_CODE (orig) == LABEL_REF
00668 || (GET_CODE (orig) == SYMBOL_REF
00669 ))
00670 {
00671
00672 rtx pic_base;
00673
00674 orig = machopic_indirect_data_reference (orig, reg);
00675
00676 if (GET_CODE (orig) == PLUS
00677 && GET_CODE (XEXP (orig, 0)) == REG)
00678 {
00679 if (reg == 0)
00680 return force_reg (mode, orig);
00681
00682 emit_move_insn (reg, orig);
00683 return reg;
00684 }
00685
00686
00687 if (MACHO_DYNAMIC_NO_PIC_P)
00688 pic_base = NULL;
00689 else
00690 pic_base = machopic_function_base_sym ();
00691
00692 if (GET_CODE (orig) == MEM)
00693 {
00694 if (reg == 0)
00695 {
00696 gcc_assert (!reload_in_progress);
00697 reg = gen_reg_rtx (Pmode);
00698 }
00699
00700 #ifdef HAVE_lo_sum
00701 if (MACHO_DYNAMIC_NO_PIC_P
00702 && (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
00703 || GET_CODE (XEXP (orig, 0)) == LABEL_REF))
00704 {
00705 #if defined (TARGET_TOC)
00706 rtx temp_reg = (no_new_pseudos) ? reg : gen_reg_rtx (Pmode);
00707 rtx asym = XEXP (orig, 0);
00708 rtx mem;
00709
00710 emit_insn (gen_macho_high (temp_reg, asym));
00711 mem = gen_const_mem (GET_MODE (orig),
00712 gen_rtx_LO_SUM (Pmode, temp_reg, asym));
00713 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
00714 #else
00715
00716 gcc_unreachable ();
00717 #endif
00718 pic_ref = reg;
00719 }
00720 else
00721 if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
00722 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
00723 {
00724 rtx offset = gen_pic_offset (XEXP (orig, 0), pic_base);
00725 #if defined (TARGET_TOC)
00726
00727
00728 rtx hi_sum_reg = no_new_pseudos ? reg : gen_reg_rtx (Pmode);
00729 rtx mem;
00730 rtx insn;
00731 rtx sum;
00732
00733 sum = gen_rtx_HIGH (Pmode, offset);
00734 if (! MACHO_DYNAMIC_NO_PIC_P)
00735 sum = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, sum);
00736
00737 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg, sum));
00738
00739 mem = gen_const_mem (GET_MODE (orig),
00740 gen_rtx_LO_SUM (Pmode,
00741 hi_sum_reg, offset));
00742 insn = emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
00743 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, pic_ref,
00744 REG_NOTES (insn));
00745
00746 pic_ref = reg;
00747 #else
00748 emit_insn (gen_rtx_USE (VOIDmode,
00749 gen_rtx_REG (Pmode,
00750 PIC_OFFSET_TABLE_REGNUM)));
00751
00752 emit_insn (gen_rtx_SET (VOIDmode, reg,
00753 gen_rtx_HIGH (Pmode,
00754 gen_rtx_CONST (Pmode,
00755 offset))));
00756 emit_insn (gen_rtx_SET (VOIDmode, reg,
00757 gen_rtx_LO_SUM (Pmode, reg,
00758 gen_rtx_CONST (Pmode, offset))));
00759 pic_ref = gen_rtx_PLUS (Pmode,
00760 pic_offset_table_rtx, reg);
00761 #endif
00762 }
00763 else
00764 #endif
00765 {
00766 rtx pic = pic_offset_table_rtx;
00767 if (GET_CODE (pic) != REG)
00768 {
00769 emit_move_insn (reg, pic);
00770 pic = reg;
00771 }
00772 #if 0
00773 emit_insn (gen_rtx_USE (VOIDmode,
00774 gen_rtx_REG (Pmode,
00775 PIC_OFFSET_TABLE_REGNUM)));
00776 #endif
00777
00778 if (reload_in_progress)
00779 regs_ever_live[REGNO (pic)] = 1;
00780 pic_ref = gen_rtx_PLUS (Pmode, pic,
00781 gen_pic_offset (XEXP (orig, 0),
00782 pic_base));
00783 }
00784
00785 #if !defined (TARGET_TOC)
00786 emit_move_insn (reg, pic_ref);
00787 pic_ref = gen_const_mem (GET_MODE (orig), reg);
00788 #endif
00789 }
00790 else
00791 {
00792
00793 #ifdef HAVE_lo_sum
00794 if (GET_CODE (orig) == SYMBOL_REF
00795 || GET_CODE (orig) == LABEL_REF)
00796 {
00797 rtx offset = gen_pic_offset (orig, pic_base);
00798 #if defined (TARGET_TOC)
00799 rtx hi_sum_reg;
00800
00801 if (reg == 0)
00802 {
00803 gcc_assert (!reload_in_progress);
00804 reg = gen_reg_rtx (Pmode);
00805 }
00806
00807 hi_sum_reg = reg;
00808
00809 emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
00810 (MACHO_DYNAMIC_NO_PIC_P)
00811 ? gen_rtx_HIGH (Pmode, offset)
00812 : gen_rtx_PLUS (Pmode,
00813 pic_offset_table_rtx,
00814 gen_rtx_HIGH (Pmode,
00815 offset))));
00816 emit_insn (gen_rtx_SET (VOIDmode, reg,
00817 gen_rtx_LO_SUM (Pmode,
00818 hi_sum_reg, offset)));
00819 pic_ref = reg;
00820 #else
00821 emit_insn (gen_rtx_SET (VOIDmode, reg,
00822 gen_rtx_HIGH (Pmode, offset)));
00823 emit_insn (gen_rtx_SET (VOIDmode, reg,
00824 gen_rtx_LO_SUM (Pmode, reg, offset)));
00825 pic_ref = gen_rtx_PLUS (Pmode,
00826 pic_offset_table_rtx, reg);
00827 #endif
00828 }
00829 else
00830 #endif
00831 {
00832 if (REG_P (orig)
00833 || GET_CODE (orig) == SUBREG)
00834 {
00835 return orig;
00836 }
00837 else
00838 {
00839 rtx pic = pic_offset_table_rtx;
00840 if (GET_CODE (pic) != REG)
00841 {
00842 emit_move_insn (reg, pic);
00843 pic = reg;
00844 }
00845 #if 0
00846 emit_insn (gen_rtx_USE (VOIDmode,
00847 pic_offset_table_rtx));
00848 #endif
00849 if (reload_in_progress)
00850 regs_ever_live[REGNO (pic)] = 1;
00851 pic_ref = gen_rtx_PLUS (Pmode,
00852 pic,
00853 gen_pic_offset (orig, pic_base));
00854 }
00855 }
00856 }
00857
00858 if (GET_CODE (pic_ref) != REG)
00859 {
00860 if (reg != 0)
00861 {
00862 emit_move_insn (reg, pic_ref);
00863 return reg;
00864 }
00865 else
00866 {
00867 return force_reg (mode, pic_ref);
00868 }
00869 }
00870 else
00871 {
00872 return pic_ref;
00873 }
00874 }
00875
00876 else if (GET_CODE (orig) == SYMBOL_REF)
00877 return orig;
00878
00879 else if (GET_CODE (orig) == PLUS
00880 && (GET_CODE (XEXP (orig, 0)) == MEM
00881 || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
00882 || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
00883 && XEXP (orig, 0) != pic_offset_table_rtx
00884 && GET_CODE (XEXP (orig, 1)) != REG)
00885
00886 {
00887 rtx base;
00888 int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
00889
00890 base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
00891 orig = machopic_legitimize_pic_address (XEXP (orig, 1),
00892 Pmode, (base == reg ? 0 : reg));
00893 if (GET_CODE (orig) == CONST_INT)
00894 {
00895 pic_ref = plus_constant (base, INTVAL (orig));
00896 is_complex = 1;
00897 }
00898 else
00899 pic_ref = gen_rtx_PLUS (Pmode, base, orig);
00900
00901 if (reg && is_complex)
00902 {
00903 emit_move_insn (reg, pic_ref);
00904 pic_ref = reg;
00905 }
00906
00907 }
00908
00909 else if (GET_CODE (orig) == CONST)
00910 {
00911 return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
00912 }
00913
00914 else if (GET_CODE (orig) == MEM
00915 && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
00916 {
00917 rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
00918 addr = replace_equiv_address (orig, addr);
00919 emit_move_insn (reg, addr);
00920 pic_ref = reg;
00921 }
00922
00923 return pic_ref;
00924 }
00925
00926
00927
00928
00929
00930 static int
00931 machopic_output_indirection (void **slot, void *data)
00932 {
00933 machopic_indirection *p = *((machopic_indirection **) slot);
00934 FILE *asm_out_file = (FILE *) data;
00935 rtx symbol;
00936 const char *sym_name;
00937 const char *ptr_name;
00938
00939 if (!p->used)
00940 return 1;
00941
00942 symbol = p->symbol;
00943 sym_name = XSTR (symbol, 0);
00944 ptr_name = p->ptr_name;
00945
00946 if (p->stub_p)
00947 {
00948 char *sym;
00949 char *stub;
00950 tree id;
00951
00952 id = maybe_get_identifier (sym_name);
00953 if (id)
00954 {
00955 tree id_orig = id;
00956
00957 while (IDENTIFIER_TRANSPARENT_ALIAS (id))
00958 id = TREE_CHAIN (id);
00959 if (id != id_orig)
00960 sym_name = IDENTIFIER_POINTER (id);
00961 }
00962
00963 sym = alloca (strlen (sym_name) + 2);
00964 if (sym_name[0] == '*' || sym_name[0] == '&')
00965 strcpy (sym, sym_name + 1);
00966 else if (sym_name[0] == '-' || sym_name[0] == '+')
00967 strcpy (sym, sym_name);
00968 else
00969 sprintf (sym, "%s%s", user_label_prefix, sym_name);
00970
00971 stub = alloca (strlen (ptr_name) + 2);
00972 if (ptr_name[0] == '*' || ptr_name[0] == '&')
00973 strcpy (stub, ptr_name + 1);
00974 else
00975 sprintf (stub, "%s%s", user_label_prefix, ptr_name);
00976
00977 machopic_output_stub (asm_out_file, sym, stub);
00978 }
00979 else if (! indirect_data (symbol)
00980 && (machopic_symbol_defined_p (symbol)
00981 || SYMBOL_REF_LOCAL_P (symbol)))
00982 {
00983 switch_to_section (data_section);
00984 assemble_align (GET_MODE_ALIGNMENT (Pmode));
00985 assemble_label (ptr_name);
00986 assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
00987 GET_MODE_SIZE (Pmode),
00988 GET_MODE_ALIGNMENT (Pmode), 1);
00989 }
00990 else
00991 {
00992 rtx init = const0_rtx;
00993
00994 switch_to_section (darwin_sections[machopic_nl_symbol_ptr_section]);
00995 assemble_name (asm_out_file, ptr_name);
00996 fprintf (asm_out_file, ":\n");
00997
00998 fprintf (asm_out_file, "\t.indirect_symbol ");
00999 assemble_name (asm_out_file, sym_name);
01000 fprintf (asm_out_file, "\n");
01001
01002
01003
01004
01005
01006
01007
01008
01009 if ((SYMBOL_REF_FLAGS (symbol) & MACHO_SYMBOL_STATIC)
01010 && machopic_symbol_defined_p (symbol))
01011 init = gen_rtx_SYMBOL_REF (Pmode, sym_name);
01012
01013 assemble_integer (init, GET_MODE_SIZE (Pmode),
01014 GET_MODE_ALIGNMENT (Pmode), 1);
01015 }
01016
01017 return 1;
01018 }
01019
01020 void
01021 machopic_finish (FILE *asm_out_file)
01022 {
01023 if (machopic_indirections)
01024 htab_traverse_noresize (machopic_indirections,
01025 machopic_output_indirection,
01026 asm_out_file);
01027 }
01028
01029 int
01030 machopic_operand_p (rtx op)
01031 {
01032 if (MACHOPIC_JUST_INDIRECT)
01033 {
01034 while (GET_CODE (op) == CONST)
01035 op = XEXP (op, 0);
01036
01037 if (GET_CODE (op) == SYMBOL_REF)
01038 return machopic_symbol_defined_p (op);
01039 else
01040 return 0;
01041 }
01042
01043 while (GET_CODE (op) == CONST)
01044 op = XEXP (op, 0);
01045
01046 if (GET_CODE (op) == MINUS
01047 && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
01048 && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
01049 && machopic_symbol_defined_p (XEXP (op, 0))
01050 && machopic_symbol_defined_p (XEXP (op, 1)))
01051 return 1;
01052
01053 return 0;
01054 }
01055
01056
01057
01058
01059
01060 void
01061 darwin_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
01062 {
01063 rtx sym_ref;
01064
01065
01066 default_encode_section_info (decl, rtl, first);
01067
01068 if (TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
01069 return;
01070
01071 sym_ref = XEXP (rtl, 0);
01072 if (TREE_CODE (decl) == VAR_DECL)
01073 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_VARIABLE;
01074
01075 if (!DECL_EXTERNAL (decl)
01076 && (!TREE_PUBLIC (decl) || !DECL_WEAK (decl))
01077 && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
01078 && ((TREE_STATIC (decl)
01079 && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
01080 || (!DECL_COMMON (decl) && DECL_INITIAL (decl)
01081 && DECL_INITIAL (decl) != error_mark_node)))
01082 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
01083
01084 if (! TREE_PUBLIC (decl))
01085 SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_STATIC;
01086 }
01087
01088 void
01089 darwin_mark_decl_preserved (const char *name)
01090 {
01091 fprintf (asm_out_file, ".no_dead_strip ");
01092 assemble_name (asm_out_file, name);
01093 fputc ('\n', asm_out_file);
01094 }
01095
01096 int
01097 machopic_reloc_rw_mask (void)
01098 {
01099 return MACHOPIC_INDIRECT ? 3 : 0;
01100 }
01101
01102 section *
01103 machopic_select_section (tree exp, int reloc,
01104 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
01105 {
01106 section *base_section;
01107 bool weak_p = (DECL_P (exp) && DECL_WEAK (exp)
01108 && (lookup_attribute ("weak", DECL_ATTRIBUTES (exp))
01109 || ! lookup_attribute ("weak_import",
01110 DECL_ATTRIBUTES (exp))));
01111
01112 if (TREE_CODE (exp) == FUNCTION_DECL)
01113 {
01114 if (reloc == 1)
01115 base_section = (weak_p
01116 ? darwin_sections[text_unlikely_coal_section]
01117 : unlikely_text_section ());
01118 else
01119 base_section = weak_p ? darwin_sections[text_coal_section] : text_section;
01120 }
01121 else if (decl_readonly_section (exp, reloc))
01122 base_section = weak_p ? darwin_sections[const_coal_section] : darwin_sections[const_section];
01123 else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
01124 base_section = weak_p ? darwin_sections[const_data_coal_section] : darwin_sections[const_data_section];
01125 else
01126 base_section = weak_p ? darwin_sections[data_coal_section] : data_section;
01127
01128 if (TREE_CODE (exp) == STRING_CST
01129 && ((size_t) TREE_STRING_LENGTH (exp)
01130 == strlen (TREE_STRING_POINTER (exp)) + 1))
01131 return darwin_sections[cstring_section];
01132 else if ((TREE_CODE (exp) == INTEGER_CST || TREE_CODE (exp) == REAL_CST)
01133 && flag_merge_constants)
01134 {
01135 tree size = TYPE_SIZE_UNIT (TREE_TYPE (exp));
01136
01137 if (TREE_CODE (size) == INTEGER_CST &&
01138 TREE_INT_CST_LOW (size) == 4 &&
01139 TREE_INT_CST_HIGH (size) == 0)
01140 return darwin_sections[literal4_section];
01141 else if (TREE_CODE (size) == INTEGER_CST &&
01142 TREE_INT_CST_LOW (size) == 8 &&
01143 TREE_INT_CST_HIGH (size) == 0)
01144 return darwin_sections[literal8_section];
01145 else if (TARGET_64BIT
01146 && TREE_CODE (size) == INTEGER_CST
01147 && TREE_INT_CST_LOW (size) == 16
01148 && TREE_INT_CST_HIGH (size) == 0)
01149 return darwin_sections[literal16_section];
01150 else
01151 return base_section;
01152 }
01153 else if (TREE_CODE (exp) == CONSTRUCTOR
01154 && TREE_TYPE (exp)
01155 && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
01156 && TYPE_NAME (TREE_TYPE (exp)))
01157 {
01158 tree name = TYPE_NAME (TREE_TYPE (exp));
01159 if (TREE_CODE (name) == TYPE_DECL)
01160 name = DECL_NAME (name);
01161
01162 if (!strcmp (IDENTIFIER_POINTER (name), "__builtin_ObjCString"))
01163 {
01164 if (flag_next_runtime)
01165 return darwin_sections[objc_constant_string_object_section];
01166 else
01167 return darwin_sections[objc_string_object_section];
01168 }
01169 else
01170 return base_section;
01171 }
01172 else if (TREE_CODE (exp) == VAR_DECL &&
01173 DECL_NAME (exp) &&
01174 TREE_CODE (DECL_NAME (exp)) == IDENTIFIER_NODE &&
01175 IDENTIFIER_POINTER (DECL_NAME (exp)) &&
01176 !strncmp (IDENTIFIER_POINTER (DECL_NAME (exp)), "_OBJC_", 6))
01177 {
01178 const char *name = IDENTIFIER_POINTER (DECL_NAME (exp));
01179
01180 if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
01181 return darwin_sections[objc_cls_meth_section];
01182 else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
01183 return darwin_sections[objc_inst_meth_section];
01184 else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
01185 return darwin_sections[objc_cat_cls_meth_section];
01186 else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
01187 return darwin_sections[objc_cat_inst_meth_section];
01188 else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
01189 return darwin_sections[objc_class_vars_section];
01190 else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
01191 return darwin_sections[objc_instance_vars_section];
01192 else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
01193 return darwin_sections[objc_cat_cls_meth_section];
01194 else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
01195 return darwin_sections[objc_class_names_section];
01196 else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
01197 return darwin_sections[objc_meth_var_names_section];
01198 else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
01199 return darwin_sections[objc_meth_var_types_section];
01200 else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
01201 return darwin_sections[objc_cls_refs_section];
01202 else if (!strncmp (name, "_OBJC_CLASS_", 12))
01203 return darwin_sections[objc_class_section];
01204 else if (!strncmp (name, "_OBJC_METACLASS_", 16))
01205 return darwin_sections[objc_meta_class_section];
01206 else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
01207 return darwin_sections[objc_category_section];
01208 else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
01209 return darwin_sections[objc_selector_refs_section];
01210 else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
01211 return darwin_sections[objc_selector_fixup_section];
01212 else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
01213 return darwin_sections[objc_symbols_section];
01214 else if (!strncmp (name, "_OBJC_MODULES", 13))
01215 return darwin_sections[objc_module_info_section];
01216 else if (!strncmp (name, "_OBJC_IMAGE_INFO", 16))
01217 return darwin_sections[objc_image_info_section];
01218 else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
01219 return darwin_sections[objc_cat_inst_meth_section];
01220 else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
01221 return darwin_sections[objc_cat_cls_meth_section];
01222 else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
01223 return darwin_sections[objc_cat_cls_meth_section];
01224 else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
01225 return darwin_sections[objc_protocol_section];
01226 else
01227 return base_section;
01228 }
01229 else
01230 return base_section;
01231 }
01232
01233
01234
01235
01236 section *
01237 machopic_select_rtx_section (enum machine_mode mode, rtx x,
01238 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
01239 {
01240 if (GET_MODE_SIZE (mode) == 8
01241 && (GET_CODE (x) == CONST_INT
01242 || GET_CODE (x) == CONST_DOUBLE))
01243 return darwin_sections[literal8_section];
01244 else if (GET_MODE_SIZE (mode) == 4
01245 && (GET_CODE (x) == CONST_INT
01246 || GET_CODE (x) == CONST_DOUBLE))
01247 return darwin_sections[literal4_section];
01248 else if (TARGET_64BIT
01249 && GET_MODE_SIZE (mode) == 16
01250 && (GET_CODE (x) == CONST_INT
01251 || GET_CODE (x) == CONST_DOUBLE
01252 || GET_CODE (x) == CONST_VECTOR))
01253 return darwin_sections[literal16_section];
01254 else if (MACHOPIC_INDIRECT
01255 && (GET_CODE (x) == SYMBOL_REF
01256 || GET_CODE (x) == CONST
01257 || GET_CODE (x) == LABEL_REF))
01258 return darwin_sections[const_data_section];
01259 else
01260 return darwin_sections[const_section];
01261 }
01262
01263 void
01264 machopic_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
01265 {
01266 if (MACHOPIC_INDIRECT)
01267 switch_to_section (darwin_sections[mod_init_section]);
01268 else
01269 switch_to_section (darwin_sections[constructor_section]);
01270 assemble_align (POINTER_SIZE);
01271 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
01272
01273 if (! MACHOPIC_INDIRECT)
01274 fprintf (asm_out_file, ".reference .constructors_used\n");
01275 }
01276
01277 void
01278 machopic_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
01279 {
01280 if (MACHOPIC_INDIRECT)
01281 switch_to_section (darwin_sections[mod_term_section]);
01282 else
01283 switch_to_section (darwin_sections[destructor_section]);
01284 assemble_align (POINTER_SIZE);
01285 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
01286
01287 if (! MACHOPIC_INDIRECT)
01288 fprintf (asm_out_file, ".reference .destructors_used\n");
01289 }
01290
01291 void
01292 darwin_globalize_label (FILE *stream, const char *name)
01293 {
01294 if (!!strncmp (name, "_OBJC_", 6))
01295 default_globalize_label (stream, name);
01296 }
01297
01298 void
01299 darwin_asm_named_section (const char *name,
01300 unsigned int flags ATTRIBUTE_UNUSED,
01301 tree decl ATTRIBUTE_UNUSED)
01302 {
01303 fprintf (asm_out_file, "\t.section %s\n", name);
01304 }
01305
01306 void
01307 darwin_unique_section (tree decl ATTRIBUTE_UNUSED, int reloc ATTRIBUTE_UNUSED)
01308 {
01309
01310 }
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323 tree
01324 darwin_handle_kext_attribute (tree *node, tree name,
01325 tree args ATTRIBUTE_UNUSED,
01326 int flags ATTRIBUTE_UNUSED,
01327 bool *no_add_attrs)
01328 {
01329
01330 if (! TARGET_KEXTABI)
01331 {
01332 warning (0, "%<%s%> 2.95 vtable-compatability attribute applies "
01333 "only when compiling a kext", IDENTIFIER_POINTER (name));
01334
01335 *no_add_attrs = true;
01336 }
01337 else if (TREE_CODE (*node) != RECORD_TYPE)
01338 {
01339 warning (0, "%<%s%> 2.95 vtable-compatability attribute applies "
01340 "only to C++ classes", IDENTIFIER_POINTER (name));
01341
01342 *no_add_attrs = true;
01343 }
01344
01345 return NULL_TREE;
01346 }
01347
01348
01349
01350
01351 tree
01352 darwin_handle_weak_import_attribute (tree *node, tree name,
01353 tree ARG_UNUSED (args),
01354 int ARG_UNUSED (flags),
01355 bool * no_add_attrs)
01356 {
01357 if (TREE_CODE (*node) != FUNCTION_DECL && TREE_CODE (*node) != VAR_DECL)
01358 {
01359 warning (OPT_Wattributes, "%qs attribute ignored",
01360 IDENTIFIER_POINTER (name));
01361 *no_add_attrs = true;
01362 }
01363 else
01364 declare_weak (*node);
01365
01366 return NULL_TREE;
01367 }
01368
01369 static void
01370 no_dead_strip (FILE *file, const char *lab)
01371 {
01372 fprintf (file, ".no_dead_strip %s\n", lab);
01373 }
01374
01375
01376
01377
01378
01379
01380 void
01381 darwin_emit_unwind_label (FILE *file, tree decl, int for_eh, int empty)
01382 {
01383 const char *base;
01384 char *lab;
01385 bool need_quotes;
01386
01387 if (DECL_ASSEMBLER_NAME_SET_P (decl))
01388 base = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
01389 else
01390 base = IDENTIFIER_POINTER (DECL_NAME (decl));
01391
01392 base = targetm.strip_name_encoding (base);
01393 need_quotes = name_needs_quotes (base);
01394
01395 if (! for_eh)
01396 return;
01397
01398 lab = concat (need_quotes ? "\"" : "", user_label_prefix, base, ".eh",
01399 need_quotes ? "\"" : "", NULL);
01400
01401 if (TREE_PUBLIC (decl))
01402 fprintf (file, "\t%s %s\n",
01403 (DECL_VISIBILITY (decl) != VISIBILITY_HIDDEN
01404 ? ".globl"
01405 : ".private_extern"),
01406 lab);
01407
01408 if (DECL_WEAK (decl))
01409 fprintf (file, "\t.weak_definition %s\n", lab);
01410
01411 if (empty)
01412 {
01413 fprintf (file, "%s = 0\n", lab);
01414
01415
01416
01417
01418
01419 no_dead_strip (file, lab);
01420 }
01421 else
01422 fprintf (file, "%s:\n", lab);
01423
01424 free (lab);
01425 }
01426
01427 static GTY(()) unsigned long except_table_label_num;
01428
01429 void
01430 darwin_emit_except_table_label (FILE *file)
01431 {
01432 char section_start_label[30];
01433
01434 ASM_GENERATE_INTERNAL_LABEL (section_start_label, "GCC_except_table",
01435 except_table_label_num++);
01436 ASM_OUTPUT_LABEL (file, section_start_label);
01437 }
01438
01439
01440 void
01441 darwin_non_lazy_pcrel (FILE *file, rtx addr)
01442 {
01443 const char *nlp_name;
01444
01445 gcc_assert (GET_CODE (addr) == SYMBOL_REF);
01446
01447 nlp_name = machopic_indirection_name (addr, false);
01448 fputs ("\t.long\t", file);
01449 ASM_OUTPUT_LABELREF (file, nlp_name);
01450 fputs ("-.", file);
01451 }
01452
01453
01454
01455
01456
01457
01458
01459 void
01460 darwin_assemble_visibility (tree decl, int vis)
01461 {
01462 if (vis == VISIBILITY_DEFAULT)
01463 ;
01464 else if (vis == VISIBILITY_HIDDEN)
01465 {
01466 fputs ("\t.private_extern ", asm_out_file);
01467 assemble_name (asm_out_file,
01468 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
01469 fputs ("\n", asm_out_file);
01470 }
01471 else
01472 warning (OPT_Wattributes, "internal and protected visibility attributes "
01473 "not supported in this configuration; ignored");
01474 }
01475
01476
01477
01478
01479
01480
01481
01482
01483 static int darwin_dwarf_label_counter;
01484
01485 void
01486 darwin_asm_output_dwarf_delta (FILE *file, int size,
01487 const char *lab1, const char *lab2)
01488 {
01489 int islocaldiff = (lab1[0] == '*' && lab1[1] == 'L'
01490 && lab2[0] == '*' && lab2[1] == 'L');
01491 const char *directive = (size == 8 ? ".quad" : ".long");
01492
01493 if (islocaldiff)
01494 fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
01495 else
01496 fprintf (file, "\t%s\t", directive);
01497 assemble_name_raw (file, lab1);
01498 fprintf (file, "-");
01499 assemble_name_raw (file, lab2);
01500 if (islocaldiff)
01501 fprintf (file, "\n\t%s L$set$%d", directive, darwin_dwarf_label_counter++);
01502 }
01503
01504
01505 void
01506 darwin_file_start (void)
01507 {
01508 if (write_symbols == DWARF2_DEBUG)
01509 {
01510 static const char * const debugnames[] =
01511 {
01512 DEBUG_FRAME_SECTION,
01513 DEBUG_INFO_SECTION,
01514 DEBUG_ABBREV_SECTION,
01515 DEBUG_ARANGES_SECTION,
01516 DEBUG_MACINFO_SECTION,
01517 DEBUG_LINE_SECTION,
01518 DEBUG_LOC_SECTION,
01519 DEBUG_PUBNAMES_SECTION,
01520 DEBUG_STR_SECTION,
01521 DEBUG_RANGES_SECTION
01522 };
01523 size_t i;
01524
01525 for (i = 0; i < ARRAY_SIZE (debugnames); i++)
01526 {
01527 int namelen;
01528
01529 switch_to_section (get_section (debugnames[i], SECTION_DEBUG, NULL));
01530
01531 gcc_assert (strncmp (debugnames[i], "__DWARF,", 8) == 0);
01532 gcc_assert (strchr (debugnames[i] + 8, ','));
01533
01534 namelen = strchr (debugnames[i] + 8, ',') - (debugnames[i] + 8);
01535 fprintf (asm_out_file, "Lsection%.*s:\n", namelen, debugnames[i] + 8);
01536 }
01537 }
01538 }
01539
01540
01541
01542
01543
01544
01545 void
01546 darwin_asm_output_dwarf_offset (FILE *file, int size, const char * lab,
01547 section *base)
01548 {
01549 char sname[64];
01550 int namelen;
01551
01552 gcc_assert (base->common.flags & SECTION_NAMED);
01553 gcc_assert (strncmp (base->named.name, "__DWARF,", 8) == 0);
01554 gcc_assert (strchr (base->named.name + 8, ','));
01555
01556 namelen = strchr (base->named.name + 8, ',') - (base->named.name + 8);
01557 sprintf (sname, "*Lsection%.*s", namelen, base->named.name + 8);
01558 darwin_asm_output_dwarf_delta (file, size, lab, sname);
01559 }
01560
01561 void
01562 darwin_file_end (void)
01563 {
01564 machopic_finish (asm_out_file);
01565 if (strcmp (lang_hooks.name, "GNU C++") == 0)
01566 {
01567 switch_to_section (darwin_sections[constructor_section]);
01568 switch_to_section (darwin_sections[destructor_section]);
01569 ASM_OUTPUT_ALIGN (asm_out_file, 1);
01570 }
01571 fprintf (asm_out_file, "\t.subsections_via_symbols\n");
01572 }
01573
01574
01575 #define DARWIN_VTABLE_P(DECL) 0
01576
01577
01578
01579
01580 bool
01581 darwin_binds_local_p (tree decl)
01582 {
01583 return default_binds_local_p_1 (decl,
01584 TARGET_KEXTABI && DARWIN_VTABLE_P (decl));
01585 }
01586
01587 #if 0
01588
01589
01590
01591
01592
01593 void
01594 darwin_asm_output_anchor (rtx symbol)
01595 {
01596 fprintf (asm_out_file, "\t.set\t");
01597 assemble_name (asm_out_file, XSTR (symbol, 0));
01598 fprintf (asm_out_file, ", . + " HOST_WIDE_INT_PRINT_DEC "\n",
01599 SYMBOL_REF_BLOCK_OFFSET (symbol));
01600 }
01601 #endif
01602
01603
01604 void
01605 darwin_set_default_type_attributes (tree type)
01606 {
01607 if (darwin_ms_struct
01608 && TREE_CODE (type) == RECORD_TYPE)
01609 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("ms_struct"),
01610 NULL_TREE,
01611 TYPE_ATTRIBUTES (type));
01612 }
01613
01614
01615
01616 bool
01617 darwin_kextabi_p (void) {
01618 return flag_apple_kext;
01619 }
01620
01621 void
01622 darwin_override_options (void)
01623 {
01624 if (flag_apple_kext && strcmp (lang_hooks.name, "GNU C++") != 0)
01625 {
01626 warning (0, "command line option %<-fapple-kext%> is only valid for C++");
01627 flag_apple_kext = 0;
01628 }
01629 if (flag_mkernel || flag_apple_kext)
01630 {
01631
01632 if (strcmp (lang_hooks.name, "GNU C++") == 0)
01633 flag_apple_kext = 1;
01634
01635 flag_no_common = 1;
01636
01637
01638 flag_exceptions = 0;
01639
01640 flag_non_call_exceptions = 0;
01641 }
01642 }
01643
01644 #include "gt-darwin.h"