Back to index

cell-binutils  2.17cvs20070401
tc-ppc.c
Go to the documentation of this file.
00001 /* tc-ppc.c -- Assemble for the PowerPC or POWER (RS/6000)
00002    Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
00003    2004, 2005, 2006 Free Software Foundation, Inc.
00004    Written by Ian Lance Taylor, Cygnus Support.
00005 
00006    This file is part of GAS, the GNU Assembler.
00007 
00008    GAS is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2, or (at your option)
00011    any later version.
00012 
00013    GAS is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with GAS; see the file COPYING.  If not, write to the Free
00020    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
00021    02110-1301, USA.  */
00022 
00023 #include "as.h"
00024 #include "safe-ctype.h"
00025 #include "subsegs.h"
00026 #include "dw2gencfi.h"
00027 #include "opcode/ppc.h"
00028 
00029 #ifdef OBJ_ELF
00030 #include "elf/ppc.h"
00031 #include "dwarf2dbg.h"
00032 #endif
00033 
00034 #ifdef TE_PE
00035 #include "coff/pe.h"
00036 #endif
00037 
00038 /* This is the assembler for the PowerPC or POWER (RS/6000) chips.  */
00039 
00040 /* Tell the main code what the endianness is.  */
00041 extern int target_big_endian;
00042 
00043 /* Whether or not, we've set target_big_endian.  */
00044 static int set_target_endian = 0;
00045 
00046 /* Whether to use user friendly register names.  */
00047 #ifndef TARGET_REG_NAMES_P
00048 #ifdef TE_PE
00049 #define TARGET_REG_NAMES_P TRUE
00050 #else
00051 #define TARGET_REG_NAMES_P FALSE
00052 #endif
00053 #endif
00054 
00055 /* Macros for calculating LO, HI, HA, HIGHER, HIGHERA, HIGHEST,
00056    HIGHESTA.  */
00057 
00058 /* #lo(value) denotes the least significant 16 bits of the indicated.  */
00059 #define PPC_LO(v) ((v) & 0xffff)
00060 
00061 /* #hi(value) denotes bits 16 through 31 of the indicated value.  */
00062 #define PPC_HI(v) (((v) >> 16) & 0xffff)
00063 
00064 /* #ha(value) denotes the high adjusted value: bits 16 through 31 of
00065   the indicated value, compensating for #lo() being treated as a
00066   signed number.  */
00067 #define PPC_HA(v) PPC_HI ((v) + 0x8000)
00068 
00069 /* #higher(value) denotes bits 32 through 47 of the indicated value.  */
00070 #define PPC_HIGHER(v) (((v) >> 16 >> 16) & 0xffff)
00071 
00072 /* #highera(value) denotes bits 32 through 47 of the indicated value,
00073    compensating for #lo() being treated as a signed number.  */
00074 #define PPC_HIGHERA(v) PPC_HIGHER ((v) + 0x8000)
00075 
00076 /* #highest(value) denotes bits 48 through 63 of the indicated value.  */
00077 #define PPC_HIGHEST(v) (((v) >> 24 >> 24) & 0xffff)
00078 
00079 /* #highesta(value) denotes bits 48 through 63 of the indicated value,
00080    compensating for #lo being treated as a signed number.  */
00081 #define PPC_HIGHESTA(v) PPC_HIGHEST ((v) + 0x8000)
00082 
00083 #define SEX16(val) ((((val) & 0xffff) ^ 0x8000) - 0x8000)
00084 
00085 static bfd_boolean reg_names_p = TARGET_REG_NAMES_P;
00086 
00087 static bfd_boolean register_name PARAMS ((expressionS *));
00088 static void ppc_set_cpu PARAMS ((void));
00089 static unsigned long ppc_insert_operand
00090   PARAMS ((unsigned long insn, const struct powerpc_operand *operand,
00091           offsetT val, char *file, unsigned int line));
00092 static void ppc_macro PARAMS ((char *str, const struct powerpc_macro *macro));
00093 static void ppc_byte PARAMS ((int));
00094 
00095 #if defined (OBJ_XCOFF) || defined (OBJ_ELF)
00096 static int ppc_is_toc_sym PARAMS ((symbolS *sym));
00097 static void ppc_tc PARAMS ((int));
00098 static void ppc_machine PARAMS ((int));
00099 #endif
00100 
00101 #ifdef OBJ_XCOFF
00102 static void ppc_comm PARAMS ((int));
00103 static void ppc_bb PARAMS ((int));
00104 static void ppc_bc PARAMS ((int));
00105 static void ppc_bf PARAMS ((int));
00106 static void ppc_biei PARAMS ((int));
00107 static void ppc_bs PARAMS ((int));
00108 static void ppc_eb PARAMS ((int));
00109 static void ppc_ec PARAMS ((int));
00110 static void ppc_ef PARAMS ((int));
00111 static void ppc_es PARAMS ((int));
00112 static void ppc_csect PARAMS ((int));
00113 static void ppc_change_csect PARAMS ((symbolS *, offsetT));
00114 static void ppc_function PARAMS ((int));
00115 static void ppc_extern PARAMS ((int));
00116 static void ppc_lglobl PARAMS ((int));
00117 static void ppc_section PARAMS ((int));
00118 static void ppc_named_section PARAMS ((int));
00119 static void ppc_stabx PARAMS ((int));
00120 static void ppc_rename PARAMS ((int));
00121 static void ppc_toc PARAMS ((int));
00122 static void ppc_xcoff_cons PARAMS ((int));
00123 static void ppc_vbyte PARAMS ((int));
00124 #endif
00125 
00126 #ifdef OBJ_ELF
00127 static bfd_reloc_code_real_type ppc_elf_suffix PARAMS ((char **, expressionS *));
00128 static void ppc_elf_cons PARAMS ((int));
00129 static void ppc_elf_rdata PARAMS ((int));
00130 static void ppc_elf_lcomm PARAMS ((int));
00131 static void ppc_elf_validate_fix PARAMS ((fixS *, segT));
00132 static void ppc_apuinfo_section_add PARAMS ((unsigned int apu, unsigned int version));
00133 #endif
00134 
00135 #ifdef TE_PE
00136 static void ppc_set_current_section PARAMS ((segT));
00137 static void ppc_previous PARAMS ((int));
00138 static void ppc_pdata PARAMS ((int));
00139 static void ppc_ydata PARAMS ((int));
00140 static void ppc_reldata PARAMS ((int));
00141 static void ppc_rdata PARAMS ((int));
00142 static void ppc_ualong PARAMS ((int));
00143 static void ppc_znop PARAMS ((int));
00144 static void ppc_pe_comm PARAMS ((int));
00145 static void ppc_pe_section PARAMS ((int));
00146 static void ppc_pe_function PARAMS ((int));
00147 static void ppc_pe_tocd PARAMS ((int));
00148 #endif
00149 
00150 /* Generic assembler global variables which must be defined by all
00151    targets.  */
00152 
00153 #ifdef OBJ_ELF
00154 /* This string holds the chars that always start a comment.  If the
00155    pre-processor is disabled, these aren't very useful.  The macro
00156    tc_comment_chars points to this.  We use this, rather than the
00157    usual comment_chars, so that we can switch for Solaris conventions.  */
00158 static const char ppc_solaris_comment_chars[] = "#!";
00159 static const char ppc_eabi_comment_chars[] = "#";
00160 
00161 #ifdef TARGET_SOLARIS_COMMENT
00162 const char *ppc_comment_chars = ppc_solaris_comment_chars;
00163 #else
00164 const char *ppc_comment_chars = ppc_eabi_comment_chars;
00165 #endif
00166 #else
00167 const char comment_chars[] = "#";
00168 #endif
00169 
00170 /* Characters which start a comment at the beginning of a line.  */
00171 const char line_comment_chars[] = "#";
00172 
00173 /* Characters which may be used to separate multiple commands on a
00174    single line.  */
00175 const char line_separator_chars[] = ";";
00176 
00177 /* Characters which are used to indicate an exponent in a floating
00178    point number.  */
00179 const char EXP_CHARS[] = "eE";
00180 
00181 /* Characters which mean that a number is a floating point constant,
00182    as in 0d1.0.  */
00183 const char FLT_CHARS[] = "dD";
00184 
00185 /* Anything that can start an operand needs to be mentioned here,
00186    to stop the input scrubber eating whitespace.  */
00187 const char ppc_symbol_chars[] = "%[";
00188 
00189 /* The dwarf2 data alignment, adjusted for 32 or 64 bit.  */
00190 int ppc_cie_data_alignment;
00191 
00192 /* The target specific pseudo-ops which we support.  */
00193 
00194 const pseudo_typeS md_pseudo_table[] =
00195 {
00196   /* Pseudo-ops which must be overridden.  */
00197   { "byte",   ppc_byte,     0 },
00198 
00199 #ifdef OBJ_XCOFF
00200   /* Pseudo-ops specific to the RS/6000 XCOFF format.  Some of these
00201      legitimately belong in the obj-*.c file.  However, XCOFF is based
00202      on COFF, and is only implemented for the RS/6000.  We just use
00203      obj-coff.c, and add what we need here.  */
00204   { "comm",   ppc_comm,     0 },
00205   { "lcomm",  ppc_comm,     1 },
00206   { "bb",     ppc_bb,              0 },
00207   { "bc",     ppc_bc,              0 },
00208   { "bf",     ppc_bf,              0 },
00209   { "bi",     ppc_biei,     0 },
00210   { "bs",     ppc_bs,              0 },
00211   { "csect",  ppc_csect,    0 },
00212   { "data",   ppc_section,  'd' },
00213   { "eb",     ppc_eb,              0 },
00214   { "ec",     ppc_ec,              0 },
00215   { "ef",     ppc_ef,              0 },
00216   { "ei",     ppc_biei,     1 },
00217   { "es",     ppc_es,              0 },
00218   { "extern", ppc_extern,   0 },
00219   { "function",      ppc_function, 0 },
00220   { "lglobl", ppc_lglobl,   0 },
00221   { "rename", ppc_rename,   0 },
00222   { "section",       ppc_named_section, 0 },
00223   { "stabx",  ppc_stabx,    0 },
00224   { "text",   ppc_section,  't' },
00225   { "toc",    ppc_toc,      0 },
00226   { "long",   ppc_xcoff_cons,      2 },
00227   { "llong",  ppc_xcoff_cons,      3 },
00228   { "word",   ppc_xcoff_cons,      1 },
00229   { "short",  ppc_xcoff_cons,      1 },
00230   { "vbyte",    ppc_vbyte,  0 },
00231 #endif
00232 
00233 #ifdef OBJ_ELF
00234   { "llong",  ppc_elf_cons, 8 },
00235   { "quad",   ppc_elf_cons, 8 },
00236   { "long",   ppc_elf_cons, 4 },
00237   { "word",   ppc_elf_cons, 2 },
00238   { "short",  ppc_elf_cons, 2 },
00239   { "rdata",  ppc_elf_rdata,       0 },
00240   { "rodata", ppc_elf_rdata,       0 },
00241   { "lcomm",  ppc_elf_lcomm,       0 },
00242 #endif
00243 
00244 #ifdef TE_PE
00245   /* Pseudo-ops specific to the Windows NT PowerPC PE (coff) format.  */
00246   { "previous", ppc_previous,   0 },
00247   { "pdata",    ppc_pdata,      0 },
00248   { "ydata",    ppc_ydata,      0 },
00249   { "reldata",  ppc_reldata,    0 },
00250   { "rdata",    ppc_rdata,      0 },
00251   { "ualong",   ppc_ualong,     0 },
00252   { "znop",     ppc_znop,       0 },
00253   { "comm",   ppc_pe_comm,  0 },
00254   { "lcomm",  ppc_pe_comm,  1 },
00255   { "section",  ppc_pe_section, 0 },
00256   { "function",      ppc_pe_function,0 },
00257   { "tocd",     ppc_pe_tocd,    0 },
00258 #endif
00259 
00260 #if defined (OBJ_XCOFF) || defined (OBJ_ELF)
00261   { "tc",     ppc_tc,              0 },
00262   { "machine",  ppc_machine,    0 },
00263 #endif
00264 
00265   { NULL,     NULL,         0 }
00266 };
00267 
00268 
00269 /* Predefined register names if -mregnames (or default for Windows NT).
00270    In general, there are lots of them, in an attempt to be compatible
00271    with a number of other Windows NT assemblers.  */
00272 
00273 /* Structure to hold information about predefined registers.  */
00274 struct pd_reg
00275   {
00276     char *name;
00277     int value;
00278   };
00279 
00280 /* List of registers that are pre-defined:
00281 
00282    Each general register has predefined names of the form:
00283    1. r<reg_num> which has the value <reg_num>.
00284    2. r.<reg_num> which has the value <reg_num>.
00285 
00286    Each floating point register has predefined names of the form:
00287    1. f<reg_num> which has the value <reg_num>.
00288    2. f.<reg_num> which has the value <reg_num>.
00289 
00290    Each vector unit register has predefined names of the form:
00291    1. v<reg_num> which has the value <reg_num>.
00292    2. v.<reg_num> which has the value <reg_num>.
00293 
00294    Each condition register has predefined names of the form:
00295    1. cr<reg_num> which has the value <reg_num>.
00296    2. cr.<reg_num> which has the value <reg_num>.
00297 
00298    There are individual registers as well:
00299    sp or r.sp     has the value 1
00300    rtoc or r.toc  has the value 2
00301    fpscr          has the value 0
00302    xer            has the value 1
00303    lr             has the value 8
00304    ctr            has the value 9
00305    pmr            has the value 0
00306    dar            has the value 19
00307    dsisr          has the value 18
00308    dec            has the value 22
00309    sdr1           has the value 25
00310    srr0           has the value 26
00311    srr1           has the value 27
00312 
00313    The table is sorted. Suitable for searching by a binary search.  */
00314 
00315 static const struct pd_reg pre_defined_registers[] =
00316 {
00317   { "cr.0", 0 },    /* Condition Registers */
00318   { "cr.1", 1 },
00319   { "cr.2", 2 },
00320   { "cr.3", 3 },
00321   { "cr.4", 4 },
00322   { "cr.5", 5 },
00323   { "cr.6", 6 },
00324   { "cr.7", 7 },
00325 
00326   { "cr0", 0 },
00327   { "cr1", 1 },
00328   { "cr2", 2 },
00329   { "cr3", 3 },
00330   { "cr4", 4 },
00331   { "cr5", 5 },
00332   { "cr6", 6 },
00333   { "cr7", 7 },
00334 
00335   { "ctr", 9 },
00336 
00337   { "dar", 19 },    /* Data Access Register */
00338   { "dec", 22 },    /* Decrementer */
00339   { "dsisr", 18 },  /* Data Storage Interrupt Status Register */
00340 
00341   { "f.0", 0 },     /* Floating point registers */
00342   { "f.1", 1 },
00343   { "f.10", 10 },
00344   { "f.11", 11 },
00345   { "f.12", 12 },
00346   { "f.13", 13 },
00347   { "f.14", 14 },
00348   { "f.15", 15 },
00349   { "f.16", 16 },
00350   { "f.17", 17 },
00351   { "f.18", 18 },
00352   { "f.19", 19 },
00353   { "f.2", 2 },
00354   { "f.20", 20 },
00355   { "f.21", 21 },
00356   { "f.22", 22 },
00357   { "f.23", 23 },
00358   { "f.24", 24 },
00359   { "f.25", 25 },
00360   { "f.26", 26 },
00361   { "f.27", 27 },
00362   { "f.28", 28 },
00363   { "f.29", 29 },
00364   { "f.3", 3 },
00365   { "f.30", 30 },
00366   { "f.31", 31 },
00367   { "f.4", 4 },
00368   { "f.5", 5 },
00369   { "f.6", 6 },
00370   { "f.7", 7 },
00371   { "f.8", 8 },
00372   { "f.9", 9 },
00373 
00374   { "f0", 0 },
00375   { "f1", 1 },
00376   { "f10", 10 },
00377   { "f11", 11 },
00378   { "f12", 12 },
00379   { "f13", 13 },
00380   { "f14", 14 },
00381   { "f15", 15 },
00382   { "f16", 16 },
00383   { "f17", 17 },
00384   { "f18", 18 },
00385   { "f19", 19 },
00386   { "f2", 2 },
00387   { "f20", 20 },
00388   { "f21", 21 },
00389   { "f22", 22 },
00390   { "f23", 23 },
00391   { "f24", 24 },
00392   { "f25", 25 },
00393   { "f26", 26 },
00394   { "f27", 27 },
00395   { "f28", 28 },
00396   { "f29", 29 },
00397   { "f3", 3 },
00398   { "f30", 30 },
00399   { "f31", 31 },
00400   { "f4", 4 },
00401   { "f5", 5 },
00402   { "f6", 6 },
00403   { "f7", 7 },
00404   { "f8", 8 },
00405   { "f9", 9 },
00406 
00407   { "fpscr", 0 },
00408 
00409   { "lr", 8 },     /* Link Register */
00410 
00411   { "pmr", 0 },
00412 
00413   { "r.0", 0 },    /* General Purpose Registers */
00414   { "r.1", 1 },
00415   { "r.10", 10 },
00416   { "r.11", 11 },
00417   { "r.12", 12 },
00418   { "r.13", 13 },
00419   { "r.14", 14 },
00420   { "r.15", 15 },
00421   { "r.16", 16 },
00422   { "r.17", 17 },
00423   { "r.18", 18 },
00424   { "r.19", 19 },
00425   { "r.2", 2 },
00426   { "r.20", 20 },
00427   { "r.21", 21 },
00428   { "r.22", 22 },
00429   { "r.23", 23 },
00430   { "r.24", 24 },
00431   { "r.25", 25 },
00432   { "r.26", 26 },
00433   { "r.27", 27 },
00434   { "r.28", 28 },
00435   { "r.29", 29 },
00436   { "r.3", 3 },
00437   { "r.30", 30 },
00438   { "r.31", 31 },
00439   { "r.4", 4 },
00440   { "r.5", 5 },
00441   { "r.6", 6 },
00442   { "r.7", 7 },
00443   { "r.8", 8 },
00444   { "r.9", 9 },
00445 
00446   { "r.sp", 1 },   /* Stack Pointer */
00447 
00448   { "r.toc", 2 },  /* Pointer to the table of contents */
00449 
00450   { "r0", 0 },     /* More general purpose registers */
00451   { "r1", 1 },
00452   { "r10", 10 },
00453   { "r11", 11 },
00454   { "r12", 12 },
00455   { "r13", 13 },
00456   { "r14", 14 },
00457   { "r15", 15 },
00458   { "r16", 16 },
00459   { "r17", 17 },
00460   { "r18", 18 },
00461   { "r19", 19 },
00462   { "r2", 2 },
00463   { "r20", 20 },
00464   { "r21", 21 },
00465   { "r22", 22 },
00466   { "r23", 23 },
00467   { "r24", 24 },
00468   { "r25", 25 },
00469   { "r26", 26 },
00470   { "r27", 27 },
00471   { "r28", 28 },
00472   { "r29", 29 },
00473   { "r3", 3 },
00474   { "r30", 30 },
00475   { "r31", 31 },
00476   { "r4", 4 },
00477   { "r5", 5 },
00478   { "r6", 6 },
00479   { "r7", 7 },
00480   { "r8", 8 },
00481   { "r9", 9 },
00482 
00483   { "rtoc", 2 },  /* Table of contents */
00484 
00485   { "sdr1", 25 }, /* Storage Description Register 1 */
00486 
00487   { "sp", 1 },
00488 
00489   { "srr0", 26 }, /* Machine Status Save/Restore Register 0 */
00490   { "srr1", 27 }, /* Machine Status Save/Restore Register 1 */
00491 
00492   { "v.0", 0 },     /* Vector registers */
00493   { "v.1", 1 },
00494   { "v.10", 10 },
00495   { "v.11", 11 },
00496   { "v.12", 12 },
00497   { "v.13", 13 },
00498   { "v.14", 14 },
00499   { "v.15", 15 },
00500   { "v.16", 16 },
00501   { "v.17", 17 },
00502   { "v.18", 18 },
00503   { "v.19", 19 },
00504   { "v.2", 2 },
00505   { "v.20", 20 },
00506   { "v.21", 21 },
00507   { "v.22", 22 },
00508   { "v.23", 23 },
00509   { "v.24", 24 },
00510   { "v.25", 25 },
00511   { "v.26", 26 },
00512   { "v.27", 27 },
00513   { "v.28", 28 },
00514   { "v.29", 29 },
00515   { "v.3", 3 },
00516   { "v.30", 30 },
00517   { "v.31", 31 },
00518   { "v.4", 4 },
00519   { "v.5", 5 },
00520   { "v.6", 6 },
00521   { "v.7", 7 },
00522   { "v.8", 8 },
00523   { "v.9", 9 },
00524 
00525   { "v0", 0 },
00526   { "v1", 1 },
00527   { "v10", 10 },
00528   { "v11", 11 },
00529   { "v12", 12 },
00530   { "v13", 13 },
00531   { "v14", 14 },
00532   { "v15", 15 },
00533   { "v16", 16 },
00534   { "v17", 17 },
00535   { "v18", 18 },
00536   { "v19", 19 },
00537   { "v2", 2 },
00538   { "v20", 20 },
00539   { "v21", 21 },
00540   { "v22", 22 },
00541   { "v23", 23 },
00542   { "v24", 24 },
00543   { "v25", 25 },
00544   { "v26", 26 },
00545   { "v27", 27 },
00546   { "v28", 28 },
00547   { "v29", 29 },
00548   { "v3", 3 },
00549   { "v30", 30 },
00550   { "v31", 31 },
00551   { "v4", 4 },
00552   { "v5", 5 },
00553   { "v6", 6 },
00554   { "v7", 7 },
00555   { "v8", 8 },
00556   { "v9", 9 },
00557 
00558   { "xer", 1 },
00559 
00560 };
00561 
00562 #define REG_NAME_CNT (sizeof (pre_defined_registers) / sizeof (struct pd_reg))
00563 
00564 /* Given NAME, find the register number associated with that name, return
00565    the integer value associated with the given name or -1 on failure.  */
00566 
00567 static int reg_name_search
00568   PARAMS ((const struct pd_reg *, int, const char * name));
00569 
00570 static int
00571 reg_name_search (regs, regcount, name)
00572      const struct pd_reg *regs;
00573      int regcount;
00574      const char *name;
00575 {
00576   int middle, low, high;
00577   int cmp;
00578 
00579   low = 0;
00580   high = regcount - 1;
00581 
00582   do
00583     {
00584       middle = (low + high) / 2;
00585       cmp = strcasecmp (name, regs[middle].name);
00586       if (cmp < 0)
00587        high = middle - 1;
00588       else if (cmp > 0)
00589        low = middle + 1;
00590       else
00591        return regs[middle].value;
00592     }
00593   while (low <= high);
00594 
00595   return -1;
00596 }
00597 
00598 /*
00599  * Summary of register_name.
00600  *
00601  * in: Input_line_pointer points to 1st char of operand.
00602  *
00603  * out:       A expressionS.
00604  *      The operand may have been a register: in this case, X_op == O_register,
00605  *      X_add_number is set to the register number, and truth is returned.
00606  *     Input_line_pointer->(next non-blank) char after operand, or is in its
00607  *      original state.
00608  */
00609 
00610 static bfd_boolean
00611 register_name (expressionP)
00612      expressionS *expressionP;
00613 {
00614   int reg_number;
00615   char *name;
00616   char *start;
00617   char c;
00618 
00619   /* Find the spelling of the operand.  */
00620   start = name = input_line_pointer;
00621   if (name[0] == '%' && ISALPHA (name[1]))
00622     name = ++input_line_pointer;
00623 
00624   else if (!reg_names_p || !ISALPHA (name[0]))
00625     return FALSE;
00626 
00627   c = get_symbol_end ();
00628   reg_number = reg_name_search (pre_defined_registers, REG_NAME_CNT, name);
00629 
00630   /* Put back the delimiting char.  */
00631   *input_line_pointer = c;
00632 
00633   /* Look to see if it's in the register table.  */
00634   if (reg_number >= 0)
00635     {
00636       expressionP->X_op = O_register;
00637       expressionP->X_add_number = reg_number;
00638 
00639       /* Make the rest nice.  */
00640       expressionP->X_add_symbol = NULL;
00641       expressionP->X_op_symbol = NULL;
00642       return TRUE;
00643     }
00644 
00645   /* Reset the line as if we had not done anything.  */
00646   input_line_pointer = start;
00647   return FALSE;
00648 }
00649 
00650 /* This function is called for each symbol seen in an expression.  It
00651    handles the special parsing which PowerPC assemblers are supposed
00652    to use for condition codes.  */
00653 
00654 /* Whether to do the special parsing.  */
00655 static bfd_boolean cr_operand;
00656 
00657 /* Names to recognize in a condition code.  This table is sorted.  */
00658 static const struct pd_reg cr_names[] =
00659 {
00660   { "cr0", 0 },
00661   { "cr1", 1 },
00662   { "cr2", 2 },
00663   { "cr3", 3 },
00664   { "cr4", 4 },
00665   { "cr5", 5 },
00666   { "cr6", 6 },
00667   { "cr7", 7 },
00668   { "eq", 2 },
00669   { "gt", 1 },
00670   { "lt", 0 },
00671   { "so", 3 },
00672   { "un", 3 }
00673 };
00674 
00675 /* Parsing function.  This returns non-zero if it recognized an
00676    expression.  */
00677 
00678 int
00679 ppc_parse_name (name, expr)
00680      const char *name;
00681      expressionS *expr;
00682 {
00683   int val;
00684 
00685   if (! cr_operand)
00686     return 0;
00687 
00688   val = reg_name_search (cr_names, sizeof cr_names / sizeof cr_names[0],
00689                       name);
00690   if (val < 0)
00691     return 0;
00692 
00693   expr->X_op = O_constant;
00694   expr->X_add_number = val;
00695 
00696   return 1;
00697 }
00698 
00699 /* Local variables.  */
00700 
00701 /* The type of processor we are assembling for.  This is one or more
00702    of the PPC_OPCODE flags defined in opcode/ppc.h.  */
00703 static unsigned long ppc_cpu = 0;
00704 
00705 /* Whether to target xcoff64/elf64.  */
00706 static unsigned int ppc_obj64 = BFD_DEFAULT_TARGET_SIZE == 64;
00707 
00708 /* Opcode hash table.  */
00709 static struct hash_control *ppc_hash;
00710 
00711 /* Macro hash table.  */
00712 static struct hash_control *ppc_macro_hash;
00713 
00714 #ifdef OBJ_ELF
00715 /* What type of shared library support to use.  */
00716 static enum { SHLIB_NONE, SHLIB_PIC, SHLIB_MRELOCATABLE } shlib = SHLIB_NONE;
00717 
00718 /* Flags to set in the elf header.  */
00719 static flagword ppc_flags = 0;
00720 
00721 /* Whether this is Solaris or not.  */
00722 #ifdef TARGET_SOLARIS_COMMENT
00723 #define SOLARIS_P TRUE
00724 #else
00725 #define SOLARIS_P FALSE
00726 #endif
00727 
00728 static bfd_boolean msolaris = SOLARIS_P;
00729 #endif
00730 
00731 #ifdef OBJ_XCOFF
00732 
00733 /* The RS/6000 assembler uses the .csect pseudo-op to generate code
00734    using a bunch of different sections.  These assembler sections,
00735    however, are all encompassed within the .text or .data sections of
00736    the final output file.  We handle this by using different
00737    subsegments within these main segments.  */
00738 
00739 /* Next subsegment to allocate within the .text segment.  */
00740 static subsegT ppc_text_subsegment = 2;
00741 
00742 /* Linked list of csects in the text section.  */
00743 static symbolS *ppc_text_csects;
00744 
00745 /* Next subsegment to allocate within the .data segment.  */
00746 static subsegT ppc_data_subsegment = 2;
00747 
00748 /* Linked list of csects in the data section.  */
00749 static symbolS *ppc_data_csects;
00750 
00751 /* The current csect.  */
00752 static symbolS *ppc_current_csect;
00753 
00754 /* The RS/6000 assembler uses a TOC which holds addresses of functions
00755    and variables.  Symbols are put in the TOC with the .tc pseudo-op.
00756    A special relocation is used when accessing TOC entries.  We handle
00757    the TOC as a subsegment within the .data segment.  We set it up if
00758    we see a .toc pseudo-op, and save the csect symbol here.  */
00759 static symbolS *ppc_toc_csect;
00760 
00761 /* The first frag in the TOC subsegment.  */
00762 static fragS *ppc_toc_frag;
00763 
00764 /* The first frag in the first subsegment after the TOC in the .data
00765    segment.  NULL if there are no subsegments after the TOC.  */
00766 static fragS *ppc_after_toc_frag;
00767 
00768 /* The current static block.  */
00769 static symbolS *ppc_current_block;
00770 
00771 /* The COFF debugging section; set by md_begin.  This is not the
00772    .debug section, but is instead the secret BFD section which will
00773    cause BFD to set the section number of a symbol to N_DEBUG.  */
00774 static asection *ppc_coff_debug_section;
00775 
00776 #endif /* OBJ_XCOFF */
00777 
00778 #ifdef TE_PE
00779 
00780 /* Various sections that we need for PE coff support.  */
00781 static segT ydata_section;
00782 static segT pdata_section;
00783 static segT reldata_section;
00784 static segT rdata_section;
00785 static segT tocdata_section;
00786 
00787 /* The current section and the previous section. See ppc_previous.  */
00788 static segT ppc_previous_section;
00789 static segT ppc_current_section;
00790 
00791 #endif /* TE_PE */
00792 
00793 #ifdef OBJ_ELF
00794 symbolS *GOT_symbol;        /* Pre-defined "_GLOBAL_OFFSET_TABLE" */
00795 #define PPC_APUINFO_ISEL    0x40
00796 #define PPC_APUINFO_PMR            0x41
00797 #define PPC_APUINFO_RFMCI   0x42
00798 #define PPC_APUINFO_CACHELCK       0x43
00799 #define PPC_APUINFO_SPE            0x100
00800 #define PPC_APUINFO_EFS            0x101
00801 #define PPC_APUINFO_BRLOCK  0x102
00802 
00803 /*
00804  * We keep a list of APUinfo
00805  */
00806 unsigned long *ppc_apuinfo_list;
00807 unsigned int ppc_apuinfo_num;
00808 unsigned int ppc_apuinfo_num_alloc;
00809 #endif /* OBJ_ELF */
00810 
00811 #ifdef OBJ_ELF
00812 const char *const md_shortopts = "b:l:usm:K:VQ:";
00813 #else
00814 const char *const md_shortopts = "um:";
00815 #endif
00816 const struct option md_longopts[] = {
00817   {NULL, no_argument, NULL, 0}
00818 };
00819 const size_t md_longopts_size = sizeof (md_longopts);
00820 
00821 
00822 /* Handle -m options that set cpu type, and .machine arg.  */
00823 
00824 static int
00825 parse_cpu (const char *arg)
00826 {
00827   /* -mpwrx and -mpwr2 mean to assemble for the IBM POWER/2
00828      (RIOS2).  */
00829   if (strcmp (arg, "pwrx") == 0 || strcmp (arg, "pwr2") == 0)
00830     ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_32;
00831   /* -mpwr means to assemble for the IBM POWER (RIOS1).  */
00832   else if (strcmp (arg, "pwr") == 0)
00833     ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_32;
00834   /* -m601 means to assemble for the PowerPC 601, which includes
00835      instructions that are holdovers from the Power.  */
00836   else if (strcmp (arg, "601") == 0)
00837     ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
00838               | PPC_OPCODE_601 | PPC_OPCODE_32);
00839   /* -mppc, -mppc32, -m603, and -m604 mean to assemble for the
00840      PowerPC 603/604.  */
00841   else if (strcmp (arg, "ppc") == 0
00842           || strcmp (arg, "ppc32") == 0
00843           || strcmp (arg, "603") == 0
00844           || strcmp (arg, "604") == 0)
00845     ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32;
00846   /* -m403 and -m405 mean to assemble for the PowerPC 403/405.  */
00847   else if (strcmp (arg, "403") == 0
00848           || strcmp (arg, "405") == 0)
00849     ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
00850               | PPC_OPCODE_403 | PPC_OPCODE_32);
00851   else if (strcmp (arg, "440") == 0)
00852     ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32
00853               | PPC_OPCODE_440 | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI);
00854   else if (strcmp (arg, "7400") == 0
00855           || strcmp (arg, "7410") == 0
00856           || strcmp (arg, "7450") == 0
00857           || strcmp (arg, "7455") == 0)
00858     ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
00859               | PPC_OPCODE_ALTIVEC | PPC_OPCODE_32);
00860   else if (strcmp (arg, "e300") == 0)
00861     ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32
00862               | PPC_OPCODE_E300);
00863   else if (strcmp (arg, "altivec") == 0)
00864     {
00865       if (ppc_cpu == 0)
00866        ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_ALTIVEC;
00867       else
00868        ppc_cpu |= PPC_OPCODE_ALTIVEC;
00869     }
00870   else if (strcmp (arg, "e500") == 0 || strcmp (arg, "e500x2") == 0)
00871     {
00872       ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
00873                | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
00874                | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK
00875                | PPC_OPCODE_RFMCI);
00876     }
00877   else if (strcmp (arg, "spe") == 0)
00878     {
00879       if (ppc_cpu == 0)
00880        ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_SPE | PPC_OPCODE_EFS;
00881       else
00882        ppc_cpu |= PPC_OPCODE_SPE;
00883     }
00884   /* -mppc64 and -m620 mean to assemble for the 64-bit PowerPC
00885      620.  */
00886   else if (strcmp (arg, "ppc64") == 0 || strcmp (arg, "620") == 0)
00887     {
00888       ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64;
00889     }
00890   else if (strcmp (arg, "ppc64bridge") == 0)
00891     {
00892       ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
00893                | PPC_OPCODE_64_BRIDGE | PPC_OPCODE_64);
00894     }
00895   /* -mbooke/-mbooke32 mean enable 32-bit BookE support.  */
00896   else if (strcmp (arg, "booke") == 0 || strcmp (arg, "booke32") == 0)
00897     {
00898       ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32;
00899     }
00900   /* -mbooke64 means enable 64-bit BookE support.  */
00901   else if (strcmp (arg, "booke64") == 0)
00902     {
00903       ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE
00904                | PPC_OPCODE_BOOKE64 | PPC_OPCODE_64);
00905     }
00906   else if (strcmp (arg, "power4") == 0)
00907     {
00908       ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
00909                | PPC_OPCODE_64 | PPC_OPCODE_POWER4);
00910     }
00911   else if (strcmp (arg, "power5") == 0)
00912     {
00913       ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
00914                | PPC_OPCODE_64 | PPC_OPCODE_POWER4
00915                | PPC_OPCODE_POWER5);
00916     }
00917   else if (strcmp (arg, "power6") == 0)
00918     {
00919       ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
00920                | PPC_OPCODE_64 | PPC_OPCODE_POWER4
00921                | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6);
00922     }
00923   else if (strcmp (arg, "cell") == 0)
00924     {
00925       ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
00926                | PPC_OPCODE_64 | PPC_OPCODE_POWER4
00927                | PPC_OPCODE_CELL);
00928     }
00929   /* -mcom means assemble for the common intersection between Power
00930      and PowerPC.  At present, we just allow the union, rather
00931      than the intersection.  */
00932   else if (strcmp (arg, "com") == 0)
00933     ppc_cpu = PPC_OPCODE_COMMON | PPC_OPCODE_32;
00934   /* -many means to assemble for any architecture (PWR/PWRX/PPC).  */
00935   else if (strcmp (arg, "any") == 0)
00936     ppc_cpu |= PPC_OPCODE_ANY;
00937   else
00938     return 0;
00939 
00940   return 1;
00941 }
00942 
00943 int
00944 md_parse_option (c, arg)
00945      int c;
00946      char *arg;
00947 {
00948   switch (c)
00949     {
00950     case 'u':
00951       /* -u means that any undefined symbols should be treated as
00952         external, which is the default for gas anyhow.  */
00953       break;
00954 
00955 #ifdef OBJ_ELF
00956     case 'l':
00957       /* Solaris as takes -le (presumably for little endian).  For completeness
00958         sake, recognize -be also.  */
00959       if (strcmp (arg, "e") == 0)
00960        {
00961          target_big_endian = 0;
00962          set_target_endian = 1;
00963        }
00964       else
00965        return 0;
00966 
00967       break;
00968 
00969     case 'b':
00970       if (strcmp (arg, "e") == 0)
00971        {
00972          target_big_endian = 1;
00973          set_target_endian = 1;
00974        }
00975       else
00976        return 0;
00977 
00978       break;
00979 
00980     case 'K':
00981       /* Recognize -K PIC.  */
00982       if (strcmp (arg, "PIC") == 0 || strcmp (arg, "pic") == 0)
00983        {
00984          shlib = SHLIB_PIC;
00985          ppc_flags |= EF_PPC_RELOCATABLE_LIB;
00986        }
00987       else
00988        return 0;
00989 
00990       break;
00991 #endif
00992 
00993       /* a64 and a32 determine whether to use XCOFF64 or XCOFF32.  */
00994     case 'a':
00995       if (strcmp (arg, "64") == 0)
00996        {
00997 #ifdef BFD64
00998          ppc_obj64 = 1;
00999 #else
01000          as_fatal (_("%s unsupported"), "-a64");
01001 #endif
01002        }
01003       else if (strcmp (arg, "32") == 0)
01004        ppc_obj64 = 0;
01005       else
01006        return 0;
01007       break;
01008 
01009     case 'm':
01010       if (parse_cpu (arg))
01011        ;
01012 
01013       else if (strcmp (arg, "regnames") == 0)
01014        reg_names_p = TRUE;
01015 
01016       else if (strcmp (arg, "no-regnames") == 0)
01017        reg_names_p = FALSE;
01018 
01019 #ifdef OBJ_ELF
01020       /* -mrelocatable/-mrelocatable-lib -- warn about initializations
01021         that require relocation.  */
01022       else if (strcmp (arg, "relocatable") == 0)
01023        {
01024          shlib = SHLIB_MRELOCATABLE;
01025          ppc_flags |= EF_PPC_RELOCATABLE;
01026        }
01027 
01028       else if (strcmp (arg, "relocatable-lib") == 0)
01029        {
01030          shlib = SHLIB_MRELOCATABLE;
01031          ppc_flags |= EF_PPC_RELOCATABLE_LIB;
01032        }
01033 
01034       /* -memb, set embedded bit.  */
01035       else if (strcmp (arg, "emb") == 0)
01036        ppc_flags |= EF_PPC_EMB;
01037 
01038       /* -mlittle/-mbig set the endianess.  */
01039       else if (strcmp (arg, "little") == 0
01040               || strcmp (arg, "little-endian") == 0)
01041        {
01042          target_big_endian = 0;
01043          set_target_endian = 1;
01044        }
01045 
01046       else if (strcmp (arg, "big") == 0 || strcmp (arg, "big-endian") == 0)
01047        {
01048          target_big_endian = 1;
01049          set_target_endian = 1;
01050        }
01051 
01052       else if (strcmp (arg, "solaris") == 0)
01053        {
01054          msolaris = TRUE;
01055          ppc_comment_chars = ppc_solaris_comment_chars;
01056        }
01057 
01058       else if (strcmp (arg, "no-solaris") == 0)
01059        {
01060          msolaris = FALSE;
01061          ppc_comment_chars = ppc_eabi_comment_chars;
01062        }
01063 #endif
01064       else
01065        {
01066          as_bad (_("invalid switch -m%s"), arg);
01067          return 0;
01068        }
01069       break;
01070 
01071 #ifdef OBJ_ELF
01072       /* -V: SVR4 argument to print version ID.  */
01073     case 'V':
01074       print_version_id ();
01075       break;
01076 
01077       /* -Qy, -Qn: SVR4 arguments controlling whether a .comment section
01078         should be emitted or not.  FIXME: Not implemented.  */
01079     case 'Q':
01080       break;
01081 
01082       /* Solaris takes -s to specify that .stabs go in a .stabs section,
01083         rather than .stabs.excl, which is ignored by the linker.
01084         FIXME: Not implemented.  */
01085     case 's':
01086       if (arg)
01087        return 0;
01088 
01089       break;
01090 #endif
01091 
01092     default:
01093       return 0;
01094     }
01095 
01096   return 1;
01097 }
01098 
01099 void
01100 md_show_usage (stream)
01101      FILE *stream;
01102 {
01103   fprintf (stream, _("\
01104 PowerPC options:\n\
01105 -a32                 generate ELF32/XCOFF32\n\
01106 -a64                 generate ELF64/XCOFF64\n\
01107 -u                   ignored\n\
01108 -mpwrx, -mpwr2              generate code for POWER/2 (RIOS2)\n\
01109 -mpwr                generate code for POWER (RIOS1)\n\
01110 -m601                generate code for PowerPC 601\n\
01111 -mppc, -mppc32, -m603, -m604\n\
01112                      generate code for PowerPC 603/604\n\
01113 -m403, -m405         generate code for PowerPC 403/405\n\
01114 -m440                generate code for PowerPC 440\n\
01115 -m7400, -m7410, -m7450, -m7455\n\
01116                      generate code For PowerPC 7400/7410/7450/7455\n"));
01117   fprintf (stream, _("\
01118 -mppc64, -m620              generate code for PowerPC 620/625/630\n\
01119 -mppc64bridge        generate code for PowerPC 64, including bridge insns\n\
01120 -mbooke64            generate code for 64-bit PowerPC BookE\n\
01121 -mbooke, mbooke32    generate code for 32-bit PowerPC BookE\n\
01122 -mpower4             generate code for Power4 architecture\n\
01123 -mpower5             generate code for Power5 architecture\n\
01124 -mpower6             generate code for Power6 architecture\n\
01125 -mcell               generate code for Cell Broadband Engine architecture\n\
01126 -mcom                generate code Power/PowerPC common instructions\n\
01127 -many                generate code for any architecture (PWR/PWRX/PPC)\n"));
01128   fprintf (stream, _("\
01129 -maltivec            generate code for AltiVec\n\
01130 -me300               generate code for PowerPC e300 family\n\
01131 -me500, -me500x2     generate code for Motorola e500 core complex\n\
01132 -mspe                generate code for Motorola SPE instructions\n\
01133 -mregnames           Allow symbolic names for registers\n\
01134 -mno-regnames        Do not allow symbolic names for registers\n"));
01135 #ifdef OBJ_ELF
01136   fprintf (stream, _("\
01137 -mrelocatable        support for GCC's -mrelocatble option\n\
01138 -mrelocatable-lib    support for GCC's -mrelocatble-lib option\n\
01139 -memb                set PPC_EMB bit in ELF flags\n\
01140 -mlittle, -mlittle-endian, -l, -le\n\
01141                      generate code for a little endian machine\n\
01142 -mbig, -mbig-endian, -b, -be\n\
01143                      generate code for a big endian machine\n\
01144 -msolaris            generate code for Solaris\n\
01145 -mno-solaris         do not generate code for Solaris\n\
01146 -V                   print assembler version number\n\
01147 -Qy, -Qn             ignored\n"));
01148 #endif
01149 }
01150 
01151 /* Set ppc_cpu if it is not already set.  */
01152 
01153 static void
01154 ppc_set_cpu ()
01155 {
01156   const char *default_os  = TARGET_OS;
01157   const char *default_cpu = TARGET_CPU;
01158 
01159   if ((ppc_cpu & ~PPC_OPCODE_ANY) == 0)
01160     {
01161       if (ppc_obj64)
01162        ppc_cpu |= PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64;
01163       else if (strncmp (default_os, "aix", 3) == 0
01164               && default_os[3] >= '4' && default_os[3] <= '9')
01165        ppc_cpu |= PPC_OPCODE_COMMON | PPC_OPCODE_32;
01166       else if (strncmp (default_os, "aix3", 4) == 0)
01167        ppc_cpu |= PPC_OPCODE_POWER | PPC_OPCODE_32;
01168       else if (strcmp (default_cpu, "rs6000") == 0)
01169        ppc_cpu |= PPC_OPCODE_POWER | PPC_OPCODE_32;
01170       else if (strncmp (default_cpu, "powerpc", 7) == 0)
01171        ppc_cpu |= PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32;
01172       else
01173        as_fatal (_("Unknown default cpu = %s, os = %s"),
01174                 default_cpu, default_os);
01175     }
01176 }
01177 
01178 /* Figure out the BFD architecture to use.  This function and ppc_mach
01179    are called well before md_begin, when the output file is opened.  */
01180 
01181 enum bfd_architecture
01182 ppc_arch ()
01183 {
01184   const char *default_cpu = TARGET_CPU;
01185   ppc_set_cpu ();
01186 
01187   if ((ppc_cpu & PPC_OPCODE_PPC) != 0)
01188     return bfd_arch_powerpc;
01189   else if ((ppc_cpu & PPC_OPCODE_POWER) != 0)
01190     return bfd_arch_rs6000;
01191   else if ((ppc_cpu & (PPC_OPCODE_COMMON | PPC_OPCODE_ANY)) != 0)
01192     {
01193       if (strcmp (default_cpu, "rs6000") == 0)
01194        return bfd_arch_rs6000;
01195       else if (strncmp (default_cpu, "powerpc", 7) == 0)
01196        return bfd_arch_powerpc;
01197     }
01198 
01199   as_fatal (_("Neither Power nor PowerPC opcodes were selected."));
01200   return bfd_arch_unknown;
01201 }
01202 
01203 unsigned long
01204 ppc_mach ()
01205 {
01206   if (ppc_obj64)
01207     return bfd_mach_ppc64;
01208   else if (ppc_arch () == bfd_arch_rs6000)
01209     return bfd_mach_rs6k;
01210   else
01211     return bfd_mach_ppc;
01212 }
01213 
01214 extern char*
01215 ppc_target_format ()
01216 {
01217 #ifdef OBJ_COFF
01218 #ifdef TE_PE
01219   return target_big_endian ? "pe-powerpc" : "pe-powerpcle";
01220 #elif TE_POWERMAC
01221   return "xcoff-powermac";
01222 #else
01223 #  ifdef TE_AIX5
01224     return (ppc_obj64 ? "aix5coff64-rs6000" : "aixcoff-rs6000");
01225 #  else
01226     return (ppc_obj64 ? "aixcoff64-rs6000" : "aixcoff-rs6000");
01227 #  endif
01228 #endif
01229 #endif
01230 #ifdef OBJ_ELF
01231 # ifdef TE_VXWORKS
01232   return "elf32-powerpc-vxworks";
01233 # else
01234   return (target_big_endian
01235          ? (ppc_obj64 ? "elf64-powerpc" : "elf32-powerpc")
01236          : (ppc_obj64 ? "elf64-powerpcle" : "elf32-powerpcle"));
01237 # endif
01238 #endif
01239 }
01240 
01241 /* Insert opcodes and macros into hash tables.  Called at startup and
01242    for .cpu pseudo.  */
01243 
01244 static void
01245 ppc_setup_opcodes (void)
01246 {
01247   register const struct powerpc_opcode *op;
01248   const struct powerpc_opcode *op_end;
01249   const struct powerpc_macro *macro;
01250   const struct powerpc_macro *macro_end;
01251   bfd_boolean dup_insn = FALSE;
01252 
01253   if (ppc_hash != NULL)
01254     hash_die (ppc_hash);
01255   if (ppc_macro_hash != NULL)
01256     hash_die (ppc_macro_hash);
01257 
01258   /* Insert the opcodes into a hash table.  */
01259   ppc_hash = hash_new ();
01260 
01261   op_end = powerpc_opcodes + powerpc_num_opcodes;
01262   for (op = powerpc_opcodes; op < op_end; op++)
01263     {
01264       know ((op->opcode & op->mask) == op->opcode);
01265 
01266       if ((op->flags & ppc_cpu & ~(PPC_OPCODE_32 | PPC_OPCODE_64)) != 0
01267          && ((op->flags & (PPC_OPCODE_32 | PPC_OPCODE_64)) == 0
01268              || ((op->flags & (PPC_OPCODE_32 | PPC_OPCODE_64))
01269                 == (ppc_cpu & (PPC_OPCODE_32 | PPC_OPCODE_64)))
01270              || (ppc_cpu & PPC_OPCODE_64_BRIDGE) != 0)
01271          /* Certain instructions (eg: extsw) do not exist in the
01272             32-bit BookE instruction set, but they do exist in the
01273             64-bit BookE instruction set, and other PPC instruction
01274             sets.  Check to see if the opcode has the BOOKE64 flag set.
01275             If it does make sure that the target CPU is not the BookE32.  */
01276          && ((op->flags & PPC_OPCODE_BOOKE64) == 0
01277              || (ppc_cpu & PPC_OPCODE_BOOKE64) == PPC_OPCODE_BOOKE64
01278              || (ppc_cpu & PPC_OPCODE_BOOKE) == 0)
01279          && ((op->flags & (PPC_OPCODE_POWER4 | PPC_OPCODE_NOPOWER4)) == 0
01280              || ((op->flags & PPC_OPCODE_POWER4)
01281                 == (ppc_cpu & PPC_OPCODE_POWER4)))
01282          && ((op->flags & PPC_OPCODE_POWER5) == 0
01283              || ((op->flags & PPC_OPCODE_POWER5)
01284                 == (ppc_cpu & PPC_OPCODE_POWER5)))
01285          && ((op->flags & PPC_OPCODE_POWER6) == 0
01286              || ((op->flags & PPC_OPCODE_POWER6)
01287                 == (ppc_cpu & PPC_OPCODE_POWER6))))
01288        {
01289          const char *retval;
01290 
01291          retval = hash_insert (ppc_hash, op->name, (PTR) op);
01292          if (retval != NULL)
01293            {
01294              /* Ignore Power duplicates for -m601.  */
01295              if ((ppc_cpu & PPC_OPCODE_601) != 0
01296                 && (op->flags & PPC_OPCODE_POWER) != 0)
01297               continue;
01298 
01299              as_bad (_("Internal assembler error for instruction %s"),
01300                     op->name);
01301              dup_insn = TRUE;
01302            }
01303        }
01304     }
01305 
01306   if ((ppc_cpu & PPC_OPCODE_ANY) != 0)
01307     for (op = powerpc_opcodes; op < op_end; op++)
01308       hash_insert (ppc_hash, op->name, (PTR) op);
01309 
01310   /* Insert the macros into a hash table.  */
01311   ppc_macro_hash = hash_new ();
01312 
01313   macro_end = powerpc_macros + powerpc_num_macros;
01314   for (macro = powerpc_macros; macro < macro_end; macro++)
01315     {
01316       if ((macro->flags & ppc_cpu) != 0)
01317        {
01318          const char *retval;
01319 
01320          retval = hash_insert (ppc_macro_hash, macro->name, (PTR) macro);
01321          if (retval != (const char *) NULL)
01322            {
01323              as_bad (_("Internal assembler error for macro %s"), macro->name);
01324              dup_insn = TRUE;
01325            }
01326        }
01327     }
01328 
01329   if (dup_insn)
01330     abort ();
01331 }
01332 
01333 /* This function is called when the assembler starts up.  It is called
01334    after the options have been parsed and the output file has been
01335    opened.  */
01336 
01337 void
01338 md_begin ()
01339 {
01340   ppc_set_cpu ();
01341 
01342   ppc_cie_data_alignment = ppc_obj64 ? -8 : -4;
01343 
01344 #ifdef OBJ_ELF
01345   /* Set the ELF flags if desired.  */
01346   if (ppc_flags && !msolaris)
01347     bfd_set_private_flags (stdoutput, ppc_flags);
01348 #endif
01349 
01350   ppc_setup_opcodes ();
01351 
01352   /* Tell the main code what the endianness is if it is not overridden
01353      by the user.  */
01354   if (!set_target_endian)
01355     {
01356       set_target_endian = 1;
01357       target_big_endian = PPC_BIG_ENDIAN;
01358     }
01359 
01360 #ifdef OBJ_XCOFF
01361   ppc_coff_debug_section = coff_section_from_bfd_index (stdoutput, N_DEBUG);
01362 
01363   /* Create dummy symbols to serve as initial csects.  This forces the
01364      text csects to precede the data csects.  These symbols will not
01365      be output.  */
01366   ppc_text_csects = symbol_make ("dummy\001");
01367   symbol_get_tc (ppc_text_csects)->within = ppc_text_csects;
01368   ppc_data_csects = symbol_make ("dummy\001");
01369   symbol_get_tc (ppc_data_csects)->within = ppc_data_csects;
01370 #endif
01371 
01372 #ifdef TE_PE
01373 
01374   ppc_current_section = text_section;
01375   ppc_previous_section = 0;
01376 
01377 #endif
01378 }
01379 
01380 void
01381 ppc_cleanup ()
01382 {
01383 #ifdef OBJ_ELF
01384   if (ppc_apuinfo_list == NULL)
01385     return;
01386 
01387   /* Ok, so write the section info out.  We have this layout:
01388 
01389   byte data          what
01390   ---- ----          ----
01391   0    8             length of "APUinfo\0"
01392   4    (n*4)         number of APU's (4 bytes each)
01393   8    2             note type 2
01394   12   "APUinfo\0"   name
01395   20   APU#1         first APU's info
01396   24   APU#2         second APU's info
01397   ...  ...
01398   */
01399   {
01400     char *p;
01401     asection *seg = now_seg;
01402     subsegT subseg = now_subseg;
01403     asection *apuinfo_secp = (asection *) NULL;
01404     unsigned int i;
01405 
01406     /* Create the .PPC.EMB.apuinfo section.  */
01407     apuinfo_secp = subseg_new (".PPC.EMB.apuinfo", 0);
01408     bfd_set_section_flags (stdoutput,
01409                         apuinfo_secp,
01410                         SEC_HAS_CONTENTS | SEC_READONLY);
01411 
01412     p = frag_more (4);
01413     md_number_to_chars (p, (valueT) 8, 4);
01414 
01415     p = frag_more (4);
01416     md_number_to_chars (p, (valueT) ppc_apuinfo_num * 4, 4);
01417 
01418     p = frag_more (4);
01419     md_number_to_chars (p, (valueT) 2, 4);
01420 
01421     p = frag_more (8);
01422     strcpy (p, "APUinfo");
01423 
01424     for (i = 0; i < ppc_apuinfo_num; i++)
01425       {
01426        p = frag_more (4);
01427        md_number_to_chars (p, (valueT) ppc_apuinfo_list[i], 4);
01428       }
01429 
01430     frag_align (2, 0, 0);
01431 
01432     /* We probably can't restore the current segment, for there likely
01433        isn't one yet...  */
01434     if (seg && subseg)
01435       subseg_set (seg, subseg);
01436   }
01437 #endif
01438 }
01439 
01440 /* Insert an operand value into an instruction.  */
01441 
01442 static unsigned long
01443 ppc_insert_operand (insn, operand, val, file, line)
01444      unsigned long insn;
01445      const struct powerpc_operand *operand;
01446      offsetT val;
01447      char *file;
01448      unsigned int line;
01449 {
01450   if (operand->bits != 32)
01451     {
01452       long min, max;
01453       offsetT test;
01454 
01455       if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
01456        {
01457          if ((operand->flags & PPC_OPERAND_SIGNOPT) != 0)
01458            max = (1 << operand->bits) - 1;
01459          else
01460            max = (1 << (operand->bits - 1)) - 1;
01461          min = - (1 << (operand->bits - 1));
01462 
01463          if (!ppc_obj64)
01464            {
01465              /* Some people write 32 bit hex constants with the sign
01466                extension done by hand.  This shouldn't really be
01467                valid, but, to permit this code to assemble on a 64
01468                bit host, we sign extend the 32 bit value.  */
01469              if (val > 0
01470                 && (val & (offsetT) 0x80000000) != 0
01471                 && (val & (offsetT) 0xffffffff) == val)
01472               {
01473                 val -= 0x80000000;
01474                 val -= 0x80000000;
01475               }
01476            }
01477        }
01478       else
01479        {
01480          max = (1 << operand->bits) - 1;
01481          min = 0;
01482        }
01483 
01484       if ((operand->flags & PPC_OPERAND_NEGATIVE) != 0)
01485        test = - val;
01486       else
01487        test = val;
01488 
01489       if (test < (offsetT) min || test > (offsetT) max)
01490        as_bad_value_out_of_range (_("operand"), test, (offsetT) min, (offsetT) max, file, line);
01491     }
01492 
01493   if (operand->insert)
01494     {
01495       const char *errmsg;
01496 
01497       errmsg = NULL;
01498       insn = (*operand->insert) (insn, (long) val, ppc_cpu, &errmsg);
01499       if (errmsg != (const char *) NULL)
01500        as_bad_where (file, line, errmsg);
01501     }
01502   else
01503     insn |= (((long) val & ((1 << operand->bits) - 1))
01504             << operand->shift);
01505 
01506   return insn;
01507 }
01508 
01509 
01510 #ifdef OBJ_ELF
01511 /* Parse @got, etc. and return the desired relocation.  */
01512 static bfd_reloc_code_real_type
01513 ppc_elf_suffix (str_p, exp_p)
01514      char **str_p;
01515      expressionS *exp_p;
01516 {
01517   struct map_bfd {
01518     char *string;
01519     unsigned int length : 8;
01520     unsigned int valid32 : 1;
01521     unsigned int valid64 : 1;
01522     unsigned int reloc;
01523   };
01524 
01525   char ident[20];
01526   char *str = *str_p;
01527   char *str2;
01528   int ch;
01529   int len;
01530   const struct map_bfd *ptr;
01531 
01532 #define MAP(str, reloc)   { str, sizeof (str) - 1, 1, 1, reloc }
01533 #define MAP32(str, reloc) { str, sizeof (str) - 1, 1, 0, reloc }
01534 #define MAP64(str, reloc) { str, sizeof (str) - 1, 0, 1, reloc }
01535 
01536   static const struct map_bfd mapping[] = {
01537     MAP ("l",               BFD_RELOC_LO16),
01538     MAP ("h",               BFD_RELOC_HI16),
01539     MAP ("ha",                     BFD_RELOC_HI16_S),
01540     MAP ("brtaken",         BFD_RELOC_PPC_B16_BRTAKEN),
01541     MAP ("brntaken",        BFD_RELOC_PPC_B16_BRNTAKEN),
01542     MAP ("got",                    BFD_RELOC_16_GOTOFF),
01543     MAP ("got@l",           BFD_RELOC_LO16_GOTOFF),
01544     MAP ("got@h",           BFD_RELOC_HI16_GOTOFF),
01545     MAP ("got@ha",          BFD_RELOC_HI16_S_GOTOFF),
01546     MAP ("plt@l",           BFD_RELOC_LO16_PLTOFF),
01547     MAP ("plt@h",           BFD_RELOC_HI16_PLTOFF),
01548     MAP ("plt@ha",          BFD_RELOC_HI16_S_PLTOFF),
01549     MAP ("copy",            BFD_RELOC_PPC_COPY),
01550     MAP ("globdat",         BFD_RELOC_PPC_GLOB_DAT),
01551     MAP ("sectoff",         BFD_RELOC_16_BASEREL),
01552     MAP ("sectoff@l",              BFD_RELOC_LO16_BASEREL),
01553     MAP ("sectoff@h",              BFD_RELOC_HI16_BASEREL),
01554     MAP ("sectoff@ha",             BFD_RELOC_HI16_S_BASEREL),
01555     MAP ("tls",                    BFD_RELOC_PPC_TLS),
01556     MAP ("dtpmod",          BFD_RELOC_PPC_DTPMOD),
01557     MAP ("dtprel",          BFD_RELOC_PPC_DTPREL),
01558     MAP ("dtprel@l",        BFD_RELOC_PPC_DTPREL16_LO),
01559     MAP ("dtprel@h",        BFD_RELOC_PPC_DTPREL16_HI),
01560     MAP ("dtprel@ha",              BFD_RELOC_PPC_DTPREL16_HA),
01561     MAP ("tprel",           BFD_RELOC_PPC_TPREL),
01562     MAP ("tprel@l",         BFD_RELOC_PPC_TPREL16_LO),
01563     MAP ("tprel@h",         BFD_RELOC_PPC_TPREL16_HI),
01564     MAP ("tprel@ha",        BFD_RELOC_PPC_TPREL16_HA),
01565     MAP ("got@tlsgd",              BFD_RELOC_PPC_GOT_TLSGD16),
01566     MAP ("got@tlsgd@l",            BFD_RELOC_PPC_GOT_TLSGD16_LO),
01567     MAP ("got@tlsgd@h",            BFD_RELOC_PPC_GOT_TLSGD16_HI),
01568     MAP ("got@tlsgd@ha",    BFD_RELOC_PPC_GOT_TLSGD16_HA),
01569     MAP ("got@tlsld",              BFD_RELOC_PPC_GOT_TLSLD16),
01570     MAP ("got@tlsld@l",            BFD_RELOC_PPC_GOT_TLSLD16_LO),
01571     MAP ("got@tlsld@h",            BFD_RELOC_PPC_GOT_TLSLD16_HI),
01572     MAP ("got@tlsld@ha",    BFD_RELOC_PPC_GOT_TLSLD16_HA),
01573     MAP ("got@dtprel",             BFD_RELOC_PPC_GOT_DTPREL16),
01574     MAP ("got@dtprel@l",    BFD_RELOC_PPC_GOT_DTPREL16_LO),
01575     MAP ("got@dtprel@h",    BFD_RELOC_PPC_GOT_DTPREL16_HI),
01576     MAP ("got@dtprel@ha",   BFD_RELOC_PPC_GOT_DTPREL16_HA),
01577     MAP ("got@tprel",              BFD_RELOC_PPC_GOT_TPREL16),
01578     MAP ("got@tprel@l",            BFD_RELOC_PPC_GOT_TPREL16_LO),
01579     MAP ("got@tprel@h",            BFD_RELOC_PPC_GOT_TPREL16_HI),
01580     MAP ("got@tprel@ha",    BFD_RELOC_PPC_GOT_TPREL16_HA),
01581     MAP32 ("fixup",         BFD_RELOC_CTOR),
01582     MAP32 ("plt",           BFD_RELOC_24_PLT_PCREL),
01583     MAP32 ("pltrel24",             BFD_RELOC_24_PLT_PCREL),
01584     MAP32 ("local24pc",            BFD_RELOC_PPC_LOCAL24PC),
01585     MAP32 ("local",         BFD_RELOC_PPC_LOCAL24PC),
01586     MAP32 ("pltrel",        BFD_RELOC_32_PLT_PCREL),
01587     MAP32 ("sdarel",        BFD_RELOC_GPREL16),
01588     MAP32 ("naddr",         BFD_RELOC_PPC_EMB_NADDR32),
01589     MAP32 ("naddr16",              BFD_RELOC_PPC_EMB_NADDR16),
01590     MAP32 ("naddr@l",              BFD_RELOC_PPC_EMB_NADDR16_LO),
01591     MAP32 ("naddr@h",              BFD_RELOC_PPC_EMB_NADDR16_HI),
01592     MAP32 ("naddr@ha",             BFD_RELOC_PPC_EMB_NADDR16_HA),
01593     MAP32 ("sdai16",        BFD_RELOC_PPC_EMB_SDAI16),
01594     MAP32 ("sda2rel",              BFD_RELOC_PPC_EMB_SDA2REL),
01595     MAP32 ("sda2i16",              BFD_RELOC_PPC_EMB_SDA2I16),
01596     MAP32 ("sda21",         BFD_RELOC_PPC_EMB_SDA21),
01597     MAP32 ("mrkref",        BFD_RELOC_PPC_EMB_MRKREF),
01598     MAP32 ("relsect",              BFD_RELOC_PPC_EMB_RELSEC16),
01599     MAP32 ("relsect@l",            BFD_RELOC_PPC_EMB_RELST_LO),
01600     MAP32 ("relsect@h",            BFD_RELOC_PPC_EMB_RELST_HI),
01601     MAP32 ("relsect@ha",    BFD_RELOC_PPC_EMB_RELST_HA),
01602     MAP32 ("bitfld",        BFD_RELOC_PPC_EMB_BIT_FLD),
01603     MAP32 ("relsda",        BFD_RELOC_PPC_EMB_RELSDA),
01604     MAP32 ("xgot",          BFD_RELOC_PPC_TOC16),
01605     MAP64 ("higher",        BFD_RELOC_PPC64_HIGHER),
01606     MAP64 ("highera",              BFD_RELOC_PPC64_HIGHER_S),
01607     MAP64 ("highest",              BFD_RELOC_PPC64_HIGHEST),
01608     MAP64 ("highesta",             BFD_RELOC_PPC64_HIGHEST_S),
01609     MAP64 ("tocbase",              BFD_RELOC_PPC64_TOC),
01610     MAP64 ("toc",           BFD_RELOC_PPC_TOC16),
01611     MAP64 ("toc@l",         BFD_RELOC_PPC64_TOC16_LO),
01612     MAP64 ("toc@h",         BFD_RELOC_PPC64_TOC16_HI),
01613     MAP64 ("toc@ha",        BFD_RELOC_PPC64_TOC16_HA),
01614     MAP64 ("dtprel@higher", BFD_RELOC_PPC64_DTPREL16_HIGHER),
01615     MAP64 ("dtprel@highera",       BFD_RELOC_PPC64_DTPREL16_HIGHERA),
01616     MAP64 ("dtprel@highest",       BFD_RELOC_PPC64_DTPREL16_HIGHEST),
01617     MAP64 ("dtprel@highesta",      BFD_RELOC_PPC64_DTPREL16_HIGHESTA),
01618     MAP64 ("tprel@higher",  BFD_RELOC_PPC64_TPREL16_HIGHER),
01619     MAP64 ("tprel@highera", BFD_RELOC_PPC64_TPREL16_HIGHERA),
01620     MAP64 ("tprel@highest", BFD_RELOC_PPC64_TPREL16_HIGHEST),
01621     MAP64 ("tprel@highesta",       BFD_RELOC_PPC64_TPREL16_HIGHESTA),
01622     { (char *) 0, 0, 0, 0,  BFD_RELOC_UNUSED }
01623   };
01624 
01625   if (*str++ != '@')
01626     return BFD_RELOC_UNUSED;
01627 
01628   for (ch = *str, str2 = ident;
01629        (str2 < ident + sizeof (ident) - 1
01630        && (ISALNUM (ch) || ch == '@'));
01631        ch = *++str)
01632     {
01633       *str2++ = TOLOWER (ch);
01634     }
01635 
01636   *str2 = '\0';
01637   len = str2 - ident;
01638 
01639   ch = ident[0];
01640   for (ptr = &mapping[0]; ptr->length > 0; ptr++)
01641     if (ch == ptr->string[0]
01642        && len == ptr->length
01643        && memcmp (ident, ptr->string, ptr->length) == 0
01644        && (ppc_obj64 ? ptr->valid64 : ptr->valid32))
01645       {
01646        int reloc = ptr->reloc;
01647 
01648        if (!ppc_obj64)
01649          if (exp_p->X_add_number != 0
01650              && (reloc == (int) BFD_RELOC_16_GOTOFF
01651                 || reloc == (int) BFD_RELOC_LO16_GOTOFF
01652                 || reloc == (int) BFD_RELOC_HI16_GOTOFF
01653                 || reloc == (int) BFD_RELOC_HI16_S_GOTOFF))
01654            as_warn (_("identifier+constant@got means identifier@got+constant"));
01655 
01656        /* Now check for identifier@suffix+constant.  */
01657        if (*str == '-' || *str == '+')
01658          {
01659            char *orig_line = input_line_pointer;
01660            expressionS new_exp;
01661 
01662            input_line_pointer = str;
01663            expression (&new_exp);
01664            if (new_exp.X_op == O_constant)
01665              {
01666               exp_p->X_add_number += new_exp.X_add_number;
01667               str = input_line_pointer;
01668              }
01669 
01670            if (&input_line_pointer != str_p)
01671              input_line_pointer = orig_line;
01672          }
01673        *str_p = str;
01674 
01675        if (reloc == (int) BFD_RELOC_PPC64_TOC
01676            && exp_p->X_op == O_symbol
01677            && strcmp (S_GET_NAME (exp_p->X_add_symbol), ".TOC.") == 0)
01678          {
01679            /* Change the symbol so that the dummy .TOC. symbol can be
01680               omitted from the object file.  */
01681            exp_p->X_add_symbol = &abs_symbol;
01682          }
01683 
01684        return (bfd_reloc_code_real_type) reloc;
01685       }
01686 
01687   return BFD_RELOC_UNUSED;
01688 }
01689 
01690 /* Like normal .long/.short/.word, except support @got, etc.
01691    Clobbers input_line_pointer, checks end-of-line.  */
01692 static void
01693 ppc_elf_cons (nbytes)
01694      register int nbytes;   /* 1=.byte, 2=.word, 4=.long, 8=.llong.  */
01695 {
01696   expressionS exp;
01697   bfd_reloc_code_real_type reloc;
01698 
01699   if (is_it_end_of_statement ())
01700     {
01701       demand_empty_rest_of_line ();
01702       return;
01703     }
01704 
01705   do
01706     {
01707       expression (&exp);
01708       if (exp.X_op == O_symbol
01709          && *input_line_pointer == '@'
01710          && (reloc = ppc_elf_suffix (&input_line_pointer,
01711                                   &exp)) != BFD_RELOC_UNUSED)
01712        {
01713          reloc_howto_type *reloc_howto;
01714          int size;
01715 
01716          reloc_howto = bfd_reloc_type_lookup (stdoutput, reloc);
01717          size = bfd_get_reloc_size (reloc_howto);
01718 
01719          if (size > nbytes)
01720            {
01721              as_bad (_("%s relocations do not fit in %d bytes\n"),
01722                     reloc_howto->name, nbytes);
01723            }
01724          else
01725            {
01726              char *p;
01727              int offset;
01728 
01729              p = frag_more (nbytes);
01730              offset = 0;
01731              if (target_big_endian)
01732               offset = nbytes - size;
01733              fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
01734                         &exp, 0, reloc);
01735            }
01736        }
01737       else
01738        emit_expr (&exp, (unsigned int) nbytes);
01739     }
01740   while (*input_line_pointer++ == ',');
01741 
01742   /* Put terminator back into stream.  */
01743   input_line_pointer--;
01744   demand_empty_rest_of_line ();
01745 }
01746 
01747 /* Solaris pseduo op to change to the .rodata section.  */
01748 static void
01749 ppc_elf_rdata (xxx)
01750      int xxx;
01751 {
01752   char *save_line = input_line_pointer;
01753   static char section[] = ".rodata\n";
01754 
01755   /* Just pretend this is .section .rodata  */
01756   input_line_pointer = section;
01757   obj_elf_section (xxx);
01758 
01759   input_line_pointer = save_line;
01760 }
01761 
01762 /* Pseudo op to make file scope bss items.  */
01763 static void
01764 ppc_elf_lcomm (xxx)
01765      int xxx ATTRIBUTE_UNUSED;
01766 {
01767   register char *name;
01768   register char c;
01769   register char *p;
01770   offsetT size;
01771   register symbolS *symbolP;
01772   offsetT align;
01773   segT old_sec;
01774   int old_subsec;
01775   char *pfrag;
01776   int align2;
01777 
01778   name = input_line_pointer;
01779   c = get_symbol_end ();
01780 
01781   /* just after name is now '\0'.  */
01782   p = input_line_pointer;
01783   *p = c;
01784   SKIP_WHITESPACE ();
01785   if (*input_line_pointer != ',')
01786     {
01787       as_bad (_("Expected comma after symbol-name: rest of line ignored."));
01788       ignore_rest_of_line ();
01789       return;
01790     }
01791 
01792   input_line_pointer++;            /* skip ',' */
01793   if ((size = get_absolute_expression ()) < 0)
01794     {
01795       as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size);
01796       ignore_rest_of_line ();
01797       return;
01798     }
01799 
01800   /* The third argument to .lcomm is the alignment.  */
01801   if (*input_line_pointer != ',')
01802     align = 8;
01803   else
01804     {
01805       ++input_line_pointer;
01806       align = get_absolute_expression ();
01807       if (align <= 0)
01808        {
01809          as_warn (_("ignoring bad alignment"));
01810          align = 8;
01811        }
01812     }
01813 
01814   *p = 0;
01815   symbolP = symbol_find_or_make (name);
01816   *p = c;
01817 
01818   if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
01819     {
01820       as_bad (_("Ignoring attempt to re-define symbol `%s'."),
01821              S_GET_NAME (symbolP));
01822       ignore_rest_of_line ();
01823       return;
01824     }
01825 
01826   if (S_GET_VALUE (symbolP) && S_GET_VALUE (symbolP) != (valueT) size)
01827     {
01828       as_bad (_("Length of .lcomm \"%s\" is already %ld. Not changed to %ld."),
01829              S_GET_NAME (symbolP),
01830              (long) S_GET_VALUE (symbolP),
01831              (long) size);
01832 
01833       ignore_rest_of_line ();
01834       return;
01835     }
01836 
01837   /* Allocate_bss.  */
01838   old_sec = now_seg;
01839   old_subsec = now_subseg;
01840   if (align)
01841     {
01842       /* Convert to a power of 2 alignment.  */
01843       for (align2 = 0; (align & 1) == 0; align >>= 1, ++align2);
01844       if (align != 1)
01845        {
01846          as_bad (_("Common alignment not a power of 2"));
01847          ignore_rest_of_line ();
01848          return;
01849        }
01850     }
01851   else
01852     align2 = 0;
01853 
01854   record_alignment (bss_section, align2);
01855   subseg_set (bss_section, 0);
01856   if (align2)
01857     frag_align (align2, 0, 0);
01858   if (S_GET_SEGMENT (symbolP) == bss_section)
01859     symbol_get_frag (symbolP)->fr_symbol = 0;
01860   symbol_set_frag (symbolP, frag_now);
01861   pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
01862                   (char *) 0);
01863   *pfrag = 0;
01864   S_SET_SIZE (symbolP, size);
01865   S_SET_SEGMENT (symbolP, bss_section);
01866   subseg_set (old_sec, old_subsec);
01867   demand_empty_rest_of_line ();
01868 }
01869 
01870 /* Validate any relocations emitted for -mrelocatable, possibly adding
01871    fixups for word relocations in writable segments, so we can adjust
01872    them at runtime.  */
01873 static void
01874 ppc_elf_validate_fix (fixp, seg)
01875      fixS *fixp;
01876      segT seg;
01877 {
01878   if (fixp->fx_done || fixp->fx_pcrel)
01879     return;
01880 
01881   switch (shlib)
01882     {
01883     case SHLIB_NONE:
01884     case SHLIB_PIC:
01885       return;
01886 
01887     case SHLIB_MRELOCATABLE:
01888       if (fixp->fx_r_type <= BFD_RELOC_UNUSED
01889          && fixp->fx_r_type != BFD_RELOC_16_GOTOFF
01890          && fixp->fx_r_type != BFD_RELOC_HI16_GOTOFF
01891          && fixp->fx_r_type != BFD_RELOC_LO16_GOTOFF
01892          && fixp->fx_r_type != BFD_RELOC_HI16_S_GOTOFF
01893          && fixp->fx_r_type != BFD_RELOC_16_BASEREL
01894          && fixp->fx_r_type != BFD_RELOC_LO16_BASEREL
01895          && fixp->fx_r_type != BFD_RELOC_HI16_BASEREL
01896          && fixp->fx_r_type != BFD_RELOC_HI16_S_BASEREL
01897          && (seg->flags & SEC_LOAD) != 0
01898          && strcmp (segment_name (seg), ".got2") != 0
01899          && strcmp (segment_name (seg), ".dtors") != 0
01900          && strcmp (segment_name (seg), ".ctors") != 0
01901          && strcmp (segment_name (seg), ".fixup") != 0
01902          && strcmp (segment_name (seg), ".gcc_except_table") != 0
01903          && strcmp (segment_name (seg), ".eh_frame") != 0
01904          && strcmp (segment_name (seg), ".ex_shared") != 0)
01905        {
01906          if ((seg->flags & (SEC_READONLY | SEC_CODE)) != 0
01907              || fixp->fx_r_type != BFD_RELOC_CTOR)
01908            {
01909              as_bad_where (fixp->fx_file, fixp->fx_line,
01910                          _("Relocation cannot be done when using -mrelocatable"));
01911            }
01912        }
01913       return;
01914     }
01915 }
01916 
01917 /* Prevent elf_frob_file_before_adjust removing a weak undefined
01918    function descriptor sym if the corresponding code sym is used.  */
01919 
01920 void
01921 ppc_frob_file_before_adjust ()
01922 {
01923   symbolS *symp;
01924   asection *toc;
01925 
01926   if (!ppc_obj64)
01927     return;
01928 
01929   for (symp = symbol_rootP; symp; symp = symbol_next (symp))
01930     {
01931       const char *name;
01932       char *dotname;
01933       symbolS *dotsym;
01934       size_t len;
01935 
01936       name = S_GET_NAME (symp);
01937       if (name[0] == '.')
01938        continue;
01939 
01940       if (! S_IS_WEAK (symp)
01941          || S_IS_DEFINED (symp))
01942        continue;
01943 
01944       len = strlen (name) + 1;
01945       dotname = xmalloc (len + 1);
01946       dotname[0] = '.';
01947       memcpy (dotname + 1, name, len);
01948       dotsym = symbol_find_noref (dotname, 1);
01949       free (dotname);
01950       if (dotsym != NULL && (symbol_used_p (dotsym)
01951                           || symbol_used_in_reloc_p (dotsym)))
01952        symbol_mark_used (symp);
01953 
01954     }
01955 
01956   toc = bfd_get_section_by_name (stdoutput, ".toc");
01957   if (toc != NULL
01958       && bfd_section_size (stdoutput, toc) > 0x10000)
01959     as_warn (_("TOC section size exceeds 64k"));
01960 
01961   /* Don't emit .TOC. symbol.  */
01962   symp = symbol_find (".TOC.");
01963   if (symp != NULL)
01964     symbol_remove (symp, &symbol_rootP, &symbol_lastP);
01965 }
01966 #endif /* OBJ_ELF */
01967 
01968 #ifdef TE_PE
01969 
01970 /*
01971  * Summary of parse_toc_entry.
01972  *
01973  * in: Input_line_pointer points to the '[' in one of:
01974  *
01975  *        [toc] [tocv] [toc32] [toc64]
01976  *
01977  *      Anything else is an error of one kind or another.
01978  *
01979  * out:
01980  *   return value: success or failure
01981  *   toc_kind:     kind of toc reference
01982  *   input_line_pointer:
01983  *     success: first char after the ']'
01984  *     failure: unchanged
01985  *
01986  * settings:
01987  *
01988  *     [toc]   - rv == success, toc_kind = default_toc
01989  *     [tocv]  - rv == success, toc_kind = data_in_toc
01990  *     [toc32] - rv == success, toc_kind = must_be_32
01991  *     [toc64] - rv == success, toc_kind = must_be_64
01992  *
01993  */
01994 
01995 enum toc_size_qualifier
01996 {
01997   default_toc, /* The toc cell constructed should be the system default size */
01998   data_in_toc, /* This is a direct reference to a toc cell                   */
01999   must_be_32,  /* The toc cell constructed must be 32 bits wide              */
02000   must_be_64   /* The toc cell constructed must be 64 bits wide              */
02001 };
02002 
02003 static int
02004 parse_toc_entry (toc_kind)
02005      enum toc_size_qualifier *toc_kind;
02006 {
02007   char *start;
02008   char *toc_spec;
02009   char c;
02010   enum toc_size_qualifier t;
02011 
02012   /* Save the input_line_pointer.  */
02013   start = input_line_pointer;
02014 
02015   /* Skip over the '[' , and whitespace.  */
02016   ++input_line_pointer;
02017   SKIP_WHITESPACE ();
02018 
02019   /* Find the spelling of the operand.  */
02020   toc_spec = input_line_pointer;
02021   c = get_symbol_end ();
02022 
02023   if (strcmp (toc_spec, "toc") == 0)
02024     {
02025       t = default_toc;
02026     }
02027   else if (strcmp (toc_spec, "tocv") == 0)
02028     {
02029       t = data_in_toc;
02030     }
02031   else if (strcmp (toc_spec, "toc32") == 0)
02032     {
02033       t = must_be_32;
02034     }
02035   else if (strcmp (toc_spec, "toc64") == 0)
02036     {
02037       t = must_be_64;
02038     }
02039   else
02040     {
02041       as_bad (_("syntax error: invalid toc specifier `%s'"), toc_spec);
02042       *input_line_pointer = c;
02043       input_line_pointer = start;
02044       return 0;
02045     }
02046 
02047   /* Now find the ']'.  */
02048   *input_line_pointer = c;
02049 
02050   SKIP_WHITESPACE ();            /* leading whitespace could be there.  */
02051   c = *input_line_pointer++; /* input_line_pointer->past char in c.  */
02052 
02053   if (c != ']')
02054     {
02055       as_bad (_("syntax error: expected `]', found  `%c'"), c);
02056       input_line_pointer = start;
02057       return 0;
02058     }
02059 
02060   *toc_kind = t;
02061   return 1;
02062 }
02063 #endif
02064 
02065 
02066 #ifdef OBJ_ELF
02067 #define APUID(a,v)   ((((a) & 0xffff) << 16) | ((v) & 0xffff))
02068 static void
02069 ppc_apuinfo_section_add (apu, version)
02070       unsigned int apu, version;
02071 {
02072   unsigned int i;
02073 
02074   /* Check we don't already exist.  */
02075   for (i = 0; i < ppc_apuinfo_num; i++)
02076     if (ppc_apuinfo_list[i] == APUID (apu, version))
02077       return;
02078 
02079   if (ppc_apuinfo_num == ppc_apuinfo_num_alloc)
02080     {
02081       if (ppc_apuinfo_num_alloc == 0)
02082        {
02083          ppc_apuinfo_num_alloc = 4;
02084          ppc_apuinfo_list = (unsigned long *)
02085              xmalloc (sizeof (unsigned long) * ppc_apuinfo_num_alloc);
02086        }
02087       else
02088        {
02089          ppc_apuinfo_num_alloc += 4;
02090          ppc_apuinfo_list = (unsigned long *) xrealloc (ppc_apuinfo_list,
02091              sizeof (unsigned long) * ppc_apuinfo_num_alloc);
02092        }
02093     }
02094   ppc_apuinfo_list[ppc_apuinfo_num++] = APUID (apu, version);
02095 }
02096 #undef APUID
02097 #endif
02098 
02099 
02100 /* We need to keep a list of fixups.  We can't simply generate them as
02101    we go, because that would require us to first create the frag, and
02102    that would screw up references to ``.''.  */
02103 
02104 struct ppc_fixup
02105 {
02106   expressionS exp;
02107   int opindex;
02108   bfd_reloc_code_real_type reloc;
02109 };
02110 
02111 #define MAX_INSN_FIXUPS (5)
02112 
02113 /* This routine is called for each instruction to be assembled.  */
02114 
02115 void
02116 md_assemble (str)
02117      char *str;
02118 {
02119   char *s;
02120   const struct powerpc_opcode *opcode;
02121   unsigned long insn;
02122   const unsigned char *opindex_ptr;
02123   int skip_optional;
02124   int need_paren;
02125   int next_opindex;
02126   struct ppc_fixup fixups[MAX_INSN_FIXUPS];
02127   int fc;
02128   char *f;
02129   int addr_mod;
02130   int i;
02131 #ifdef OBJ_ELF
02132   bfd_reloc_code_real_type reloc;
02133 #endif
02134 
02135   /* Get the opcode.  */
02136   for (s = str; *s != '\0' && ! ISSPACE (*s); s++)
02137     ;
02138   if (*s != '\0')
02139     *s++ = '\0';
02140 
02141   /* Look up the opcode in the hash table.  */
02142   opcode = (const struct powerpc_opcode *) hash_find (ppc_hash, str);
02143   if (opcode == (const struct powerpc_opcode *) NULL)
02144     {
02145       const struct powerpc_macro *macro;
02146 
02147       macro = (const struct powerpc_macro *) hash_find (ppc_macro_hash, str);
02148       if (macro == (const struct powerpc_macro *) NULL)
02149        as_bad (_("Unrecognized opcode: `%s'"), str);
02150       else
02151        ppc_macro (s, macro);
02152 
02153       return;
02154     }
02155 
02156   insn = opcode->opcode;
02157 
02158   str = s;
02159   while (ISSPACE (*str))
02160     ++str;
02161 
02162   /* PowerPC operands are just expressions.  The only real issue is
02163      that a few operand types are optional.  All cases which might use
02164      an optional operand separate the operands only with commas (in some
02165      cases parentheses are used, as in ``lwz 1,0(1)'' but such cases never
02166      have optional operands).  Most instructions with optional operands
02167      have only one.  Those that have more than one optional operand can
02168      take either all their operands or none.  So, before we start seriously
02169      parsing the operands, we check to see if we have optional operands,
02170      and if we do, we count the number of commas to see which operands
02171      have been omitted.  */
02172   skip_optional = 0;
02173   for (opindex_ptr = opcode->operands; *opindex_ptr != 0; opindex_ptr++)
02174     {
02175       const struct powerpc_operand *operand;
02176 
02177       operand = &powerpc_operands[*opindex_ptr];
02178       if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0)
02179        {
02180          unsigned int opcount;
02181          unsigned int num_operands_expected;
02182          unsigned int i;
02183 
02184          /* There is an optional operand.  Count the number of
02185             commas in the input line.  */
02186          if (*str == '\0')
02187            opcount = 0;
02188          else
02189            {
02190              opcount = 1;
02191              s = str;
02192              while ((s = strchr (s, ',')) != (char *) NULL)
02193               {
02194                 ++opcount;
02195                 ++s;
02196               }
02197            }
02198 
02199          /* Compute the number of expected operands.
02200             Do not count fake operands.  */
02201          for (num_operands_expected = 0, i = 0; opcode->operands[i]; i ++)
02202            if ((powerpc_operands [opcode->operands[i]].flags & PPC_OPERAND_FAKE) == 0)
02203              ++ num_operands_expected;
02204 
02205          /* If there are fewer operands in the line then are called
02206             for by the instruction, we want to skip the optional
02207             operands.  */
02208          if (opcount < num_operands_expected)
02209            skip_optional = 1;
02210 
02211          break;
02212        }
02213     }
02214 
02215   /* Gather the operands.  */
02216   need_paren = 0;
02217   next_opindex = 0;
02218   fc = 0;
02219   for (opindex_ptr = opcode->operands; *opindex_ptr != 0; opindex_ptr++)
02220     {
02221       const struct powerpc_operand *operand;
02222       const char *errmsg;
02223       char *hold;
02224       expressionS ex;
02225       char endc;
02226 
02227       if (next_opindex == 0)
02228        operand = &powerpc_operands[*opindex_ptr];
02229       else
02230        {
02231          operand = &powerpc_operands[next_opindex];
02232          next_opindex = 0;
02233        }
02234       errmsg = NULL;
02235 
02236       /* If this is a fake operand, then we do not expect anything
02237         from the input.  */
02238       if ((operand->flags & PPC_OPERAND_FAKE) != 0)
02239        {
02240          insn = (*operand->insert) (insn, 0L, ppc_cpu, &errmsg);
02241          if (errmsg != (const char *) NULL)
02242            as_bad (errmsg);
02243          continue;
02244        }
02245 
02246       /* If this is an optional operand, and we are skipping it, just
02247         insert a zero.  */
02248       if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
02249          && skip_optional)
02250        {
02251          if (operand->insert)
02252            {
02253              insn = (*operand->insert) (insn, 0L, ppc_cpu, &errmsg);
02254              if (errmsg != (const char *) NULL)
02255               as_bad (errmsg);
02256            }
02257          if ((operand->flags & PPC_OPERAND_NEXT) != 0)
02258            next_opindex = *opindex_ptr + 1;
02259          continue;
02260        }
02261 
02262       /* Gather the operand.  */
02263       hold = input_line_pointer;
02264       input_line_pointer = str;
02265 
02266 #ifdef TE_PE
02267       if (*input_line_pointer == '[')
02268        {
02269          /* We are expecting something like the second argument here:
02270           *
02271           *    lwz r4,[toc].GS.0.static_int(rtoc)
02272           *           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
02273           * The argument following the `]' must be a symbol name, and the
02274           * register must be the toc register: 'rtoc' or '2'
02275           *
02276           * The effect is to 0 as the displacement field
02277           * in the instruction, and issue an IMAGE_REL_PPC_TOCREL16 (or
02278           * the appropriate variation) reloc against it based on the symbol.
02279           * The linker will build the toc, and insert the resolved toc offset.
02280           *
02281           * Note:
02282           * o The size of the toc entry is currently assumed to be
02283           *   32 bits. This should not be assumed to be a hard coded
02284           *   number.
02285           * o In an effort to cope with a change from 32 to 64 bits,
02286           *   there are also toc entries that are specified to be
02287           *   either 32 or 64 bits:
02288           *     lwz r4,[toc32].GS.0.static_int(rtoc)
02289           *     lwz r4,[toc64].GS.0.static_int(rtoc)
02290           *   These demand toc entries of the specified size, and the
02291           *   instruction probably requires it.
02292           */
02293 
02294          int valid_toc;
02295          enum toc_size_qualifier toc_kind;
02296          bfd_reloc_code_real_type toc_reloc;
02297 
02298          /* Go parse off the [tocXX] part.  */
02299          valid_toc = parse_toc_entry (&toc_kind);
02300 
02301          if (!valid_toc)
02302            {
02303              /* Note: message has already been issued.
02304                FIXME: what sort of recovery should we do?
02305                demand_rest_of_line (); return; ?  */
02306            }
02307 
02308          /* Now get the symbol following the ']'.  */
02309          expression (&ex);
02310 
02311          switch (toc_kind)
02312            {
02313            case default_toc:
02314              /* In this case, we may not have seen the symbol yet,
02315                since  it is allowed to appear on a .extern or .globl
02316                or just be a label in the .data section.  */
02317              toc_reloc = BFD_RELOC_PPC_TOC16;
02318              break;
02319            case data_in_toc:
02320              /* 1. The symbol must be defined and either in the toc
02321                section, or a global.
02322                2. The reloc generated must have the TOCDEFN flag set
02323                in upper bit mess of the reloc type.
02324                FIXME: It's a little confusing what the tocv
02325                qualifier can be used for.  At the very least, I've
02326                seen three uses, only one of which I'm sure I can
02327                explain.  */
02328              if (ex.X_op == O_symbol)
02329               {
02330                 assert (ex.X_add_symbol != NULL);
02331                 if (symbol_get_bfdsym (ex.X_add_symbol)->section
02332                     != tocdata_section)
02333                   {
02334                     as_bad (_("[tocv] symbol is not a toc symbol"));
02335                   }
02336               }
02337 
02338              toc_reloc = BFD_RELOC_PPC_TOC16;
02339              break;
02340            case must_be_32:
02341              /* FIXME: these next two specifically specify 32/64 bit
02342                toc entries.  We don't support them today.  Is this
02343                the right way to say that?  */
02344              toc_reloc = BFD_RELOC_UNUSED;
02345              as_bad (_("Unimplemented toc32 expression modifier"));
02346              break;
02347            case must_be_64:
02348              /* FIXME: see above.  */
02349              toc_reloc = BFD_RELOC_UNUSED;
02350              as_bad (_("Unimplemented toc64 expression modifier"));
02351              break;
02352            default:
02353              fprintf (stderr,
02354                      _("Unexpected return value [%d] from parse_toc_entry!\n"),
02355                      toc_kind);
02356              abort ();
02357              break;
02358            }
02359 
02360          /* We need to generate a fixup for this expression.  */
02361          if (fc >= MAX_INSN_FIXUPS)
02362            as_fatal (_("too many fixups"));
02363 
02364          fixups[fc].reloc = toc_reloc;
02365          fixups[fc].exp = ex;
02366          fixups[fc].opindex = *opindex_ptr;
02367          ++fc;
02368 
02369          /* Ok. We've set up the fixup for the instruction. Now make it
02370             look like the constant 0 was found here.  */
02371          ex.X_unsigned = 1;
02372          ex.X_op = O_constant;
02373          ex.X_add_number = 0;
02374          ex.X_add_symbol = NULL;
02375          ex.X_op_symbol = NULL;
02376        }
02377 
02378       else
02379 #endif        /* TE_PE */
02380        {
02381          if (! register_name (&ex))
02382            {
02383              if ((operand->flags & PPC_OPERAND_CR) != 0)
02384               cr_operand = TRUE;
02385              expression (&ex);
02386              cr_operand = FALSE;
02387            }
02388        }
02389 
02390       str = input_line_pointer;
02391       input_line_pointer = hold;
02392 
02393       if (ex.X_op == O_illegal)
02394        as_bad (_("illegal operand"));
02395       else if (ex.X_op == O_absent)
02396        as_bad (_("missing operand"));
02397       else if (ex.X_op == O_register)
02398        {
02399          insn = ppc_insert_operand (insn, operand, ex.X_add_number,
02400                                  (char *) NULL, 0);
02401        }
02402       else if (ex.X_op == O_constant)
02403        {
02404 #ifdef OBJ_ELF
02405          /* Allow @HA, @L, @H on constants.  */
02406          char *orig_str = str;
02407 
02408          if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_UNUSED)
02409            switch (reloc)
02410              {
02411              default:
02412               str = orig_str;
02413               break;
02414 
02415              case BFD_RELOC_LO16:
02416               /* X_unsigned is the default, so if the user has done
02417                  something which cleared it, we always produce a
02418                  signed value.  */
02419               if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
02420                 ex.X_add_number &= 0xffff;
02421               else
02422                 ex.X_add_number = SEX16 (ex.X_add_number);
02423               break;
02424 
02425              case BFD_RELOC_HI16:
02426               if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
02427                 ex.X_add_number = PPC_HI (ex.X_add_number);
02428               else
02429                 ex.X_add_number = SEX16 (PPC_HI (ex.X_add_number));
02430               break;
02431 
02432              case BFD_RELOC_HI16_S:
02433               if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
02434                 ex.X_add_number = PPC_HA (ex.X_add_number);
02435               else
02436                 ex.X_add_number = SEX16 (PPC_HA (ex.X_add_number));
02437               break;
02438 
02439              case BFD_RELOC_PPC64_HIGHER:
02440               if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
02441                 ex.X_add_number = PPC_HIGHER (ex.X_add_number);
02442               else
02443                 ex.X_add_number = SEX16 (PPC_HIGHER (ex.X_add_number));
02444               break;
02445 
02446              case BFD_RELOC_PPC64_HIGHER_S:
02447               if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
02448                 ex.X_add_number = PPC_HIGHERA (ex.X_add_number);
02449               else
02450                 ex.X_add_number = SEX16 (PPC_HIGHERA (ex.X_add_number));
02451               break;
02452 
02453              case BFD_RELOC_PPC64_HIGHEST:
02454               if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
02455                 ex.X_add_number = PPC_HIGHEST (ex.X_add_number);
02456               else
02457                 ex.X_add_number = SEX16 (PPC_HIGHEST (ex.X_add_number));
02458               break;
02459 
02460              case BFD_RELOC_PPC64_HIGHEST_S:
02461               if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
02462                 ex.X_add_number = PPC_HIGHESTA (ex.X_add_number);
02463               else
02464                 ex.X_add_number = SEX16 (PPC_HIGHESTA (ex.X_add_number));
02465               break;
02466              }
02467 #endif /* OBJ_ELF */
02468          insn = ppc_insert_operand (insn, operand, ex.X_add_number,
02469                                  (char *) NULL, 0);
02470        }
02471 #ifdef OBJ_ELF
02472       else if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_UNUSED)
02473        {
02474          /* Some TLS tweaks.  */
02475          switch (reloc)
02476            {
02477            default:
02478              break;
02479            case BFD_RELOC_PPC_TLS:
02480              insn = ppc_insert_operand (insn, operand, ppc_obj64 ? 13 : 2,
02481                                     (char *) NULL, 0);
02482              break;
02483          /* We'll only use the 32 (or 64) bit form of these relocations
02484             in constants.  Instructions get the 16 bit form.  */
02485            case BFD_RELOC_PPC_DTPREL:
02486              reloc = BFD_RELOC_PPC_DTPREL16;
02487              break;
02488            case BFD_RELOC_PPC_TPREL:
02489              reloc = BFD_RELOC_PPC_TPREL16;
02490              break;
02491            }
02492 
02493          /* For the absolute forms of branches, convert the PC
02494             relative form back into the absolute.  */
02495          if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
02496            {
02497              switch (reloc)
02498               {
02499               case BFD_RELOC_PPC_B26:
02500                 reloc = BFD_RELOC_PPC_BA26;
02501                 break;
02502               case BFD_RELOC_PPC_B16:
02503                 reloc = BFD_RELOC_PPC_BA16;
02504                 break;
02505               case BFD_RELOC_PPC_B16_BRTAKEN:
02506                 reloc = BFD_RELOC_PPC_BA16_BRTAKEN;
02507                 break;
02508               case BFD_RELOC_PPC_B16_BRNTAKEN:
02509                 reloc = BFD_RELOC_PPC_BA16_BRNTAKEN;
02510                 break;
02511               default:
02512                 break;
02513               }
02514            }
02515 
02516          if (ppc_obj64
02517              && (operand->flags & (PPC_OPERAND_DS | PPC_OPERAND_DQ)) != 0)
02518            {
02519              switch (reloc)
02520               {
02521               case BFD_RELOC_16:
02522                 reloc = BFD_RELOC_PPC64_ADDR16_DS;
02523                 break;
02524               case BFD_RELOC_LO16:
02525                 reloc = BFD_RELOC_PPC64_ADDR16_LO_DS;
02526                 break;
02527               case BFD_RELOC_16_GOTOFF:
02528                 reloc = BFD_RELOC_PPC64_GOT16_DS;
02529                 break;
02530               case BFD_RELOC_LO16_GOTOFF:
02531                 reloc = BFD_RELOC_PPC64_GOT16_LO_DS;
02532                 break;
02533               case BFD_RELOC_LO16_PLTOFF:
02534                 reloc = BFD_RELOC_PPC64_PLT16_LO_DS;
02535                 break;
02536               case BFD_RELOC_16_BASEREL:
02537                 reloc = BFD_RELOC_PPC64_SECTOFF_DS;
02538                 break;
02539               case BFD_RELOC_LO16_BASEREL:
02540                 reloc = BFD_RELOC_PPC64_SECTOFF_LO_DS;
02541                 break;
02542               case BFD_RELOC_PPC_TOC16:
02543                 reloc = BFD_RELOC_PPC64_TOC16_DS;
02544                 break;
02545               case BFD_RELOC_PPC64_TOC16_LO:
02546                 reloc = BFD_RELOC_PPC64_TOC16_LO_DS;
02547                 break;
02548               case BFD_RELOC_PPC64_PLTGOT16:
02549                 reloc = BFD_RELOC_PPC64_PLTGOT16_DS;
02550                 break;
02551               case BFD_RELOC_PPC64_PLTGOT16_LO:
02552                 reloc = BFD_RELOC_PPC64_PLTGOT16_LO_DS;
02553                 break;
02554               case BFD_RELOC_PPC_DTPREL16:
02555                 reloc = BFD_RELOC_PPC64_DTPREL16_DS;
02556                 break;
02557               case BFD_RELOC_PPC_DTPREL16_LO:
02558                 reloc = BFD_RELOC_PPC64_DTPREL16_LO_DS;
02559                 break;
02560               case BFD_RELOC_PPC_TPREL16:
02561                 reloc = BFD_RELOC_PPC64_TPREL16_DS;
02562                 break;
02563               case BFD_RELOC_PPC_TPREL16_LO:
02564                 reloc = BFD_RELOC_PPC64_TPREL16_LO_DS;
02565                 break;
02566               case BFD_RELOC_PPC_GOT_DTPREL16:
02567               case BFD_RELOC_PPC_GOT_DTPREL16_LO:
02568               case BFD_RELOC_PPC_GOT_TPREL16:
02569               case BFD_RELOC_PPC_GOT_TPREL16_LO:
02570                 break;
02571               default:
02572                 as_bad (_("unsupported relocation for DS offset field"));
02573                 break;
02574               }
02575            }
02576 
02577          /* We need to generate a fixup for this expression.  */
02578          if (fc >= MAX_INSN_FIXUPS)
02579            as_fatal (_("too many fixups"));
02580          fixups[fc].exp = ex;
02581          fixups[fc].opindex = 0;
02582          fixups[fc].reloc = reloc;
02583          ++fc;
02584        }
02585 #endif /* OBJ_ELF */
02586 
02587       else
02588        {
02589          /* We need to generate a fixup for this expression.  */
02590          if (fc >= MAX_INSN_FIXUPS)
02591            as_fatal (_("too many fixups"));
02592          fixups[fc].exp = ex;
02593          fixups[fc].opindex = *opindex_ptr;
02594          fixups[fc].reloc = BFD_RELOC_UNUSED;
02595          ++fc;
02596        }
02597 
02598       if (need_paren)
02599        {
02600          endc = ')';
02601          need_paren = 0;
02602        }
02603       else if ((operand->flags & PPC_OPERAND_PARENS) != 0)
02604        {
02605          endc = '(';
02606          need_paren = 1;
02607        }
02608       else
02609        endc = ',';
02610 
02611       /* The call to expression should have advanced str past any
02612         whitespace.  */
02613       if (*str != endc
02614          && (endc != ',' || *str != '\0'))
02615        {
02616          as_bad (_("syntax error; found `%c' but expected `%c'"), *str, endc);
02617          break;
02618        }
02619 
02620       if (*str != '\0')
02621        ++str;
02622     }
02623 
02624   while (ISSPACE (*str))
02625     ++str;
02626 
02627   if (*str != '\0')
02628     as_bad (_("junk at end of line: `%s'"), str);
02629 
02630 #ifdef OBJ_ELF
02631   /* Do we need/want a APUinfo section? */
02632   if (ppc_cpu & (PPC_OPCODE_SPE
02633               | PPC_OPCODE_ISEL | PPC_OPCODE_EFS
02634               | PPC_OPCODE_BRLOCK | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK
02635               | PPC_OPCODE_RFMCI))
02636     {
02637       /* These are all version "1".  */
02638       if (opcode->flags & PPC_OPCODE_SPE)
02639        ppc_apuinfo_section_add (PPC_APUINFO_SPE, 1);
02640       if (opcode->flags & PPC_OPCODE_ISEL)
02641        ppc_apuinfo_section_add (PPC_APUINFO_ISEL, 1);
02642       if (opcode->flags & PPC_OPCODE_EFS)
02643        ppc_apuinfo_section_add (PPC_APUINFO_EFS, 1);
02644       if (opcode->flags & PPC_OPCODE_BRLOCK)
02645        ppc_apuinfo_section_add (PPC_APUINFO_BRLOCK, 1);
02646       if (opcode->flags & PPC_OPCODE_PMR)
02647        ppc_apuinfo_section_add (PPC_APUINFO_PMR, 1);
02648       if (opcode->flags & PPC_OPCODE_CACHELCK)
02649        ppc_apuinfo_section_add (PPC_APUINFO_CACHELCK, 1);
02650       if (opcode->flags & PPC_OPCODE_RFMCI)
02651        ppc_apuinfo_section_add (PPC_APUINFO_RFMCI, 1);
02652     }
02653 #endif
02654 
02655   /* Write out the instruction.  */
02656   f = frag_more (4);
02657   addr_mod = frag_now_fix () & 3;
02658   if (frag_now->has_code && frag_now->insn_addr != addr_mod)
02659     as_bad (_("instruction address is not a multiple of 4"));
02660   frag_now->insn_addr = addr_mod;
02661   frag_now->has_code = 1;
02662   md_number_to_chars (f, insn, 4);
02663 
02664 #ifdef OBJ_ELF
02665   dwarf2_emit_insn (4);
02666 #endif
02667 
02668   /* Create any fixups.  At this point we do not use a
02669      bfd_reloc_code_real_type, but instead just use the
02670      BFD_RELOC_UNUSED plus the operand index.  This lets us easily
02671      handle fixups for any operand type, although that is admittedly
02672      not a very exciting feature.  We pick a BFD reloc type in
02673      md_apply_fix.  */
02674   for (i = 0; i < fc; i++)
02675     {
02676       const struct powerpc_operand *operand;
02677 
02678       operand = &powerpc_operands[fixups[i].opindex];
02679       if (fixups[i].reloc != BFD_RELOC_UNUSED)
02680        {
02681          reloc_howto_type *reloc_howto;
02682          int size;
02683          int offset;
02684          fixS *fixP;
02685 
02686          reloc_howto = bfd_reloc_type_lookup (stdoutput, fixups[i].reloc);
02687          if (!reloc_howto)
02688            abort ();
02689 
02690          size = bfd_get_reloc_size (reloc_howto);
02691          offset = target_big_endian ? (4 - size) : 0;
02692 
02693          if (size < 1 || size > 4)
02694            abort ();
02695 
02696          fixP = fix_new_exp (frag_now,
02697                            f - frag_now->fr_literal + offset,
02698                            size,
02699                            &fixups[i].exp,
02700                            reloc_howto->pc_relative,
02701                            fixups[i].reloc);
02702 
02703          /* Turn off complaints that the addend is too large for things like
02704             foo+100000@ha.  */
02705          switch (fixups[i].reloc)
02706            {
02707            case BFD_RELOC_16_GOTOFF:
02708            case BFD_RELOC_PPC_TOC16:
02709            case BFD_RELOC_LO16:
02710            case BFD_RELOC_HI16:
02711            case BFD_RELOC_HI16_S:
02712 #ifdef OBJ_ELF
02713            case BFD_RELOC_PPC64_HIGHER:
02714            case BFD_RELOC_PPC64_HIGHER_S:
02715            case BFD_RELOC_PPC64_HIGHEST:
02716            case BFD_RELOC_PPC64_HIGHEST_S:
02717 #endif
02718              fixP->fx_no_overflow = 1;
02719              break;
02720            default:
02721              break;
02722            }
02723        }
02724       else
02725        fix_new_exp (frag_now,
02726                    f - frag_now->fr_literal,
02727                    4,
02728                    &fixups[i].exp,
02729                    (operand->flags & PPC_OPERAND_RELATIVE) != 0,
02730                    ((bfd_reloc_code_real_type)
02731                     (fixups[i].opindex + (int) BFD_RELOC_UNUSED)));
02732     }
02733 }
02734 
02735 /* Handle a macro.  Gather all the operands, transform them as
02736    described by the macro, and call md_assemble recursively.  All the
02737    operands are separated by commas; we don't accept parentheses
02738    around operands here.  */
02739 
02740 static void
02741 ppc_macro (str, macro)
02742      char *str;
02743      const struct powerpc_macro *macro;
02744 {
02745   char *operands[10];
02746   unsigned int count;
02747   char *s;
02748   unsigned int len;
02749   const char *format;
02750   int arg;
02751   char *send;
02752   char *complete;
02753 
02754   /* Gather the users operands into the operands array.  */
02755   count = 0;
02756   s = str;
02757   while (1)
02758     {
02759       if (count >= sizeof operands / sizeof operands[0])
02760        break;
02761       operands[count++] = s;
02762       s = strchr (s, ',');
02763       if (s == (char *) NULL)
02764        break;
02765       *s++ = '\0';
02766     }
02767 
02768   if (count != macro->operands)
02769     {
02770       as_bad (_("wrong number of operands"));
02771       return;
02772     }
02773 
02774   /* Work out how large the string must be (the size is unbounded
02775      because it includes user input).  */
02776   len = 0;
02777   format = macro->format;
02778   while (*format != '\0')
02779     {
02780       if (*format != '%')
02781        {
02782          ++len;
02783          ++format;
02784        }
02785       else
02786        {
02787          arg = strtol (format + 1, &send, 10);
02788          know (send != format && arg >= 0 && arg < count);
02789          len += strlen (operands[arg]);
02790          format = send;
02791        }
02792     }
02793 
02794   /* Put the string together.  */
02795   complete = s = (char *) alloca (len + 1);
02796   format = macro->format;
02797   while (*format != '\0')
02798     {
02799       if (*format != '%')
02800        *s++ = *format++;
02801       else
02802        {
02803          arg = strtol (format + 1, &send, 10);
02804          strcpy (s, operands[arg]);
02805          s += strlen (s);
02806          format = send;
02807        }
02808     }
02809   *s = '\0';
02810 
02811   /* Assemble the constructed instruction.  */
02812   md_assemble (complete);
02813 }
02814 
02815 #ifdef OBJ_ELF
02816 /* For ELF, add support for SHF_EXCLUDE and SHT_ORDERED.  */
02817 
02818 int
02819 ppc_section_letter (letter, ptr_msg)
02820      int letter;
02821      char **ptr_msg;
02822 {
02823   if (letter == 'e')
02824     return SHF_EXCLUDE;
02825 
02826   *ptr_msg = _("Bad .section directive: want a,e,w,x,M,S,G,T in string");
02827   return -1;
02828 }
02829 
02830 int
02831 ppc_section_word (str, len)
02832      char *str;
02833      size_t len;
02834 {
02835   if (len == 7 && strncmp (str, "exclude", 7) == 0)
02836     return SHF_EXCLUDE;
02837 
02838   return -1;
02839 }
02840 
02841 int
02842 ppc_section_type (str, len)
02843      char *str;
02844      size_t len;
02845 {
02846   if (len == 7 && strncmp (str, "ordered", 7) == 0)
02847     return SHT_ORDERED;
02848 
02849   return -1;
02850 }
02851 
02852 int
02853 ppc_section_flags (flags, attr, type)
02854      int flags;
02855      int attr;
02856      int type;
02857 {
02858   if (type == SHT_ORDERED)
02859     flags |= SEC_ALLOC | SEC_LOAD | SEC_SORT_ENTRIES;
02860 
02861   if (attr & SHF_EXCLUDE)
02862     flags |= SEC_EXCLUDE;
02863 
02864   return flags;
02865 }
02866 #endif /* OBJ_ELF */
02867 
02868 
02869 /* Pseudo-op handling.  */
02870 
02871 /* The .byte pseudo-op.  This is similar to the normal .byte
02872    pseudo-op, but it can also take a single ASCII string.  */
02873 
02874 static void
02875 ppc_byte (ignore)
02876      int ignore ATTRIBUTE_UNUSED;
02877 {
02878   if (*input_line_pointer != '\"')
02879     {
02880       cons (1);
02881       return;
02882     }
02883 
02884   /* Gather characters.  A real double quote is doubled.  Unusual
02885      characters are not permitted.  */
02886   ++input_line_pointer;
02887   while (1)
02888     {
02889       char c;
02890 
02891       c = *input_line_pointer++;
02892 
02893       if (c == '\"')
02894        {
02895          if (*input_line_pointer != '\"')
02896            break;
02897          ++input_line_pointer;
02898        }
02899 
02900       FRAG_APPEND_1_CHAR (c);
02901     }
02902 
02903   demand_empty_rest_of_line ();
02904 }
02905 
02906 #ifdef OBJ_XCOFF
02907 
02908 /* XCOFF specific pseudo-op handling.  */
02909 
02910 /* This is set if we are creating a .stabx symbol, since we don't want
02911    to handle symbol suffixes for such symbols.  */
02912 static bfd_boolean ppc_stab_symbol;
02913 
02914 /* The .comm and .lcomm pseudo-ops for XCOFF.  XCOFF puts common
02915    symbols in the .bss segment as though they were local common
02916    symbols, and uses a different smclas.  The native Aix 4.3.3 assembler
02917    aligns .comm and .lcomm to 4 bytes.  */
02918 
02919 static void
02920 ppc_comm (lcomm)
02921      int lcomm;
02922 {
02923   asection *current_seg = now_seg;
02924   subsegT current_subseg = now_subseg;
02925   char *name;
02926   char endc;
02927   char *end_name;
02928   offsetT size;
02929   offsetT align;
02930   symbolS *lcomm_sym = NULL;
02931   symbolS *sym;
02932   char *pfrag;
02933 
02934   name = input_line_pointer;
02935   endc = get_symbol_end ();
02936   end_name = input_line_pointer;
02937   *end_name = endc;
02938 
02939   if (*input_line_pointer != ',')
02940     {
02941       as_bad (_("missing size"));
02942       ignore_rest_of_line ();
02943       return;
02944     }
02945   ++input_line_pointer;
02946 
02947   size = get_absolute_expression ();
02948   if (size < 0)
02949     {
02950       as_bad (_("negative size"));
02951       ignore_rest_of_line ();
02952       return;
02953     }
02954 
02955   if (! lcomm)
02956     {
02957       /* The third argument to .comm is the alignment.  */
02958       if (*input_line_pointer != ',')
02959        align = 2;
02960       else
02961        {
02962          ++input_line_pointer;
02963          align = get_absolute_expression ();
02964          if (align <= 0)
02965            {
02966              as_warn (_("ignoring bad alignment"));
02967              align = 2;
02968            }
02969        }
02970     }
02971   else
02972     {
02973       char *lcomm_name;
02974       char lcomm_endc;
02975 
02976       if (size <= 4)
02977        align = 2;
02978       else
02979        align = 3;
02980 
02981       /* The third argument to .lcomm appears to be the real local
02982         common symbol to create.  References to the symbol named in
02983         the first argument are turned into references to the third
02984         argument.  */
02985       if (*input_line_pointer != ',')
02986        {
02987          as_bad (_("missing real symbol name"));
02988          ignore_rest_of_line ();
02989          return;
02990        }
02991       ++input_line_pointer;
02992 
02993       lcomm_name = input_line_pointer;
02994       lcomm_endc = get_symbol_end ();
02995 
02996       lcomm_sym = symbol_find_or_make (lcomm_name);
02997 
02998       *input_line_pointer = lcomm_endc;
02999     }
03000 
03001   *end_name = '\0';
03002   sym = symbol_find_or_make (name);
03003   *end_name = endc;
03004 
03005   if (S_IS_DEFINED (sym)
03006       || S_GET_VALUE (sym) != 0)
03007     {
03008       as_bad (_("attempt to redefine symbol"));
03009       ignore_rest_of_line ();
03010       return;
03011     }
03012 
03013   record_alignment (bss_section, align);
03014 
03015   if (! lcomm
03016       || ! S_IS_DEFINED (lcomm_sym))
03017     {
03018       symbolS *def_sym;
03019       offsetT def_size;
03020 
03021       if (! lcomm)
03022        {
03023          def_sym = sym;
03024          def_size = size;
03025          S_SET_EXTERNAL (sym);
03026        }
03027       else
03028        {
03029          symbol_get_tc (lcomm_sym)->output = 1;
03030          def_sym = lcomm_sym;
03031          def_size = 0;
03032        }
03033 
03034       subseg_set (bss_section, 1);
03035       frag_align (align, 0, 0);
03036 
03037       symbol_set_frag (def_sym, frag_now);
03038       pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, def_sym,
03039                      def_size, (char *) NULL);
03040       *pfrag = 0;
03041       S_SET_SEGMENT (def_sym, bss_section);
03042       symbol_get_tc (def_sym)->align = align;
03043     }
03044   else if (lcomm)
03045     {
03046       /* Align the size of lcomm_sym.  */
03047       symbol_get_frag (lcomm_sym)->fr_offset =
03048        ((symbol_get_frag (lcomm_sym)->fr_offset + (1 << align) - 1)
03049         &~ ((1 << align) - 1));
03050       if (align > symbol_get_tc (lcomm_sym)->align)
03051        symbol_get_tc (lcomm_sym)->align = align;
03052     }
03053 
03054   if (lcomm)
03055     {
03056       /* Make sym an offset from lcomm_sym.  */
03057       S_SET_SEGMENT (sym, bss_section);
03058       symbol_set_frag (sym, symbol_get_frag (lcomm_sym));
03059       S_SET_VALUE (sym, symbol_get_frag (lcomm_sym)->fr_offset);
03060       symbol_get_frag (lcomm_sym)->fr_offset += size;
03061     }
03062 
03063   subseg_set (current_seg, current_subseg);
03064 
03065   demand_empty_rest_of_line ();
03066 }
03067 
03068 /* The .csect pseudo-op.  This switches us into a different
03069    subsegment.  The first argument is a symbol whose value is the
03070    start of the .csect.  In COFF, csect symbols get special aux
03071    entries defined by the x_csect field of union internal_auxent.  The
03072    optional second argument is the alignment (the default is 2).  */
03073 
03074 static void
03075 ppc_csect (ignore)
03076      int ignore ATTRIBUTE_UNUSED;
03077 {
03078   char *name;
03079   char endc;
03080   symbolS *sym;
03081   offsetT align;
03082 
03083   name = input_line_pointer;
03084   endc = get_symbol_end ();
03085 
03086   sym = symbol_find_or_make (name);
03087 
03088   *input_line_pointer = endc;
03089 
03090   if (S_GET_NAME (sym)[0] == '\0')
03091     {
03092       /* An unnamed csect is assumed to be [PR].  */
03093       symbol_get_tc (sym)->class = XMC_PR;
03094     }
03095 
03096   align = 2;
03097   if (*input_line_pointer == ',')
03098     {
03099       ++input_line_pointer;
03100       align = get_absolute_expression ();
03101     }
03102 
03103   ppc_change_csect (sym, align);
03104 
03105   demand_empty_rest_of_line ();
03106 }
03107 
03108 /* Change to a different csect.  */
03109 
03110 static void
03111 ppc_change_csect (sym, align)
03112      symbolS *sym;
03113      offsetT align;
03114 {
03115   if (S_IS_DEFINED (sym))
03116     subseg_set (S_GET_SEGMENT (sym), symbol_get_tc (sym)->subseg);
03117   else
03118     {
03119       symbolS **list_ptr;
03120       int after_toc;
03121       int hold_chunksize;
03122       symbolS *list;
03123       int is_code;
03124       segT sec;
03125 
03126       /* This is a new csect.  We need to look at the symbol class to
03127         figure out whether it should go in the text section or the
03128         data section.  */
03129       after_toc = 0;
03130       is_code = 0;
03131       switch (symbol_get_tc (sym)->class)
03132        {
03133        case XMC_PR:
03134        case XMC_RO:
03135        case XMC_DB:
03136        case XMC_GL:
03137        case XMC_XO:
03138        case XMC_SV:
03139        case XMC_TI:
03140        case XMC_TB:
03141          S_SET_SEGMENT (sym, text_section);
03142          symbol_get_tc (sym)->subseg = ppc_text_subsegment;
03143          ++ppc_text_subsegment;
03144          list_ptr = &ppc_text_csects;
03145          is_code = 1;
03146          break;
03147        case XMC_RW:
03148        case XMC_TC0:
03149        case XMC_TC:
03150        case XMC_DS:
03151        case XMC_UA:
03152        case XMC_BS:
03153        case XMC_UC:
03154          if (ppc_toc_csect != NULL
03155              && (symbol_get_tc (ppc_toc_csect)->subseg + 1
03156                 == ppc_data_subsegment))
03157            after_toc = 1;
03158          S_SET_SEGMENT (sym, data_section);
03159          symbol_get_tc (sym)->subseg = ppc_data_subsegment;
03160          ++ppc_data_subsegment;
03161          list_ptr = &ppc_data_csects;
03162          break;
03163        default:
03164          abort ();
03165        }
03166 
03167       /* We set the obstack chunk size to a small value before
03168         changing subsegments, so that we don't use a lot of memory
03169         space for what may be a small section.  */
03170       hold_chunksize = chunksize;
03171       chunksize = 64;
03172 
03173       sec = subseg_new (segment_name (S_GET_SEGMENT (sym)),
03174                      symbol_get_tc (sym)->subseg);
03175 
03176       chunksize = hold_chunksize;
03177 
03178       if (after_toc)
03179        ppc_after_toc_frag = frag_now;
03180 
03181       record_alignment (sec, align);
03182       if (is_code)
03183        frag_align_code (align, 0);
03184       else
03185        frag_align (align, 0, 0);
03186 
03187       symbol_set_frag (sym, frag_now);
03188       S_SET_VALUE (sym, (valueT) frag_now_fix ());
03189 
03190       symbol_get_tc (sym)->align = align;
03191       symbol_get_tc (sym)->output = 1;
03192       symbol_get_tc (sym)->within = sym;
03193 
03194       for (list = *list_ptr;
03195           symbol_get_tc (list)->next != (symbolS *) NULL;
03196           list = symbol_get_tc (list)->next)
03197        ;
03198       symbol_get_tc (list)->next = sym;
03199 
03200       symbol_remove (sym, &symbol_rootP, &symbol_lastP);
03201       symbol_append (sym, symbol_get_tc (list)->within, &symbol_rootP,
03202                    &symbol_lastP);
03203     }
03204 
03205   ppc_current_csect = sym;
03206 }
03207 
03208 /* This function handles the .text and .data pseudo-ops.  These
03209    pseudo-ops aren't really used by XCOFF; we implement them for the
03210    convenience of people who aren't used to XCOFF.  */
03211 
03212 static void
03213 ppc_section (type)
03214      int type;
03215 {
03216   const char *name;
03217   symbolS *sym;
03218 
03219   if (type == 't')
03220     name = ".text[PR]";
03221   else if (type == 'd')
03222     name = ".data[RW]";
03223   else
03224     abort ();
03225 
03226   sym = symbol_find_or_make (name);
03227 
03228   ppc_change_csect (sym, 2);
03229 
03230   demand_empty_rest_of_line ();
03231 }
03232 
03233 /* This function handles the .section pseudo-op.  This is mostly to
03234    give an error, since XCOFF only supports .text, .data and .bss, but
03235    we do permit the user to name the text or data section.  */
03236 
03237 static void
03238 ppc_named_section (ignore)
03239      int ignore ATTRIBUTE_UNUSED;
03240 {
03241   char *user_name;
03242   const char *real_name;
03243   char c;
03244   symbolS *sym;
03245 
03246   user_name = input_line_pointer;
03247   c = get_symbol_end ();
03248 
03249   if (strcmp (user_name, ".text") == 0)
03250     real_name = ".text[PR]";
03251   else if (strcmp (user_name, ".data") == 0)
03252     real_name = ".data[RW]";
03253   else
03254     {
03255       as_bad (_("The XCOFF file format does not support arbitrary sections"));
03256       *input_line_pointer = c;
03257       ignore_rest_of_line ();
03258       return;
03259     }
03260 
03261   *input_line_pointer = c;
03262 
03263   sym = symbol_find_or_make (real_name);
03264 
03265   ppc_change_csect (sym, 2);
03266 
03267   demand_empty_rest_of_line ();
03268 }
03269 
03270 /* The .extern pseudo-op.  We create an undefined symbol.  */
03271 
03272 static void
03273 ppc_extern (ignore)
03274      int ignore ATTRIBUTE_UNUSED;
03275 {
03276   char *name;
03277   char endc;
03278 
03279   name = input_line_pointer;
03280   endc = get_symbol_end ();
03281 
03282   (void) symbol_find_or_make (name);
03283 
03284   *input_line_pointer = endc;
03285 
03286   demand_empty_rest_of_line ();
03287 }
03288 
03289 /* The .lglobl pseudo-op.  Keep the symbol in the symbol table.  */
03290 
03291 static void
03292 ppc_lglobl (ignore)
03293      int ignore ATTRIBUTE_UNUSED;
03294 {
03295   char *name;
03296   char endc;
03297   symbolS *sym;
03298 
03299   name = input_line_pointer;
03300   endc = get_symbol_end ();
03301 
03302   sym = symbol_find_or_make (name);
03303 
03304   *input_line_pointer = endc;
03305 
03306   symbol_get_tc (sym)->output = 1;
03307 
03308   demand_empty_rest_of_line ();
03309 }
03310 
03311 /* The .rename pseudo-op.  The RS/6000 assembler can rename symbols,
03312    although I don't know why it bothers.  */
03313 
03314 static void
03315 ppc_rename (ignore)
03316      int ignore ATTRIBUTE_UNUSED;
03317 {
03318   char *name;
03319   char endc;
03320   symbolS *sym;
03321   int len;
03322 
03323   name = input_line_pointer;
03324   endc = get_symbol_end ();
03325 
03326   sym = symbol_find_or_make (name);
03327 
03328   *input_line_pointer = endc;
03329 
03330   if (*input_line_pointer != ',')
03331     {
03332       as_bad (_("missing rename string"));
03333       ignore_rest_of_line ();
03334       return;
03335     }
03336   ++input_line_pointer;
03337 
03338   symbol_get_tc (sym)->real_name = demand_copy_C_string (&len);
03339 
03340   demand_empty_rest_of_line ();
03341 }
03342 
03343 /* The .stabx pseudo-op.  This is similar to a normal .stabs
03344    pseudo-op, but slightly different.  A sample is
03345        .stabx "main:F-1",.main,142,0
03346    The first argument is the symbol name to create.  The second is the
03347    value, and the third is the storage class.  The fourth seems to be
03348    always zero, and I am assuming it is the type.  */
03349 
03350 static void
03351 ppc_stabx (ignore)
03352      int ignore ATTRIBUTE_UNUSED;
03353 {
03354   char *name;
03355   int len;
03356   symbolS *sym;
03357   expressionS exp;
03358 
03359   name = demand_copy_C_string (&len);
03360 
03361   if (*input_line_pointer != ',')
03362     {
03363       as_bad (_("missing value"));
03364       return;
03365     }
03366   ++input_line_pointer;
03367 
03368   ppc_stab_symbol = TRUE;
03369   sym = symbol_make (name);
03370   ppc_stab_symbol = FALSE;
03371 
03372   symbol_get_tc (sym)->real_name = name;
03373 
03374   (void) expression (&exp);
03375 
03376   switch (exp.X_op)
03377     {
03378     case O_illegal:
03379     case O_absent:
03380     case O_big:
03381       as_bad (_("illegal .stabx expression; zero assumed"));
03382       exp.X_add_number = 0;
03383       /* Fall through.  */
03384     case O_constant:
03385       S_SET_VALUE (sym, (valueT) exp.X_add_number);
03386       symbol_set_frag (sym, &zero_address_frag);
03387       break;
03388 
03389     case O_symbol:
03390       if (S_GET_SEGMENT (exp.X_add_symbol) == undefined_section)
03391        symbol_set_value_expression (sym, &exp);
03392       else
03393        {
03394          S_SET_VALUE (sym,
03395                      exp.X_add_number + S_GET_VALUE (exp.X_add_symbol));
03396          symbol_set_frag (sym, symbol_get_frag (exp.X_add_symbol));
03397        }
03398       break;
03399 
03400     default:
03401       /* The value is some complex expression.  This will probably
03402         fail at some later point, but this is probably the right
03403         thing to do here.  */
03404       symbol_set_value_expression (sym, &exp);
03405       break;
03406     }
03407 
03408   S_SET_SEGMENT (sym, ppc_coff_debug_section);
03409   symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING;
03410 
03411   if (*input_line_pointer != ',')
03412     {
03413       as_bad (_("missing class"));
03414       return;
03415     }
03416   ++input_line_pointer;
03417 
03418   S_SET_STORAGE_CLASS (sym, get_absolute_expression ());
03419 
03420   if (*input_line_pointer != ',')
03421     {
03422       as_bad (_("missing type"));
03423       return;
03424     }
03425   ++input_line_pointer;
03426 
03427   S_SET_DATA_TYPE (sym, get_absolute_expression ());
03428 
03429   symbol_get_tc (sym)->output = 1;
03430 
03431   if (S_GET_STORAGE_CLASS (sym) == C_STSYM) {
03432 
03433     symbol_get_tc (sym)->within = ppc_current_block;
03434 
03435     /* In this case :
03436 
03437        .bs name
03438        .stabx "z",arrays_,133,0
03439        .es
03440 
03441        .comm arrays_,13768,3
03442 
03443        resolve_symbol_value will copy the exp's "within" into sym's when the
03444        offset is 0.  Since this seems to be corner case problem,
03445        only do the correction for storage class C_STSYM.  A better solution
03446        would be to have the tc field updated in ppc_symbol_new_hook.  */
03447 
03448     if (exp.X_op == O_symbol)
03449       {
03450        symbol_get_tc (exp.X_add_symbol)->within = ppc_current_block;
03451       }
03452   }
03453 
03454   if (exp.X_op != O_symbol
03455       || ! S_IS_EXTERNAL (exp.X_add_symbol)
03456       || S_GET_SEGMENT (exp.X_add_symbol) != bss_section)
03457     ppc_frob_label (sym);
03458   else
03459     {
03460       symbol_remove (sym, &symbol_rootP, &symbol_lastP);
03461       symbol_append (sym, exp.X_add_symbol, &symbol_rootP, &symbol_lastP);
03462       if (symbol_get_tc (ppc_current_csect)->within == exp.X_add_symbol)
03463        symbol_get_tc (ppc_current_csect)->within = sym;
03464     }
03465 
03466   demand_empty_rest_of_line ();
03467 }
03468 
03469 /* The .function pseudo-op.  This takes several arguments.  The first
03470    argument seems to be the external name of the symbol.  The second
03471    argument seems to be the label for the start of the function.  gcc
03472    uses the same name for both.  I have no idea what the third and
03473    fourth arguments are meant to be.  The optional fifth argument is
03474    an expression for the size of the function.  In COFF this symbol
03475    gets an aux entry like that used for a csect.  */
03476 
03477 static void
03478 ppc_function (ignore)
03479      int ignore ATTRIBUTE_UNUSED;
03480 {
03481   char *name;
03482   char endc;
03483   char *s;
03484   symbolS *ext_sym;
03485   symbolS *lab_sym;
03486 
03487   name = input_line_pointer;
03488   endc = get_symbol_end ();
03489 
03490   /* Ignore any [PR] suffix.  */
03491   name = ppc_canonicalize_symbol_name (name);
03492   s = strchr (name, '[');
03493   if (s != (char *) NULL
03494       && strcmp (s + 1, "PR]") == 0)
03495     *s = '\0';
03496 
03497   ext_sym = symbol_find_or_make (name);
03498 
03499   *input_line_pointer = endc;
03500 
03501   if (*input_line_pointer != ',')
03502     {
03503       as_bad (_("missing symbol name"));
03504       ignore_rest_of_line ();
03505       return;
03506     }
03507   ++input_line_pointer;
03508 
03509   name = input_line_pointer;
03510   endc = get_symbol_end ();
03511 
03512   lab_sym = symbol_find_or_make (name);
03513 
03514   *input_line_pointer = endc;
03515 
03516   if (ext_sym != lab_sym)
03517     {
03518       expressionS exp;
03519 
03520       exp.X_op = O_symbol;
03521       exp.X_add_symbol = lab_sym;
03522       exp.X_op_symbol = NULL;
03523       exp.X_add_number = 0;
03524       exp.X_unsigned = 0;
03525       symbol_set_value_expression (ext_sym, &exp);
03526     }
03527 
03528   if (symbol_get_tc (ext_sym)->class == -1)
03529     symbol_get_tc (ext_sym)->class = XMC_PR;
03530   symbol_get_tc (ext_sym)->output = 1;
03531 
03532   if (*input_line_pointer == ',')
03533     {
03534       expressionS ignore;
03535 
03536       /* Ignore the third argument.  */
03537       ++input_line_pointer;
03538       expression (&ignore);
03539       if (*input_line_pointer == ',')
03540        {
03541          /* Ignore the fourth argument.  */
03542          ++input_line_pointer;
03543          expression (&ignore);
03544          if (*input_line_pointer == ',')
03545            {
03546              /* The fifth argument is the function size.  */
03547              ++input_line_pointer;
03548              symbol_get_tc (ext_sym)->size = symbol_new ("L0\001",
03549                                                    absolute_section,
03550                                                    (valueT) 0,
03551                                                    &zero_address_frag);
03552              pseudo_set (symbol_get_tc (ext_sym)->size);
03553            }
03554        }
03555     }
03556 
03557   S_SET_DATA_TYPE (ext_sym, DT_FCN << N_BTSHFT);
03558   SF_SET_FUNCTION (ext_sym);
03559   SF_SET_PROCESS (ext_sym);
03560   coff_add_linesym (ext_sym);
03561 
03562   demand_empty_rest_of_line ();
03563 }
03564 
03565 /* The .bf pseudo-op.  This is just like a COFF C_FCN symbol named
03566    ".bf".  If the pseudo op .bi was seen before .bf, patch the .bi sym
03567    with the correct line number */
03568 
03569 static symbolS *saved_bi_sym = 0;
03570 
03571 static void
03572 ppc_bf (ignore)
03573      int ignore ATTRIBUTE_UNUSED;
03574 {
03575   symbolS *sym;
03576 
03577   sym = symbol_make (".bf");
03578   S_SET_SEGMENT (sym, text_section);
03579   symbol_set_frag (sym, frag_now);
03580   S_SET_VALUE (sym, frag_now_fix ());
03581   S_SET_STORAGE_CLASS (sym, C_FCN);
03582 
03583   coff_line_base = get_absolute_expression ();
03584 
03585   S_SET_NUMBER_AUXILIARY (sym, 1);
03586   SA_SET_SYM_LNNO (sym, coff_line_base);
03587 
03588   /* Line number for bi.  */
03589   if (saved_bi_sym)
03590     {
03591       S_SET_VALUE (saved_bi_sym, coff_n_line_nos);
03592       saved_bi_sym = 0;
03593     }
03594 
03595 
03596   symbol_get_tc (sym)->output = 1;
03597 
03598   ppc_frob_label (sym);
03599 
03600   demand_empty_rest_of_line ();
03601 }
03602 
03603 /* The .ef pseudo-op.  This is just like a COFF C_FCN symbol named
03604    ".ef", except that the line number is absolute, not relative to the
03605    most recent ".bf" symbol.  */
03606 
03607 static void
03608 ppc_ef (ignore)
03609      int ignore ATTRIBUTE_UNUSED;
03610 {
03611   symbolS *sym;
03612 
03613   sym = symbol_make (".ef");
03614   S_SET_SEGMENT (sym, text_section);
03615   symbol_set_frag (sym, frag_now);
03616   S_SET_VALUE (sym, frag_now_fix ());
03617   S_SET_STORAGE_CLASS (sym, C_FCN);
03618   S_SET_NUMBER_AUXILIARY (sym, 1);
03619   SA_SET_SYM_LNNO (sym, get_absolute_expression ());
03620   symbol_get_tc (sym)->output = 1;
03621 
03622   ppc_frob_label (sym);
03623 
03624   demand_empty_rest_of_line ();
03625 }
03626 
03627 /* The .bi and .ei pseudo-ops.  These take a string argument and
03628    generates a C_BINCL or C_EINCL symbol, which goes at the start of
03629    the symbol list.  The value of .bi will be know when the next .bf
03630    is encountered.  */
03631 
03632 static void
03633 ppc_biei (ei)
03634      int ei;
03635 {
03636   static symbolS *last_biei;
03637 
03638   char *name;
03639   int len;
03640   symbolS *sym;
03641   symbolS *look;
03642 
03643   name = demand_copy_C_string (&len);
03644 
03645   /* The value of these symbols is actually file offset.  Here we set
03646      the value to the index into the line number entries.  In
03647      ppc_frob_symbols we set the fix_line field, which will cause BFD
03648      to do the right thing.  */
03649 
03650   sym = symbol_make (name);
03651   /* obj-coff.c currently only handles line numbers correctly in the
03652      .text section.  */
03653   S_SET_SEGMENT (sym, text_section);
03654   S_SET_VALUE (sym, coff_n_line_nos);
03655   symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING;
03656 
03657   S_SET_STORAGE_CLASS (sym, ei ? C_EINCL : C_BINCL);
03658   symbol_get_tc (sym)->output = 1;
03659 
03660   /* Save bi.  */
03661   if (ei)
03662     saved_bi_sym = 0;
03663   else
03664     saved_bi_sym = sym;
03665 
03666   for (look = last_biei ? last_biei : symbol_rootP;
03667        (look != (symbolS *) NULL
03668        && (S_GET_STORAGE_CLASS (look) == C_FILE
03669            || S_GET_STORAGE_CLASS (look) == C_BINCL
03670            || S_GET_STORAGE_CLASS (look) == C_EINCL));
03671        look = symbol_next (look))
03672     ;
03673   if (look != (symbolS *) NULL)
03674     {
03675       symbol_remove (sym, &symbol_rootP, &symbol_lastP);
03676       symbol_insert (sym, look, &symbol_rootP, &symbol_lastP);
03677       last_biei = sym;
03678     }
03679 
03680   demand_empty_rest_of_line ();
03681 }
03682 
03683 /* The .bs pseudo-op.  This generates a C_BSTAT symbol named ".bs".
03684    There is one argument, which is a csect symbol.  The value of the
03685    .bs symbol is the index of this csect symbol.  */
03686 
03687 static void
03688 ppc_bs (ignore)
03689      int ignore ATTRIBUTE_UNUSED;
03690 {
03691   char *name;
03692   char endc;
03693   symbolS *csect;
03694   symbolS *sym;
03695 
03696   if (ppc_current_block != NULL)
03697     as_bad (_("nested .bs blocks"));
03698 
03699   name = input_line_pointer;
03700   endc = get_symbol_end ();
03701 
03702   csect = symbol_find_or_make (name);
03703 
03704   *input_line_pointer = endc;
03705 
03706   sym = symbol_make (".bs");
03707   S_SET_SEGMENT (sym, now_seg);
03708   S_SET_STORAGE_CLASS (sym, C_BSTAT);
03709   symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING;
03710   symbol_get_tc (sym)->output = 1;
03711 
03712   symbol_get_tc (sym)->within = csect;
03713 
03714   ppc_frob_label (sym);
03715 
03716   ppc_current_block = sym;
03717 
03718   demand_empty_rest_of_line ();
03719 }
03720 
03721 /* The .es pseudo-op.  Generate a C_ESTART symbol named .es.  */
03722 
03723 static void
03724 ppc_es (ignore)
03725      int ignore ATTRIBUTE_UNUSED;
03726 {
03727   symbolS *sym;
03728 
03729   if (ppc_current_block == NULL)
03730     as_bad (_(".es without preceding .bs"));
03731 
03732   sym = symbol_make (".es");
03733   S_SET_SEGMENT (sym, now_seg);
03734   S_SET_STORAGE_CLASS (sym, C_ESTAT);
03735   symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING;
03736   symbol_get_tc (sym)->output = 1;
03737 
03738   ppc_frob_label (sym);
03739 
03740   ppc_current_block = NULL;
03741 
03742   demand_empty_rest_of_line ();
03743 }
03744 
03745 /* The .bb pseudo-op.  Generate a C_BLOCK symbol named .bb, with a
03746    line number.  */
03747 
03748 static void
03749 ppc_bb (ignore)
03750      int ignore ATTRIBUTE_UNUSED;
03751 {
03752   symbolS *sym;
03753 
03754   sym = symbol_make (".bb");
03755   S_SET_SEGMENT (sym, text_section);
03756   symbol_set_frag (sym, frag_now);
03757   S_SET_VALUE (sym, frag_now_fix ());
03758   S_SET_STORAGE_CLASS (sym, C_BLOCK);
03759 
03760   S_SET_NUMBER_AUXILIARY (sym, 1);
03761   SA_SET_SYM_LNNO (sym, get_absolute_expression ());
03762 
03763   symbol_get_tc (sym)->output = 1;
03764 
03765   SF_SET_PROCESS (sym);
03766 
03767   ppc_frob_label (sym);
03768 
03769   demand_empty_rest_of_line ();
03770 }
03771 
03772 /* The .eb pseudo-op.  Generate a C_BLOCK symbol named .eb, with a
03773    line number.  */
03774 
03775 static void
03776 ppc_eb (ignore)
03777      int ignore ATTRIBUTE_UNUSED;
03778 {
03779   symbolS *sym;
03780 
03781   sym = symbol_make (".eb");
03782   S_SET_SEGMENT (sym, text_section);
03783   symbol_set_frag (sym, frag_now);
03784   S_SET_VALUE (sym, frag_now_fix ());
03785   S_SET_STORAGE_CLASS (sym, C_BLOCK);
03786   S_SET_NUMBER_AUXILIARY (sym, 1);
03787   SA_SET_SYM_LNNO (sym, get_absolute_expression ());
03788   symbol_get_tc (sym)->output = 1;
03789 
03790   SF_SET_PROCESS (sym);
03791 
03792   ppc_frob_label (sym);
03793 
03794   demand_empty_rest_of_line ();
03795 }
03796 
03797 /* The .bc pseudo-op.  This just creates a C_BCOMM symbol with a
03798    specified name.  */
03799 
03800 static void
03801 ppc_bc (ignore)
03802      int ignore ATTRIBUTE_UNUSED;
03803 {
03804   char *name;
03805   int len;
03806   symbolS *sym;
03807 
03808   name = demand_copy_C_string (&len);
03809   sym = symbol_make (name);
03810   S_SET_SEGMENT (sym, ppc_coff_debug_section);
03811   symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING;
03812   S_SET_STORAGE_CLASS (sym, C_BCOMM);
03813   S_SET_VALUE (sym, 0);
03814   symbol_get_tc (sym)->output = 1;
03815 
03816   ppc_frob_label (sym);
03817 
03818   demand_empty_rest_of_line ();
03819 }
03820 
03821 /* The .ec pseudo-op.  This just creates a C_ECOMM symbol.  */
03822 
03823 static void
03824 ppc_ec (ignore)
03825      int ignore ATTRIBUTE_UNUSED;
03826 {
03827   symbolS *sym;
03828 
03829   sym = symbol_make (".ec");
03830   S_SET_SEGMENT (sym, ppc_coff_debug_section);
03831   symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING;
03832   S_SET_STORAGE_CLASS (sym, C_ECOMM);
03833   S_SET_VALUE (sym, 0);
03834   symbol_get_tc (sym)->output = 1;
03835 
03836   ppc_frob_label (sym);
03837 
03838   demand_empty_rest_of_line ();
03839 }
03840 
03841 /* The .toc pseudo-op.  Switch to the .toc subsegment.  */
03842 
03843 static void
03844 ppc_toc (ignore)
03845      int ignore ATTRIBUTE_UNUSED;
03846 {
03847   if (ppc_toc_csect != (symbolS *) NULL)
03848     subseg_set (data_section, symbol_get_tc (ppc_toc_csect)->subseg);
03849   else
03850     {
03851       subsegT subseg;
03852       symbolS *sym;
03853       symbolS *list;
03854 
03855       subseg = ppc_data_subsegment;
03856       ++ppc_data_subsegment;
03857 
03858       subseg_new (segment_name (data_section), subseg);
03859       ppc_toc_frag = frag_now;
03860 
03861       sym = symbol_find_or_make ("TOC[TC0]");
03862       symbol_set_frag (sym, frag_now);
03863       S_SET_SEGMENT (sym, data_section);
03864       S_SET_VALUE (sym, (valueT) frag_now_fix ());
03865       symbol_get_tc (sym)->subseg = subseg;
03866       symbol_get_tc (sym)->output = 1;
03867       symbol_get_tc (sym)->within = sym;
03868 
03869       ppc_toc_csect = sym;
03870 
03871       for (list = ppc_data_csects;
03872           symbol_get_tc (list)->next != (symbolS *) NULL;
03873           list = symbol_get_tc (list)->next)
03874        ;
03875       symbol_get_tc (list)->next = sym;
03876 
03877       symbol_remove (sym, &symbol_rootP, &symbol_lastP);
03878       symbol_append (sym, symbol_get_tc (list)->within, &symbol_rootP,
03879                    &symbol_lastP);
03880     }
03881 
03882   ppc_current_csect = ppc_toc_csect;
03883 
03884   demand_empty_rest_of_line ();
03885 }
03886 
03887 /* The AIX assembler automatically aligns the operands of a .long or
03888    .short pseudo-op, and we want to be compatible.  */
03889 
03890 static void
03891 ppc_xcoff_cons (log_size)
03892      int log_size;
03893 {
03894   frag_align (log_size, 0, 0);
03895   record_alignment (now_seg, log_size);
03896   cons (1 << log_size);
03897 }
03898 
03899 static void
03900 ppc_vbyte (dummy)
03901      int dummy ATTRIBUTE_UNUSED;
03902 {
03903   expressionS exp;
03904   int byte_count;
03905 
03906   (void) expression (&exp);
03907 
03908   if (exp.X_op != O_constant)
03909     {
03910       as_bad (_("non-constant byte count"));
03911       return;
03912     }
03913 
03914   byte_count = exp.X_add_number;
03915 
03916   if (*input_line_pointer != ',')
03917     {
03918       as_bad (_("missing value"));
03919       return;
03920     }
03921 
03922   ++input_line_pointer;
03923   cons (byte_count);
03924 }
03925 
03926 #endif /* OBJ_XCOFF */
03927 #if defined (OBJ_XCOFF) || defined (OBJ_ELF)
03928 
03929 /* The .tc pseudo-op.  This is used when generating either XCOFF or
03930    ELF.  This takes two or more arguments.
03931 
03932    When generating XCOFF output, the first argument is the name to
03933    give to this location in the toc; this will be a symbol with class
03934    TC.  The rest of the arguments are N-byte values to actually put at
03935    this location in the TOC; often there is just one more argument, a
03936    relocatable symbol reference.  The size of the value to store
03937    depends on target word size.  A 32-bit target uses 4-byte values, a
03938    64-bit target uses 8-byte values.
03939 
03940    When not generating XCOFF output, the arguments are the same, but
03941    the first argument is simply ignored.  */
03942 
03943 static void
03944 ppc_tc (ignore)
03945      int ignore ATTRIBUTE_UNUSED;
03946 {
03947 #ifdef OBJ_XCOFF
03948 
03949   /* Define the TOC symbol name.  */
03950   {
03951     char *name;
03952     char endc;
03953     symbolS *sym;
03954 
03955     if (ppc_toc_csect == (symbolS *) NULL
03956        || ppc_toc_csect != ppc_current_csect)
03957       {
03958        as_bad (_(".tc not in .toc section"));
03959        ignore_rest_of_line ();
03960        return;
03961       }
03962 
03963     name = input_line_pointer;
03964     endc = get_symbol_end ();
03965 
03966     sym = symbol_find_or_make (name);
03967 
03968     *input_line_pointer = endc;
03969 
03970     if (S_IS_DEFINED (sym))
03971       {
03972        symbolS *label;
03973 
03974        label = symbol_get_tc (ppc_current_csect)->within;
03975        if (symbol_get_tc (label)->class != XMC_TC0)
03976          {
03977            as_bad (_(".tc with no label"));
03978            ignore_rest_of_line ();
03979            return;
03980          }
03981 
03982        S_SET_SEGMENT (label, S_GET_SEGMENT (sym));
03983        symbol_set_frag (label, symbol_get_frag (sym));
03984        S_SET_VALUE (label, S_GET_VALUE (sym));
03985 
03986        while (! is_end_of_line[(unsigned char) *input_line_pointer])
03987          ++input_line_pointer;
03988 
03989        return;
03990       }
03991 
03992     S_SET_SEGMENT (sym, now_seg);
03993     symbol_set_frag (sym, frag_now);
03994     S_SET_VALUE (sym, (valueT) frag_now_fix ());
03995     symbol_get_tc (sym)->class = XMC_TC;
03996     symbol_get_tc (sym)->output = 1;
03997 
03998     ppc_frob_label (sym);
03999   }
04000 
04001 #endif /* OBJ_XCOFF */
04002 #ifdef OBJ_ELF
04003   int align;
04004 
04005   /* Skip the TOC symbol name.  */
04006   while (is_part_of_name (*input_line_pointer)
04007         || *input_line_pointer == '['
04008         || *input_line_pointer == ']'
04009         || *input_line_pointer == '{'
04010         || *input_line_pointer == '}')
04011     ++input_line_pointer;
04012 
04013   /* Align to a four/eight byte boundary.  */
04014   align = ppc_obj64 ? 3 : 2;
04015   frag_align (align, 0, 0);
04016   record_alignment (now_seg, align);
04017 #endif /* OBJ_ELF */
04018 
04019   if (*input_line_pointer != ',')
04020     demand_empty_rest_of_line ();
04021   else
04022     {
04023       ++input_line_pointer;
04024       cons (ppc_obj64 ? 8 : 4);
04025     }
04026 }
04027 
04028 /* Pseudo-op .machine.  */
04029 
04030 static void
04031 ppc_machine (ignore)
04032      int ignore ATTRIBUTE_UNUSED;
04033 {
04034   char *cpu_string;
04035 #define MAX_HISTORY 100
04036   static unsigned long *cpu_history;
04037   static int curr_hist;
04038 
04039   SKIP_WHITESPACE ();
04040 
04041   if (*input_line_pointer == '"')
04042     {
04043       int len;
04044       cpu_string = demand_copy_C_string (&len);
04045     }
04046   else
04047     {
04048       char c;
04049       cpu_string = input_line_pointer;
04050       c = get_symbol_end ();
04051       cpu_string = xstrdup (cpu_string);
04052       *input_line_pointer = c;
04053     }
04054 
04055   if (cpu_string != NULL)
04056     {
04057       unsigned long old_cpu = ppc_cpu;
04058       char *p;
04059 
04060       for (p = cpu_string; *p != 0; p++)
04061        *p = TOLOWER (*p);
04062 
04063       if (strcmp (cpu_string, "push") == 0)
04064        {
04065          if (cpu_history == NULL)
04066            cpu_history = xmalloc (MAX_HISTORY * sizeof (*cpu_history));
04067 
04068          if (curr_hist >= MAX_HISTORY)
04069            as_bad (_(".machine stack overflow"));
04070          else
04071            cpu_history[curr_hist++] = ppc_cpu;
04072        }
04073       else if (strcmp (cpu_string, "pop") == 0)
04074        {
04075          if (curr_hist <= 0)
04076            as_bad (_(".machine stack underflow"));
04077          else
04078            ppc_cpu = cpu_history[--curr_hist];
04079        }
04080       else if (parse_cpu (cpu_string))
04081        ;
04082       else
04083        as_bad (_("invalid machine `%s'"), cpu_string);
04084 
04085       if (ppc_cpu != old_cpu)
04086        ppc_setup_opcodes ();
04087     }
04088 
04089   demand_empty_rest_of_line ();
04090 }
04091 
04092 /* See whether a symbol is in the TOC section.  */
04093 
04094 static int
04095 ppc_is_toc_sym (sym)
04096      symbolS *sym;
04097 {
04098 #ifdef OBJ_XCOFF
04099   return symbol_get_tc (sym)->class == XMC_TC;
04100 #endif
04101 #ifdef OBJ_ELF
04102   const char *sname = segment_name (S_GET_SEGMENT (sym));
04103   if (ppc_obj64)
04104     return strcmp (sname, ".toc") == 0;
04105   else
04106     return strcmp (sname, ".got") == 0;
04107 #endif
04108 }
04109 #endif /* defined (OBJ_XCOFF) || defined (OBJ_ELF) */
04110 
04111 #ifdef TE_PE
04112 
04113 /* Pseudo-ops specific to the Windows NT PowerPC PE (coff) format.  */
04114 
04115 /* Set the current section.  */
04116 static void
04117 ppc_set_current_section (new)
04118      segT new;
04119 {
04120   ppc_previous_section = ppc_current_section;
04121   ppc_current_section = new;
04122 }
04123 
04124 /* pseudo-op: .previous
04125    behaviour: toggles the current section with the previous section.
04126    errors:    None
04127    warnings:  "No previous section"  */
04128 
04129 static void
04130 ppc_previous (ignore)
04131      int ignore ATTRIBUTE_UNUSED;
04132 {
04133   symbolS *tmp;
04134 
04135   if (ppc_previous_section == NULL)
04136     {
04137       as_warn (_("No previous section to return to. Directive ignored."));
04138       return;
04139     }
04140 
04141   subseg_set (ppc_previous_section, 0);
04142 
04143   ppc_set_current_section (ppc_previous_section);
04144 }
04145 
04146 /* pseudo-op: .pdata
04147    behaviour: predefined read only data section
04148              double word aligned
04149    errors:    None
04150    warnings:  None
04151    initial:   .section .pdata "adr3"
04152              a - don't know -- maybe a misprint
04153              d - initialized data
04154              r - readable
04155              3 - double word aligned (that would be 4 byte boundary)
04156 
04157    commentary:
04158    Tag index tables (also known as the function table) for exception
04159    handling, debugging, etc.  */
04160 
04161 static void
04162 ppc_pdata (ignore)
04163      int ignore ATTRIBUTE_UNUSED;
04164 {
04165   if (pdata_section == 0)
04166     {
04167       pdata_section = subseg_new (".pdata", 0);
04168 
04169       bfd_set_section_flags (stdoutput, pdata_section,
04170                           (SEC_ALLOC | SEC_LOAD | SEC_RELOC
04171                            | SEC_READONLY | SEC_DATA ));
04172 
04173       bfd_set_section_alignment (stdoutput, pdata_section, 2);
04174     }
04175   else
04176     {
04177       pdata_section = subseg_new (".pdata", 0);
04178     }
04179   ppc_set_current_section (pdata_section);
04180 }
04181 
04182 /* pseudo-op: .ydata
04183    behaviour: predefined read only data section
04184              double word aligned
04185    errors:    None
04186    warnings:  None
04187    initial:   .section .ydata "drw3"
04188              a - don't know -- maybe a misprint
04189              d - initialized data
04190              r - readable
04191              3 - double word aligned (that would be 4 byte boundary)
04192    commentary:
04193    Tag tables (also known as the scope table) for exception handling,
04194    debugging, etc.  */
04195 
04196 static void
04197 ppc_ydata (ignore)
04198      int ignore ATTRIBUTE_UNUSED;
04199 {
04200   if (ydata_section == 0)
04201     {
04202       ydata_section = subseg_new (".ydata", 0);
04203       bfd_set_section_flags (stdoutput, ydata_section,
04204                           (SEC_ALLOC | SEC_LOAD | SEC_RELOC
04205                            | SEC_READONLY | SEC_DATA ));
04206 
04207       bfd_set_section_alignment (stdoutput, ydata_section, 3);
04208     }
04209   else
04210     {
04211       ydata_section = subseg_new (".ydata", 0);
04212     }
04213   ppc_set_current_section (ydata_section);
04214 }
04215 
04216 /* pseudo-op: .reldata
04217    behaviour: predefined read write data section
04218              double word aligned (4-byte)
04219              FIXME: relocation is applied to it
04220              FIXME: what's the difference between this and .data?
04221    errors:    None
04222    warnings:  None
04223    initial:   .section .reldata "drw3"
04224              d - initialized data
04225              r - readable
04226              w - writeable
04227              3 - double word aligned (that would be 8 byte boundary)
04228 
04229    commentary:
04230    Like .data, but intended to hold data subject to relocation, such as
04231    function descriptors, etc.  */
04232 
04233 static void
04234 ppc_reldata (ignore)
04235      int ignore ATTRIBUTE_UNUSED;
04236 {
04237   if (reldata_section == 0)
04238     {
04239       reldata_section = subseg_new (".reldata", 0);
04240 
04241       bfd_set_section_flags (stdoutput, reldata_section,
04242                           (SEC_ALLOC | SEC_LOAD | SEC_RELOC
04243                            | SEC_DATA));
04244 
04245       bfd_set_section_alignment (stdoutput, reldata_section, 2);
04246     }
04247   else
04248     {
04249       reldata_section = subseg_new (".reldata", 0);
04250     }
04251   ppc_set_current_section (reldata_section);
04252 }
04253 
04254 /* pseudo-op: .rdata
04255    behaviour: predefined read only data section
04256              double word aligned
04257    errors:    None
04258    warnings:  None
04259    initial:   .section .rdata "dr3"
04260              d - initialized data
04261              r - readable
04262              3 - double word aligned (that would be 4 byte boundary)  */
04263 
04264 static void
04265 ppc_rdata (ignore)
04266      int ignore ATTRIBUTE_UNUSED;
04267 {
04268   if (rdata_section == 0)
04269     {
04270       rdata_section = subseg_new (".rdata", 0);
04271       bfd_set_section_flags (stdoutput, rdata_section,
04272                           (SEC_ALLOC | SEC_LOAD | SEC_RELOC
04273                            | SEC_READONLY | SEC_DATA ));
04274 
04275       bfd_set_section_alignment (stdoutput, rdata_section, 2);
04276     }
04277   else
04278     {
04279       rdata_section = subseg_new (".rdata", 0);
04280     }
04281   ppc_set_current_section (rdata_section);
04282 }
04283 
04284 /* pseudo-op: .ualong
04285    behaviour: much like .int, with the exception that no alignment is
04286              performed.
04287              FIXME: test the alignment statement
04288    errors:    None
04289    warnings:  None  */
04290 
04291 static void
04292 ppc_ualong (ignore)
04293      int ignore ATTRIBUTE_UNUSED;
04294 {
04295   /* Try for long.  */
04296   cons (4);
04297 }
04298 
04299 /* pseudo-op: .znop  <symbol name>
04300    behaviour: Issue a nop instruction
04301              Issue a IMAGE_REL_PPC_IFGLUE relocation against it, using
04302              the supplied symbol name.
04303    errors:    None
04304    warnings:  Missing symbol name  */
04305 
04306 static void
04307 ppc_znop (ignore)
04308      int ignore ATTRIBUTE_UNUSED;
04309 {
04310   unsigned long insn;
04311   const struct powerpc_opcode *opcode;
04312   expressionS ex;
04313   char *f;
04314   symbolS *sym;
04315   char *symbol_name;
04316   char c;
04317   char *name;
04318   unsigned int exp;
04319   flagword flags;
04320   asection *sec;
04321 
04322   /* Strip out the symbol name.  */
04323   symbol_name = input_line_pointer;
04324   c = get_symbol_end ();
04325 
04326   name = xmalloc (input_line_pointer - symbol_name + 1);
04327   strcpy (name, symbol_name);
04328 
04329   sym = symbol_find_or_make (name);
04330 
04331   *input_line_pointer = c;
04332 
04333   SKIP_WHITESPACE ();
04334 
04335   /* Look up the opcode in the hash table.  */
04336   opcode = (const struct powerpc_opcode *) hash_find (ppc_hash, "nop");
04337 
04338   /* Stick in the nop.  */
04339   insn = opcode->opcode;
04340 
04341   /* Write out the instruction.  */
04342   f = frag_more (4);
04343   md_number_to_chars (f, insn, 4);
04344   fix_new (frag_now,
04345           f - frag_now->fr_literal,
04346           4,
04347           sym,
04348           0,
04349           0,
04350           BFD_RELOC_16_GOT_PCREL);
04351 
04352 }
04353 
04354 /* pseudo-op:
04355    behaviour:
04356    errors:
04357    warnings:  */
04358 
04359 static void
04360 ppc_pe_comm (lcomm)
04361      int lcomm;
04362 {
04363   register char *name;
04364   register char c;
04365   register char *p;
04366   offsetT temp;
04367   register symbolS *symbolP;
04368   offsetT align;
04369 
04370   name = input_line_pointer;
04371   c = get_symbol_end ();
04372 
04373   /* just after name is now '\0'.  */
04374   p = input_line_pointer;
04375   *p = c;
04376   SKIP_WHITESPACE ();
04377   if (*input_line_pointer != ',')
04378     {
04379       as_bad (_("Expected comma after symbol-name: rest of line ignored."));
04380       ignore_rest_of_line ();
04381       return;
04382     }
04383 
04384   input_line_pointer++;            /* skip ',' */
04385   if ((temp = get_absolute_expression ()) < 0)
04386     {
04387       as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp);
04388       ignore_rest_of_line ();
04389       return;
04390     }
04391 
04392   if (! lcomm)
04393     {
04394       /* The third argument to .comm is the alignment.  */
04395       if (*input_line_pointer != ',')
04396        align = 3;
04397       else
04398        {
04399          ++input_line_pointer;
04400          align = get_absolute_expression ();
04401          if (align <= 0)
04402            {
04403              as_warn (_("ignoring bad alignment"));
04404              align = 3;
04405            }
04406        }
04407     }
04408 
04409   *p = 0;
04410   symbolP = symbol_find_or_make (name);
04411 
04412   *p = c;
04413   if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
04414     {
04415       as_bad (_("Ignoring attempt to re-define symbol `%s'."),
04416              S_GET_NAME (symbolP));
04417       ignore_rest_of_line ();
04418       return;
04419     }
04420 
04421   if (S_GET_VALUE (symbolP))
04422     {
04423       if (S_GET_VALUE (symbolP) != (valueT) temp)
04424        as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
04425               S_GET_NAME (symbolP),
04426               (long) S_GET_VALUE (symbolP),
04427               (long) temp);
04428     }
04429   else
04430     {
04431       S_SET_VALUE (symbolP, (valueT) temp);
04432       S_SET_EXTERNAL (symbolP);
04433       S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
04434     }
04435 
04436   demand_empty_rest_of_line ();
04437 }
04438 
04439 /*
04440  * implement the .section pseudo op:
04441  *     .section name {, "flags"}
04442  *                ^         ^
04443  *                |         +--- optional flags: 'b' for bss
04444  *                |                              'i' for info
04445  *                +-- section name               'l' for lib
04446  *                                               'n' for noload
04447  *                                               'o' for over
04448  *                                               'w' for data
04449  *                                         'd' (apparently m88k for data)
04450  *                                               'x' for text
04451  * But if the argument is not a quoted string, treat it as a
04452  * subsegment number.
04453  *
04454  * FIXME: this is a copy of the section processing from obj-coff.c, with
04455  * additions/changes for the moto-pas assembler support. There are three
04456  * categories:
04457  *
04458  * FIXME: I just noticed this. This doesn't work at all really. It it
04459  *        setting bits that bfd probably neither understands or uses. The
04460  *        correct approach (?) will have to incorporate extra fields attached
04461  *        to the section to hold the system specific stuff. (krk)
04462  *
04463  * Section Contents:
04464  * 'a' - unknown - referred to in documentation, but no definition supplied
04465  * 'c' - section has code
04466  * 'd' - section has initialized data
04467  * 'u' - section has uninitialized data
04468  * 'i' - section contains directives (info)
04469  * 'n' - section can be discarded
04470  * 'R' - remove section at link time
04471  *
04472  * Section Protection:
04473  * 'r' - section is readable
04474  * 'w' - section is writeable
04475  * 'x' - section is executable
04476  * 's' - section is sharable
04477  *
04478  * Section Alignment:
04479  * '0' - align to byte boundary
04480  * '1' - align to halfword undary
04481  * '2' - align to word boundary
04482  * '3' - align to doubleword boundary
04483  * '4' - align to quadword boundary
04484  * '5' - align to 32 byte boundary
04485  * '6' - align to 64 byte boundary
04486  *
04487  */
04488 
04489 void
04490 ppc_pe_section (ignore)
04491      int ignore ATTRIBUTE_UNUSED;
04492 {
04493   /* Strip out the section name.  */
04494   char *section_name;
04495   char c;
04496   char *name;
04497   unsigned int exp;
04498   flagword flags;
04499   segT sec;
04500   int align;
04501 
04502   section_name = input_line_pointer;
04503   c = get_symbol_end ();
04504 
04505   name = xmalloc (input_line_pointer - section_name + 1);
04506   strcpy (name, section_name);
04507 
04508   *input_line_pointer = c;
04509 
04510   SKIP_WHITESPACE ();
04511 
04512   exp = 0;
04513   flags = SEC_NO_FLAGS;
04514 
04515   if (strcmp (name, ".idata$2") == 0)
04516     {
04517       align = 0;
04518     }
04519   else if (strcmp (name, ".idata$3") == 0)
04520     {
04521       align = 0;
04522     }
04523   else if (strcmp (name, ".idata$4") == 0)
04524     {
04525       align = 2;
04526     }
04527   else if (strcmp (name, ".idata$5") == 0)
04528     {
04529       align = 2;
04530     }
04531   else if (strcmp (name, ".idata$6") == 0)
04532     {
04533       align = 1;
04534     }
04535   else
04536     /* Default alignment to 16 byte boundary.  */
04537     align = 4;
04538 
04539   if (*input_line_pointer == ',')
04540     {
04541       ++input_line_pointer;
04542       SKIP_WHITESPACE ();
04543       if (*input_line_pointer != '"')
04544        exp = get_absolute_expression ();
04545       else
04546        {
04547          ++input_line_pointer;
04548          while (*input_line_pointer != '"'
04549                && ! is_end_of_line[(unsigned char) *input_line_pointer])
04550            {
04551              switch (*input_line_pointer)
04552               {
04553                 /* Section Contents */
04554               case 'a': /* unknown */
04555                 as_bad (_("Unsupported section attribute -- 'a'"));
04556                 break;
04557               case 'c': /* code section */
04558                 flags |= SEC_CODE;
04559                 break;
04560               case 'd': /* section has initialized data */
04561                 flags |= SEC_DATA;
04562                 break;
04563               case 'u': /* section has uninitialized data */
04564                 /* FIXME: This is IMAGE_SCN_CNT_UNINITIALIZED_DATA
04565                    in winnt.h */
04566                 flags |= SEC_ROM;
04567                 break;
04568               case 'i': /* section contains directives (info) */
04569                 /* FIXME: This is IMAGE_SCN_LNK_INFO
04570                    in winnt.h */
04571                 flags |= SEC_HAS_CONTENTS;
04572                 break;
04573               case 'n': /* section can be discarded */
04574                 flags &=~ SEC_LOAD;
04575                 break;
04576               case 'R': /* Remove section at link time */
04577                 flags |= SEC_NEVER_LOAD;
04578                 break;
04579 
04580                 /* Section Protection */
04581               case 'r': /* section is readable */
04582                 flags |= IMAGE_SCN_MEM_READ;
04583                 break;
04584               case 'w': /* section is writeable */
04585                 flags |= IMAGE_SCN_MEM_WRITE;
04586                 break;
04587               case 'x': /* section is executable */
04588                 flags |= IMAGE_SCN_MEM_EXECUTE;
04589                 break;
04590               case 's': /* section is sharable */
04591                 flags |= IMAGE_SCN_MEM_SHARED;
04592                 break;
04593 
04594                 /* Section Alignment */
04595               case '0': /* align to byte boundary */
04596                 flags |= IMAGE_SCN_ALIGN_1BYTES;
04597                 align = 0;
04598                 break;
04599               case '1':  /* align to halfword boundary */
04600                 flags |= IMAGE_SCN_ALIGN_2BYTES;
04601                 align = 1;
04602                 break;
04603               case '2':  /* align to word boundary */
04604                 flags |= IMAGE_SCN_ALIGN_4BYTES;
04605                 align = 2;
04606                 break;
04607               case '3':  /* align to doubleword boundary */
04608                 flags |= IMAGE_SCN_ALIGN_8BYTES;
04609                 align = 3;
04610                 break;
04611               case '4':  /* align to quadword boundary */
04612                 flags |= IMAGE_SCN_ALIGN_16BYTES;
04613                 align = 4;
04614                 break;
04615               case '5':  /* align to 32 byte boundary */
04616                 flags |= IMAGE_SCN_ALIGN_32BYTES;
04617                 align = 5;
04618                 break;
04619               case '6':  /* align to 64 byte boundary */
04620                 flags |= IMAGE_SCN_ALIGN_64BYTES;
04621                 align = 6;
04622                 break;
04623 
04624               default:
04625                 as_bad (_("unknown section attribute '%c'"),
04626                        *input_line_pointer);
04627                 break;
04628               }
04629              ++input_line_pointer;
04630            }
04631          if (*input_line_pointer == '"')
04632            ++input_line_pointer;
04633        }
04634     }
04635 
04636   sec = subseg_new (name, (subsegT) exp);
04637 
04638   ppc_set_current_section (sec);
04639 
04640   if (flags != SEC_NO_FLAGS)
04641     {
04642       if (! bfd_set_section_flags (stdoutput, sec, flags))
04643        as_bad (_("error setting flags for \"%s\": %s"),
04644               bfd_section_name (stdoutput, sec),
04645               bfd_errmsg (bfd_get_error ()));
04646     }
04647 
04648   bfd_set_section_alignment (stdoutput, sec, align);
04649 
04650 }
04651 
04652 static void
04653 ppc_pe_function (ignore)
04654      int ignore ATTRIBUTE_UNUSED;
04655 {
04656   char *name;
04657   char endc;
04658   symbolS *ext_sym;
04659 
04660   name = input_line_pointer;
04661   endc = get_symbol_end ();
04662 
04663   ext_sym = symbol_find_or_make (name);
04664 
04665   *input_line_pointer = endc;
04666 
04667   S_SET_DATA_TYPE (ext_sym, DT_FCN << N_BTSHFT);
04668   SF_SET_FUNCTION (ext_sym);
04669   SF_SET_PROCESS (ext_sym);
04670   coff_add_linesym (ext_sym);
04671 
04672   demand_empty_rest_of_line ();
04673 }
04674 
04675 static void
04676 ppc_pe_tocd (ignore)
04677      int ignore ATTRIBUTE_UNUSED;
04678 {
04679   if (tocdata_section == 0)
04680     {
04681       tocdata_section = subseg_new (".tocd", 0);
04682       /* FIXME: section flags won't work.  */
04683       bfd_set_section_flags (stdoutput, tocdata_section,
04684                           (SEC_ALLOC | SEC_LOAD | SEC_RELOC
04685                            | SEC_READONLY | SEC_DATA));
04686 
04687       bfd_set_section_alignment (stdoutput, tocdata_section, 2);
04688     }
04689   else
04690     {
04691       rdata_section = subseg_new (".tocd", 0);
04692     }
04693 
04694   ppc_set_current_section (tocdata_section);
04695 
04696   demand_empty_rest_of_line ();
04697 }
04698 
04699 /* Don't adjust TOC relocs to use the section symbol.  */
04700 
04701 int
04702 ppc_pe_fix_adjustable (fix)
04703      fixS *fix;
04704 {
04705   return fix->fx_r_type != BFD_RELOC_PPC_TOC16;
04706 }
04707 
04708 #endif
04709 
04710 #ifdef OBJ_XCOFF
04711 
04712 /* XCOFF specific symbol and file handling.  */
04713 
04714 /* Canonicalize the symbol name.  We use the to force the suffix, if
04715    any, to use square brackets, and to be in upper case.  */
04716 
04717 char *
04718 ppc_canonicalize_symbol_name (name)
04719      char *name;
04720 {
04721   char *s;
04722 
04723   if (ppc_stab_symbol)
04724     return name;
04725 
04726   for (s = name; *s != '\0' && *s != '{' && *s != '['; s++)
04727     ;
04728   if (*s != '\0')
04729     {
04730       char brac;
04731 
04732       if (*s == '[')
04733        brac = ']';
04734       else
04735        {
04736          *s = '[';
04737          brac = '}';
04738        }
04739 
04740       for (s++; *s != '\0' && *s != brac; s++)
04741        *s = TOUPPER (*s);
04742 
04743       if (*s == '\0' || s[1] != '\0')
04744        as_bad (_("bad symbol suffix"));
04745 
04746       *s = ']';
04747     }
04748 
04749   return name;
04750 }
04751 
04752 /* Set the class of a symbol based on the suffix, if any.  This is
04753    called whenever a new symbol is created.  */
04754 
04755 void
04756 ppc_symbol_new_hook (sym)
04757      symbolS *sym;
04758 {
04759   struct ppc_tc_sy *tc;
04760   const char *s;
04761 
04762   tc = symbol_get_tc (sym);
04763   tc->next = NULL;
04764   tc->output = 0;
04765   tc->class = -1;
04766   tc->real_name = NULL;
04767   tc->subseg = 0;
04768   tc->align = 0;
04769   tc->size = NULL;
04770   tc->within = NULL;
04771 
04772   if (ppc_stab_symbol)
04773     return;
04774 
04775   s = strchr (S_GET_NAME (sym), '[');
04776   if (s == (const char *) NULL)
04777     {
04778       /* There is no suffix.  */
04779       return;
04780     }
04781 
04782   ++s;
04783 
04784   switch (s[0])
04785     {
04786     case 'B':
04787       if (strcmp (s, "BS]") == 0)
04788        tc->class = XMC_BS;
04789       break;
04790     case 'D':
04791       if (strcmp (s, "DB]") == 0)
04792        tc->class = XMC_DB;
04793       else if (strcmp (s, "DS]") == 0)
04794        tc->class = XMC_DS;
04795       break;
04796     case 'G':
04797       if (strcmp (s, "GL]") == 0)
04798        tc->class = XMC_GL;
04799       break;
04800     case 'P':
04801       if (strcmp (s, "PR]") == 0)
04802        tc->class = XMC_PR;
04803       break;
04804     case 'R':
04805       if (strcmp (s, "RO]") == 0)
04806        tc->class = XMC_RO;
04807       else if (strcmp (s, "RW]") == 0)
04808        tc->class = XMC_RW;
04809       break;
04810     case 'S':
04811       if (strcmp (s, "SV]") == 0)
04812        tc->class = XMC_SV;
04813       break;
04814     case 'T':
04815       if (strcmp (s, "TC]") == 0)
04816        tc->class = XMC_TC;
04817       else if (strcmp (s, "TI]") == 0)
04818        tc->class = XMC_TI;
04819       else if (strcmp (s, "TB]") == 0)
04820        tc->class = XMC_TB;
04821       else if (strcmp (s, "TC0]") == 0 || strcmp (s, "T0]") == 0)
04822        tc->class = XMC_TC0;
04823       break;
04824     case 'U':
04825       if (strcmp (s, "UA]") == 0)
04826        tc->class = XMC_UA;
04827       else if (strcmp (s, "UC]") == 0)
04828        tc->class = XMC_UC;
04829       break;
04830     case 'X':
04831       if (strcmp (s, "XO]") == 0)
04832        tc->class = XMC_XO;
04833       break;
04834     }
04835 
04836   if (tc->class == -1)
04837     as_bad (_("Unrecognized symbol suffix"));
04838 }
04839 
04840 /* Set the class of a label based on where it is defined.  This
04841    handles symbols without suffixes.  Also, move the symbol so that it
04842    follows the csect symbol.  */
04843 
04844 void
04845 ppc_frob_label (sym)
04846      symbolS *sym;
04847 {
04848   if (ppc_current_csect != (symbolS *) NULL)
04849     {
04850       if (symbol_get_tc (sym)->class == -1)
04851        symbol_get_tc (sym)->class = symbol_get_tc (ppc_current_csect)->class;
04852 
04853       symbol_remove (sym, &symbol_rootP, &symbol_lastP);
04854       symbol_append (sym, symbol_get_tc (ppc_current_csect)->within,
04855                    &symbol_rootP, &symbol_lastP);
04856       symbol_get_tc (ppc_current_csect)->within = sym;
04857     }
04858 
04859 #ifdef OBJ_ELF
04860   dwarf2_emit_label (sym);
04861 #endif
04862 }
04863 
04864 /* This variable is set by ppc_frob_symbol if any absolute symbols are
04865    seen.  It tells ppc_adjust_symtab whether it needs to look through
04866    the symbols.  */
04867 
04868 static bfd_boolean ppc_saw_abs;
04869 
04870 /* Change the name of a symbol just before writing it out.  Set the
04871    real name if the .rename pseudo-op was used.  Otherwise, remove any
04872    class suffix.  Return 1 if the symbol should not be included in the
04873    symbol table.  */
04874 
04875 int
04876 ppc_frob_symbol (sym)
04877      symbolS *sym;
04878 {
04879   static symbolS *ppc_last_function;
04880   static symbolS *set_end;
04881 
04882   /* Discard symbols that should not be included in the output symbol
04883      table.  */
04884   if (! symbol_used_in_reloc_p (sym)
04885       && ((symbol_get_bfdsym (sym)->flags & BSF_SECTION_SYM) != 0
04886          || (! (S_IS_EXTERNAL (sym) || S_IS_WEAK (sym))
04887              && ! symbol_get_tc (sym)->output
04888              && S_GET_STORAGE_CLASS (sym) != C_FILE)))
04889     return 1;
04890 
04891   /* This one will disappear anyway.  Don't make a csect sym for it.  */
04892   if (sym == abs_section_sym)
04893     return 1;
04894 
04895   if (symbol_get_tc (sym)->real_name != (char *) NULL)
04896     S_SET_NAME (sym, symbol_get_tc (sym)->real_name);
04897   else
04898     {
04899       const char *name;
04900       const char *s;
04901 
04902       name = S_GET_NAME (sym);
04903       s = strchr (name, '[');
04904       if (s != (char *) NULL)
04905        {
04906          unsigned int len;
04907          char *snew;
04908 
04909          len = s - name;
04910          snew = xmalloc (len + 1);
04911          memcpy (snew, name, len);
04912          snew[len] = '\0';
04913 
04914          S_SET_NAME (sym, snew);
04915        }
04916     }
04917 
04918   if (set_end != (symbolS *) NULL)
04919     {
04920       SA_SET_SYM_ENDNDX (set_end, sym);
04921       set_end = NULL;
04922     }
04923 
04924   if (SF_GET_FUNCTION (sym))
04925     {
04926       if (ppc_last_function != (symbolS *) NULL)
04927        as_bad (_("two .function pseudo-ops with no intervening .ef"));
04928       ppc_last_function = sym;
04929       if (symbol_get_tc (sym)->size != (symbolS *) NULL)
04930        {
04931          resolve_symbol_value (symbol_get_tc (sym)->size);
04932          SA_SET_SYM_FSIZE (sym,
04933                          (long) S_GET_VALUE (symbol_get_tc (sym)->size));
04934        }
04935     }
04936   else if (S_GET_STORAGE_CLASS (sym) == C_FCN
04937           && strcmp (S_GET_NAME (sym), ".ef") == 0)
04938     {
04939       if (ppc_last_function == (symbolS *) NULL)
04940        as_bad (_(".ef with no preceding .function"));
04941       else
04942        {
04943          set_end = ppc_last_function;
04944          ppc_last_function = NULL;
04945 
04946          /* We don't have a C_EFCN symbol, but we need to force the
04947             COFF backend to believe that it has seen one.  */
04948          coff_last_function = NULL;
04949        }
04950     }
04951 
04952   if (! (S_IS_EXTERNAL (sym) || S_IS_WEAK (sym))
04953       && (symbol_get_bfdsym (sym)->flags & BSF_SECTION_SYM) == 0
04954       && S_GET_STORAGE_CLASS (sym) != C_FILE
04955       && S_GET_STORAGE_CLASS (sym) != C_FCN
04956       && S_GET_STORAGE_CLASS (sym) != C_BLOCK
04957       && S_GET_STORAGE_CLASS (sym) != C_BSTAT
04958       && S_GET_STORAGE_CLASS (sym) != C_ESTAT
04959       && S_GET_STORAGE_CLASS (sym) != C_BINCL
04960       && S_GET_STORAGE_CLASS (sym) != C_EINCL
04961       && S_GET_SEGMENT (sym) != ppc_coff_debug_section)
04962     S_SET_STORAGE_CLASS (sym, C_HIDEXT);
04963 
04964   if (S_GET_STORAGE_CLASS (sym) == C_EXT
04965       || S_GET_STORAGE_CLASS (sym) == C_HIDEXT)
04966     {
04967       int i;
04968       union internal_auxent *a;
04969 
04970       /* Create a csect aux.  */
04971       i = S_GET_NUMBER_AUXILIARY (sym);
04972       S_SET_NUMBER_AUXILIARY (sym, i + 1);
04973       a = &coffsymbol (symbol_get_bfdsym (sym))->native[i + 1].u.auxent;
04974       if (symbol_get_tc (sym)->class == XMC_TC0)
04975        {
04976          /* This is the TOC table.  */
04977          know (strcmp (S_GET_NAME (sym), "TOC") == 0);
04978          a->x_csect.x_scnlen.l = 0;
04979          a->x_csect.x_smtyp = (2 << 3) | XTY_SD;
04980        }
04981       else if (symbol_get_tc (sym)->subseg != 0)
04982        {
04983          /* This is a csect symbol.  x_scnlen is the size of the
04984             csect.  */
04985          if (symbol_get_tc (sym)->next == (symbolS *) NULL)
04986            a->x_csect.x_scnlen.l = (bfd_section_size (stdoutput,
04987                                                  S_GET_SEGMENT (sym))
04988                                  - S_GET_VALUE (sym));
04989          else
04990            {
04991              resolve_symbol_value (symbol_get_tc (sym)->next);
04992              a->x_csect.x_scnlen.l = (S_GET_VALUE (symbol_get_tc (sym)->next)
04993                                    - S_GET_VALUE (sym));
04994            }
04995          a->x_csect.x_smtyp = (symbol_get_tc (sym)->align << 3) | XTY_SD;
04996        }
04997       else if (S_GET_SEGMENT (sym) == bss_section)
04998        {
04999          /* This is a common symbol.  */
05000          a->x_csect.x_scnlen.l = symbol_get_frag (sym)->fr_offset;
05001          a->x_csect.x_smtyp = (symbol_get_tc (sym)->align << 3) | XTY_CM;
05002          if (S_IS_EXTERNAL (sym))
05003            symbol_get_tc (sym)->class = XMC_RW;
05004          else
05005            symbol_get_tc (sym)->class = XMC_BS;
05006        }
05007       else if (S_GET_SEGMENT (sym) == absolute_section)
05008        {
05009          /* This is an absolute symbol.  The csect will be created by
05010             ppc_adjust_symtab.  */
05011          ppc_saw_abs = TRUE;
05012          a->x_csect.x_smtyp = XTY_LD;
05013          if (symbol_get_tc (sym)->class == -1)
05014            symbol_get_tc (sym)->class = XMC_XO;
05015        }
05016       else if (! S_IS_DEFINED (sym))
05017        {
05018          /* This is an external symbol.  */
05019          a->x_csect.x_scnlen.l = 0;
05020          a->x_csect.x_smtyp = XTY_ER;
05021        }
05022       else if (symbol_get_tc (sym)->class == XMC_TC)
05023        {
05024          symbolS *next;
05025 
05026          /* This is a TOC definition.  x_scnlen is the size of the
05027             TOC entry.  */
05028          next = symbol_next (sym);
05029          while (symbol_get_tc (next)->class == XMC_TC0)
05030            next = symbol_next (next);
05031          if (next == (symbolS *) NULL
05032              || symbol_get_tc (next)->class != XMC_TC)
05033            {
05034              if (ppc_after_toc_frag == (fragS *) NULL)
05035               a->x_csect.x_scnlen.l = (bfd_section_size (stdoutput,
05036                                                     data_section)
05037                                     - S_GET_VALUE (sym));
05038              else
05039               a->x_csect.x_scnlen.l = (ppc_after_toc_frag->fr_address
05040                                     - S_GET_VALUE (sym));
05041            }
05042          else
05043            {
05044              resolve_symbol_value (next);
05045              a->x_csect.x_scnlen.l = (S_GET_VALUE (next)
05046                                    - S_GET_VALUE (sym));
05047            }
05048          a->x_csect.x_smtyp = (2 << 3) | XTY_SD;
05049        }
05050       else
05051        {
05052          symbolS *csect;
05053 
05054          /* This is a normal symbol definition.  x_scnlen is the
05055             symbol index of the containing csect.  */
05056          if (S_GET_SEGMENT (sym) == text_section)
05057            csect = ppc_text_csects;
05058          else if (S_GET_SEGMENT (sym) == data_section)
05059            csect = ppc_data_csects;
05060          else
05061            abort ();
05062 
05063          /* Skip the initial dummy symbol.  */
05064          csect = symbol_get_tc (csect)->next;
05065 
05066          if (csect == (symbolS *) NULL)
05067            {
05068              as_warn (_("warning: symbol %s has no csect"), S_GET_NAME (sym));
05069              a->x_csect.x_scnlen.l = 0;
05070            }
05071          else
05072            {
05073              while (symbol_get_tc (csect)->next != (symbolS *) NULL)
05074               {
05075                 resolve_symbol_value (symbol_get_tc (csect)->next);
05076                 if (S_GET_VALUE (symbol_get_tc (csect)->next)
05077                     > S_GET_VALUE (sym))
05078                   break;
05079                 csect = symbol_get_tc (csect)->next;
05080               }
05081 
05082              a->x_csect.x_scnlen.p =
05083               coffsymbol (symbol_get_bfdsym (csect))->native;
05084              coffsymbol (symbol_get_bfdsym (sym))->native[i + 1].fix_scnlen =
05085               1;
05086            }
05087          a->x_csect.x_smtyp = XTY_LD;
05088        }
05089 
05090       a->x_csect.x_parmhash = 0;
05091       a->x_csect.x_snhash = 0;
05092       if (symbol_get_tc (sym)->class == -1)
05093        a->x_csect.x_smclas = XMC_PR;
05094       else
05095        a->x_csect.x_smclas = symbol_get_tc (sym)->class;
05096       a->x_csect.x_stab = 0;
05097       a->x_csect.x_snstab = 0;
05098 
05099       /* Don't let the COFF backend resort these symbols.  */
05100       symbol_get_bfdsym (sym)->flags |= BSF_NOT_AT_END;
05101     }
05102   else if (S_GET_STORAGE_CLASS (sym) == C_BSTAT)
05103     {
05104       /* We want the value to be the symbol index of the referenced
05105         csect symbol.  BFD will do that for us if we set the right
05106         flags.  */
05107       asymbol *bsym = symbol_get_bfdsym (symbol_get_tc (sym)->within);
05108       combined_entry_type *c = coffsymbol (bsym)->native;
05109 
05110       S_SET_VALUE (sym, (valueT) (size_t) c);
05111       coffsymbol (symbol_get_bfdsym (sym))->native->fix_value = 1;
05112     }
05113   else if (S_GET_STORAGE_CLASS (sym) == C_STSYM)
05114     {
05115       symbolS *block;
05116       symbolS *csect;
05117 
05118       /* The value is the offset from the enclosing csect.  */
05119       block = symbol_get_tc (sym)->within;
05120       csect = symbol_get_tc (block)->within;
05121       resolve_symbol_value (csect);
05122       S_SET_VALUE (sym, S_GET_VALUE (sym) - S_GET_VALUE (csect));
05123     }
05124   else if (S_GET_STORAGE_CLASS (sym) == C_BINCL
05125           || S_GET_STORAGE_CLASS (sym) == C_EINCL)
05126     {
05127       /* We want the value to be a file offset into the line numbers.
05128         BFD will do that for us if we set the right flags.  We have
05129         already set the value correctly.  */
05130       coffsymbol (symbol_get_bfdsym (sym))->native->fix_line = 1;
05131     }
05132 
05133   return 0;
05134 }
05135 
05136 /* Adjust the symbol table.  This creates csect symbols for all
05137    absolute symbols.  */
05138 
05139 void
05140 ppc_adjust_symtab ()
05141 {
05142   symbolS *sym;
05143 
05144   if (! ppc_saw_abs)
05145     return;
05146 
05147   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
05148     {
05149       symbolS *csect;
05150       int i;
05151       union internal_auxent *a;
05152 
05153       if (S_GET_SEGMENT (sym) != absolute_section)
05154        continue;
05155 
05156       csect = symbol_create (".abs[XO]", absolute_section,
05157                           S_GET_VALUE (sym), &zero_address_frag);
05158       symbol_get_bfdsym (csect)->value = S_GET_VALUE (sym);
05159       S_SET_STORAGE_CLASS (csect, C_HIDEXT);
05160       i = S_GET_NUMBER_AUXILIARY (csect);
05161       S_SET_NUMBER_AUXILIARY (csect, i + 1);
05162       a = &coffsymbol (symbol_get_bfdsym (csect))->native[i + 1].u.auxent;
05163       a->x_csect.x_scnlen.l = 0;
05164       a->x_csect.x_smtyp = XTY_SD;
05165       a->x_csect.x_parmhash = 0;
05166       a->x_csect.x_snhash = 0;
05167       a->x_csect.x_smclas = XMC_XO;
05168       a->x_csect.x_stab = 0;
05169       a->x_csect.x_snstab = 0;
05170 
05171       symbol_insert (csect, sym, &symbol_rootP, &symbol_lastP);
05172 
05173       i = S_GET_NUMBER_AUXILIARY (sym);
05174       a = &coffsymbol (symbol_get_bfdsym (sym))->native[i].u.auxent;
05175       a->x_csect.x_scnlen.p = coffsymbol (symbol_get_bfdsym (csect))->native;
05176       coffsymbol (symbol_get_bfdsym (sym))->native[i].fix_scnlen = 1;
05177     }
05178 
05179   ppc_saw_abs = FALSE;
05180 }
05181 
05182 /* Set the VMA for a section.  This is called on all the sections in
05183    turn.  */
05184 
05185 void
05186 ppc_frob_section (sec)
05187      asection *sec;
05188 {
05189   static bfd_vma vma = 0;
05190 
05191   vma = md_section_align (sec, vma);
05192   bfd_set_section_vma (stdoutput, sec, vma);
05193   vma += bfd_section_size (stdoutput, sec);
05194 }
05195 
05196 #endif /* OBJ_XCOFF */
05197 
05198 /* Turn a string in input_line_pointer into a floating point constant
05199    of type TYPE, and store the appropriate bytes in *LITP.  The number
05200    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
05201    returned, or NULL on OK.  */
05202 
05203 char *
05204 md_atof (type, litp, sizep)
05205      int type;
05206      char *litp;
05207      int *sizep;
05208 {
05209   int prec;
05210   LITTLENUM_TYPE words[4];
05211   char *t;
05212   int i;
05213 
05214   switch (type)
05215     {
05216     case 'f':
05217       prec = 2;
05218       break;
05219 
05220     case 'd':
05221       prec = 4;
05222       break;
05223 
05224     default:
05225       *sizep = 0;
05226       return _("bad call to md_atof");
05227     }
05228 
05229   t = atof_ieee (input_line_pointer, type, words);
05230   if (t)
05231     input_line_pointer = t;
05232 
05233   *sizep = prec * 2;
05234 
05235   if (target_big_endian)
05236     {
05237       for (i = 0; i < prec; i++)
05238        {
05239          md_number_to_chars (litp, (valueT) words[i], 2);
05240          litp += 2;
05241        }
05242     }
05243   else
05244     {
05245       for (i = prec - 1; i >= 0; i--)
05246        {
05247          md_number_to_chars (litp, (valueT) words[i], 2);
05248          litp += 2;
05249        }
05250     }
05251 
05252   return NULL;
05253 }
05254 
05255 /* Write a value out to the object file, using the appropriate
05256    endianness.  */
05257 
05258 void
05259 md_number_to_chars (buf, val, n)
05260      char *buf;
05261      valueT val;
05262      int n;
05263 {
05264   if (target_big_endian)
05265     number_to_chars_bigendian (buf, val, n);
05266   else
05267     number_to_chars_littleendian (buf, val, n);
05268 }
05269 
05270 /* Align a section (I don't know why this is machine dependent).  */
05271 
05272 valueT
05273 md_section_align (asection *seg ATTRIBUTE_UNUSED, valueT addr)
05274 {
05275 #ifdef OBJ_ELF
05276   return addr;
05277 #else
05278   int align = bfd_get_section_alignment (stdoutput, seg);
05279 
05280   return ((addr + (1 << align) - 1) & (-1 << align));
05281 #endif
05282 }
05283 
05284 /* We don't have any form of relaxing.  */
05285 
05286 int
05287 md_estimate_size_before_relax (fragp, seg)
05288      fragS *fragp ATTRIBUTE_UNUSED;
05289      asection *seg ATTRIBUTE_UNUSED;
05290 {
05291   abort ();
05292   return 0;
05293 }
05294 
05295 /* Convert a machine dependent frag.  We never generate these.  */
05296 
05297 void
05298 md_convert_frag (abfd, sec, fragp)
05299      bfd *abfd ATTRIBUTE_UNUSED;
05300      asection *sec ATTRIBUTE_UNUSED;
05301      fragS *fragp ATTRIBUTE_UNUSED;
05302 {
05303   abort ();
05304 }
05305 
05306 /* We have no need to default values of symbols.  */
05307 
05308 symbolS *
05309 md_undefined_symbol (name)
05310      char *name ATTRIBUTE_UNUSED;
05311 {
05312   return 0;
05313 }
05314 
05315 /* Functions concerning relocs.  */
05316 
05317 /* The location from which a PC relative jump should be calculated,
05318    given a PC relative reloc.  */
05319 
05320 long
05321 md_pcrel_from_section (fixp, sec)
05322      fixS *fixp;
05323      segT sec ATTRIBUTE_UNUSED;
05324 {
05325   return fixp->fx_frag->fr_address + fixp->fx_where;
05326 }
05327 
05328 #ifdef OBJ_XCOFF
05329 
05330 /* This is called to see whether a fixup should be adjusted to use a
05331    section symbol.  We take the opportunity to change a fixup against
05332    a symbol in the TOC subsegment into a reloc against the
05333    corresponding .tc symbol.  */
05334 
05335 int
05336 ppc_fix_adjustable (fix)
05337      fixS *fix;
05338 {
05339   valueT val = resolve_symbol_value (fix->fx_addsy);
05340   segT symseg = S_GET_SEGMENT (fix->fx_addsy);
05341   TC_SYMFIELD_TYPE *tc;
05342 
05343   if (symseg == absolute_section)
05344     return 0;
05345 
05346   if (ppc_toc_csect != (symbolS *) NULL
05347       && fix->fx_addsy != ppc_toc_csect
05348       && symseg == data_section
05349       && val >= ppc_toc_frag->fr_address
05350       && (ppc_after_toc_frag == (fragS *) NULL
05351          || val < ppc_after_toc_frag->fr_address))
05352     {
05353       symbolS *sy;
05354 
05355       for (sy = symbol_next (ppc_toc_csect);
05356           sy != (symbolS *) NULL;
05357           sy = symbol_next (sy))
05358        {
05359          TC_SYMFIELD_TYPE *sy_tc = symbol_get_tc (sy);
05360 
05361          if (sy_tc->class == XMC_TC0)
05362            continue;
05363          if (sy_tc->class != XMC_TC)
05364            break;
05365          if (val == resolve_symbol_value (sy))
05366            {
05367              fix->fx_addsy = sy;
05368              fix->fx_addnumber = val - ppc_toc_frag->fr_address;
05369              return 0;
05370            }
05371        }
05372 
05373       as_bad_where (fix->fx_file, fix->fx_line,
05374                   _("symbol in .toc does not match any .tc"));
05375     }
05376 
05377   /* Possibly adjust the reloc to be against the csect.  */
05378   tc = symbol_get_tc (fix->fx_addsy);
05379   if (tc->subseg == 0
05380       && tc->class != XMC_TC0
05381       && tc->class != XMC_TC
05382       && symseg != bss_section
05383       /* Don't adjust if this is a reloc in the toc section.  */
05384       && (symseg != data_section
05385          || ppc_toc_csect == NULL
05386          || val < ppc_toc_frag->fr_address
05387          || (ppc_after_toc_frag != NULL
05388              && val >= ppc_after_toc_frag->fr_address)))
05389     {
05390       symbolS *csect;
05391       symbolS *next_csect;
05392 
05393       if (symseg == text_section)
05394        csect = ppc_text_csects;
05395       else if (symseg == data_section)
05396        csect = ppc_data_csects;
05397       else
05398        abort ();
05399 
05400       /* Skip the initial dummy symbol.  */
05401       csect = symbol_get_tc (csect)->next;
05402 
05403       if (csect != (symbolS *) NULL)
05404        {
05405          while ((next_csect = symbol_get_tc (csect)->next) != (symbolS *) NULL
05406                && (symbol_get_frag (next_csect)->fr_address <= val))
05407            {
05408              /* If the csect address equals the symbol value, then we
05409                have to look through the full symbol table to see
05410                whether this is the csect we want.  Note that we will
05411                only get here if the csect has zero length.  */
05412              if (symbol_get_frag (csect)->fr_address == val
05413                 && S_GET_VALUE (csect) == val)
05414               {
05415                 symbolS *scan;
05416 
05417                 for (scan = symbol_next (csect);
05418                      scan != NULL;
05419                      scan = symbol_next (scan))
05420                   {
05421                     if (symbol_get_tc (scan)->subseg != 0)
05422                      break;
05423                     if (scan == fix->fx_addsy)
05424                      break;
05425                   }
05426 
05427                 /* If we found the symbol before the next csect
05428                    symbol, then this is the csect we want.  */
05429                 if (scan == fix->fx_addsy)
05430                   break;
05431               }
05432 
05433              csect = next_csect;
05434            }
05435 
05436          fix->fx_offset += val - symbol_get_frag (csect)->fr_address;
05437          fix->fx_addsy = csect;
05438        }
05439       return 0;
05440     }
05441 
05442   /* Adjust a reloc against a .lcomm symbol to be against the base
05443      .lcomm.  */
05444   if (symseg == bss_section
05445       && ! S_IS_EXTERNAL (fix->fx_addsy))
05446     {
05447       symbolS *sy = symbol_get_frag (fix->fx_addsy)->fr_symbol;
05448 
05449       fix->fx_offset += val - resolve_symbol_value (sy);
05450       fix->fx_addsy = sy;
05451     }
05452 
05453   return 0;
05454 }
05455 
05456 /* A reloc from one csect to another must be kept.  The assembler
05457    will, of course, keep relocs between sections, and it will keep
05458    absolute relocs, but we need to force it to keep PC relative relocs
05459    between two csects in the same section.  */
05460 
05461 int
05462 ppc_force_relocation (fix)
05463      fixS *fix;
05464 {
05465   /* At this point fix->fx_addsy should already have been converted to
05466      a csect symbol.  If the csect does not include the fragment, then
05467      we need to force the relocation.  */
05468   if (fix->fx_pcrel
05469       && fix->fx_addsy != NULL
05470       && symbol_get_tc (fix->fx_addsy)->subseg != 0
05471       && ((symbol_get_frag (fix->fx_addsy)->fr_address
05472           > fix->fx_frag->fr_address)
05473          || (symbol_get_tc (fix->fx_addsy)->next != NULL
05474              && (symbol_get_frag (symbol_get_tc (fix->fx_addsy)->next)->fr_address
05475                 <= fix->fx_frag->fr_address))))
05476     return 1;
05477 
05478   return generic_force_reloc (fix);
05479 }
05480 
05481 #endif /* OBJ_XCOFF */
05482 
05483 #ifdef OBJ_ELF
05484 /* If this function returns non-zero, it guarantees that a relocation
05485    will be emitted for a fixup.  */
05486 
05487 int
05488 ppc_force_relocation (fix)
05489      fixS *fix;
05490 {
05491   /* Branch prediction relocations must force a relocation, as must
05492      the vtable description relocs.  */
05493   switch (fix->fx_r_type)
05494     {
05495     case BFD_RELOC_PPC_B16_BRTAKEN:
05496     case BFD_RELOC_PPC_B16_BRNTAKEN:
05497     case BFD_RELOC_PPC_BA16_BRTAKEN:
05498     case BFD_RELOC_PPC_BA16_BRNTAKEN:
05499     case BFD_RELOC_24_PLT_PCREL:
05500     case BFD_RELOC_PPC64_TOC:
05501       return 1;
05502     default:
05503       break;
05504     }
05505 
05506   if (fix->fx_r_type >= BFD_RELOC_PPC_TLS
05507       && fix->fx_r_type <= BFD_RELOC_PPC64_DTPREL16_HIGHESTA)
05508     return 1;
05509 
05510   return generic_force_reloc (fix);
05511 }
05512 
05513 int
05514 ppc_fix_adjustable (fix)
05515      fixS *fix;
05516 {
05517   return (fix->fx_r_type != BFD_RELOC_16_GOTOFF
05518          && fix->fx_r_type != BFD_RELOC_LO16_GOTOFF
05519          && fix->fx_r_type != BFD_RELOC_HI16_GOTOFF
05520          && fix->fx_r_type != BFD_RELOC_HI16_S_GOTOFF
05521          && fix->fx_r_type != BFD_RELOC_GPREL16
05522          && fix->fx_r_type != BFD_RELOC_VTABLE_INHERIT
05523          && fix->fx_r_type != BFD_RELOC_VTABLE_ENTRY
05524          && !(fix->fx_r_type >= BFD_RELOC_PPC_TLS
05525               && fix->fx_r_type <= BFD_RELOC_PPC64_DTPREL16_HIGHESTA));
05526 }
05527 #endif
05528 
05529 /* Implement HANDLE_ALIGN.  This writes the NOP pattern into an
05530    rs_align_code frag.  */
05531 
05532 void
05533 ppc_handle_align (struct frag *fragP)
05534 {
05535   valueT count = (fragP->fr_next->fr_address
05536                 - (fragP->fr_address + fragP->fr_fix));
05537 
05538   if (count != 0 && (count & 3) == 0)
05539     {
05540       char *dest = fragP->fr_literal + fragP->fr_fix;
05541 
05542       fragP->fr_var = 4;
05543       md_number_to_chars (dest, 0x60000000, 4);
05544 
05545       if ((ppc_cpu & PPC_OPCODE_POWER6) != 0)
05546        {
05547          /* For power6, we want the last nop to be a group terminating
05548             one, "ori 1,1,0".  Do this by inserting an rs_fill frag
05549             immediately after this one, with its address set to the last
05550             nop location.  This will automatically reduce the number of
05551             nops in the current frag by one.  */
05552          if (count > 4)
05553            {
05554              struct frag *group_nop = xmalloc (SIZEOF_STRUCT_FRAG + 4);
05555 
05556              memcpy (group_nop, fragP, SIZEOF_STRUCT_FRAG);
05557              group_nop->fr_address = group_nop->fr_next->fr_address - 4;
05558              group_nop->fr_fix = 0;
05559              group_nop->fr_offset = 1;
05560              group_nop->fr_type = rs_fill;
05561              fragP->fr_next = group_nop;
05562              dest = group_nop->fr_literal;
05563            }
05564 
05565          md_number_to_chars (dest, 0x60210000, 4);
05566        }
05567     }
05568 }
05569 
05570 /* Apply a fixup to the object code.  This is called for all the
05571    fixups we generated by the call to fix_new_exp, above.  In the call
05572    above we used a reloc code which was the largest legal reloc code
05573    plus the operand index.  Here we undo that to recover the operand
05574    index.  At this point all symbol values should be fully resolved,
05575    and we attempt to completely resolve the reloc.  If we can not do
05576    that, we determine the correct reloc code and put it back in the
05577    fixup.  */
05578 
05579 void
05580 md_apply_fix (fixP, valP, seg)
05581      fixS *fixP;
05582      valueT * valP;
05583      segT seg ATTRIBUTE_UNUSED;
05584 {
05585   valueT value = * valP;
05586 
05587 #ifdef OBJ_ELF
05588   if (fixP->fx_addsy != NULL)
05589     {
05590       /* Hack around bfd_install_relocation brain damage.  */
05591       if (fixP->fx_pcrel)
05592        value += fixP->fx_frag->fr_address + fixP->fx_where;
05593     }
05594   else
05595     fixP->fx_done = 1;
05596 #else
05597   /* FIXME FIXME FIXME: The value we are passed in *valP includes
05598      the symbol values.  If we are doing this relocation the code in
05599      write.c is going to call bfd_install_relocation, which is also
05600      going to use the symbol value.  That means that if the reloc is
05601      fully resolved we want to use *valP since bfd_install_relocation is
05602      not being used.
05603      However, if the reloc is not fully resolved we do not want to use
05604      *valP, and must use fx_offset instead.  However, if the reloc
05605      is PC relative, we do want to use *valP since it includes the
05606      result of md_pcrel_from.  This is confusing.  */
05607   if (fixP->fx_addsy == (symbolS *) NULL)
05608     fixP->fx_done = 1;
05609 
05610   else if (fixP->fx_pcrel)
05611     ;
05612 
05613   else
05614     value = fixP->fx_offset;
05615 #endif
05616 
05617   if (fixP->fx_subsy != (symbolS *) NULL)
05618     {
05619       /* We can't actually support subtracting a symbol.  */
05620       as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
05621     }
05622 
05623   if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
05624     {
05625       int opindex;
05626       const struct powerpc_operand *operand;
05627       char *where;
05628       unsigned long insn;
05629 
05630       opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
05631 
05632       operand = &powerpc_operands[opindex];
05633 
05634 #ifdef OBJ_XCOFF
05635       /* An instruction like `lwz 9,sym(30)' when `sym' is not a TOC symbol
05636         does not generate a reloc.  It uses the offset of `sym' within its
05637         csect.  Other usages, such as `.long sym', generate relocs.  This
05638         is the documented behaviour of non-TOC symbols.  */
05639       if ((operand->flags & PPC_OPERAND_PARENS) != 0
05640          && operand->bits == 16
05641          && operand->shift == 0
05642          && (operand->insert == NULL || ppc_obj64)
05643          && fixP->fx_addsy != NULL
05644          && symbol_get_tc (fixP->fx_addsy)->subseg != 0
05645          && symbol_get_tc (fixP->fx_addsy)->class != XMC_TC
05646          && symbol_get_tc (fixP->fx_addsy)->class != XMC_TC0
05647          && S_GET_SEGMENT (fixP->fx_addsy) != bss_section)
05648        {
05649          value = fixP->fx_offset;
05650          fixP->fx_done = 1;
05651        }
05652 #endif
05653 
05654       /* Fetch the instruction, insert the fully resolved operand
05655         value, and stuff the instruction back again.  */
05656       where = fixP->fx_frag->fr_literal + fixP->fx_where;
05657       if (target_big_endian)
05658        insn = bfd_getb32 ((unsigned char *) where);
05659       else
05660        insn = bfd_getl32 ((unsigned char *) where);
05661       insn = ppc_insert_operand (insn, operand, (offsetT) value,
05662                              fixP->fx_file, fixP->fx_line);
05663       if (target_big_endian)
05664        bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
05665       else
05666        bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
05667 
05668       if (fixP->fx_done)
05669        /* Nothing else to do here.  */
05670        return;
05671 
05672       assert (fixP->fx_addsy != NULL);
05673 
05674       /* Determine a BFD reloc value based on the operand information.
05675         We are only prepared to turn a few of the operands into
05676         relocs.  */
05677       if ((operand->flags & PPC_OPERAND_RELATIVE) != 0
05678          && operand->bits == 26
05679          && operand->shift == 0)
05680        fixP->fx_r_type = BFD_RELOC_PPC_B26;
05681       else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0
05682          && operand->bits == 16
05683          && operand->shift == 0)
05684        {
05685          fixP->fx_r_type = BFD_RELOC_PPC_B16;
05686 #ifdef OBJ_XCOFF
05687          fixP->fx_size = 2;
05688          if (target_big_endian)
05689            fixP->fx_where += 2;
05690 #endif
05691        }
05692       else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0
05693               && operand->bits == 26
05694               && operand->shift == 0)
05695        fixP->fx_r_type = BFD_RELOC_PPC_BA26;
05696       else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0
05697               && operand->bits == 16
05698               && operand->shift == 0)
05699        {
05700          fixP->fx_r_type = BFD_RELOC_PPC_BA16;
05701 #ifdef OBJ_XCOFF
05702          fixP->fx_size = 2;
05703          if (target_big_endian)
05704            fixP->fx_where += 2;
05705 #endif
05706        }
05707 #if defined (OBJ_XCOFF) || defined (OBJ_ELF)
05708       else if ((operand->flags & PPC_OPERAND_PARENS) != 0
05709               && operand->bits == 16
05710               && operand->shift == 0)
05711        {
05712          if (ppc_is_toc_sym (fixP->fx_addsy))
05713            {
05714              fixP->fx_r_type = BFD_RELOC_PPC_TOC16;
05715 #ifdef OBJ_ELF
05716              if (ppc_obj64
05717                 && (operand->flags & PPC_OPERAND_DS) != 0)
05718               fixP->fx_r_type = BFD_RELOC_PPC64_TOC16_DS;
05719 #endif
05720            }
05721          else
05722            {
05723              fixP->fx_r_type = BFD_RELOC_16;
05724 #ifdef OBJ_ELF
05725              if (ppc_obj64
05726                 && (operand->flags & PPC_OPERAND_DS) != 0)
05727               fixP->fx_r_type = BFD_RELOC_PPC64_ADDR16_DS;
05728 #endif
05729            }
05730          fixP->fx_size = 2;
05731          if (target_big_endian)
05732            fixP->fx_where += 2;
05733        }
05734 #endif /* defined (OBJ_XCOFF) || defined (OBJ_ELF) */
05735       else
05736        {
05737          char *sfile;
05738          unsigned int sline;
05739 
05740          /* Use expr_symbol_where to see if this is an expression
05741             symbol.  */
05742          if (expr_symbol_where (fixP->fx_addsy, &sfile, &sline))
05743            as_bad_where (fixP->fx_file, fixP->fx_line,
05744                        _("unresolved expression that must be resolved"));
05745          else
05746            as_bad_where (fixP->fx_file, fixP->fx_line,
05747                        _("unsupported relocation against %s"),
05748                        S_GET_NAME (fixP->fx_addsy));
05749          fixP->fx_done = 1;
05750          return;
05751        }
05752     }
05753   else
05754     {
05755 #ifdef OBJ_ELF
05756       ppc_elf_validate_fix (fixP, seg);
05757 #endif
05758       switch (fixP->fx_r_type)
05759        {
05760        case BFD_RELOC_CTOR:
05761          if (ppc_obj64)
05762            goto ctor64;
05763          /* fall through */
05764 
05765        case BFD_RELOC_32:
05766          if (fixP->fx_pcrel)
05767            fixP->fx_r_type = BFD_RELOC_32_PCREL;
05768          /* fall through */
05769 
05770        case BFD_RELOC_RVA:
05771        case BFD_RELOC_32_PCREL:
05772        case BFD_RELOC_PPC_EMB_NADDR32:
05773          md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
05774                            value, 4);
05775          break;
05776 
05777        case BFD_RELOC_64:
05778        ctor64:
05779          if (fixP->fx_pcrel)
05780            fixP->fx_r_type = BFD_RELOC_64_PCREL;
05781          /* fall through */
05782 
05783        case BFD_RELOC_64_PCREL:
05784          md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
05785                            value, 8);
05786          break;
05787 
05788        case BFD_RELOC_GPREL16:
05789        case BFD_RELOC_16_GOT_PCREL:
05790        case BFD_RELOC_16_GOTOFF:
05791        case BFD_RELOC_LO16_GOTOFF:
05792        case BFD_RELOC_HI16_GOTOFF:
05793        case BFD_RELOC_HI16_S_GOTOFF:
05794        case BFD_RELOC_16_BASEREL:
05795        case BFD_RELOC_LO16_BASEREL:
05796        case BFD_RELOC_HI16_BASEREL:
05797        case BFD_RELOC_HI16_S_BASEREL:
05798        case BFD_RELOC_PPC_EMB_NADDR16:
05799        case BFD_RELOC_PPC_EMB_NADDR16_LO:
05800        case BFD_RELOC_PPC_EMB_NADDR16_HI:
05801        case BFD_RELOC_PPC_EMB_NADDR16_HA:
05802        case BFD_RELOC_PPC_EMB_SDAI16:
05803        case BFD_RELOC_PPC_EMB_SDA2REL:
05804        case BFD_RELOC_PPC_EMB_SDA2I16:
05805        case BFD_RELOC_PPC_EMB_RELSEC16:
05806        case BFD_RELOC_PPC_EMB_RELST_LO:
05807        case BFD_RELOC_PPC_EMB_RELST_HI:
05808        case BFD_RELOC_PPC_EMB_RELST_HA:
05809        case BFD_RELOC_PPC_EMB_RELSDA:
05810        case BFD_RELOC_PPC_TOC16:
05811 #ifdef OBJ_ELF
05812        case BFD_RELOC_PPC64_TOC16_LO:
05813        case BFD_RELOC_PPC64_TOC16_HI:
05814        case BFD_RELOC_PPC64_TOC16_HA:
05815 #endif
05816          if (fixP->fx_pcrel)
05817            {
05818              if (fixP->fx_addsy != NULL)
05819               as_bad_where (fixP->fx_file, fixP->fx_line,
05820                            _("cannot emit PC relative %s relocation against %s"),
05821                            bfd_get_reloc_code_name (fixP->fx_r_type),
05822                            S_GET_NAME (fixP->fx_addsy));
05823              else
05824               as_bad_where (fixP->fx_file, fixP->fx_line,
05825                            _("cannot emit PC relative %s relocation"),
05826                            bfd_get_reloc_code_name (fixP->fx_r_type));
05827            }
05828 
05829          md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
05830                            value, 2);
05831          break;
05832 
05833        case BFD_RELOC_16:
05834          if (fixP->fx_pcrel)
05835            fixP->fx_r_type = BFD_RELOC_16_PCREL;
05836          /* fall through */
05837 
05838        case BFD_RELOC_16_PCREL:
05839          md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
05840                            value, 2);
05841          break;
05842 
05843        case BFD_RELOC_LO16:
05844          if (fixP->fx_pcrel)
05845            fixP->fx_r_type = BFD_RELOC_LO16_PCREL;
05846          /* fall through */
05847 
05848        case BFD_RELOC_LO16_PCREL:
05849          md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
05850                            value, 2);
05851          break;
05852 
05853          /* This case happens when you write, for example,
05854             lis %r3,(L1-L2)@ha
05855             where L1 and L2 are defined later.  */
05856        case BFD_RELOC_HI16:
05857          if (fixP->fx_pcrel)
05858            fixP->fx_r_type = BFD_RELOC_HI16_PCREL;
05859          /* fall through */
05860 
05861        case BFD_RELOC_HI16_PCREL:
05862          md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
05863                            PPC_HI (value), 2);
05864          break;
05865 
05866        case BFD_RELOC_HI16_S:
05867          if (fixP->fx_pcrel)
05868            fixP->fx_r_type = BFD_RELOC_HI16_S_PCREL;
05869          /* fall through */
05870 
05871        case BFD_RELOC_HI16_S_PCREL:
05872          md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
05873                            PPC_HA (value), 2);
05874          break;
05875 
05876 #ifdef OBJ_ELF
05877        case BFD_RELOC_PPC64_HIGHER:
05878          if (fixP->fx_pcrel)
05879            abort ();
05880          md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
05881                            PPC_HIGHER (value), 2);
05882          break;
05883 
05884        case BFD_RELOC_PPC64_HIGHER_S:
05885          if (fixP->fx_pcrel)
05886            abort ();
05887          md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
05888                            PPC_HIGHERA (value), 2);
05889          break;
05890 
05891        case BFD_RELOC_PPC64_HIGHEST:
05892          if (fixP->fx_pcrel)
05893            abort ();
05894          md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
05895                            PPC_HIGHEST (value), 2);
05896          break;
05897 
05898        case BFD_RELOC_PPC64_HIGHEST_S:
05899          if (fixP->fx_pcrel)
05900            abort ();
05901          md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
05902                            PPC_HIGHESTA (value), 2);
05903          break;
05904 
05905        case BFD_RELOC_PPC64_ADDR16_DS:
05906        case BFD_RELOC_PPC64_ADDR16_LO_DS:
05907        case BFD_RELOC_PPC64_GOT16_DS:
05908        case BFD_RELOC_PPC64_GOT16_LO_DS:
05909        case BFD_RELOC_PPC64_PLT16_LO_DS:
05910        case BFD_RELOC_PPC64_SECTOFF_DS:
05911        case BFD_RELOC_PPC64_SECTOFF_LO_DS:
05912        case BFD_RELOC_PPC64_TOC16_DS:
05913        case BFD_RELOC_PPC64_TOC16_LO_DS:
05914        case BFD_RELOC_PPC64_PLTGOT16_DS:
05915        case BFD_RELOC_PPC64_PLTGOT16_LO_DS:
05916          if (fixP->fx_pcrel)
05917            abort ();
05918          {
05919            char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
05920            unsigned long val, mask;
05921 
05922            if (target_big_endian)
05923              val = bfd_getb32 (where - 2);
05924            else
05925              val = bfd_getl32 (where);
05926            mask = 0xfffc;
05927            /* lq insns reserve the four lsbs.  */
05928            if ((ppc_cpu & PPC_OPCODE_POWER4) != 0
05929               && (val & (0x3f << 26)) == (56u << 26))
05930              mask = 0xfff0;
05931            val |= value & mask;
05932            if (target_big_endian)
05933              bfd_putb16 ((bfd_vma) val, where);
05934            else
05935              bfd_putl16 ((bfd_vma) val, where);
05936          }
05937          break;
05938 
05939        case BFD_RELOC_PPC_B16_BRTAKEN:
05940        case BFD_RELOC_PPC_B16_BRNTAKEN:
05941        case BFD_RELOC_PPC_BA16_BRTAKEN:
05942        case BFD_RELOC_PPC_BA16_BRNTAKEN:
05943          break;
05944 
05945        case BFD_RELOC_PPC_TLS:
05946          break;
05947 
05948        case BFD_RELOC_PPC_DTPMOD:
05949        case BFD_RELOC_PPC_TPREL16:
05950        case BFD_RELOC_PPC_TPREL16_LO:
05951        case BFD_RELOC_PPC_TPREL16_HI:
05952        case BFD_RELOC_PPC_TPREL16_HA:
05953        case BFD_RELOC_PPC_TPREL:
05954        case BFD_RELOC_PPC_DTPREL16:
05955        case BFD_RELOC_PPC_DTPREL16_LO:
05956        case BFD_RELOC_PPC_DTPREL16_HI:
05957        case BFD_RELOC_PPC_DTPREL16_HA:
05958        case BFD_RELOC_PPC_DTPREL:
05959        case BFD_RELOC_PPC_GOT_TLSGD16:
05960        case BFD_RELOC_PPC_GOT_TLSGD16_LO:
05961        case BFD_RELOC_PPC_GOT_TLSGD16_HI:
05962        case BFD_RELOC_PPC_GOT_TLSGD16_HA:
05963        case BFD_RELOC_PPC_GOT_TLSLD16:
05964        case BFD_RELOC_PPC_GOT_TLSLD16_LO:
05965        case BFD_RELOC_PPC_GOT_TLSLD16_HI:
05966        case BFD_RELOC_PPC_GOT_TLSLD16_HA:
05967        case BFD_RELOC_PPC_GOT_TPREL16:
05968        case BFD_RELOC_PPC_GOT_TPREL16_LO:
05969        case BFD_RELOC_PPC_GOT_TPREL16_HI:
05970        case BFD_RELOC_PPC_GOT_TPREL16_HA:
05971        case BFD_RELOC_PPC_GOT_DTPREL16:
05972        case BFD_RELOC_PPC_GOT_DTPREL16_LO:
05973        case BFD_RELOC_PPC_GOT_DTPREL16_HI:
05974        case BFD_RELOC_PPC_GOT_DTPREL16_HA:
05975        case BFD_RELOC_PPC64_TPREL16_DS:
05976        case BFD_RELOC_PPC64_TPREL16_LO_DS:
05977        case BFD_RELOC_PPC64_TPREL16_HIGHER:
05978        case BFD_RELOC_PPC64_TPREL16_HIGHERA:
05979        case BFD_RELOC_PPC64_TPREL16_HIGHEST:
05980        case BFD_RELOC_PPC64_TPREL16_HIGHESTA:
05981        case BFD_RELOC_PPC64_DTPREL16_DS:
05982        case BFD_RELOC_PPC64_DTPREL16_LO_DS:
05983        case BFD_RELOC_PPC64_DTPREL16_HIGHER:
05984        case BFD_RELOC_PPC64_DTPREL16_HIGHERA:
05985        case BFD_RELOC_PPC64_DTPREL16_HIGHEST:
05986        case BFD_RELOC_PPC64_DTPREL16_HIGHESTA:
05987          S_SET_THREAD_LOCAL (fixP->fx_addsy);
05988          break;
05989 #endif
05990          /* Because SDA21 modifies the register field, the size is set to 4
05991             bytes, rather than 2, so offset it here appropriately.  */
05992        case BFD_RELOC_PPC_EMB_SDA21:
05993          if (fixP->fx_pcrel)
05994            abort ();
05995 
05996          md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where
05997                            + ((target_big_endian) ? 2 : 0),
05998                            value, 2);
05999          break;
06000 
06001        case BFD_RELOC_8:
06002          if (fixP->fx_pcrel)
06003            {
06004              /* This can occur if there is a bug in the input assembler, eg:
06005                ".byte <undefined_symbol> - ."  */
06006              if (fixP->fx_addsy)
06007               as_bad (_("Unable to handle reference to symbol %s"),
06008                      S_GET_NAME (fixP->fx_addsy));
06009              else
06010               as_bad (_("Unable to resolve expression"));
06011              fixP->fx_done = 1;
06012            }
06013          else
06014            md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
06015                             value, 1);
06016          break;
06017 
06018        case BFD_RELOC_24_PLT_PCREL:
06019        case BFD_RELOC_PPC_LOCAL24PC:
06020          if (!fixP->fx_pcrel && !fixP->fx_done)
06021            abort ();
06022 
06023          if (fixP->fx_done)
06024            {
06025              char *where;
06026              unsigned long insn;
06027 
06028              /* Fetch the instruction, insert the fully resolved operand
06029                value, and stuff the instruction back again.  */
06030              where = fixP->fx_frag->fr_literal + fixP->fx_where;
06031              if (target_big_endian)
06032               insn = bfd_getb32 ((unsigned char *) where);
06033              else
06034               insn = bfd_getl32 ((unsigned char *) where);
06035              if ((value & 3) != 0)
06036               as_bad_where (fixP->fx_file, fixP->fx_line,
06037                            _("must branch to an address a multiple of 4"));
06038              if ((offsetT) value < -0x40000000
06039                 || (offsetT) value >= 0x40000000)
06040               as_bad_where (fixP->fx_file, fixP->fx_line,
06041                            _("@local or @plt branch destination is too far away, %ld bytes"),
06042                            (long) value);
06043              insn = insn | (value & 0x03fffffc);
06044              if (target_big_endian)
06045               bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
06046              else
06047               bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
06048            }
06049          break;
06050 
06051        case BFD_RELOC_VTABLE_INHERIT:
06052          fixP->fx_done = 0;
06053          if (fixP->fx_addsy
06054              && !S_IS_DEFINED (fixP->fx_addsy)
06055              && !S_IS_WEAK (fixP->fx_addsy))
06056            S_SET_WEAK (fixP->fx_addsy);
06057          break;
06058 
06059        case BFD_RELOC_VTABLE_ENTRY:
06060          fixP->fx_done = 0;
06061          break;
06062 
06063 #ifdef OBJ_ELF
06064          /* Generated by reference to `sym@tocbase'.  The sym is
06065             ignored by the linker.  */
06066        case BFD_RELOC_PPC64_TOC:
06067          fixP->fx_done = 0;
06068          break;
06069 #endif
06070        default:
06071          fprintf (stderr,
06072                  _("Gas failure, reloc value %d\n"), fixP->fx_r_type);
06073          fflush (stderr);
06074          abort ();
06075        }
06076     }
06077 
06078 #ifdef OBJ_ELF
06079   fixP->fx_addnumber = value;
06080 
06081   /* PowerPC uses RELA relocs, ie. the reloc addend is stored separately
06082      from the section contents.  If we are going to be emitting a reloc
06083      then the section contents are immaterial, so don't warn if they
06084      happen to overflow.  Leave such warnings to ld.  */
06085   if (!fixP->fx_done)
06086     fixP->fx_no_overflow = 1;
06087 #else
06088   if (fixP->fx_r_type != BFD_RELOC_PPC_TOC16)
06089     fixP->fx_addnumber = 0;
06090   else
06091     {
06092 #ifdef TE_PE
06093       fixP->fx_addnumber = 0;
06094 #else
06095       /* We want to use the offset within the data segment of the
06096         symbol, not the actual VMA of the symbol.  */
06097       fixP->fx_addnumber =
06098        - bfd_get_section_vma (stdoutput, S_GET_SEGMENT (fixP->fx_addsy));
06099 #endif
06100     }
06101 #endif
06102 }
06103 
06104 /* Generate a reloc for a fixup.  */
06105 
06106 arelent *
06107 tc_gen_reloc (seg, fixp)
06108      asection *seg ATTRIBUTE_UNUSED;
06109      fixS *fixp;
06110 {
06111   arelent *reloc;
06112 
06113   reloc = (arelent *) xmalloc (sizeof (arelent));
06114 
06115   reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
06116   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
06117   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
06118   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
06119   if (reloc->howto == (reloc_howto_type *) NULL)
06120     {
06121       as_bad_where (fixp->fx_file, fixp->fx_line,
06122                   _("reloc %d not supported by object file format"),
06123                   (int) fixp->fx_r_type);
06124       return NULL;
06125     }
06126   reloc->addend = fixp->fx_addnumber;
06127 
06128   return reloc;
06129 }
06130 
06131 void
06132 ppc_cfi_frame_initial_instructions ()
06133 {
06134   cfi_add_CFA_def_cfa (1, 0);
06135 }
06136 
06137 int
06138 tc_ppc_regname_to_dw2regnum (char *regname)
06139 {
06140   unsigned int regnum = -1;
06141   unsigned int i;
06142   const char *p;
06143   char *q;
06144   static struct { char *name; int dw2regnum; } regnames[] =
06145     {
06146       { "sp", 1 }, { "r.sp", 1 }, { "rtoc", 2 }, { "r.toc", 2 },
06147       { "mq", 64 }, { "lr", 65 }, { "ctr", 66 }, { "ap", 67 },
06148       { "cr", 70 }, { "xer", 76 }, { "vrsave", 109 }, { "vscr", 110 },
06149       { "spe_acc", 111 }, { "spefscr", 112 }
06150     };
06151 
06152   for (i = 0; i < ARRAY_SIZE (regnames); ++i)
06153     if (strcmp (regnames[i].name, regname) == 0)
06154       return regnames[i].dw2regnum;
06155 
06156   if (regname[0] == 'r' || regname[0] == 'f' || regname[0] == 'v')
06157     {
06158       p = regname + 1 + (regname[1] == '.');
06159       regnum = strtoul (p, &q, 10);
06160       if (p == q || *q || regnum >= 32)
06161        return -1;
06162       if (regname[0] == 'f')
06163        regnum += 32;
06164       else if (regname[0] == 'v')
06165        regnum += 77;
06166     }
06167   else if (regname[0] == 'c' && regname[1] == 'r')
06168     {
06169       p = regname + 2 + (regname[2] == '.');
06170       if (p[0] < '0' || p[0] > '7' || p[1])
06171        return -1;
06172       regnum = p[0] - '0' + 68;
06173     }
06174   return regnum;
06175 }