Home | History | Annotate | Line # | Download | only in config
      1   1.1  christos /* tc-ia64.c -- Assembler for the HP/Intel IA-64 architecture.
      2  1.10  christos    Copyright (C) 1998-2025 Free Software Foundation, Inc.
      3   1.1  christos    Contributed by David Mosberger-Tang <davidm (at) hpl.hp.com>
      4   1.1  christos 
      5   1.1  christos    This file is part of GAS, the GNU Assembler.
      6   1.1  christos 
      7   1.1  christos    GAS is free software; you can redistribute it and/or modify
      8   1.1  christos    it under the terms of the GNU General Public License as published by
      9   1.1  christos    the Free Software Foundation; either version 3, or (at your option)
     10   1.1  christos    any later version.
     11   1.1  christos 
     12   1.1  christos    GAS is distributed in the hope that it will be useful,
     13   1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14   1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15   1.1  christos    GNU General Public License for more details.
     16   1.1  christos 
     17   1.1  christos    You should have received a copy of the GNU General Public License
     18   1.1  christos    along with GAS; see the file COPYING.  If not, write to
     19   1.1  christos    the Free Software Foundation, 51 Franklin Street - Fifth Floor,
     20   1.1  christos    Boston, MA 02110-1301, USA.  */
     21   1.1  christos 
     22   1.1  christos /*
     23   1.1  christos   TODO:
     24   1.1  christos 
     25   1.1  christos   - optional operands
     26   1.1  christos   - directives:
     27   1.1  christos 	.eb
     28   1.1  christos 	.estate
     29   1.1  christos 	.lb
     30   1.1  christos 	.popsection
     31   1.1  christos 	.previous
     32   1.1  christos 	.psr
     33   1.1  christos 	.pushsection
     34   1.1  christos   - labels are wrong if automatic alignment is introduced
     35   1.1  christos     (e.g., checkout the second real10 definition in test-data.s)
     36   1.1  christos   - DV-related stuff:
     37   1.1  christos 	<reg>.safe_across_calls and any other DV-related directives I don't
     38   1.1  christos 	  have documentation for.
     39   1.1  christos 	verify mod-sched-brs reads/writes are checked/marked (and other
     40   1.1  christos 	notes)
     41   1.1  christos 
     42   1.1  christos  */
     43   1.1  christos 
     44   1.1  christos #include "as.h"
     45   1.1  christos #include "safe-ctype.h"
     46   1.1  christos #include "dwarf2dbg.h"
     47   1.1  christos #include "subsegs.h"
     48   1.1  christos 
     49   1.1  christos #include "opcode/ia64.h"
     50   1.1  christos 
     51   1.1  christos #include "elf/ia64.h"
     52   1.1  christos #include "bfdver.h"
     53   1.1  christos #include <time.h>
     54   1.1  christos #include <limits.h>
     55   1.1  christos 
     56   1.1  christos #define NELEMS(a)	((int) (sizeof (a)/sizeof ((a)[0])))
     57   1.1  christos 
     58   1.1  christos /* Some systems define MIN in, e.g., param.h.  */
     59   1.1  christos #undef MIN
     60   1.1  christos #define MIN(a,b)	((a) < (b) ? (a) : (b))
     61   1.1  christos 
     62   1.1  christos #define NUM_SLOTS	4
     63   1.1  christos #define PREV_SLOT	md.slot[(md.curr_slot + NUM_SLOTS - 1) % NUM_SLOTS]
     64   1.1  christos #define CURR_SLOT	md.slot[md.curr_slot]
     65   1.1  christos 
     66   1.1  christos #define O_pseudo_fixup (O_max + 1)
     67   1.1  christos 
     68   1.1  christos enum special_section
     69   1.1  christos   {
     70   1.1  christos     /* IA-64 ABI section pseudo-ops.  */
     71   1.9  christos     SPECIAL_SECTION_SBSS = 0,
     72   1.1  christos     SPECIAL_SECTION_SDATA,
     73   1.1  christos     SPECIAL_SECTION_RODATA,
     74   1.1  christos     SPECIAL_SECTION_COMMENT,
     75   1.1  christos     SPECIAL_SECTION_UNWIND,
     76   1.1  christos     SPECIAL_SECTION_UNWIND_INFO,
     77   1.1  christos     /* HPUX specific section pseudo-ops.  */
     78   1.1  christos     SPECIAL_SECTION_INIT_ARRAY,
     79   1.1  christos     SPECIAL_SECTION_FINI_ARRAY,
     80   1.1  christos   };
     81   1.1  christos 
     82   1.1  christos enum reloc_func
     83   1.1  christos   {
     84   1.1  christos     FUNC_DTP_MODULE,
     85   1.1  christos     FUNC_DTP_RELATIVE,
     86   1.1  christos     FUNC_FPTR_RELATIVE,
     87   1.1  christos     FUNC_GP_RELATIVE,
     88   1.1  christos     FUNC_LT_RELATIVE,
     89   1.1  christos     FUNC_LT_RELATIVE_X,
     90   1.1  christos     FUNC_PC_RELATIVE,
     91   1.1  christos     FUNC_PLT_RELATIVE,
     92   1.1  christos     FUNC_SEC_RELATIVE,
     93   1.1  christos     FUNC_SEG_RELATIVE,
     94   1.1  christos     FUNC_TP_RELATIVE,
     95   1.1  christos     FUNC_LTV_RELATIVE,
     96   1.1  christos     FUNC_LT_FPTR_RELATIVE,
     97   1.1  christos     FUNC_LT_DTP_MODULE,
     98   1.1  christos     FUNC_LT_DTP_RELATIVE,
     99   1.1  christos     FUNC_LT_TP_RELATIVE,
    100   1.1  christos     FUNC_IPLT_RELOC,
    101   1.1  christos #ifdef TE_VMS
    102   1.1  christos     FUNC_SLOTCOUNT_RELOC,
    103   1.1  christos #endif
    104   1.1  christos   };
    105   1.1  christos 
    106   1.1  christos enum reg_symbol
    107   1.1  christos   {
    108   1.1  christos     REG_GR	= 0,
    109   1.1  christos     REG_FR	= (REG_GR + 128),
    110   1.1  christos     REG_AR	= (REG_FR + 128),
    111   1.1  christos     REG_CR	= (REG_AR + 128),
    112   1.1  christos     REG_DAHR	= (REG_CR + 128),
    113   1.1  christos     REG_P	= (REG_DAHR + 8),
    114   1.1  christos     REG_BR	= (REG_P  + 64),
    115   1.1  christos     REG_IP	= (REG_BR + 8),
    116   1.1  christos     REG_CFM,
    117   1.1  christos     REG_PR,
    118   1.1  christos     REG_PR_ROT,
    119   1.1  christos     REG_PSR,
    120   1.1  christos     REG_PSR_L,
    121   1.1  christos     REG_PSR_UM,
    122   1.1  christos     /* The following are pseudo-registers for use by gas only.  */
    123   1.1  christos     IND_CPUID,
    124   1.1  christos     IND_DBR,
    125   1.1  christos     IND_DTR,
    126   1.1  christos     IND_ITR,
    127   1.1  christos     IND_IBR,
    128   1.1  christos     IND_MSR,
    129   1.1  christos     IND_PKR,
    130   1.1  christos     IND_PMC,
    131   1.1  christos     IND_PMD,
    132   1.1  christos     IND_DAHR,
    133   1.1  christos     IND_RR,
    134   1.1  christos     /* The following pseudo-registers are used for unwind directives only:  */
    135   1.1  christos     REG_PSP,
    136   1.1  christos     REG_PRIUNAT,
    137   1.1  christos     REG_NUM
    138   1.1  christos   };
    139   1.1  christos 
    140   1.1  christos enum dynreg_type
    141   1.1  christos   {
    142   1.1  christos     DYNREG_GR = 0,	/* dynamic general purpose register */
    143   1.1  christos     DYNREG_FR,		/* dynamic floating point register */
    144   1.1  christos     DYNREG_PR,		/* dynamic predicate register */
    145   1.1  christos     DYNREG_NUM_TYPES
    146   1.1  christos   };
    147   1.1  christos 
    148   1.1  christos enum operand_match_result
    149   1.1  christos   {
    150   1.1  christos     OPERAND_MATCH,
    151   1.1  christos     OPERAND_OUT_OF_RANGE,
    152   1.1  christos     OPERAND_MISMATCH
    153   1.1  christos   };
    154   1.1  christos 
    155   1.1  christos /* On the ia64, we can't know the address of a text label until the
    156   1.1  christos    instructions are packed into a bundle.  To handle this, we keep
    157   1.1  christos    track of the list of labels that appear in front of each
    158   1.1  christos    instruction.  */
    159   1.1  christos struct label_fix
    160   1.1  christos {
    161   1.1  christos   struct label_fix *next;
    162   1.1  christos   struct symbol *sym;
    163   1.8  christos   bool dw2_mark_labels;
    164   1.1  christos };
    165   1.1  christos 
    166   1.1  christos #ifdef TE_VMS
    167   1.1  christos /* An internally used relocation.  */
    168   1.1  christos #define DUMMY_RELOC_IA64_SLOTCOUNT	(BFD_RELOC_UNUSED + 1)
    169   1.1  christos #endif
    170   1.1  christos 
    171   1.1  christos /* This is the endianness of the current section.  */
    172   1.1  christos extern int target_big_endian;
    173   1.1  christos 
    174   1.1  christos /* This is the default endianness.  */
    175   1.1  christos static int default_big_endian = TARGET_BYTES_BIG_ENDIAN;
    176   1.1  christos 
    177   1.1  christos void (*ia64_number_to_chars) (char *, valueT, int);
    178   1.1  christos 
    179   1.1  christos static void ia64_float_to_chars_bigendian (char *, LITTLENUM_TYPE *, int);
    180   1.1  christos static void ia64_float_to_chars_littleendian (char *, LITTLENUM_TYPE *, int);
    181   1.1  christos 
    182   1.1  christos static void (*ia64_float_to_chars) (char *, LITTLENUM_TYPE *, int);
    183   1.1  christos 
    184   1.8  christos static htab_t alias_hash;
    185   1.8  christos static htab_t alias_name_hash;
    186   1.8  christos static htab_t secalias_hash;
    187   1.8  christos static htab_t secalias_name_hash;
    188   1.1  christos 
    189   1.1  christos /* List of chars besides those in app.c:symbol_chars that can start an
    190   1.1  christos    operand.  Used to prevent the scrubber eating vital white-space.  */
    191   1.1  christos const char ia64_symbol_chars[] = "@?";
    192   1.1  christos 
    193   1.1  christos /* Characters which always start a comment.  */
    194   1.1  christos const char comment_chars[] = "";
    195   1.1  christos 
    196   1.1  christos /* Characters which start a comment at the beginning of a line.  */
    197   1.1  christos const char line_comment_chars[] = "#";
    198   1.1  christos 
    199   1.1  christos /* Characters which may be used to separate multiple commands on a
    200   1.1  christos    single line.  */
    201   1.1  christos const char line_separator_chars[] = ";{}";
    202   1.1  christos 
    203   1.1  christos /* Characters which are used to indicate an exponent in a floating
    204   1.1  christos    point number.  */
    205   1.1  christos const char EXP_CHARS[] = "eE";
    206   1.1  christos 
    207   1.1  christos /* Characters which mean that a number is a floating point constant,
    208   1.1  christos    as in 0d1.0.  */
    209   1.1  christos const char FLT_CHARS[] = "rRsSfFdDxXpP";
    210   1.1  christos 
    211   1.1  christos /* ia64-specific option processing:  */
    212   1.1  christos 
    213  1.10  christos const char md_shortopts[] = "m:N:x::";
    214   1.1  christos 
    215  1.10  christos const struct option md_longopts[] =
    216   1.1  christos   {
    217   1.1  christos #define OPTION_MCONSTANT_GP (OPTION_MD_BASE + 1)
    218   1.1  christos     {"mconstant-gp", no_argument, NULL, OPTION_MCONSTANT_GP},
    219   1.1  christos #define OPTION_MAUTO_PIC (OPTION_MD_BASE + 2)
    220   1.1  christos     {"mauto-pic", no_argument, NULL, OPTION_MAUTO_PIC}
    221   1.1  christos   };
    222   1.1  christos 
    223  1.10  christos const size_t md_longopts_size = sizeof (md_longopts);
    224   1.1  christos 
    225   1.1  christos static struct
    226   1.1  christos   {
    227   1.8  christos     htab_t pseudo_hash;	/* pseudo opcode hash table */
    228   1.8  christos     htab_t reg_hash;	/* register name hash table */
    229   1.8  christos     htab_t dynreg_hash;	/* dynamic register hash table */
    230   1.8  christos     htab_t const_hash;	/* constant hash table */
    231   1.8  christos     htab_t entry_hash;    /* code entry hint hash table */
    232   1.1  christos 
    233   1.6  christos     /* If X_op is != O_absent, the register name for the instruction's
    234   1.1  christos        qualifying predicate.  If NULL, p0 is assumed for instructions
    235   1.1  christos        that are predictable.  */
    236   1.1  christos     expressionS qp;
    237   1.1  christos 
    238   1.1  christos     /* Optimize for which CPU.  */
    239   1.1  christos     enum
    240   1.1  christos       {
    241   1.1  christos 	itanium1,
    242   1.1  christos 	itanium2
    243   1.1  christos       } tune;
    244   1.1  christos 
    245   1.1  christos     /* What to do when hint.b is used.  */
    246   1.1  christos     enum
    247   1.1  christos       {
    248   1.1  christos 	hint_b_error,
    249   1.1  christos 	hint_b_warning,
    250   1.1  christos 	hint_b_ok
    251   1.1  christos       } hint_b;
    252   1.1  christos 
    253   1.1  christos     unsigned int
    254   1.1  christos       manual_bundling : 1,
    255   1.1  christos       debug_dv: 1,
    256   1.1  christos       detect_dv: 1,
    257   1.1  christos       explicit_mode : 1,            /* which mode we're in */
    258   1.1  christos       default_explicit_mode : 1,    /* which mode is the default */
    259   1.1  christos       mode_explicitly_set : 1,      /* was the current mode explicitly set? */
    260   1.1  christos       auto_align : 1,
    261   1.1  christos       keep_pending_output : 1;
    262   1.1  christos 
    263   1.1  christos     /* What to do when something is wrong with unwind directives.  */
    264   1.1  christos     enum
    265   1.1  christos       {
    266   1.1  christos 	unwind_check_warning,
    267   1.1  christos 	unwind_check_error
    268   1.1  christos       } unwind_check;
    269   1.1  christos 
    270   1.1  christos     /* Each bundle consists of up to three instructions.  We keep
    271   1.1  christos        track of four most recent instructions so we can correctly set
    272   1.1  christos        the end_of_insn_group for the last instruction in a bundle.  */
    273   1.1  christos     int curr_slot;
    274   1.1  christos     int num_slots_in_use;
    275   1.1  christos     struct slot
    276   1.1  christos       {
    277   1.1  christos 	unsigned int
    278   1.1  christos 	  end_of_insn_group : 1,
    279   1.1  christos 	  manual_bundling_on : 1,
    280   1.1  christos 	  manual_bundling_off : 1,
    281   1.1  christos 	  loc_directive_seen : 1;
    282   1.1  christos 	signed char user_template;	/* user-selected template, if any */
    283   1.1  christos 	unsigned char qp_regno;		/* qualifying predicate */
    284   1.1  christos 	/* This duplicates a good fraction of "struct fix" but we
    285   1.1  christos 	   can't use a "struct fix" instead since we can't call
    286   1.1  christos 	   fix_new_exp() until we know the address of the instruction.  */
    287   1.1  christos 	int num_fixups;
    288   1.1  christos 	struct insn_fix
    289   1.1  christos 	  {
    290   1.1  christos 	    bfd_reloc_code_real_type code;
    291   1.1  christos 	    enum ia64_opnd opnd;	/* type of operand in need of fix */
    292   1.1  christos 	    unsigned int is_pcrel : 1;	/* is operand pc-relative? */
    293   1.1  christos 	    expressionS expr;		/* the value to be inserted */
    294   1.1  christos 	  }
    295   1.1  christos 	fixup[2];			/* at most two fixups per insn */
    296   1.1  christos 	struct ia64_opcode *idesc;
    297   1.1  christos 	struct label_fix *label_fixups;
    298   1.1  christos 	struct label_fix *tag_fixups;
    299   1.1  christos 	struct unw_rec_list *unwind_record;	/* Unwind directive.  */
    300   1.1  christos 	expressionS opnd[6];
    301   1.5  christos 	const char *src_file;
    302   1.1  christos 	unsigned int src_line;
    303   1.1  christos 	struct dwarf2_line_info debug_line;
    304   1.1  christos       }
    305   1.1  christos     slot[NUM_SLOTS];
    306   1.1  christos 
    307   1.1  christos     segT last_text_seg;
    308   1.8  christos     subsegT last_text_subseg;
    309   1.1  christos 
    310   1.1  christos     struct dynreg
    311   1.1  christos       {
    312   1.1  christos 	struct dynreg *next;		/* next dynamic register */
    313   1.1  christos 	const char *name;
    314   1.1  christos 	unsigned short base;		/* the base register number */
    315   1.1  christos 	unsigned short num_regs;	/* # of registers in this set */
    316   1.1  christos       }
    317   1.1  christos     *dynreg[DYNREG_NUM_TYPES], in, loc, out, rot;
    318   1.1  christos 
    319   1.1  christos     flagword flags;			/* ELF-header flags */
    320   1.1  christos 
    321   1.1  christos     struct mem_offset {
    322   1.1  christos       unsigned hint:1;              /* is this hint currently valid? */
    323   1.1  christos       bfd_vma offset;               /* mem.offset offset */
    324   1.1  christos       bfd_vma base;                 /* mem.offset base */
    325   1.1  christos     } mem_offset;
    326   1.1  christos 
    327   1.1  christos     int path;                       /* number of alt. entry points seen */
    328   1.1  christos     const char **entry_labels;      /* labels of all alternate paths in
    329   1.1  christos 				       the current DV-checking block.  */
    330   1.1  christos     int maxpaths;                   /* size currently allocated for
    331   1.1  christos 				       entry_labels */
    332   1.1  christos 
    333   1.1  christos     int pointer_size;       /* size in bytes of a pointer */
    334   1.1  christos     int pointer_size_shift; /* shift size of a pointer for alignment */
    335   1.1  christos 
    336   1.1  christos     symbolS *indregsym[IND_RR - IND_CPUID + 1];
    337   1.1  christos   }
    338   1.1  christos md;
    339   1.1  christos 
    340   1.1  christos /* These are not const, because they are modified to MMI for non-itanium1
    341   1.1  christos    targets below.  */
    342   1.1  christos /* MFI bundle of nops.  */
    343   1.1  christos static unsigned char le_nop[16] =
    344   1.1  christos {
    345   1.1  christos   0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
    346   1.1  christos   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00
    347   1.1  christos };
    348   1.1  christos /* MFI bundle of nops with stop-bit.  */
    349   1.1  christos static unsigned char le_nop_stop[16] =
    350   1.1  christos {
    351   1.1  christos   0x0d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
    352   1.1  christos   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00
    353   1.1  christos };
    354   1.1  christos 
    355   1.1  christos /* application registers:  */
    356   1.1  christos 
    357   1.1  christos #define AR_K0		0
    358   1.1  christos #define AR_K7		7
    359   1.1  christos #define AR_RSC		16
    360   1.1  christos #define AR_BSP		17
    361   1.1  christos #define AR_BSPSTORE	18
    362   1.1  christos #define AR_RNAT		19
    363   1.1  christos #define AR_FCR		21
    364   1.1  christos #define AR_EFLAG	24
    365   1.1  christos #define AR_CSD		25
    366   1.1  christos #define AR_SSD		26
    367   1.1  christos #define AR_CFLG		27
    368   1.1  christos #define AR_FSR		28
    369   1.1  christos #define AR_FIR		29
    370   1.1  christos #define AR_FDR		30
    371   1.1  christos #define AR_CCV		32
    372   1.1  christos #define AR_UNAT		36
    373   1.1  christos #define AR_FPSR		40
    374   1.1  christos #define AR_ITC		44
    375   1.1  christos #define AR_RUC		45
    376   1.1  christos #define AR_PFS		64
    377   1.1  christos #define AR_LC		65
    378   1.1  christos #define AR_EC		66
    379   1.1  christos 
    380   1.1  christos static const struct
    381   1.1  christos   {
    382   1.1  christos     const char *name;
    383   1.1  christos     unsigned int regnum;
    384   1.1  christos   }
    385   1.1  christos ar[] =
    386   1.1  christos   {
    387   1.1  christos     {"ar.k0",		AR_K0},		{"ar.k1",	AR_K0 + 1},
    388   1.1  christos     {"ar.k2",		AR_K0 + 2},	{"ar.k3",	AR_K0 + 3},
    389   1.1  christos     {"ar.k4",		AR_K0 + 4},	{"ar.k5",	AR_K0 + 5},
    390   1.1  christos     {"ar.k6",		AR_K0 + 6},	{"ar.k7",	AR_K7},
    391   1.1  christos     {"ar.rsc",		AR_RSC},	{"ar.bsp",	AR_BSP},
    392   1.1  christos     {"ar.bspstore",	AR_BSPSTORE},	{"ar.rnat",	AR_RNAT},
    393   1.1  christos     {"ar.fcr",		AR_FCR},	{"ar.eflag",	AR_EFLAG},
    394   1.1  christos     {"ar.csd",		AR_CSD},	{"ar.ssd",	AR_SSD},
    395   1.1  christos     {"ar.cflg",		AR_CFLG},	{"ar.fsr",	AR_FSR},
    396   1.1  christos     {"ar.fir",		AR_FIR},	{"ar.fdr",	AR_FDR},
    397   1.1  christos     {"ar.ccv",		AR_CCV},	{"ar.unat",	AR_UNAT},
    398   1.1  christos     {"ar.fpsr",		AR_FPSR},	{"ar.itc",	AR_ITC},
    399   1.1  christos     {"ar.ruc",		AR_RUC},	{"ar.pfs",	AR_PFS},
    400   1.1  christos     {"ar.lc",		AR_LC},		{"ar.ec",	AR_EC},
    401   1.1  christos   };
    402   1.1  christos 
    403   1.1  christos /* control registers:  */
    404   1.1  christos 
    405   1.1  christos #define CR_DCR           0
    406   1.1  christos #define CR_ITM           1
    407   1.1  christos #define CR_IVA           2
    408   1.1  christos #define CR_PTA           8
    409   1.1  christos #define CR_GPTA          9
    410   1.1  christos #define CR_IPSR         16
    411   1.1  christos #define CR_ISR          17
    412   1.1  christos #define CR_IIP          19
    413   1.1  christos #define CR_IFA          20
    414   1.1  christos #define CR_ITIR         21
    415   1.1  christos #define CR_IIPA         22
    416   1.1  christos #define CR_IFS          23
    417   1.1  christos #define CR_IIM          24
    418   1.1  christos #define CR_IHA          25
    419   1.1  christos #define CR_IIB0         26
    420   1.1  christos #define CR_IIB1         27
    421   1.1  christos #define CR_LID          64
    422   1.1  christos #define CR_IVR          65
    423   1.1  christos #define CR_TPR          66
    424   1.1  christos #define CR_EOI          67
    425   1.1  christos #define CR_IRR0         68
    426   1.1  christos #define CR_IRR3         71
    427   1.1  christos #define CR_ITV          72
    428   1.1  christos #define CR_PMV          73
    429   1.1  christos #define CR_CMCV         74
    430   1.1  christos #define CR_LRR0         80
    431   1.1  christos #define CR_LRR1         81
    432   1.1  christos 
    433   1.1  christos static const struct
    434   1.1  christos   {
    435   1.1  christos     const char *name;
    436   1.1  christos     unsigned int regnum;
    437   1.1  christos   }
    438   1.1  christos cr[] =
    439   1.1  christos   {
    440   1.1  christos     {"cr.dcr",	CR_DCR},
    441   1.1  christos     {"cr.itm",	CR_ITM},
    442   1.1  christos     {"cr.iva",	CR_IVA},
    443   1.1  christos     {"cr.pta",	CR_PTA},
    444   1.1  christos     {"cr.gpta",	CR_GPTA},
    445   1.1  christos     {"cr.ipsr",	CR_IPSR},
    446   1.1  christos     {"cr.isr",	CR_ISR},
    447   1.1  christos     {"cr.iip",	CR_IIP},
    448   1.1  christos     {"cr.ifa",	CR_IFA},
    449   1.1  christos     {"cr.itir",	CR_ITIR},
    450   1.1  christos     {"cr.iipa",	CR_IIPA},
    451   1.1  christos     {"cr.ifs",	CR_IFS},
    452   1.1  christos     {"cr.iim",	CR_IIM},
    453   1.1  christos     {"cr.iha",	CR_IHA},
    454   1.1  christos     {"cr.iib0",	CR_IIB0},
    455   1.1  christos     {"cr.iib1",	CR_IIB1},
    456   1.1  christos     {"cr.lid",	CR_LID},
    457   1.1  christos     {"cr.ivr",	CR_IVR},
    458   1.1  christos     {"cr.tpr",	CR_TPR},
    459   1.1  christos     {"cr.eoi",	CR_EOI},
    460   1.1  christos     {"cr.irr0",	CR_IRR0},
    461   1.1  christos     {"cr.irr1",	CR_IRR0 + 1},
    462   1.1  christos     {"cr.irr2",	CR_IRR0 + 2},
    463   1.1  christos     {"cr.irr3",	CR_IRR3},
    464   1.1  christos     {"cr.itv",	CR_ITV},
    465   1.1  christos     {"cr.pmv",	CR_PMV},
    466   1.1  christos     {"cr.cmcv",	CR_CMCV},
    467   1.1  christos     {"cr.lrr0",	CR_LRR0},
    468   1.1  christos     {"cr.lrr1",	CR_LRR1}
    469   1.1  christos   };
    470   1.1  christos 
    471   1.1  christos #define PSR_MFL         4
    472   1.1  christos #define PSR_IC          13
    473   1.1  christos #define PSR_DFL         18
    474   1.1  christos #define PSR_CPL         32
    475   1.1  christos 
    476   1.1  christos static const struct const_desc
    477   1.1  christos   {
    478   1.1  christos     const char *name;
    479   1.1  christos     valueT value;
    480   1.1  christos   }
    481   1.1  christos const_bits[] =
    482   1.1  christos   {
    483   1.1  christos     /* PSR constant masks:  */
    484   1.1  christos 
    485   1.1  christos     /* 0: reserved */
    486   1.1  christos     {"psr.be",	((valueT) 1) << 1},
    487   1.1  christos     {"psr.up",	((valueT) 1) << 2},
    488   1.1  christos     {"psr.ac",	((valueT) 1) << 3},
    489   1.1  christos     {"psr.mfl",	((valueT) 1) << 4},
    490   1.1  christos     {"psr.mfh",	((valueT) 1) << 5},
    491   1.1  christos     /* 6-12: reserved */
    492   1.1  christos     {"psr.ic",	((valueT) 1) << 13},
    493   1.1  christos     {"psr.i",	((valueT) 1) << 14},
    494   1.1  christos     {"psr.pk",	((valueT) 1) << 15},
    495   1.1  christos     /* 16: reserved */
    496   1.1  christos     {"psr.dt",	((valueT) 1) << 17},
    497   1.1  christos     {"psr.dfl",	((valueT) 1) << 18},
    498   1.1  christos     {"psr.dfh",	((valueT) 1) << 19},
    499   1.1  christos     {"psr.sp",	((valueT) 1) << 20},
    500   1.1  christos     {"psr.pp",	((valueT) 1) << 21},
    501   1.1  christos     {"psr.di",	((valueT) 1) << 22},
    502   1.1  christos     {"psr.si",	((valueT) 1) << 23},
    503   1.1  christos     {"psr.db",	((valueT) 1) << 24},
    504   1.1  christos     {"psr.lp",	((valueT) 1) << 25},
    505   1.1  christos     {"psr.tb",	((valueT) 1) << 26},
    506   1.1  christos     {"psr.rt",	((valueT) 1) << 27},
    507   1.1  christos     /* 28-31: reserved */
    508   1.1  christos     /* 32-33: cpl (current privilege level) */
    509   1.1  christos     {"psr.is",	((valueT) 1) << 34},
    510   1.1  christos     {"psr.mc",	((valueT) 1) << 35},
    511   1.1  christos     {"psr.it",	((valueT) 1) << 36},
    512   1.1  christos     {"psr.id",	((valueT) 1) << 37},
    513   1.1  christos     {"psr.da",	((valueT) 1) << 38},
    514   1.1  christos     {"psr.dd",	((valueT) 1) << 39},
    515   1.1  christos     {"psr.ss",	((valueT) 1) << 40},
    516   1.1  christos     /* 41-42: ri (restart instruction) */
    517   1.1  christos     {"psr.ed",	((valueT) 1) << 43},
    518   1.1  christos     {"psr.bn",	((valueT) 1) << 44},
    519   1.1  christos   };
    520   1.1  christos 
    521   1.1  christos /* indirect register-sets/memory:  */
    522   1.1  christos 
    523   1.1  christos static const struct
    524   1.1  christos   {
    525   1.1  christos     const char *name;
    526   1.1  christos     unsigned int regnum;
    527   1.1  christos   }
    528   1.1  christos indirect_reg[] =
    529   1.1  christos   {
    530   1.1  christos     { "CPUID",	IND_CPUID },
    531   1.1  christos     { "cpuid",	IND_CPUID },
    532   1.1  christos     { "dbr",	IND_DBR },
    533   1.1  christos     { "dtr",	IND_DTR },
    534   1.1  christos     { "itr",	IND_ITR },
    535   1.1  christos     { "ibr",	IND_IBR },
    536   1.1  christos     { "msr",	IND_MSR },
    537   1.1  christos     { "pkr",	IND_PKR },
    538   1.1  christos     { "pmc",	IND_PMC },
    539   1.1  christos     { "pmd",	IND_PMD },
    540   1.1  christos     { "dahr",	IND_DAHR },
    541   1.1  christos     { "rr",	IND_RR },
    542   1.1  christos   };
    543   1.1  christos 
    544   1.1  christos /* Pseudo functions used to indicate relocation types (these functions
    545   1.1  christos    start with an at sign (@).  */
    546   1.1  christos static struct
    547   1.1  christos   {
    548   1.1  christos     const char *name;
    549   1.1  christos     enum pseudo_type
    550   1.1  christos       {
    551   1.1  christos 	PSEUDO_FUNC_NONE,
    552   1.1  christos 	PSEUDO_FUNC_RELOC,
    553   1.1  christos 	PSEUDO_FUNC_CONST,
    554   1.1  christos 	PSEUDO_FUNC_REG,
    555   1.1  christos 	PSEUDO_FUNC_FLOAT
    556   1.1  christos       }
    557   1.1  christos     type;
    558   1.1  christos     union
    559   1.1  christos       {
    560   1.1  christos 	unsigned long ival;
    561   1.1  christos 	symbolS *sym;
    562   1.1  christos       }
    563   1.1  christos     u;
    564   1.1  christos   }
    565   1.1  christos pseudo_func[] =
    566   1.1  christos   {
    567   1.1  christos     /* reloc pseudo functions (these must come first!):  */
    568   1.1  christos     { "dtpmod",	PSEUDO_FUNC_RELOC, { 0 } },
    569   1.1  christos     { "dtprel",	PSEUDO_FUNC_RELOC, { 0 } },
    570   1.1  christos     { "fptr",	PSEUDO_FUNC_RELOC, { 0 } },
    571   1.1  christos     { "gprel",	PSEUDO_FUNC_RELOC, { 0 } },
    572   1.1  christos     { "ltoff",	PSEUDO_FUNC_RELOC, { 0 } },
    573   1.1  christos     { "ltoffx",	PSEUDO_FUNC_RELOC, { 0 } },
    574   1.1  christos     { "pcrel",	PSEUDO_FUNC_RELOC, { 0 } },
    575   1.1  christos     { "pltoff",	PSEUDO_FUNC_RELOC, { 0 } },
    576   1.1  christos     { "secrel",	PSEUDO_FUNC_RELOC, { 0 } },
    577   1.1  christos     { "segrel",	PSEUDO_FUNC_RELOC, { 0 } },
    578   1.1  christos     { "tprel",	PSEUDO_FUNC_RELOC, { 0 } },
    579   1.1  christos     { "ltv",	PSEUDO_FUNC_RELOC, { 0 } },
    580   1.1  christos     { NULL, 0, { 0 } },	/* placeholder for FUNC_LT_FPTR_RELATIVE */
    581   1.1  christos     { NULL, 0, { 0 } },	/* placeholder for FUNC_LT_DTP_MODULE */
    582   1.1  christos     { NULL, 0, { 0 } },	/* placeholder for FUNC_LT_DTP_RELATIVE */
    583   1.1  christos     { NULL, 0, { 0 } },	/* placeholder for FUNC_LT_TP_RELATIVE */
    584   1.1  christos     { "iplt",	PSEUDO_FUNC_RELOC, { 0 } },
    585   1.1  christos #ifdef TE_VMS
    586   1.1  christos     { "slotcount", PSEUDO_FUNC_RELOC, { 0 } },
    587   1.1  christos #endif
    588   1.1  christos 
    589   1.1  christos     /* mbtype4 constants:  */
    590   1.1  christos     { "alt",	PSEUDO_FUNC_CONST, { 0xa } },
    591   1.1  christos     { "brcst",	PSEUDO_FUNC_CONST, { 0x0 } },
    592   1.1  christos     { "mix",	PSEUDO_FUNC_CONST, { 0x8 } },
    593   1.1  christos     { "rev",	PSEUDO_FUNC_CONST, { 0xb } },
    594   1.1  christos     { "shuf",	PSEUDO_FUNC_CONST, { 0x9 } },
    595   1.1  christos 
    596   1.1  christos     /* fclass constants:  */
    597   1.1  christos     { "nat",	PSEUDO_FUNC_CONST, { 0x100 } },
    598   1.1  christos     { "qnan",	PSEUDO_FUNC_CONST, { 0x080 } },
    599   1.1  christos     { "snan",	PSEUDO_FUNC_CONST, { 0x040 } },
    600   1.1  christos     { "pos",	PSEUDO_FUNC_CONST, { 0x001 } },
    601   1.1  christos     { "neg",	PSEUDO_FUNC_CONST, { 0x002 } },
    602   1.1  christos     { "zero",	PSEUDO_FUNC_CONST, { 0x004 } },
    603   1.1  christos     { "unorm",	PSEUDO_FUNC_CONST, { 0x008 } },
    604   1.1  christos     { "norm",	PSEUDO_FUNC_CONST, { 0x010 } },
    605   1.1  christos     { "inf",	PSEUDO_FUNC_CONST, { 0x020 } },
    606   1.1  christos 
    607   1.1  christos     { "natval",	PSEUDO_FUNC_CONST, { 0x100 } }, /* old usage */
    608   1.1  christos 
    609   1.1  christos     /* hint constants: */
    610   1.1  christos     { "pause",	PSEUDO_FUNC_CONST, { 0x0 } },
    611   1.1  christos     { "priority", PSEUDO_FUNC_CONST, { 0x1 } },
    612   1.1  christos 
    613   1.1  christos     /* tf constants: */
    614   1.1  christos     { "clz",	PSEUDO_FUNC_CONST, {  32 } },
    615   1.1  christos     { "mpy",	PSEUDO_FUNC_CONST, {  33 } },
    616   1.1  christos     { "datahints",	PSEUDO_FUNC_CONST, {  34 } },
    617   1.1  christos 
    618   1.1  christos     /* unwind-related constants:  */
    619   1.1  christos     { "svr4",	PSEUDO_FUNC_CONST,	{ ELFOSABI_NONE } },
    620   1.1  christos     { "hpux",	PSEUDO_FUNC_CONST,	{ ELFOSABI_HPUX } },
    621   1.1  christos     { "nt",	PSEUDO_FUNC_CONST,	{ 2 } },		/* conflicts w/ELFOSABI_NETBSD */
    622   1.1  christos     { "linux",	PSEUDO_FUNC_CONST,	{ ELFOSABI_GNU } },
    623   1.1  christos     { "freebsd", PSEUDO_FUNC_CONST,	{ ELFOSABI_FREEBSD } },
    624   1.1  christos     { "openvms", PSEUDO_FUNC_CONST,	{ ELFOSABI_OPENVMS } },
    625   1.1  christos     { "nsk",	PSEUDO_FUNC_CONST,	{ ELFOSABI_NSK } },
    626   1.1  christos 
    627   1.1  christos     /* unwind-related registers:  */
    628   1.1  christos     { "priunat",PSEUDO_FUNC_REG, { REG_PRIUNAT } }
    629   1.1  christos   };
    630   1.1  christos 
    631   1.1  christos /* 41-bit nop opcodes (one per unit):  */
    632   1.1  christos static const bfd_vma nop[IA64_NUM_UNITS] =
    633   1.1  christos   {
    634   1.1  christos     0x0000000000LL,	/* NIL => break 0 */
    635   1.1  christos     0x0008000000LL,	/* I-unit nop */
    636   1.1  christos     0x0008000000LL,	/* M-unit nop */
    637   1.1  christos     0x4000000000LL,	/* B-unit nop */
    638   1.1  christos     0x0008000000LL,	/* F-unit nop */
    639   1.1  christos     0x0000000000LL,	/* L-"unit" nop immediate */
    640   1.1  christos     0x0008000000LL,	/* X-unit nop */
    641   1.1  christos   };
    642   1.1  christos 
    643   1.1  christos /* Can't be `const' as it's passed to input routines (which have the
    644   1.1  christos    habit of setting temporary sentinels.  */
    645   1.1  christos static char special_section_name[][20] =
    646   1.1  christos   {
    647   1.9  christos     {".sbss"}, {".sdata"}, {".rodata"}, {".comment"},
    648   1.1  christos     {".IA_64.unwind"}, {".IA_64.unwind_info"},
    649   1.1  christos     {".init_array"}, {".fini_array"}
    650   1.1  christos   };
    651   1.1  christos 
    652   1.1  christos /* The best template for a particular sequence of up to three
    653   1.1  christos    instructions:  */
    654   1.1  christos #define N	IA64_NUM_TYPES
    655   1.1  christos static unsigned char best_template[N][N][N];
    656   1.1  christos #undef N
    657   1.1  christos 
    658   1.1  christos /* Resource dependencies currently in effect */
    659   1.1  christos static struct rsrc {
    660   1.1  christos   int depind;                       /* dependency index */
    661   1.1  christos   const struct ia64_dependency *dependency; /* actual dependency */
    662   1.1  christos   unsigned specific:1,              /* is this a specific bit/regno? */
    663   1.1  christos     link_to_qp_branch:1;           /* will a branch on the same QP clear it?*/
    664   1.1  christos   int index;                        /* specific regno/bit within dependency */
    665   1.1  christos   int note;                         /* optional qualifying note (0 if none) */
    666   1.1  christos #define STATE_NONE 0
    667   1.1  christos #define STATE_STOP 1
    668   1.1  christos #define STATE_SRLZ 2
    669   1.1  christos   int insn_srlz;                    /* current insn serialization state */
    670   1.1  christos   int data_srlz;                    /* current data serialization state */
    671   1.1  christos   int qp_regno;                     /* qualifying predicate for this usage */
    672   1.5  christos   const char *file;                       /* what file marked this dependency */
    673   1.1  christos   unsigned int line;                /* what line marked this dependency */
    674   1.1  christos   struct mem_offset mem_offset;     /* optional memory offset hint */
    675   1.1  christos   enum { CMP_NONE, CMP_OR, CMP_AND } cmp_type; /* OR or AND compare? */
    676   1.1  christos   int path;                         /* corresponding code entry index */
    677   1.1  christos } *regdeps = NULL;
    678   1.1  christos static int regdepslen = 0;
    679   1.1  christos static int regdepstotlen = 0;
    680   1.1  christos static const char *dv_mode[] = { "RAW", "WAW", "WAR" };
    681   1.1  christos static const char *dv_sem[] = { "none", "implied", "impliedf",
    682   1.1  christos 				"data", "instr", "specific", "stop", "other" };
    683   1.1  christos static const char *dv_cmp_type[] = { "none", "OR", "AND" };
    684   1.1  christos 
    685   1.1  christos /* Current state of PR mutexation */
    686   1.1  christos static struct qpmutex {
    687   1.1  christos   valueT prmask;
    688   1.1  christos   int path;
    689   1.1  christos } *qp_mutexes = NULL;          /* QP mutex bitmasks */
    690   1.1  christos static int qp_mutexeslen = 0;
    691   1.1  christos static int qp_mutexestotlen = 0;
    692   1.1  christos static valueT qp_safe_across_calls = 0;
    693   1.1  christos 
    694   1.1  christos /* Current state of PR implications */
    695   1.1  christos static struct qp_imply {
    696   1.1  christos   unsigned p1:6;
    697   1.1  christos   unsigned p2:6;
    698   1.1  christos   unsigned p2_branched:1;
    699   1.1  christos   int path;
    700   1.1  christos } *qp_implies = NULL;
    701   1.1  christos static int qp_implieslen = 0;
    702   1.1  christos static int qp_impliestotlen = 0;
    703   1.1  christos 
    704   1.1  christos /* Keep track of static GR values so that indirect register usage can
    705   1.1  christos    sometimes be tracked.  */
    706   1.1  christos static struct gr {
    707   1.1  christos   unsigned known:1;
    708   1.1  christos   int path;
    709   1.1  christos   valueT value;
    710   1.1  christos } gr_values[128] = {
    711   1.1  christos   {
    712   1.1  christos     1,
    713   1.1  christos #ifdef INT_MAX
    714   1.1  christos     INT_MAX,
    715   1.1  christos #else
    716   1.1  christos     (((1 << (8 * sizeof(gr_values->path) - 2)) - 1) << 1) + 1,
    717   1.1  christos #endif
    718   1.1  christos     0
    719   1.1  christos   }
    720   1.1  christos };
    721   1.1  christos 
    722   1.1  christos /* Remember the alignment frag.  */
    723   1.1  christos static fragS *align_frag;
    724   1.1  christos 
    725   1.1  christos /* These are the routines required to output the various types of
    726   1.1  christos    unwind records.  */
    727   1.1  christos 
    728   1.1  christos /* A slot_number is a frag address plus the slot index (0-2).  We use the
    729   1.1  christos    frag address here so that if there is a section switch in the middle of
    730   1.1  christos    a function, then instructions emitted to a different section are not
    731   1.1  christos    counted.  Since there may be more than one frag for a function, this
    732   1.1  christos    means we also need to keep track of which frag this address belongs to
    733   1.1  christos    so we can compute inter-frag distances.  This also nicely solves the
    734   1.1  christos    problem with nops emitted for align directives, which can't easily be
    735   1.1  christos    counted, but can easily be derived from frag sizes.  */
    736   1.1  christos 
    737   1.1  christos typedef struct unw_rec_list {
    738   1.1  christos   unwind_record r;
    739   1.1  christos   unsigned long slot_number;
    740   1.1  christos   fragS *slot_frag;
    741   1.1  christos   struct unw_rec_list *next;
    742   1.1  christos } unw_rec_list;
    743   1.1  christos 
    744  1.10  christos #define SLOT_NUM_NOT_SET        -1UL
    745   1.1  christos 
    746   1.1  christos /* Linked list of saved prologue counts.  A very poor
    747   1.1  christos    implementation of a map from label numbers to prologue counts.  */
    748   1.1  christos typedef struct label_prologue_count
    749   1.1  christos {
    750   1.1  christos   struct label_prologue_count *next;
    751   1.1  christos   unsigned long label_number;
    752   1.1  christos   unsigned int prologue_count;
    753   1.1  christos } label_prologue_count;
    754   1.1  christos 
    755   1.1  christos typedef struct proc_pending
    756   1.1  christos {
    757   1.1  christos   symbolS *sym;
    758   1.1  christos   struct proc_pending *next;
    759   1.1  christos } proc_pending;
    760   1.1  christos 
    761   1.1  christos static struct
    762   1.1  christos {
    763   1.1  christos   /* Maintain a list of unwind entries for the current function.  */
    764   1.1  christos   unw_rec_list *list;
    765   1.1  christos   unw_rec_list *tail;
    766   1.1  christos 
    767   1.1  christos   /* Any unwind entries that should be attached to the current slot
    768   1.1  christos      that an insn is being constructed for.  */
    769   1.1  christos   unw_rec_list *current_entry;
    770   1.1  christos 
    771   1.1  christos   /* These are used to create the unwind table entry for this function.  */
    772   1.1  christos   proc_pending proc_pending;
    773   1.1  christos   symbolS *info;		/* pointer to unwind info */
    774   1.1  christos   symbolS *personality_routine;
    775   1.1  christos   segT saved_text_seg;
    776   1.1  christos   subsegT saved_text_subseg;
    777   1.1  christos   unsigned int force_unwind_entry : 1;	/* force generation of unwind entry? */
    778   1.1  christos 
    779   1.1  christos   /* TRUE if processing unwind directives in a prologue region.  */
    780   1.1  christos   unsigned int prologue : 1;
    781   1.1  christos   unsigned int prologue_mask : 4;
    782   1.1  christos   unsigned int prologue_gr : 7;
    783   1.1  christos   unsigned int body : 1;
    784   1.1  christos   unsigned int insn : 1;
    785   1.1  christos   unsigned int prologue_count;	/* number of .prologues seen so far */
    786   1.1  christos   /* Prologue counts at previous .label_state directives.  */
    787   1.1  christos   struct label_prologue_count * saved_prologue_counts;
    788   1.1  christos 
    789   1.1  christos   /* List of split up .save-s.  */
    790   1.1  christos   unw_p_record *pending_saves;
    791   1.1  christos } unwind;
    792   1.1  christos 
    793   1.1  christos /* The input value is a negated offset from psp, and specifies an address
    794   1.1  christos    psp - offset.  The encoded value is psp + 16 - (4 * offset).  Thus we
    795   1.1  christos    must add 16 and divide by 4 to get the encoded value.  */
    796   1.1  christos 
    797   1.1  christos #define ENCODED_PSP_OFFSET(OFFSET) (((OFFSET) + 16) / 4)
    798   1.1  christos 
    799   1.1  christos typedef void (*vbyte_func) (int, char *, char *);
    800   1.1  christos 
    801   1.1  christos /* Forward declarations:  */
    802   1.1  christos static void dot_alias (int);
    803   1.1  christos static int parse_operand_and_eval (expressionS *, int);
    804   1.1  christos static void emit_one_bundle (void);
    805   1.1  christos static bfd_reloc_code_real_type ia64_gen_real_reloc_type (struct symbol *,
    806   1.1  christos 							  bfd_reloc_code_real_type);
    807   1.1  christos static void insn_group_break (int, int, int);
    808   1.1  christos static void add_qp_mutex (valueT);
    809   1.1  christos static void add_qp_imply (int, int);
    810   1.1  christos static void clear_qp_mutex (valueT);
    811   1.1  christos static void clear_qp_implies (valueT, valueT);
    812   1.1  christos static void print_dependency (const char *, int);
    813   1.1  christos static void instruction_serialization (void);
    814   1.1  christos static void data_serialization (void);
    815   1.1  christos static void output_R3_format (vbyte_func, unw_record_type, unsigned long);
    816   1.1  christos static void output_B3_format (vbyte_func, unsigned long, unsigned long);
    817   1.1  christos static void output_B4_format (vbyte_func, unw_record_type, unsigned long);
    818   1.1  christos static void free_saved_prologue_counts (void);
    819   1.1  christos 
    820   1.1  christos /* Determine if application register REGNUM resides only in the integer
    821   1.1  christos    unit (as opposed to the memory unit).  */
    822   1.1  christos static int
    823   1.1  christos ar_is_only_in_integer_unit (int reg)
    824   1.1  christos {
    825   1.1  christos   reg -= REG_AR;
    826   1.1  christos   return reg >= 64 && reg <= 111;
    827   1.1  christos }
    828   1.1  christos 
    829   1.3  christos /* Determine if application register REGNUM resides only in the memory
    830   1.1  christos    unit (as opposed to the integer unit).  */
    831   1.1  christos static int
    832   1.1  christos ar_is_only_in_memory_unit (int reg)
    833   1.1  christos {
    834   1.1  christos   reg -= REG_AR;
    835   1.1  christos   return reg >= 0 && reg <= 47;
    836   1.1  christos }
    837   1.1  christos 
    838   1.1  christos /* Switch to section NAME and create section if necessary.  It's
    839   1.1  christos    rather ugly that we have to manipulate input_line_pointer but I
    840   1.1  christos    don't see any other way to accomplish the same thing without
    841   1.1  christos    changing obj-elf.c (which may be the Right Thing, in the end).  */
    842   1.1  christos static void
    843   1.1  christos set_section (char *name)
    844   1.1  christos {
    845   1.1  christos   char *saved_input_line_pointer;
    846   1.1  christos 
    847   1.1  christos   saved_input_line_pointer = input_line_pointer;
    848   1.1  christos   input_line_pointer = name;
    849   1.1  christos   obj_elf_section (0);
    850   1.1  christos   input_line_pointer = saved_input_line_pointer;
    851   1.1  christos }
    852   1.1  christos 
    853   1.1  christos /* Map 's' to SHF_IA_64_SHORT.  */
    854   1.1  christos 
    855   1.1  christos bfd_vma
    856   1.5  christos ia64_elf_section_letter (int letter, const char **ptr_msg)
    857   1.1  christos {
    858   1.1  christos   if (letter == 's')
    859   1.1  christos     return SHF_IA_64_SHORT;
    860   1.1  christos   else if (letter == 'o')
    861   1.1  christos     return SHF_LINK_ORDER;
    862   1.1  christos #ifdef TE_VMS
    863   1.1  christos   else if (letter == 'O')
    864   1.1  christos     return SHF_IA_64_VMS_OVERLAID;
    865   1.1  christos   else if (letter == 'g')
    866   1.1  christos     return SHF_IA_64_VMS_GLOBAL;
    867   1.1  christos #endif
    868   1.1  christos 
    869   1.1  christos   *ptr_msg = _("bad .section directive: want a,o,s,w,x,M,S,G,T in string");
    870   1.1  christos   return -1;
    871   1.1  christos }
    872   1.1  christos 
    873   1.1  christos /* Map SHF_IA_64_SHORT to SEC_SMALL_DATA.  */
    874   1.1  christos 
    875   1.1  christos flagword
    876   1.1  christos ia64_elf_section_flags (flagword flags,
    877   1.1  christos 			bfd_vma attr,
    878   1.1  christos 			int type ATTRIBUTE_UNUSED)
    879   1.1  christos {
    880   1.1  christos   if (attr & SHF_IA_64_SHORT)
    881   1.1  christos     flags |= SEC_SMALL_DATA;
    882   1.1  christos   return flags;
    883   1.1  christos }
    884   1.1  christos 
    885   1.1  christos int
    886   1.1  christos ia64_elf_section_type (const char *str, size_t len)
    887   1.1  christos {
    888   1.1  christos #define STREQ(s) ((len == sizeof (s) - 1) && (strncmp (str, s, sizeof (s) - 1) == 0))
    889   1.1  christos 
    890   1.1  christos   if (STREQ (ELF_STRING_ia64_unwind_info))
    891   1.1  christos     return SHT_PROGBITS;
    892   1.1  christos 
    893   1.1  christos   if (STREQ (ELF_STRING_ia64_unwind_info_once))
    894   1.1  christos     return SHT_PROGBITS;
    895   1.1  christos 
    896   1.1  christos   if (STREQ (ELF_STRING_ia64_unwind))
    897   1.1  christos     return SHT_IA_64_UNWIND;
    898   1.1  christos 
    899   1.1  christos   if (STREQ (ELF_STRING_ia64_unwind_once))
    900   1.1  christos     return SHT_IA_64_UNWIND;
    901   1.1  christos 
    902   1.1  christos   if (STREQ ("unwind"))
    903   1.1  christos     return SHT_IA_64_UNWIND;
    904   1.1  christos 
    905   1.1  christos   return -1;
    906   1.1  christos #undef STREQ
    907   1.1  christos }
    908   1.1  christos 
    909   1.1  christos static unsigned int
    910   1.1  christos set_regstack (unsigned int ins,
    911   1.1  christos 	      unsigned int locs,
    912   1.1  christos 	      unsigned int outs,
    913   1.1  christos 	      unsigned int rots)
    914   1.1  christos {
    915   1.1  christos   /* Size of frame.  */
    916   1.1  christos   unsigned int sof;
    917   1.1  christos 
    918   1.1  christos   sof = ins + locs + outs;
    919   1.1  christos   if (sof > 96)
    920   1.1  christos     {
    921   1.1  christos       as_bad (_("Size of frame exceeds maximum of 96 registers"));
    922   1.1  christos       return 0;
    923   1.1  christos     }
    924   1.1  christos   if (rots > sof)
    925   1.1  christos     {
    926   1.1  christos       as_warn (_("Size of rotating registers exceeds frame size"));
    927   1.1  christos       return 0;
    928   1.1  christos     }
    929   1.1  christos   md.in.base = REG_GR + 32;
    930   1.1  christos   md.loc.base = md.in.base + ins;
    931   1.1  christos   md.out.base = md.loc.base + locs;
    932   1.1  christos 
    933   1.1  christos   md.in.num_regs  = ins;
    934   1.1  christos   md.loc.num_regs = locs;
    935   1.1  christos   md.out.num_regs = outs;
    936   1.1  christos   md.rot.num_regs = rots;
    937   1.1  christos   return sof;
    938   1.1  christos }
    939   1.1  christos 
    940   1.1  christos void
    941   1.1  christos ia64_flush_insns (void)
    942   1.1  christos {
    943   1.1  christos   struct label_fix *lfix;
    944   1.1  christos   segT saved_seg;
    945   1.1  christos   subsegT saved_subseg;
    946   1.1  christos   unw_rec_list *ptr;
    947   1.8  christos   bool mark;
    948   1.1  christos 
    949   1.1  christos   if (!md.last_text_seg)
    950   1.1  christos     return;
    951   1.1  christos 
    952   1.1  christos   saved_seg = now_seg;
    953   1.1  christos   saved_subseg = now_subseg;
    954   1.1  christos 
    955   1.8  christos   subseg_set (md.last_text_seg, md.last_text_subseg);
    956   1.1  christos 
    957   1.1  christos   while (md.num_slots_in_use > 0)
    958   1.1  christos     emit_one_bundle ();		/* force out queued instructions */
    959   1.1  christos 
    960   1.1  christos   /* In case there are labels following the last instruction, resolve
    961   1.1  christos      those now.  */
    962   1.8  christos   mark = false;
    963   1.1  christos   for (lfix = CURR_SLOT.label_fixups; lfix; lfix = lfix->next)
    964   1.1  christos     {
    965   1.1  christos       symbol_set_value_now (lfix->sym);
    966   1.1  christos       mark |= lfix->dw2_mark_labels;
    967   1.1  christos     }
    968   1.1  christos   if (mark)
    969   1.1  christos     {
    970   1.1  christos       dwarf2_where (&CURR_SLOT.debug_line);
    971   1.1  christos       CURR_SLOT.debug_line.flags |= DWARF2_FLAG_BASIC_BLOCK;
    972   1.1  christos       dwarf2_gen_line_info (frag_now_fix (), &CURR_SLOT.debug_line);
    973   1.1  christos       dwarf2_consume_line_info ();
    974   1.1  christos     }
    975   1.1  christos   CURR_SLOT.label_fixups = 0;
    976   1.1  christos 
    977   1.1  christos   for (lfix = CURR_SLOT.tag_fixups; lfix; lfix = lfix->next)
    978   1.1  christos     symbol_set_value_now (lfix->sym);
    979   1.1  christos   CURR_SLOT.tag_fixups = 0;
    980   1.1  christos 
    981   1.1  christos   /* In case there are unwind directives following the last instruction,
    982   1.1  christos      resolve those now.  We only handle prologue, body, and endp directives
    983   1.1  christos      here.  Give an error for others.  */
    984   1.1  christos   for (ptr = unwind.current_entry; ptr; ptr = ptr->next)
    985   1.1  christos     {
    986   1.1  christos       switch (ptr->r.type)
    987   1.1  christos 	{
    988   1.1  christos 	case prologue:
    989   1.1  christos 	case prologue_gr:
    990   1.1  christos 	case body:
    991   1.1  christos 	case endp:
    992   1.1  christos 	  ptr->slot_number = (unsigned long) frag_more (0);
    993   1.1  christos 	  ptr->slot_frag = frag_now;
    994   1.1  christos 	  break;
    995   1.1  christos 
    996   1.1  christos 	  /* Allow any record which doesn't have a "t" field (i.e.,
    997   1.1  christos 	     doesn't relate to a particular instruction).  */
    998   1.1  christos 	case unwabi:
    999   1.1  christos 	case br_gr:
   1000   1.1  christos 	case copy_state:
   1001   1.1  christos 	case fr_mem:
   1002   1.1  christos 	case frgr_mem:
   1003   1.1  christos 	case gr_gr:
   1004   1.1  christos 	case gr_mem:
   1005   1.1  christos 	case label_state:
   1006   1.1  christos 	case rp_br:
   1007   1.1  christos 	case spill_base:
   1008   1.1  christos 	case spill_mask:
   1009   1.1  christos 	  /* nothing */
   1010   1.1  christos 	  break;
   1011   1.1  christos 
   1012   1.1  christos 	default:
   1013   1.1  christos 	  as_bad (_("Unwind directive not followed by an instruction."));
   1014   1.1  christos 	  break;
   1015   1.1  christos 	}
   1016   1.1  christos     }
   1017   1.1  christos   unwind.current_entry = NULL;
   1018   1.1  christos 
   1019   1.1  christos   subseg_set (saved_seg, saved_subseg);
   1020   1.1  christos 
   1021   1.1  christos   if (md.qp.X_op == O_register)
   1022   1.1  christos     as_bad (_("qualifying predicate not followed by instruction"));
   1023   1.1  christos }
   1024   1.1  christos 
   1025   1.1  christos void
   1026   1.1  christos ia64_cons_align (int nbytes)
   1027   1.1  christos {
   1028   1.1  christos   if (md.auto_align)
   1029   1.1  christos     {
   1030   1.5  christos       int log;
   1031   1.5  christos       for (log = 0; (nbytes & 1) != 1; nbytes >>= 1)
   1032   1.5  christos 	log++;
   1033   1.5  christos 
   1034   1.5  christos       do_align (log, NULL, 0, 0);
   1035   1.1  christos     }
   1036   1.1  christos }
   1037   1.1  christos 
   1038   1.1  christos #ifdef TE_VMS
   1039   1.1  christos 
   1040   1.1  christos /* .vms_common section, symbol, size, alignment  */
   1041   1.1  christos 
   1042   1.1  christos static void
   1043   1.1  christos obj_elf_vms_common (int ignore ATTRIBUTE_UNUSED)
   1044   1.1  christos {
   1045   1.5  christos   const char *sec_name;
   1046   1.1  christos   char *sym_name;
   1047   1.1  christos   char c;
   1048  1.10  christos   valueT size;
   1049  1.10  christos   valueT cur_size;
   1050  1.10  christos   valueT temp;
   1051   1.1  christos   symbolS *symbolP;
   1052   1.1  christos   segT current_seg = now_seg;
   1053   1.1  christos   subsegT current_subseg = now_subseg;
   1054   1.1  christos   offsetT log_align;
   1055   1.1  christos 
   1056   1.1  christos   /* Section name.  */
   1057   1.1  christos   sec_name = obj_elf_section_name ();
   1058   1.1  christos   if (sec_name == NULL)
   1059   1.1  christos     return;
   1060   1.1  christos 
   1061   1.1  christos   /* Symbol name.  */
   1062   1.1  christos   SKIP_WHITESPACE ();
   1063   1.1  christos   if (*input_line_pointer == ',')
   1064   1.1  christos     {
   1065   1.1  christos       input_line_pointer++;
   1066   1.1  christos       SKIP_WHITESPACE ();
   1067   1.1  christos     }
   1068   1.1  christos   else
   1069   1.1  christos     {
   1070   1.1  christos       as_bad (_("expected ',' after section name"));
   1071   1.1  christos       ignore_rest_of_line ();
   1072   1.1  christos       return;
   1073   1.1  christos     }
   1074   1.1  christos 
   1075   1.3  christos   c = get_symbol_name (&sym_name);
   1076   1.1  christos 
   1077   1.1  christos   if (input_line_pointer == sym_name)
   1078   1.1  christos     {
   1079   1.3  christos       (void) restore_line_pointer (c);
   1080   1.1  christos       as_bad (_("expected symbol name"));
   1081   1.1  christos       ignore_rest_of_line ();
   1082   1.1  christos       return;
   1083   1.1  christos     }
   1084   1.1  christos 
   1085   1.1  christos   symbolP = symbol_find_or_make (sym_name);
   1086   1.3  christos   (void) restore_line_pointer (c);
   1087   1.1  christos 
   1088   1.1  christos   if ((S_IS_DEFINED (symbolP) || symbol_equated_p (symbolP))
   1089   1.1  christos       && !S_IS_COMMON (symbolP))
   1090   1.1  christos     {
   1091   1.1  christos       as_bad (_("Ignoring attempt to re-define symbol"));
   1092   1.1  christos       ignore_rest_of_line ();
   1093   1.1  christos       return;
   1094   1.1  christos     }
   1095   1.1  christos 
   1096   1.1  christos   /* Symbol size.  */
   1097   1.1  christos   SKIP_WHITESPACE ();
   1098   1.1  christos   if (*input_line_pointer == ',')
   1099   1.1  christos     {
   1100   1.1  christos       input_line_pointer++;
   1101   1.1  christos       SKIP_WHITESPACE ();
   1102   1.1  christos     }
   1103   1.1  christos   else
   1104   1.1  christos     {
   1105   1.1  christos       as_bad (_("expected ',' after symbol name"));
   1106   1.1  christos       ignore_rest_of_line ();
   1107   1.1  christos       return;
   1108   1.1  christos     }
   1109   1.1  christos 
   1110   1.1  christos   temp = get_absolute_expression ();
   1111   1.1  christos   size = temp;
   1112  1.10  christos   size &= ((valueT) 2 << (stdoutput->arch_info->bits_per_address - 1)) - 1;
   1113   1.1  christos   if (temp != size)
   1114   1.1  christos     {
   1115   1.1  christos       as_warn (_("size (%ld) out of range, ignored"), (long) temp);
   1116   1.1  christos       ignore_rest_of_line ();
   1117   1.1  christos       return;
   1118   1.1  christos     }
   1119   1.1  christos 
   1120   1.1  christos   /* Alignment.  */
   1121   1.1  christos   SKIP_WHITESPACE ();
   1122   1.1  christos   if (*input_line_pointer == ',')
   1123   1.1  christos     {
   1124   1.1  christos       input_line_pointer++;
   1125   1.1  christos       SKIP_WHITESPACE ();
   1126   1.1  christos     }
   1127   1.1  christos   else
   1128   1.1  christos     {
   1129   1.1  christos       as_bad (_("expected ',' after symbol size"));
   1130   1.1  christos       ignore_rest_of_line ();
   1131   1.1  christos       return;
   1132   1.1  christos     }
   1133   1.1  christos 
   1134   1.1  christos   log_align = get_absolute_expression ();
   1135   1.1  christos 
   1136   1.1  christos   demand_empty_rest_of_line ();
   1137   1.1  christos 
   1138   1.1  christos   obj_elf_change_section
   1139   1.8  christos     (sec_name, SHT_NOBITS,
   1140   1.1  christos      SHF_ALLOC | SHF_WRITE | SHF_IA_64_VMS_OVERLAID | SHF_IA_64_VMS_GLOBAL,
   1141   1.9  christos      0, NULL, true);
   1142   1.1  christos 
   1143   1.1  christos   S_SET_VALUE (symbolP, 0);
   1144   1.1  christos   S_SET_SIZE (symbolP, size);
   1145   1.1  christos   S_SET_EXTERNAL (symbolP);
   1146   1.1  christos   S_SET_SEGMENT (symbolP, now_seg);
   1147   1.1  christos 
   1148   1.1  christos   symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
   1149   1.1  christos 
   1150   1.1  christos   record_alignment (now_seg, log_align);
   1151   1.1  christos 
   1152   1.7  christos   cur_size = bfd_section_size (now_seg);
   1153  1.10  christos   if (size > cur_size)
   1154   1.1  christos     {
   1155  1.10  christos       char *pfrag = frag_var (rs_fill, 1, 1, 0, NULL, size - cur_size, NULL);
   1156   1.1  christos       *pfrag = 0;
   1157   1.7  christos       bfd_set_section_size (now_seg, size);
   1158   1.1  christos     }
   1159   1.1  christos 
   1160   1.1  christos   /* Switch back to current segment.  */
   1161   1.1  christos   subseg_set (current_seg, current_subseg);
   1162   1.1  christos 
   1163   1.1  christos #ifdef md_elf_section_change_hook
   1164   1.1  christos   md_elf_section_change_hook ();
   1165   1.1  christos #endif
   1166   1.1  christos }
   1167   1.1  christos 
   1168   1.1  christos #endif /* TE_VMS */
   1169   1.1  christos 
   1170   1.1  christos /* Output COUNT bytes to a memory location.  */
   1171   1.1  christos static char *vbyte_mem_ptr = NULL;
   1172   1.1  christos 
   1173   1.1  christos static void
   1174   1.1  christos output_vbyte_mem (int count, char *ptr, char *comment ATTRIBUTE_UNUSED)
   1175   1.1  christos {
   1176   1.1  christos   int x;
   1177   1.1  christos   if (vbyte_mem_ptr == NULL)
   1178   1.1  christos     abort ();
   1179   1.1  christos 
   1180   1.1  christos   if (count == 0)
   1181   1.1  christos     return;
   1182   1.1  christos   for (x = 0; x < count; x++)
   1183   1.1  christos     *(vbyte_mem_ptr++) = ptr[x];
   1184   1.1  christos }
   1185   1.1  christos 
   1186   1.1  christos /* Count the number of bytes required for records.  */
   1187   1.1  christos static int vbyte_count = 0;
   1188   1.1  christos static void
   1189   1.1  christos count_output (int count,
   1190   1.1  christos 	      char *ptr ATTRIBUTE_UNUSED,
   1191   1.1  christos 	      char *comment ATTRIBUTE_UNUSED)
   1192   1.1  christos {
   1193   1.1  christos   vbyte_count += count;
   1194   1.1  christos }
   1195   1.1  christos 
   1196   1.1  christos static void
   1197   1.1  christos output_R1_format (vbyte_func f, unw_record_type rtype, int rlen)
   1198   1.1  christos {
   1199   1.1  christos   int r = 0;
   1200   1.1  christos   char byte;
   1201   1.1  christos   if (rlen > 0x1f)
   1202   1.1  christos     {
   1203   1.1  christos       output_R3_format (f, rtype, rlen);
   1204   1.1  christos       return;
   1205   1.1  christos     }
   1206   1.1  christos 
   1207   1.1  christos   if (rtype == body)
   1208   1.1  christos     r = 1;
   1209   1.1  christos   else if (rtype != prologue)
   1210   1.1  christos     as_bad (_("record type is not valid"));
   1211   1.1  christos 
   1212   1.1  christos   byte = UNW_R1 | (r << 5) | (rlen & 0x1f);
   1213   1.1  christos   (*f) (1, &byte, NULL);
   1214   1.1  christos }
   1215   1.1  christos 
   1216   1.1  christos static void
   1217   1.1  christos output_R2_format (vbyte_func f, int mask, int grsave, unsigned long rlen)
   1218   1.1  christos {
   1219   1.1  christos   char bytes[20];
   1220   1.1  christos   int count = 2;
   1221   1.1  christos   mask = (mask & 0x0f);
   1222   1.1  christos   grsave = (grsave & 0x7f);
   1223   1.1  christos 
   1224   1.1  christos   bytes[0] = (UNW_R2 | (mask >> 1));
   1225   1.1  christos   bytes[1] = (((mask & 0x01) << 7) | grsave);
   1226   1.1  christos   count += output_leb128 (bytes + 2, rlen, 0);
   1227   1.1  christos   (*f) (count, bytes, NULL);
   1228   1.1  christos }
   1229   1.1  christos 
   1230   1.1  christos static void
   1231   1.1  christos output_R3_format (vbyte_func f, unw_record_type rtype, unsigned long rlen)
   1232   1.1  christos {
   1233   1.1  christos   int r = 0, count;
   1234   1.1  christos   char bytes[20];
   1235   1.1  christos   if (rlen <= 0x1f)
   1236   1.1  christos     {
   1237   1.1  christos       output_R1_format (f, rtype, rlen);
   1238   1.1  christos       return;
   1239   1.1  christos     }
   1240   1.1  christos 
   1241   1.1  christos   if (rtype == body)
   1242   1.1  christos     r = 1;
   1243   1.1  christos   else if (rtype != prologue)
   1244   1.1  christos     as_bad (_("record type is not valid"));
   1245   1.1  christos   bytes[0] = (UNW_R3 | r);
   1246   1.1  christos   count = output_leb128 (bytes + 1, rlen, 0);
   1247   1.1  christos   (*f) (count + 1, bytes, NULL);
   1248   1.1  christos }
   1249   1.1  christos 
   1250   1.1  christos static void
   1251   1.1  christos output_P1_format (vbyte_func f, int brmask)
   1252   1.1  christos {
   1253   1.1  christos   char byte;
   1254   1.1  christos   byte = UNW_P1 | (brmask & 0x1f);
   1255   1.1  christos   (*f) (1, &byte, NULL);
   1256   1.1  christos }
   1257   1.1  christos 
   1258   1.1  christos static void
   1259   1.1  christos output_P2_format (vbyte_func f, int brmask, int gr)
   1260   1.1  christos {
   1261   1.1  christos   char bytes[2];
   1262   1.1  christos   brmask = (brmask & 0x1f);
   1263   1.1  christos   bytes[0] = UNW_P2 | (brmask >> 1);
   1264   1.1  christos   bytes[1] = (((brmask & 1) << 7) | gr);
   1265   1.1  christos   (*f) (2, bytes, NULL);
   1266   1.1  christos }
   1267   1.1  christos 
   1268   1.1  christos static void
   1269   1.1  christos output_P3_format (vbyte_func f, unw_record_type rtype, int reg)
   1270   1.1  christos {
   1271   1.1  christos   char bytes[2];
   1272   1.1  christos   int r = 0;
   1273   1.1  christos   reg = (reg & 0x7f);
   1274   1.1  christos   switch (rtype)
   1275   1.1  christos     {
   1276   1.1  christos     case psp_gr:
   1277   1.1  christos       r = 0;
   1278   1.1  christos       break;
   1279   1.1  christos     case rp_gr:
   1280   1.1  christos       r = 1;
   1281   1.1  christos       break;
   1282   1.1  christos     case pfs_gr:
   1283   1.1  christos       r = 2;
   1284   1.1  christos       break;
   1285   1.1  christos     case preds_gr:
   1286   1.1  christos       r = 3;
   1287   1.1  christos       break;
   1288   1.1  christos     case unat_gr:
   1289   1.1  christos       r = 4;
   1290   1.1  christos       break;
   1291   1.1  christos     case lc_gr:
   1292   1.1  christos       r = 5;
   1293   1.1  christos       break;
   1294   1.1  christos     case rp_br:
   1295   1.1  christos       r = 6;
   1296   1.1  christos       break;
   1297   1.1  christos     case rnat_gr:
   1298   1.1  christos       r = 7;
   1299   1.1  christos       break;
   1300   1.1  christos     case bsp_gr:
   1301   1.1  christos       r = 8;
   1302   1.1  christos       break;
   1303   1.1  christos     case bspstore_gr:
   1304   1.1  christos       r = 9;
   1305   1.1  christos       break;
   1306   1.1  christos     case fpsr_gr:
   1307   1.1  christos       r = 10;
   1308   1.1  christos       break;
   1309   1.1  christos     case priunat_gr:
   1310   1.1  christos       r = 11;
   1311   1.1  christos       break;
   1312   1.1  christos     default:
   1313   1.1  christos       as_bad (_("Invalid record type for P3 format."));
   1314   1.1  christos     }
   1315   1.1  christos   bytes[0] = (UNW_P3 | (r >> 1));
   1316   1.1  christos   bytes[1] = (((r & 1) << 7) | reg);
   1317   1.1  christos   (*f) (2, bytes, NULL);
   1318   1.1  christos }
   1319   1.1  christos 
   1320   1.1  christos static void
   1321   1.1  christos output_P4_format (vbyte_func f, unsigned char *imask, unsigned long imask_size)
   1322   1.1  christos {
   1323   1.1  christos   imask[0] = UNW_P4;
   1324   1.1  christos   (*f) (imask_size, (char *) imask, NULL);
   1325   1.1  christos }
   1326   1.1  christos 
   1327   1.1  christos static void
   1328   1.1  christos output_P5_format (vbyte_func f, int grmask, unsigned long frmask)
   1329   1.1  christos {
   1330   1.1  christos   char bytes[4];
   1331   1.1  christos   grmask = (grmask & 0x0f);
   1332   1.1  christos 
   1333   1.1  christos   bytes[0] = UNW_P5;
   1334   1.1  christos   bytes[1] = ((grmask << 4) | ((frmask & 0x000f0000) >> 16));
   1335   1.1  christos   bytes[2] = ((frmask & 0x0000ff00) >> 8);
   1336   1.1  christos   bytes[3] = (frmask & 0x000000ff);
   1337   1.1  christos   (*f) (4, bytes, NULL);
   1338   1.1  christos }
   1339   1.1  christos 
   1340   1.1  christos static void
   1341   1.1  christos output_P6_format (vbyte_func f, unw_record_type rtype, int rmask)
   1342   1.1  christos {
   1343   1.1  christos   char byte;
   1344   1.1  christos   int r = 0;
   1345   1.1  christos 
   1346   1.1  christos   if (rtype == gr_mem)
   1347   1.1  christos     r = 1;
   1348   1.1  christos   else if (rtype != fr_mem)
   1349   1.1  christos     as_bad (_("Invalid record type for format P6"));
   1350   1.1  christos   byte = (UNW_P6 | (r << 4) | (rmask & 0x0f));
   1351   1.1  christos   (*f) (1, &byte, NULL);
   1352   1.1  christos }
   1353   1.1  christos 
   1354   1.1  christos static void
   1355   1.1  christos output_P7_format (vbyte_func f,
   1356   1.1  christos 		  unw_record_type rtype,
   1357   1.1  christos 		  unsigned long w1,
   1358   1.1  christos 		  unsigned long w2)
   1359   1.1  christos {
   1360   1.1  christos   char bytes[20];
   1361   1.1  christos   int count = 1;
   1362   1.1  christos   int r = 0;
   1363   1.1  christos   count += output_leb128 (bytes + 1, w1, 0);
   1364   1.1  christos   switch (rtype)
   1365   1.1  christos     {
   1366   1.1  christos     case mem_stack_f:
   1367   1.1  christos       r = 0;
   1368   1.1  christos       count += output_leb128 (bytes + count, w2 >> 4, 0);
   1369   1.1  christos       break;
   1370   1.1  christos     case mem_stack_v:
   1371   1.1  christos       r = 1;
   1372   1.1  christos       break;
   1373   1.1  christos     case spill_base:
   1374   1.1  christos       r = 2;
   1375   1.1  christos       break;
   1376   1.1  christos     case psp_sprel:
   1377   1.1  christos       r = 3;
   1378   1.1  christos       break;
   1379   1.1  christos     case rp_when:
   1380   1.1  christos       r = 4;
   1381   1.1  christos       break;
   1382   1.1  christos     case rp_psprel:
   1383   1.1  christos       r = 5;
   1384   1.1  christos       break;
   1385   1.1  christos     case pfs_when:
   1386   1.1  christos       r = 6;
   1387   1.1  christos       break;
   1388   1.1  christos     case pfs_psprel:
   1389   1.1  christos       r = 7;
   1390   1.1  christos       break;
   1391   1.1  christos     case preds_when:
   1392   1.1  christos       r = 8;
   1393   1.1  christos       break;
   1394   1.1  christos     case preds_psprel:
   1395   1.1  christos       r = 9;
   1396   1.1  christos       break;
   1397   1.1  christos     case lc_when:
   1398   1.1  christos       r = 10;
   1399   1.1  christos       break;
   1400   1.1  christos     case lc_psprel:
   1401   1.1  christos       r = 11;
   1402   1.1  christos       break;
   1403   1.1  christos     case unat_when:
   1404   1.1  christos       r = 12;
   1405   1.1  christos       break;
   1406   1.1  christos     case unat_psprel:
   1407   1.1  christos       r = 13;
   1408   1.1  christos       break;
   1409   1.1  christos     case fpsr_when:
   1410   1.1  christos       r = 14;
   1411   1.1  christos       break;
   1412   1.1  christos     case fpsr_psprel:
   1413   1.1  christos       r = 15;
   1414   1.1  christos       break;
   1415   1.1  christos     default:
   1416   1.1  christos       break;
   1417   1.1  christos     }
   1418   1.1  christos   bytes[0] = (UNW_P7 | r);
   1419   1.1  christos   (*f) (count, bytes, NULL);
   1420   1.1  christos }
   1421   1.1  christos 
   1422   1.1  christos static void
   1423   1.1  christos output_P8_format (vbyte_func f, unw_record_type rtype, unsigned long t)
   1424   1.1  christos {
   1425   1.1  christos   char bytes[20];
   1426   1.1  christos   int r = 0;
   1427   1.1  christos   int count = 2;
   1428   1.1  christos   bytes[0] = UNW_P8;
   1429   1.1  christos   switch (rtype)
   1430   1.1  christos     {
   1431   1.1  christos     case rp_sprel:
   1432   1.1  christos       r = 1;
   1433   1.1  christos       break;
   1434   1.1  christos     case pfs_sprel:
   1435   1.1  christos       r = 2;
   1436   1.1  christos       break;
   1437   1.1  christos     case preds_sprel:
   1438   1.1  christos       r = 3;
   1439   1.1  christos       break;
   1440   1.1  christos     case lc_sprel:
   1441   1.1  christos       r = 4;
   1442   1.1  christos       break;
   1443   1.1  christos     case unat_sprel:
   1444   1.1  christos       r = 5;
   1445   1.1  christos       break;
   1446   1.1  christos     case fpsr_sprel:
   1447   1.1  christos       r = 6;
   1448   1.1  christos       break;
   1449   1.1  christos     case bsp_when:
   1450   1.1  christos       r = 7;
   1451   1.1  christos       break;
   1452   1.1  christos     case bsp_psprel:
   1453   1.1  christos       r = 8;
   1454   1.1  christos       break;
   1455   1.1  christos     case bsp_sprel:
   1456   1.1  christos       r = 9;
   1457   1.1  christos       break;
   1458   1.1  christos     case bspstore_when:
   1459   1.1  christos       r = 10;
   1460   1.1  christos       break;
   1461   1.1  christos     case bspstore_psprel:
   1462   1.1  christos       r = 11;
   1463   1.1  christos       break;
   1464   1.1  christos     case bspstore_sprel:
   1465   1.1  christos       r = 12;
   1466   1.1  christos       break;
   1467   1.1  christos     case rnat_when:
   1468   1.1  christos       r = 13;
   1469   1.1  christos       break;
   1470   1.1  christos     case rnat_psprel:
   1471   1.1  christos       r = 14;
   1472   1.1  christos       break;
   1473   1.1  christos     case rnat_sprel:
   1474   1.1  christos       r = 15;
   1475   1.1  christos       break;
   1476   1.1  christos     case priunat_when_gr:
   1477   1.1  christos       r = 16;
   1478   1.1  christos       break;
   1479   1.1  christos     case priunat_psprel:
   1480   1.1  christos       r = 17;
   1481   1.1  christos       break;
   1482   1.1  christos     case priunat_sprel:
   1483   1.1  christos       r = 18;
   1484   1.1  christos       break;
   1485   1.1  christos     case priunat_when_mem:
   1486   1.1  christos       r = 19;
   1487   1.1  christos       break;
   1488   1.1  christos     default:
   1489   1.1  christos       break;
   1490   1.1  christos     }
   1491   1.1  christos   bytes[1] = r;
   1492   1.1  christos   count += output_leb128 (bytes + 2, t, 0);
   1493   1.1  christos   (*f) (count, bytes, NULL);
   1494   1.1  christos }
   1495   1.1  christos 
   1496   1.1  christos static void
   1497   1.1  christos output_P9_format (vbyte_func f, int grmask, int gr)
   1498   1.1  christos {
   1499   1.1  christos   char bytes[3];
   1500   1.1  christos   bytes[0] = UNW_P9;
   1501   1.1  christos   bytes[1] = (grmask & 0x0f);
   1502   1.1  christos   bytes[2] = (gr & 0x7f);
   1503   1.1  christos   (*f) (3, bytes, NULL);
   1504   1.1  christos }
   1505   1.1  christos 
   1506   1.1  christos static void
   1507   1.1  christos output_P10_format (vbyte_func f, int abi, int context)
   1508   1.1  christos {
   1509   1.1  christos   char bytes[3];
   1510   1.1  christos   bytes[0] = UNW_P10;
   1511   1.1  christos   bytes[1] = (abi & 0xff);
   1512   1.1  christos   bytes[2] = (context & 0xff);
   1513   1.1  christos   (*f) (3, bytes, NULL);
   1514   1.1  christos }
   1515   1.1  christos 
   1516   1.1  christos static void
   1517   1.1  christos output_B1_format (vbyte_func f, unw_record_type rtype, unsigned long label)
   1518   1.1  christos {
   1519   1.1  christos   char byte;
   1520   1.1  christos   int r = 0;
   1521   1.1  christos   if (label > 0x1f)
   1522   1.1  christos     {
   1523   1.1  christos       output_B4_format (f, rtype, label);
   1524   1.1  christos       return;
   1525   1.1  christos     }
   1526   1.1  christos   if (rtype == copy_state)
   1527   1.1  christos     r = 1;
   1528   1.1  christos   else if (rtype != label_state)
   1529   1.1  christos     as_bad (_("Invalid record type for format B1"));
   1530   1.1  christos 
   1531   1.1  christos   byte = (UNW_B1 | (r << 5) | (label & 0x1f));
   1532   1.1  christos   (*f) (1, &byte, NULL);
   1533   1.1  christos }
   1534   1.1  christos 
   1535   1.1  christos static void
   1536   1.1  christos output_B2_format (vbyte_func f, unsigned long ecount, unsigned long t)
   1537   1.1  christos {
   1538   1.1  christos   char bytes[20];
   1539   1.1  christos   int count = 1;
   1540   1.1  christos   if (ecount > 0x1f)
   1541   1.1  christos     {
   1542   1.1  christos       output_B3_format (f, ecount, t);
   1543   1.1  christos       return;
   1544   1.1  christos     }
   1545   1.1  christos   bytes[0] = (UNW_B2 | (ecount & 0x1f));
   1546   1.1  christos   count += output_leb128 (bytes + 1, t, 0);
   1547   1.1  christos   (*f) (count, bytes, NULL);
   1548   1.1  christos }
   1549   1.1  christos 
   1550   1.1  christos static void
   1551   1.1  christos output_B3_format (vbyte_func f, unsigned long ecount, unsigned long t)
   1552   1.1  christos {
   1553   1.1  christos   char bytes[20];
   1554   1.1  christos   int count = 1;
   1555   1.1  christos   if (ecount <= 0x1f)
   1556   1.1  christos     {
   1557   1.1  christos       output_B2_format (f, ecount, t);
   1558   1.1  christos       return;
   1559   1.1  christos     }
   1560   1.1  christos   bytes[0] = UNW_B3;
   1561   1.1  christos   count += output_leb128 (bytes + 1, t, 0);
   1562   1.1  christos   count += output_leb128 (bytes + count, ecount, 0);
   1563   1.1  christos   (*f) (count, bytes, NULL);
   1564   1.1  christos }
   1565   1.1  christos 
   1566   1.1  christos static void
   1567   1.1  christos output_B4_format (vbyte_func f, unw_record_type rtype, unsigned long label)
   1568   1.1  christos {
   1569   1.1  christos   char bytes[20];
   1570   1.1  christos   int r = 0;
   1571   1.1  christos   int count = 1;
   1572   1.1  christos   if (label <= 0x1f)
   1573   1.1  christos     {
   1574   1.1  christos       output_B1_format (f, rtype, label);
   1575   1.1  christos       return;
   1576   1.1  christos     }
   1577   1.1  christos 
   1578   1.1  christos   if (rtype == copy_state)
   1579   1.1  christos     r = 1;
   1580   1.1  christos   else if (rtype != label_state)
   1581   1.1  christos     as_bad (_("Invalid record type for format B1"));
   1582   1.1  christos 
   1583   1.1  christos   bytes[0] = (UNW_B4 | (r << 3));
   1584   1.1  christos   count += output_leb128 (bytes + 1, label, 0);
   1585   1.1  christos   (*f) (count, bytes, NULL);
   1586   1.1  christos }
   1587   1.1  christos 
   1588   1.1  christos static char
   1589   1.1  christos format_ab_reg (int ab, int reg)
   1590   1.1  christos {
   1591   1.1  christos   int ret;
   1592   1.1  christos   ab = (ab & 3);
   1593   1.1  christos   reg = (reg & 0x1f);
   1594   1.1  christos   ret = (ab << 5) | reg;
   1595   1.1  christos   return ret;
   1596   1.1  christos }
   1597   1.1  christos 
   1598   1.1  christos static void
   1599   1.1  christos output_X1_format (vbyte_func f,
   1600   1.1  christos 		  unw_record_type rtype,
   1601   1.1  christos 		  int ab,
   1602   1.1  christos 		  int reg,
   1603   1.1  christos 		  unsigned long t,
   1604   1.1  christos 		  unsigned long w1)
   1605   1.1  christos {
   1606   1.1  christos   char bytes[20];
   1607   1.1  christos   int r = 0;
   1608   1.1  christos   int count = 2;
   1609   1.1  christos   bytes[0] = UNW_X1;
   1610   1.1  christos 
   1611   1.1  christos   if (rtype == spill_sprel)
   1612   1.1  christos     r = 1;
   1613   1.1  christos   else if (rtype != spill_psprel)
   1614   1.1  christos     as_bad (_("Invalid record type for format X1"));
   1615   1.1  christos   bytes[1] = ((r << 7) | format_ab_reg (ab, reg));
   1616   1.1  christos   count += output_leb128 (bytes + 2, t, 0);
   1617   1.1  christos   count += output_leb128 (bytes + count, w1, 0);
   1618   1.1  christos   (*f) (count, bytes, NULL);
   1619   1.1  christos }
   1620   1.1  christos 
   1621   1.1  christos static void
   1622   1.1  christos output_X2_format (vbyte_func f,
   1623   1.1  christos 		  int ab,
   1624   1.1  christos 		  int reg,
   1625   1.1  christos 		  int x,
   1626   1.1  christos 		  int y,
   1627   1.1  christos 		  int treg,
   1628   1.1  christos 		  unsigned long t)
   1629   1.1  christos {
   1630   1.1  christos   char bytes[20];
   1631   1.1  christos   int count = 3;
   1632   1.1  christos   bytes[0] = UNW_X2;
   1633   1.1  christos   bytes[1] = (((x & 1) << 7) | format_ab_reg (ab, reg));
   1634   1.1  christos   bytes[2] = (((y & 1) << 7) | (treg & 0x7f));
   1635   1.1  christos   count += output_leb128 (bytes + 3, t, 0);
   1636   1.1  christos   (*f) (count, bytes, NULL);
   1637   1.1  christos }
   1638   1.1  christos 
   1639   1.1  christos static void
   1640   1.1  christos output_X3_format (vbyte_func f,
   1641   1.1  christos 		  unw_record_type rtype,
   1642   1.1  christos 		  int qp,
   1643   1.1  christos 		  int ab,
   1644   1.1  christos 		  int reg,
   1645   1.1  christos 		  unsigned long t,
   1646   1.1  christos 		  unsigned long w1)
   1647   1.1  christos {
   1648   1.1  christos   char bytes[20];
   1649   1.1  christos   int r = 0;
   1650   1.1  christos   int count = 3;
   1651   1.1  christos   bytes[0] = UNW_X3;
   1652   1.1  christos 
   1653   1.1  christos   if (rtype == spill_sprel_p)
   1654   1.1  christos     r = 1;
   1655   1.1  christos   else if (rtype != spill_psprel_p)
   1656   1.1  christos     as_bad (_("Invalid record type for format X3"));
   1657   1.1  christos   bytes[1] = ((r << 7) | (qp & 0x3f));
   1658   1.1  christos   bytes[2] = format_ab_reg (ab, reg);
   1659   1.1  christos   count += output_leb128 (bytes + 3, t, 0);
   1660   1.1  christos   count += output_leb128 (bytes + count, w1, 0);
   1661   1.1  christos   (*f) (count, bytes, NULL);
   1662   1.1  christos }
   1663   1.1  christos 
   1664   1.1  christos static void
   1665   1.1  christos output_X4_format (vbyte_func f,
   1666   1.1  christos 		  int qp,
   1667   1.1  christos 		  int ab,
   1668   1.1  christos 		  int reg,
   1669   1.1  christos 		  int x,
   1670   1.1  christos 		  int y,
   1671   1.1  christos 		  int treg,
   1672   1.1  christos 		  unsigned long t)
   1673   1.1  christos {
   1674   1.1  christos   char bytes[20];
   1675   1.1  christos   int count = 4;
   1676   1.1  christos   bytes[0] = UNW_X4;
   1677   1.1  christos   bytes[1] = (qp & 0x3f);
   1678   1.1  christos   bytes[2] = (((x & 1) << 7) | format_ab_reg (ab, reg));
   1679   1.1  christos   bytes[3] = (((y & 1) << 7) | (treg & 0x7f));
   1680   1.1  christos   count += output_leb128 (bytes + 4, t, 0);
   1681   1.1  christos   (*f) (count, bytes, NULL);
   1682   1.1  christos }
   1683   1.1  christos 
   1684   1.1  christos /* This function checks whether there are any outstanding .save-s and
   1685   1.1  christos    discards them if so.  */
   1686   1.1  christos 
   1687   1.1  christos static void
   1688   1.1  christos check_pending_save (void)
   1689   1.1  christos {
   1690   1.1  christos   if (unwind.pending_saves)
   1691   1.1  christos     {
   1692   1.1  christos       unw_rec_list *cur, *prev;
   1693   1.1  christos 
   1694   1.1  christos       as_warn (_("Previous .save incomplete"));
   1695   1.1  christos       for (cur = unwind.list, prev = NULL; cur; )
   1696   1.1  christos 	if (&cur->r.record.p == unwind.pending_saves)
   1697   1.1  christos 	  {
   1698   1.1  christos 	    if (prev)
   1699   1.1  christos 	      prev->next = cur->next;
   1700   1.1  christos 	    else
   1701   1.1  christos 	      unwind.list = cur->next;
   1702   1.1  christos 	    if (cur == unwind.tail)
   1703   1.1  christos 	      unwind.tail = prev;
   1704   1.1  christos 	    if (cur == unwind.current_entry)
   1705   1.1  christos 	      unwind.current_entry = cur->next;
   1706   1.1  christos 	    /* Don't free the first discarded record, it's being used as
   1707   1.1  christos 	       terminator for (currently) br_gr and gr_gr processing, and
   1708   1.1  christos 	       also prevents leaving a dangling pointer to it in its
   1709   1.1  christos 	       predecessor.  */
   1710   1.1  christos 	    cur->r.record.p.grmask = 0;
   1711   1.1  christos 	    cur->r.record.p.brmask = 0;
   1712   1.1  christos 	    cur->r.record.p.frmask = 0;
   1713   1.1  christos 	    prev = cur->r.record.p.next;
   1714   1.1  christos 	    cur->r.record.p.next = NULL;
   1715   1.1  christos 	    cur = prev;
   1716   1.1  christos 	    break;
   1717   1.1  christos 	  }
   1718   1.1  christos 	else
   1719   1.1  christos 	  {
   1720   1.1  christos 	    prev = cur;
   1721   1.1  christos 	    cur = cur->next;
   1722   1.1  christos 	  }
   1723   1.1  christos       while (cur)
   1724   1.1  christos 	{
   1725   1.1  christos 	  prev = cur;
   1726   1.1  christos 	  cur = cur->r.record.p.next;
   1727   1.1  christos 	  free (prev);
   1728   1.1  christos 	}
   1729   1.1  christos       unwind.pending_saves = NULL;
   1730   1.1  christos     }
   1731   1.1  christos }
   1732   1.1  christos 
   1733   1.1  christos /* This function allocates a record list structure, and initializes fields.  */
   1734   1.1  christos 
   1735   1.1  christos static unw_rec_list *
   1736   1.1  christos alloc_record (unw_record_type t)
   1737   1.1  christos {
   1738   1.1  christos   unw_rec_list *ptr;
   1739   1.5  christos   ptr = XNEW (unw_rec_list);
   1740   1.1  christos   memset (ptr, 0, sizeof (*ptr));
   1741   1.1  christos   ptr->slot_number = SLOT_NUM_NOT_SET;
   1742   1.1  christos   ptr->r.type = t;
   1743   1.1  christos   return ptr;
   1744   1.1  christos }
   1745   1.1  christos 
   1746   1.1  christos /* Dummy unwind record used for calculating the length of the last prologue or
   1747   1.1  christos    body region.  */
   1748   1.1  christos 
   1749   1.1  christos static unw_rec_list *
   1750   1.1  christos output_endp (void)
   1751   1.1  christos {
   1752   1.1  christos   unw_rec_list *ptr = alloc_record (endp);
   1753   1.1  christos   return ptr;
   1754   1.1  christos }
   1755   1.1  christos 
   1756   1.1  christos static unw_rec_list *
   1757   1.1  christos output_prologue (void)
   1758   1.1  christos {
   1759   1.1  christos   unw_rec_list *ptr = alloc_record (prologue);
   1760   1.1  christos   return ptr;
   1761   1.1  christos }
   1762   1.1  christos 
   1763   1.1  christos static unw_rec_list *
   1764   1.1  christos output_prologue_gr (unsigned int saved_mask, unsigned int reg)
   1765   1.1  christos {
   1766   1.1  christos   unw_rec_list *ptr = alloc_record (prologue_gr);
   1767   1.1  christos   ptr->r.record.r.grmask = saved_mask;
   1768   1.1  christos   ptr->r.record.r.grsave = reg;
   1769   1.1  christos   return ptr;
   1770   1.1  christos }
   1771   1.1  christos 
   1772   1.1  christos static unw_rec_list *
   1773   1.1  christos output_body (void)
   1774   1.1  christos {
   1775   1.1  christos   unw_rec_list *ptr = alloc_record (body);
   1776   1.1  christos   return ptr;
   1777   1.1  christos }
   1778   1.1  christos 
   1779   1.1  christos static unw_rec_list *
   1780   1.1  christos output_mem_stack_f (unsigned int size)
   1781   1.1  christos {
   1782   1.1  christos   unw_rec_list *ptr = alloc_record (mem_stack_f);
   1783   1.1  christos   ptr->r.record.p.size = size;
   1784   1.1  christos   return ptr;
   1785   1.1  christos }
   1786   1.1  christos 
   1787   1.1  christos static unw_rec_list *
   1788   1.1  christos output_mem_stack_v (void)
   1789   1.1  christos {
   1790   1.1  christos   unw_rec_list *ptr = alloc_record (mem_stack_v);
   1791   1.1  christos   return ptr;
   1792   1.1  christos }
   1793   1.1  christos 
   1794   1.1  christos static unw_rec_list *
   1795   1.1  christos output_psp_gr (unsigned int gr)
   1796   1.1  christos {
   1797   1.1  christos   unw_rec_list *ptr = alloc_record (psp_gr);
   1798   1.1  christos   ptr->r.record.p.r.gr = gr;
   1799   1.1  christos   return ptr;
   1800   1.1  christos }
   1801   1.1  christos 
   1802   1.1  christos static unw_rec_list *
   1803   1.1  christos output_psp_sprel (unsigned int offset)
   1804   1.1  christos {
   1805   1.1  christos   unw_rec_list *ptr = alloc_record (psp_sprel);
   1806   1.1  christos   ptr->r.record.p.off.sp = offset / 4;
   1807   1.1  christos   return ptr;
   1808   1.1  christos }
   1809   1.1  christos 
   1810   1.1  christos static unw_rec_list *
   1811   1.1  christos output_rp_when (void)
   1812   1.1  christos {
   1813   1.1  christos   unw_rec_list *ptr = alloc_record (rp_when);
   1814   1.1  christos   return ptr;
   1815   1.1  christos }
   1816   1.1  christos 
   1817   1.1  christos static unw_rec_list *
   1818   1.1  christos output_rp_gr (unsigned int gr)
   1819   1.1  christos {
   1820   1.1  christos   unw_rec_list *ptr = alloc_record (rp_gr);
   1821   1.1  christos   ptr->r.record.p.r.gr = gr;
   1822   1.1  christos   return ptr;
   1823   1.1  christos }
   1824   1.1  christos 
   1825   1.1  christos static unw_rec_list *
   1826   1.1  christos output_rp_br (unsigned int br)
   1827   1.1  christos {
   1828   1.1  christos   unw_rec_list *ptr = alloc_record (rp_br);
   1829   1.1  christos   ptr->r.record.p.r.br = br;
   1830   1.1  christos   return ptr;
   1831   1.1  christos }
   1832   1.1  christos 
   1833   1.1  christos static unw_rec_list *
   1834   1.1  christos output_rp_psprel (unsigned int offset)
   1835   1.1  christos {
   1836   1.1  christos   unw_rec_list *ptr = alloc_record (rp_psprel);
   1837   1.1  christos   ptr->r.record.p.off.psp = ENCODED_PSP_OFFSET (offset);
   1838   1.1  christos   return ptr;
   1839   1.1  christos }
   1840   1.1  christos 
   1841   1.1  christos static unw_rec_list *
   1842   1.1  christos output_rp_sprel (unsigned int offset)
   1843   1.1  christos {
   1844   1.1  christos   unw_rec_list *ptr = alloc_record (rp_sprel);
   1845   1.1  christos   ptr->r.record.p.off.sp = offset / 4;
   1846   1.1  christos   return ptr;
   1847   1.1  christos }
   1848   1.1  christos 
   1849   1.1  christos static unw_rec_list *
   1850   1.1  christos output_pfs_when (void)
   1851   1.1  christos {
   1852   1.1  christos   unw_rec_list *ptr = alloc_record (pfs_when);
   1853   1.1  christos   return ptr;
   1854   1.1  christos }
   1855   1.1  christos 
   1856   1.1  christos static unw_rec_list *
   1857   1.1  christos output_pfs_gr (unsigned int gr)
   1858   1.1  christos {
   1859   1.1  christos   unw_rec_list *ptr = alloc_record (pfs_gr);
   1860   1.1  christos   ptr->r.record.p.r.gr = gr;
   1861   1.1  christos   return ptr;
   1862   1.1  christos }
   1863   1.1  christos 
   1864   1.1  christos static unw_rec_list *
   1865   1.1  christos output_pfs_psprel (unsigned int offset)
   1866   1.1  christos {
   1867   1.1  christos   unw_rec_list *ptr = alloc_record (pfs_psprel);
   1868   1.1  christos   ptr->r.record.p.off.psp = ENCODED_PSP_OFFSET (offset);
   1869   1.1  christos   return ptr;
   1870   1.1  christos }
   1871   1.1  christos 
   1872   1.1  christos static unw_rec_list *
   1873   1.1  christos output_pfs_sprel (unsigned int offset)
   1874   1.1  christos {
   1875   1.1  christos   unw_rec_list *ptr = alloc_record (pfs_sprel);
   1876   1.1  christos   ptr->r.record.p.off.sp = offset / 4;
   1877   1.1  christos   return ptr;
   1878   1.1  christos }
   1879   1.1  christos 
   1880   1.1  christos static unw_rec_list *
   1881   1.1  christos output_preds_when (void)
   1882   1.1  christos {
   1883   1.1  christos   unw_rec_list *ptr = alloc_record (preds_when);
   1884   1.1  christos   return ptr;
   1885   1.1  christos }
   1886   1.1  christos 
   1887   1.1  christos static unw_rec_list *
   1888   1.1  christos output_preds_gr (unsigned int gr)
   1889   1.1  christos {
   1890   1.1  christos   unw_rec_list *ptr = alloc_record (preds_gr);
   1891   1.1  christos   ptr->r.record.p.r.gr = gr;
   1892   1.1  christos   return ptr;
   1893   1.1  christos }
   1894   1.1  christos 
   1895   1.1  christos static unw_rec_list *
   1896   1.1  christos output_preds_psprel (unsigned int offset)
   1897   1.1  christos {
   1898   1.1  christos   unw_rec_list *ptr = alloc_record (preds_psprel);
   1899   1.1  christos   ptr->r.record.p.off.psp = ENCODED_PSP_OFFSET (offset);
   1900   1.1  christos   return ptr;
   1901   1.1  christos }
   1902   1.1  christos 
   1903   1.1  christos static unw_rec_list *
   1904   1.1  christos output_preds_sprel (unsigned int offset)
   1905   1.1  christos {
   1906   1.1  christos   unw_rec_list *ptr = alloc_record (preds_sprel);
   1907   1.1  christos   ptr->r.record.p.off.sp = offset / 4;
   1908   1.1  christos   return ptr;
   1909   1.1  christos }
   1910   1.1  christos 
   1911   1.1  christos static unw_rec_list *
   1912   1.1  christos output_fr_mem (unsigned int mask)
   1913   1.1  christos {
   1914   1.1  christos   unw_rec_list *ptr = alloc_record (fr_mem);
   1915   1.1  christos   unw_rec_list *cur = ptr;
   1916   1.1  christos 
   1917   1.1  christos   ptr->r.record.p.frmask = mask;
   1918   1.1  christos   unwind.pending_saves = &ptr->r.record.p;
   1919   1.1  christos   for (;;)
   1920   1.1  christos     {
   1921   1.1  christos       unw_rec_list *prev = cur;
   1922   1.1  christos 
   1923   1.1  christos       /* Clear least significant set bit.  */
   1924   1.1  christos       mask &= ~(mask & (~mask + 1));
   1925   1.1  christos       if (!mask)
   1926   1.1  christos 	return ptr;
   1927   1.1  christos       cur = alloc_record (fr_mem);
   1928   1.1  christos       cur->r.record.p.frmask = mask;
   1929   1.1  christos       /* Retain only least significant bit.  */
   1930   1.1  christos       prev->r.record.p.frmask ^= mask;
   1931   1.1  christos       prev->r.record.p.next = cur;
   1932   1.1  christos     }
   1933   1.1  christos }
   1934   1.1  christos 
   1935   1.1  christos static unw_rec_list *
   1936   1.1  christos output_frgr_mem (unsigned int gr_mask, unsigned int fr_mask)
   1937   1.1  christos {
   1938   1.1  christos   unw_rec_list *ptr = alloc_record (frgr_mem);
   1939   1.1  christos   unw_rec_list *cur = ptr;
   1940   1.1  christos 
   1941   1.1  christos   unwind.pending_saves = &cur->r.record.p;
   1942   1.1  christos   cur->r.record.p.frmask = fr_mask;
   1943   1.1  christos   while (fr_mask)
   1944   1.1  christos     {
   1945   1.1  christos       unw_rec_list *prev = cur;
   1946   1.1  christos 
   1947   1.1  christos       /* Clear least significant set bit.  */
   1948   1.1  christos       fr_mask &= ~(fr_mask & (~fr_mask + 1));
   1949   1.1  christos       if (!gr_mask && !fr_mask)
   1950   1.1  christos 	return ptr;
   1951   1.1  christos       cur = alloc_record (frgr_mem);
   1952   1.1  christos       cur->r.record.p.frmask = fr_mask;
   1953   1.1  christos       /* Retain only least significant bit.  */
   1954   1.1  christos       prev->r.record.p.frmask ^= fr_mask;
   1955   1.1  christos       prev->r.record.p.next = cur;
   1956   1.1  christos     }
   1957   1.1  christos   cur->r.record.p.grmask = gr_mask;
   1958   1.1  christos   for (;;)
   1959   1.1  christos     {
   1960   1.1  christos       unw_rec_list *prev = cur;
   1961   1.1  christos 
   1962   1.1  christos       /* Clear least significant set bit.  */
   1963   1.1  christos       gr_mask &= ~(gr_mask & (~gr_mask + 1));
   1964   1.1  christos       if (!gr_mask)
   1965   1.1  christos 	return ptr;
   1966   1.1  christos       cur = alloc_record (frgr_mem);
   1967   1.1  christos       cur->r.record.p.grmask = gr_mask;
   1968   1.1  christos       /* Retain only least significant bit.  */
   1969   1.1  christos       prev->r.record.p.grmask ^= gr_mask;
   1970   1.1  christos       prev->r.record.p.next = cur;
   1971   1.1  christos     }
   1972   1.1  christos }
   1973   1.1  christos 
   1974   1.1  christos static unw_rec_list *
   1975   1.1  christos output_gr_gr (unsigned int mask, unsigned int reg)
   1976   1.1  christos {
   1977   1.1  christos   unw_rec_list *ptr = alloc_record (gr_gr);
   1978   1.1  christos   unw_rec_list *cur = ptr;
   1979   1.1  christos 
   1980   1.1  christos   ptr->r.record.p.grmask = mask;
   1981   1.1  christos   ptr->r.record.p.r.gr = reg;
   1982   1.1  christos   unwind.pending_saves = &ptr->r.record.p;
   1983   1.1  christos   for (;;)
   1984   1.1  christos     {
   1985   1.1  christos       unw_rec_list *prev = cur;
   1986   1.1  christos 
   1987   1.1  christos       /* Clear least significant set bit.  */
   1988   1.1  christos       mask &= ~(mask & (~mask + 1));
   1989   1.1  christos       if (!mask)
   1990   1.1  christos 	return ptr;
   1991   1.1  christos       cur = alloc_record (gr_gr);
   1992   1.1  christos       cur->r.record.p.grmask = mask;
   1993   1.1  christos       /* Indicate this record shouldn't be output.  */
   1994   1.1  christos       cur->r.record.p.r.gr = REG_NUM;
   1995   1.1  christos       /* Retain only least significant bit.  */
   1996   1.1  christos       prev->r.record.p.grmask ^= mask;
   1997   1.1  christos       prev->r.record.p.next = cur;
   1998   1.1  christos     }
   1999   1.1  christos }
   2000   1.1  christos 
   2001   1.1  christos static unw_rec_list *
   2002   1.1  christos output_gr_mem (unsigned int mask)
   2003   1.1  christos {
   2004   1.1  christos   unw_rec_list *ptr = alloc_record (gr_mem);
   2005   1.1  christos   unw_rec_list *cur = ptr;
   2006   1.1  christos 
   2007   1.1  christos   ptr->r.record.p.grmask = mask;
   2008   1.1  christos   unwind.pending_saves = &ptr->r.record.p;
   2009   1.1  christos   for (;;)
   2010   1.1  christos     {
   2011   1.1  christos       unw_rec_list *prev = cur;
   2012   1.1  christos 
   2013   1.1  christos       /* Clear least significant set bit.  */
   2014   1.1  christos       mask &= ~(mask & (~mask + 1));
   2015   1.1  christos       if (!mask)
   2016   1.1  christos 	return ptr;
   2017   1.1  christos       cur = alloc_record (gr_mem);
   2018   1.1  christos       cur->r.record.p.grmask = mask;
   2019   1.1  christos       /* Retain only least significant bit.  */
   2020   1.1  christos       prev->r.record.p.grmask ^= mask;
   2021   1.1  christos       prev->r.record.p.next = cur;
   2022   1.1  christos     }
   2023   1.1  christos }
   2024   1.1  christos 
   2025   1.1  christos static unw_rec_list *
   2026   1.1  christos output_br_mem (unsigned int mask)
   2027   1.1  christos {
   2028   1.1  christos   unw_rec_list *ptr = alloc_record (br_mem);
   2029   1.1  christos   unw_rec_list *cur = ptr;
   2030   1.1  christos 
   2031   1.1  christos   ptr->r.record.p.brmask = mask;
   2032   1.1  christos   unwind.pending_saves = &ptr->r.record.p;
   2033   1.1  christos   for (;;)
   2034   1.1  christos     {
   2035   1.1  christos       unw_rec_list *prev = cur;
   2036   1.1  christos 
   2037   1.1  christos       /* Clear least significant set bit.  */
   2038   1.1  christos       mask &= ~(mask & (~mask + 1));
   2039   1.1  christos       if (!mask)
   2040   1.1  christos 	return ptr;
   2041   1.1  christos       cur = alloc_record (br_mem);
   2042   1.1  christos       cur->r.record.p.brmask = mask;
   2043   1.1  christos       /* Retain only least significant bit.  */
   2044   1.1  christos       prev->r.record.p.brmask ^= mask;
   2045   1.1  christos       prev->r.record.p.next = cur;
   2046   1.1  christos     }
   2047   1.1  christos }
   2048   1.1  christos 
   2049   1.1  christos static unw_rec_list *
   2050   1.1  christos output_br_gr (unsigned int mask, unsigned int reg)
   2051   1.1  christos {
   2052   1.1  christos   unw_rec_list *ptr = alloc_record (br_gr);
   2053   1.1  christos   unw_rec_list *cur = ptr;
   2054   1.1  christos 
   2055   1.1  christos   ptr->r.record.p.brmask = mask;
   2056   1.1  christos   ptr->r.record.p.r.gr = reg;
   2057   1.1  christos   unwind.pending_saves = &ptr->r.record.p;
   2058   1.1  christos   for (;;)
   2059   1.1  christos     {
   2060   1.1  christos       unw_rec_list *prev = cur;
   2061   1.1  christos 
   2062   1.1  christos       /* Clear least significant set bit.  */
   2063   1.1  christos       mask &= ~(mask & (~mask + 1));
   2064   1.1  christos       if (!mask)
   2065   1.1  christos 	return ptr;
   2066   1.1  christos       cur = alloc_record (br_gr);
   2067   1.1  christos       cur->r.record.p.brmask = mask;
   2068   1.1  christos       /* Indicate this record shouldn't be output.  */
   2069   1.1  christos       cur->r.record.p.r.gr = REG_NUM;
   2070   1.1  christos       /* Retain only least significant bit.  */
   2071   1.1  christos       prev->r.record.p.brmask ^= mask;
   2072   1.1  christos       prev->r.record.p.next = cur;
   2073   1.1  christos     }
   2074   1.1  christos }
   2075   1.1  christos 
   2076   1.1  christos static unw_rec_list *
   2077   1.1  christos output_spill_base (unsigned int offset)
   2078   1.1  christos {
   2079   1.1  christos   unw_rec_list *ptr = alloc_record (spill_base);
   2080   1.1  christos   ptr->r.record.p.off.psp = ENCODED_PSP_OFFSET (offset);
   2081   1.1  christos   return ptr;
   2082   1.1  christos }
   2083   1.1  christos 
   2084   1.1  christos static unw_rec_list *
   2085   1.1  christos output_unat_when (void)
   2086   1.1  christos {
   2087   1.1  christos   unw_rec_list *ptr = alloc_record (unat_when);
   2088   1.1  christos   return ptr;
   2089   1.1  christos }
   2090   1.1  christos 
   2091   1.1  christos static unw_rec_list *
   2092   1.1  christos output_unat_gr (unsigned int gr)
   2093   1.1  christos {
   2094   1.1  christos   unw_rec_list *ptr = alloc_record (unat_gr);
   2095   1.1  christos   ptr->r.record.p.r.gr = gr;
   2096   1.1  christos   return ptr;
   2097   1.1  christos }
   2098   1.1  christos 
   2099   1.1  christos static unw_rec_list *
   2100   1.1  christos output_unat_psprel (unsigned int offset)
   2101   1.1  christos {
   2102   1.1  christos   unw_rec_list *ptr = alloc_record (unat_psprel);
   2103   1.1  christos   ptr->r.record.p.off.psp = ENCODED_PSP_OFFSET (offset);
   2104   1.1  christos   return ptr;
   2105   1.1  christos }
   2106   1.1  christos 
   2107   1.1  christos static unw_rec_list *
   2108   1.1  christos output_unat_sprel (unsigned int offset)
   2109   1.1  christos {
   2110   1.1  christos   unw_rec_list *ptr = alloc_record (unat_sprel);
   2111   1.1  christos   ptr->r.record.p.off.sp = offset / 4;
   2112   1.1  christos   return ptr;
   2113   1.1  christos }
   2114   1.1  christos 
   2115   1.1  christos static unw_rec_list *
   2116   1.1  christos output_lc_when (void)
   2117   1.1  christos {
   2118   1.1  christos   unw_rec_list *ptr = alloc_record (lc_when);
   2119   1.1  christos   return ptr;
   2120   1.1  christos }
   2121   1.1  christos 
   2122   1.1  christos static unw_rec_list *
   2123   1.1  christos output_lc_gr (unsigned int gr)
   2124   1.1  christos {
   2125   1.1  christos   unw_rec_list *ptr = alloc_record (lc_gr);
   2126   1.1  christos   ptr->r.record.p.r.gr = gr;
   2127   1.1  christos   return ptr;
   2128   1.1  christos }
   2129   1.1  christos 
   2130   1.1  christos static unw_rec_list *
   2131   1.1  christos output_lc_psprel (unsigned int offset)
   2132   1.1  christos {
   2133   1.1  christos   unw_rec_list *ptr = alloc_record (lc_psprel);
   2134   1.1  christos   ptr->r.record.p.off.psp = ENCODED_PSP_OFFSET (offset);
   2135   1.1  christos   return ptr;
   2136   1.1  christos }
   2137   1.1  christos 
   2138   1.1  christos static unw_rec_list *
   2139   1.1  christos output_lc_sprel (unsigned int offset)
   2140   1.1  christos {
   2141   1.1  christos   unw_rec_list *ptr = alloc_record (lc_sprel);
   2142   1.1  christos   ptr->r.record.p.off.sp = offset / 4;
   2143   1.1  christos   return ptr;
   2144   1.1  christos }
   2145   1.1  christos 
   2146   1.1  christos static unw_rec_list *
   2147   1.1  christos output_fpsr_when (void)
   2148   1.1  christos {
   2149   1.1  christos   unw_rec_list *ptr = alloc_record (fpsr_when);
   2150   1.1  christos   return ptr;
   2151   1.1  christos }
   2152   1.1  christos 
   2153   1.1  christos static unw_rec_list *
   2154   1.1  christos output_fpsr_gr (unsigned int gr)
   2155   1.1  christos {
   2156   1.1  christos   unw_rec_list *ptr = alloc_record (fpsr_gr);
   2157   1.1  christos   ptr->r.record.p.r.gr = gr;
   2158   1.1  christos   return ptr;
   2159   1.1  christos }
   2160   1.1  christos 
   2161   1.1  christos static unw_rec_list *
   2162   1.1  christos output_fpsr_psprel (unsigned int offset)
   2163   1.1  christos {
   2164   1.1  christos   unw_rec_list *ptr = alloc_record (fpsr_psprel);
   2165   1.1  christos   ptr->r.record.p.off.psp = ENCODED_PSP_OFFSET (offset);
   2166   1.1  christos   return ptr;
   2167   1.1  christos }
   2168   1.1  christos 
   2169   1.1  christos static unw_rec_list *
   2170   1.1  christos output_fpsr_sprel (unsigned int offset)
   2171   1.1  christos {
   2172   1.1  christos   unw_rec_list *ptr = alloc_record (fpsr_sprel);
   2173   1.1  christos   ptr->r.record.p.off.sp = offset / 4;
   2174   1.1  christos   return ptr;
   2175   1.1  christos }
   2176   1.1  christos 
   2177   1.1  christos static unw_rec_list *
   2178   1.1  christos output_priunat_when_gr (void)
   2179   1.1  christos {
   2180   1.1  christos   unw_rec_list *ptr = alloc_record (priunat_when_gr);
   2181   1.1  christos   return ptr;
   2182   1.1  christos }
   2183   1.1  christos 
   2184   1.1  christos static unw_rec_list *
   2185   1.1  christos output_priunat_when_mem (void)
   2186   1.1  christos {
   2187   1.1  christos   unw_rec_list *ptr = alloc_record (priunat_when_mem);
   2188   1.1  christos   return ptr;
   2189   1.1  christos }
   2190   1.1  christos 
   2191   1.1  christos static unw_rec_list *
   2192   1.1  christos output_priunat_gr (unsigned int gr)
   2193   1.1  christos {
   2194   1.1  christos   unw_rec_list *ptr = alloc_record (priunat_gr);
   2195   1.1  christos   ptr->r.record.p.r.gr = gr;
   2196   1.1  christos   return ptr;
   2197   1.1  christos }
   2198   1.1  christos 
   2199   1.1  christos static unw_rec_list *
   2200   1.1  christos output_priunat_psprel (unsigned int offset)
   2201   1.1  christos {
   2202   1.1  christos   unw_rec_list *ptr = alloc_record (priunat_psprel);
   2203   1.1  christos   ptr->r.record.p.off.psp = ENCODED_PSP_OFFSET (offset);
   2204   1.1  christos   return ptr;
   2205   1.1  christos }
   2206   1.1  christos 
   2207   1.1  christos static unw_rec_list *
   2208   1.1  christos output_priunat_sprel (unsigned int offset)
   2209   1.1  christos {
   2210   1.1  christos   unw_rec_list *ptr = alloc_record (priunat_sprel);
   2211   1.1  christos   ptr->r.record.p.off.sp = offset / 4;
   2212   1.1  christos   return ptr;
   2213   1.1  christos }
   2214   1.1  christos 
   2215   1.1  christos static unw_rec_list *
   2216   1.1  christos output_bsp_when (void)
   2217   1.1  christos {
   2218   1.1  christos   unw_rec_list *ptr = alloc_record (bsp_when);
   2219   1.1  christos   return ptr;
   2220   1.1  christos }
   2221   1.1  christos 
   2222   1.1  christos static unw_rec_list *
   2223   1.1  christos output_bsp_gr (unsigned int gr)
   2224   1.1  christos {
   2225   1.1  christos   unw_rec_list *ptr = alloc_record (bsp_gr);
   2226   1.1  christos   ptr->r.record.p.r.gr = gr;
   2227   1.1  christos   return ptr;
   2228   1.1  christos }
   2229   1.1  christos 
   2230   1.1  christos static unw_rec_list *
   2231   1.1  christos output_bsp_psprel (unsigned int offset)
   2232   1.1  christos {
   2233   1.1  christos   unw_rec_list *ptr = alloc_record (bsp_psprel);
   2234   1.1  christos   ptr->r.record.p.off.psp = ENCODED_PSP_OFFSET (offset);
   2235   1.1  christos   return ptr;
   2236   1.1  christos }
   2237   1.1  christos 
   2238   1.1  christos static unw_rec_list *
   2239   1.1  christos output_bsp_sprel (unsigned int offset)
   2240   1.1  christos {
   2241   1.1  christos   unw_rec_list *ptr = alloc_record (bsp_sprel);
   2242   1.1  christos   ptr->r.record.p.off.sp = offset / 4;
   2243   1.1  christos   return ptr;
   2244   1.1  christos }
   2245   1.1  christos 
   2246   1.1  christos static unw_rec_list *
   2247   1.1  christos output_bspstore_when (void)
   2248   1.1  christos {
   2249   1.1  christos   unw_rec_list *ptr = alloc_record (bspstore_when);
   2250   1.1  christos   return ptr;
   2251   1.1  christos }
   2252   1.1  christos 
   2253   1.1  christos static unw_rec_list *
   2254   1.1  christos output_bspstore_gr (unsigned int gr)
   2255   1.1  christos {
   2256   1.1  christos   unw_rec_list *ptr = alloc_record (bspstore_gr);
   2257   1.1  christos   ptr->r.record.p.r.gr = gr;
   2258   1.1  christos   return ptr;
   2259   1.1  christos }
   2260   1.1  christos 
   2261   1.1  christos static unw_rec_list *
   2262   1.1  christos output_bspstore_psprel (unsigned int offset)
   2263   1.1  christos {
   2264   1.1  christos   unw_rec_list *ptr = alloc_record (bspstore_psprel);
   2265   1.1  christos   ptr->r.record.p.off.psp = ENCODED_PSP_OFFSET (offset);
   2266   1.1  christos   return ptr;
   2267   1.1  christos }
   2268   1.1  christos 
   2269   1.1  christos static unw_rec_list *
   2270   1.1  christos output_bspstore_sprel (unsigned int offset)
   2271   1.1  christos {
   2272   1.1  christos   unw_rec_list *ptr = alloc_record (bspstore_sprel);
   2273   1.1  christos   ptr->r.record.p.off.sp = offset / 4;
   2274   1.1  christos   return ptr;
   2275   1.1  christos }
   2276   1.1  christos 
   2277   1.1  christos static unw_rec_list *
   2278   1.1  christos output_rnat_when (void)
   2279   1.1  christos {
   2280   1.1  christos   unw_rec_list *ptr = alloc_record (rnat_when);
   2281   1.1  christos   return ptr;
   2282   1.1  christos }
   2283   1.1  christos 
   2284   1.1  christos static unw_rec_list *
   2285   1.1  christos output_rnat_gr (unsigned int gr)
   2286   1.1  christos {
   2287   1.1  christos   unw_rec_list *ptr = alloc_record (rnat_gr);
   2288   1.1  christos   ptr->r.record.p.r.gr = gr;
   2289   1.1  christos   return ptr;
   2290   1.1  christos }
   2291   1.1  christos 
   2292   1.1  christos static unw_rec_list *
   2293   1.1  christos output_rnat_psprel (unsigned int offset)
   2294   1.1  christos {
   2295   1.1  christos   unw_rec_list *ptr = alloc_record (rnat_psprel);
   2296   1.1  christos   ptr->r.record.p.off.psp = ENCODED_PSP_OFFSET (offset);
   2297   1.1  christos   return ptr;
   2298   1.1  christos }
   2299   1.1  christos 
   2300   1.1  christos static unw_rec_list *
   2301   1.1  christos output_rnat_sprel (unsigned int offset)
   2302   1.1  christos {
   2303   1.1  christos   unw_rec_list *ptr = alloc_record (rnat_sprel);
   2304   1.1  christos   ptr->r.record.p.off.sp = offset / 4;
   2305   1.1  christos   return ptr;
   2306   1.1  christos }
   2307   1.1  christos 
   2308   1.1  christos static unw_rec_list *
   2309   1.1  christos output_unwabi (unsigned long abi, unsigned long context)
   2310   1.1  christos {
   2311   1.1  christos   unw_rec_list *ptr = alloc_record (unwabi);
   2312   1.1  christos   ptr->r.record.p.abi = abi;
   2313   1.1  christos   ptr->r.record.p.context = context;
   2314   1.1  christos   return ptr;
   2315   1.1  christos }
   2316   1.1  christos 
   2317   1.1  christos static unw_rec_list *
   2318   1.1  christos output_epilogue (unsigned long ecount)
   2319   1.1  christos {
   2320   1.1  christos   unw_rec_list *ptr = alloc_record (epilogue);
   2321   1.1  christos   ptr->r.record.b.ecount = ecount;
   2322   1.1  christos   return ptr;
   2323   1.1  christos }
   2324   1.1  christos 
   2325   1.1  christos static unw_rec_list *
   2326   1.1  christos output_label_state (unsigned long label)
   2327   1.1  christos {
   2328   1.1  christos   unw_rec_list *ptr = alloc_record (label_state);
   2329   1.1  christos   ptr->r.record.b.label = label;
   2330   1.1  christos   return ptr;
   2331   1.1  christos }
   2332   1.1  christos 
   2333   1.1  christos static unw_rec_list *
   2334   1.1  christos output_copy_state (unsigned long label)
   2335   1.1  christos {
   2336   1.1  christos   unw_rec_list *ptr = alloc_record (copy_state);
   2337   1.1  christos   ptr->r.record.b.label = label;
   2338   1.1  christos   return ptr;
   2339   1.1  christos }
   2340   1.1  christos 
   2341   1.1  christos static unw_rec_list *
   2342   1.1  christos output_spill_psprel (unsigned int ab,
   2343   1.1  christos 		     unsigned int reg,
   2344   1.1  christos 		     unsigned int offset,
   2345   1.1  christos 		     unsigned int predicate)
   2346   1.1  christos {
   2347   1.1  christos   unw_rec_list *ptr = alloc_record (predicate ? spill_psprel_p : spill_psprel);
   2348   1.1  christos   ptr->r.record.x.ab = ab;
   2349   1.1  christos   ptr->r.record.x.reg = reg;
   2350   1.1  christos   ptr->r.record.x.where.pspoff = ENCODED_PSP_OFFSET (offset);
   2351   1.1  christos   ptr->r.record.x.qp = predicate;
   2352   1.1  christos   return ptr;
   2353   1.1  christos }
   2354   1.1  christos 
   2355   1.1  christos static unw_rec_list *
   2356   1.1  christos output_spill_sprel (unsigned int ab,
   2357   1.1  christos 		    unsigned int reg,
   2358   1.1  christos 		    unsigned int offset,
   2359   1.1  christos 		    unsigned int predicate)
   2360   1.1  christos {
   2361   1.1  christos   unw_rec_list *ptr = alloc_record (predicate ? spill_sprel_p : spill_sprel);
   2362   1.1  christos   ptr->r.record.x.ab = ab;
   2363   1.1  christos   ptr->r.record.x.reg = reg;
   2364   1.1  christos   ptr->r.record.x.where.spoff = offset / 4;
   2365   1.1  christos   ptr->r.record.x.qp = predicate;
   2366   1.1  christos   return ptr;
   2367   1.1  christos }
   2368   1.1  christos 
   2369   1.1  christos static unw_rec_list *
   2370   1.1  christos output_spill_reg (unsigned int ab,
   2371   1.1  christos 		  unsigned int reg,
   2372   1.1  christos 		  unsigned int targ_reg,
   2373   1.1  christos 		  unsigned int xy,
   2374   1.1  christos 		  unsigned int predicate)
   2375   1.1  christos {
   2376   1.1  christos   unw_rec_list *ptr = alloc_record (predicate ? spill_reg_p : spill_reg);
   2377   1.1  christos   ptr->r.record.x.ab = ab;
   2378   1.1  christos   ptr->r.record.x.reg = reg;
   2379   1.1  christos   ptr->r.record.x.where.reg = targ_reg;
   2380   1.1  christos   ptr->r.record.x.xy = xy;
   2381   1.1  christos   ptr->r.record.x.qp = predicate;
   2382   1.1  christos   return ptr;
   2383   1.1  christos }
   2384   1.1  christos 
   2385   1.1  christos /* Given a unw_rec_list process the correct format with the
   2386   1.1  christos    specified function.  */
   2387   1.1  christos 
   2388   1.1  christos static void
   2389   1.1  christos process_one_record (unw_rec_list *ptr, vbyte_func f)
   2390   1.1  christos {
   2391   1.1  christos   unsigned int fr_mask, gr_mask;
   2392   1.1  christos 
   2393   1.1  christos   switch (ptr->r.type)
   2394   1.1  christos     {
   2395   1.1  christos       /* This is a dummy record that takes up no space in the output.  */
   2396   1.1  christos     case endp:
   2397   1.1  christos       break;
   2398   1.1  christos 
   2399   1.1  christos     case gr_mem:
   2400   1.1  christos     case fr_mem:
   2401   1.1  christos     case br_mem:
   2402   1.1  christos     case frgr_mem:
   2403   1.1  christos       /* These are taken care of by prologue/prologue_gr.  */
   2404   1.1  christos       break;
   2405   1.1  christos 
   2406   1.1  christos     case prologue_gr:
   2407   1.1  christos     case prologue:
   2408   1.1  christos       if (ptr->r.type == prologue_gr)
   2409   1.1  christos 	output_R2_format (f, ptr->r.record.r.grmask,
   2410   1.1  christos 			  ptr->r.record.r.grsave, ptr->r.record.r.rlen);
   2411   1.1  christos       else
   2412   1.1  christos 	output_R1_format (f, ptr->r.type, ptr->r.record.r.rlen);
   2413   1.1  christos 
   2414   1.1  christos       /* Output descriptor(s) for union of register spills (if any).  */
   2415   1.1  christos       gr_mask = ptr->r.record.r.mask.gr_mem;
   2416   1.1  christos       fr_mask = ptr->r.record.r.mask.fr_mem;
   2417   1.1  christos       if (fr_mask)
   2418   1.1  christos 	{
   2419   1.1  christos 	  if ((fr_mask & ~0xfUL) == 0)
   2420   1.1  christos 	    output_P6_format (f, fr_mem, fr_mask);
   2421   1.1  christos 	  else
   2422   1.1  christos 	    {
   2423   1.1  christos 	      output_P5_format (f, gr_mask, fr_mask);
   2424   1.1  christos 	      gr_mask = 0;
   2425   1.1  christos 	    }
   2426   1.1  christos 	}
   2427   1.1  christos       if (gr_mask)
   2428   1.1  christos 	output_P6_format (f, gr_mem, gr_mask);
   2429   1.1  christos       if (ptr->r.record.r.mask.br_mem)
   2430   1.1  christos 	output_P1_format (f, ptr->r.record.r.mask.br_mem);
   2431   1.1  christos 
   2432   1.1  christos       /* output imask descriptor if necessary:  */
   2433   1.1  christos       if (ptr->r.record.r.mask.i)
   2434   1.1  christos 	output_P4_format (f, ptr->r.record.r.mask.i,
   2435   1.1  christos 			  ptr->r.record.r.imask_size);
   2436   1.1  christos       break;
   2437   1.1  christos 
   2438   1.1  christos     case body:
   2439   1.1  christos       output_R1_format (f, ptr->r.type, ptr->r.record.r.rlen);
   2440   1.1  christos       break;
   2441   1.1  christos     case mem_stack_f:
   2442   1.1  christos     case mem_stack_v:
   2443   1.1  christos       output_P7_format (f, ptr->r.type, ptr->r.record.p.t,
   2444   1.1  christos 			ptr->r.record.p.size);
   2445   1.1  christos       break;
   2446   1.1  christos     case psp_gr:
   2447   1.1  christos     case rp_gr:
   2448   1.1  christos     case pfs_gr:
   2449   1.1  christos     case preds_gr:
   2450   1.1  christos     case unat_gr:
   2451   1.1  christos     case lc_gr:
   2452   1.1  christos     case fpsr_gr:
   2453   1.1  christos     case priunat_gr:
   2454   1.1  christos     case bsp_gr:
   2455   1.1  christos     case bspstore_gr:
   2456   1.1  christos     case rnat_gr:
   2457   1.1  christos       output_P3_format (f, ptr->r.type, ptr->r.record.p.r.gr);
   2458   1.1  christos       break;
   2459   1.1  christos     case rp_br:
   2460   1.1  christos       output_P3_format (f, rp_br, ptr->r.record.p.r.br);
   2461   1.1  christos       break;
   2462   1.1  christos     case psp_sprel:
   2463   1.1  christos       output_P7_format (f, psp_sprel, ptr->r.record.p.off.sp, 0);
   2464   1.1  christos       break;
   2465   1.1  christos     case rp_when:
   2466   1.1  christos     case pfs_when:
   2467   1.1  christos     case preds_when:
   2468   1.1  christos     case unat_when:
   2469   1.1  christos     case lc_when:
   2470   1.1  christos     case fpsr_when:
   2471   1.1  christos       output_P7_format (f, ptr->r.type, ptr->r.record.p.t, 0);
   2472   1.1  christos       break;
   2473   1.1  christos     case rp_psprel:
   2474   1.1  christos     case pfs_psprel:
   2475   1.1  christos     case preds_psprel:
   2476   1.1  christos     case unat_psprel:
   2477   1.1  christos     case lc_psprel:
   2478   1.1  christos     case fpsr_psprel:
   2479   1.1  christos     case spill_base:
   2480   1.1  christos       output_P7_format (f, ptr->r.type, ptr->r.record.p.off.psp, 0);
   2481   1.1  christos       break;
   2482   1.1  christos     case rp_sprel:
   2483   1.1  christos     case pfs_sprel:
   2484   1.1  christos     case preds_sprel:
   2485   1.1  christos     case unat_sprel:
   2486   1.1  christos     case lc_sprel:
   2487   1.1  christos     case fpsr_sprel:
   2488   1.1  christos     case priunat_sprel:
   2489   1.1  christos     case bsp_sprel:
   2490   1.1  christos     case bspstore_sprel:
   2491   1.1  christos     case rnat_sprel:
   2492   1.1  christos       output_P8_format (f, ptr->r.type, ptr->r.record.p.off.sp);
   2493   1.1  christos       break;
   2494   1.1  christos     case gr_gr:
   2495   1.1  christos       if (ptr->r.record.p.r.gr < REG_NUM)
   2496   1.1  christos 	{
   2497   1.1  christos 	  const unw_rec_list *cur = ptr;
   2498   1.1  christos 
   2499   1.1  christos 	  gr_mask = cur->r.record.p.grmask;
   2500   1.1  christos 	  while ((cur = cur->r.record.p.next) != NULL)
   2501   1.1  christos 	    gr_mask |= cur->r.record.p.grmask;
   2502   1.1  christos 	  output_P9_format (f, gr_mask, ptr->r.record.p.r.gr);
   2503   1.1  christos 	}
   2504   1.1  christos       break;
   2505   1.1  christos     case br_gr:
   2506   1.1  christos       if (ptr->r.record.p.r.gr < REG_NUM)
   2507   1.1  christos 	{
   2508   1.1  christos 	  const unw_rec_list *cur = ptr;
   2509   1.1  christos 
   2510   1.1  christos 	  gr_mask = cur->r.record.p.brmask;
   2511   1.1  christos 	  while ((cur = cur->r.record.p.next) != NULL)
   2512   1.1  christos 	    gr_mask |= cur->r.record.p.brmask;
   2513   1.1  christos 	  output_P2_format (f, gr_mask, ptr->r.record.p.r.gr);
   2514   1.1  christos 	}
   2515   1.1  christos       break;
   2516   1.1  christos     case spill_mask:
   2517   1.1  christos       as_bad (_("spill_mask record unimplemented."));
   2518   1.1  christos       break;
   2519   1.1  christos     case priunat_when_gr:
   2520   1.1  christos     case priunat_when_mem:
   2521   1.1  christos     case bsp_when:
   2522   1.1  christos     case bspstore_when:
   2523   1.1  christos     case rnat_when:
   2524   1.1  christos       output_P8_format (f, ptr->r.type, ptr->r.record.p.t);
   2525   1.1  christos       break;
   2526   1.1  christos     case priunat_psprel:
   2527   1.1  christos     case bsp_psprel:
   2528   1.1  christos     case bspstore_psprel:
   2529   1.1  christos     case rnat_psprel:
   2530   1.1  christos       output_P8_format (f, ptr->r.type, ptr->r.record.p.off.psp);
   2531   1.1  christos       break;
   2532   1.1  christos     case unwabi:
   2533   1.1  christos       output_P10_format (f, ptr->r.record.p.abi, ptr->r.record.p.context);
   2534   1.1  christos       break;
   2535   1.1  christos     case epilogue:
   2536   1.1  christos       output_B3_format (f, ptr->r.record.b.ecount, ptr->r.record.b.t);
   2537   1.1  christos       break;
   2538   1.1  christos     case label_state:
   2539   1.1  christos     case copy_state:
   2540   1.1  christos       output_B4_format (f, ptr->r.type, ptr->r.record.b.label);
   2541   1.1  christos       break;
   2542   1.1  christos     case spill_psprel:
   2543   1.1  christos       output_X1_format (f, ptr->r.type, ptr->r.record.x.ab,
   2544   1.1  christos 			ptr->r.record.x.reg, ptr->r.record.x.t,
   2545   1.1  christos 			ptr->r.record.x.where.pspoff);
   2546   1.1  christos       break;
   2547   1.1  christos     case spill_sprel:
   2548   1.1  christos       output_X1_format (f, ptr->r.type, ptr->r.record.x.ab,
   2549   1.1  christos 			ptr->r.record.x.reg, ptr->r.record.x.t,
   2550   1.1  christos 			ptr->r.record.x.where.spoff);
   2551   1.1  christos       break;
   2552   1.1  christos     case spill_reg:
   2553   1.1  christos       output_X2_format (f, ptr->r.record.x.ab, ptr->r.record.x.reg,
   2554   1.1  christos 			ptr->r.record.x.xy >> 1, ptr->r.record.x.xy,
   2555   1.1  christos 			ptr->r.record.x.where.reg, ptr->r.record.x.t);
   2556   1.1  christos       break;
   2557   1.1  christos     case spill_psprel_p:
   2558   1.1  christos       output_X3_format (f, ptr->r.type, ptr->r.record.x.qp,
   2559   1.1  christos 			ptr->r.record.x.ab, ptr->r.record.x.reg,
   2560   1.1  christos 			ptr->r.record.x.t, ptr->r.record.x.where.pspoff);
   2561   1.1  christos       break;
   2562   1.1  christos     case spill_sprel_p:
   2563   1.1  christos       output_X3_format (f, ptr->r.type, ptr->r.record.x.qp,
   2564   1.1  christos 			ptr->r.record.x.ab, ptr->r.record.x.reg,
   2565   1.1  christos 			ptr->r.record.x.t, ptr->r.record.x.where.spoff);
   2566   1.1  christos       break;
   2567   1.1  christos     case spill_reg_p:
   2568   1.1  christos       output_X4_format (f, ptr->r.record.x.qp, ptr->r.record.x.ab,
   2569   1.1  christos 			ptr->r.record.x.reg, ptr->r.record.x.xy >> 1,
   2570   1.1  christos 			ptr->r.record.x.xy, ptr->r.record.x.where.reg,
   2571   1.1  christos 			ptr->r.record.x.t);
   2572   1.1  christos       break;
   2573   1.1  christos     default:
   2574   1.1  christos       as_bad (_("record_type_not_valid"));
   2575   1.1  christos       break;
   2576   1.1  christos     }
   2577   1.1  christos }
   2578   1.1  christos 
   2579   1.1  christos /* Given a unw_rec_list list, process all the records with
   2580   1.1  christos    the specified function.  */
   2581   1.1  christos static void
   2582   1.1  christos process_unw_records (unw_rec_list *list, vbyte_func f)
   2583   1.1  christos {
   2584   1.1  christos   unw_rec_list *ptr;
   2585   1.1  christos   for (ptr = list; ptr; ptr = ptr->next)
   2586   1.1  christos     process_one_record (ptr, f);
   2587   1.1  christos }
   2588   1.1  christos 
   2589   1.1  christos /* Determine the size of a record list in bytes.  */
   2590   1.1  christos static int
   2591   1.1  christos calc_record_size (unw_rec_list *list)
   2592   1.1  christos {
   2593   1.1  christos   vbyte_count = 0;
   2594   1.1  christos   process_unw_records (list, count_output);
   2595   1.1  christos   return vbyte_count;
   2596   1.1  christos }
   2597   1.1  christos 
   2598   1.1  christos /* Return the number of bits set in the input value.
   2599   1.1  christos    Perhaps this has a better place...  */
   2600   1.1  christos #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
   2601   1.1  christos # define popcount __builtin_popcount
   2602   1.1  christos #else
   2603   1.1  christos static int
   2604   1.1  christos popcount (unsigned x)
   2605   1.1  christos {
   2606   1.1  christos   static const unsigned char popcnt[16] =
   2607   1.1  christos     {
   2608   1.1  christos       0, 1, 1, 2,
   2609   1.1  christos       1, 2, 2, 3,
   2610   1.1  christos       1, 2, 2, 3,
   2611   1.1  christos       2, 3, 3, 4
   2612   1.1  christos     };
   2613   1.1  christos 
   2614   1.1  christos   if (x < NELEMS (popcnt))
   2615   1.1  christos     return popcnt[x];
   2616   1.1  christos   return popcnt[x % NELEMS (popcnt)] + popcount (x / NELEMS (popcnt));
   2617   1.1  christos }
   2618   1.1  christos #endif
   2619   1.1  christos 
   2620   1.1  christos /* Update IMASK bitmask to reflect the fact that one or more registers
   2621   1.1  christos    of type TYPE are saved starting at instruction with index T.  If N
   2622   1.1  christos    bits are set in REGMASK, it is assumed that instructions T through
   2623   1.1  christos    T+N-1 save these registers.
   2624   1.1  christos 
   2625   1.1  christos    TYPE values:
   2626   1.1  christos 	0: no save
   2627   1.1  christos 	1: instruction saves next fp reg
   2628   1.1  christos 	2: instruction saves next general reg
   2629   1.1  christos 	3: instruction saves next branch reg */
   2630   1.1  christos static void
   2631   1.1  christos set_imask (unw_rec_list *region,
   2632   1.1  christos 	   unsigned long regmask,
   2633   1.1  christos 	   unsigned long t,
   2634   1.1  christos 	   unsigned int type)
   2635   1.1  christos {
   2636   1.1  christos   unsigned char *imask;
   2637   1.1  christos   unsigned long imask_size;
   2638   1.1  christos   unsigned int i;
   2639   1.1  christos   int pos;
   2640   1.1  christos 
   2641   1.1  christos   imask = region->r.record.r.mask.i;
   2642   1.1  christos   imask_size = region->r.record.r.imask_size;
   2643   1.1  christos   if (!imask)
   2644   1.1  christos     {
   2645   1.1  christos       imask_size = (region->r.record.r.rlen * 2 + 7) / 8 + 1;
   2646   1.5  christos       imask = XCNEWVEC (unsigned char, imask_size);
   2647   1.1  christos 
   2648   1.1  christos       region->r.record.r.imask_size = imask_size;
   2649   1.1  christos       region->r.record.r.mask.i = imask;
   2650   1.1  christos     }
   2651   1.1  christos 
   2652   1.1  christos   i = (t / 4) + 1;
   2653   1.1  christos   pos = 2 * (3 - t % 4);
   2654   1.1  christos   while (regmask)
   2655   1.1  christos     {
   2656   1.1  christos       if (i >= imask_size)
   2657   1.1  christos 	{
   2658   1.1  christos 	  as_bad (_("Ignoring attempt to spill beyond end of region"));
   2659   1.1  christos 	  return;
   2660   1.1  christos 	}
   2661   1.1  christos 
   2662   1.1  christos       imask[i] |= (type & 0x3) << pos;
   2663   1.1  christos 
   2664   1.1  christos       regmask &= (regmask - 1);
   2665   1.1  christos       pos -= 2;
   2666   1.1  christos       if (pos < 0)
   2667   1.1  christos 	{
   2668   1.1  christos 	  pos = 0;
   2669   1.1  christos 	  ++i;
   2670   1.1  christos 	}
   2671   1.1  christos     }
   2672   1.1  christos }
   2673   1.1  christos 
   2674   1.1  christos /* Return the number of instruction slots from FIRST_ADDR to SLOT_ADDR.
   2675   1.1  christos    SLOT_FRAG is the frag containing SLOT_ADDR, and FIRST_FRAG is the frag
   2676   1.1  christos    containing FIRST_ADDR.  If BEFORE_RELAX, then we use worst-case estimates
   2677   1.1  christos    for frag sizes.  */
   2678   1.1  christos 
   2679   1.1  christos static unsigned long
   2680   1.1  christos slot_index (unsigned long slot_addr,
   2681   1.1  christos 	    fragS *slot_frag,
   2682   1.1  christos 	    unsigned long first_addr,
   2683   1.1  christos 	    fragS *first_frag,
   2684   1.1  christos 	    int before_relax)
   2685   1.1  christos {
   2686   1.1  christos   unsigned long s_index = 0;
   2687   1.1  christos 
   2688   1.1  christos   /* First time we are called, the initial address and frag are invalid.  */
   2689   1.1  christos   if (first_addr == 0)
   2690   1.1  christos     return 0;
   2691   1.1  christos 
   2692   1.1  christos   /* If the two addresses are in different frags, then we need to add in
   2693   1.1  christos      the remaining size of this frag, and then the entire size of intermediate
   2694   1.1  christos      frags.  */
   2695   1.1  christos   while (slot_frag != first_frag)
   2696   1.1  christos     {
   2697   1.1  christos       unsigned long start_addr = (unsigned long) &first_frag->fr_literal;
   2698   1.1  christos 
   2699   1.1  christos       if (! before_relax)
   2700   1.1  christos 	{
   2701   1.1  christos 	  /* We can get the final addresses only during and after
   2702   1.1  christos 	     relaxation.  */
   2703   1.1  christos 	  if (first_frag->fr_next && first_frag->fr_next->fr_address)
   2704   1.1  christos 	    s_index += 3 * ((first_frag->fr_next->fr_address
   2705   1.1  christos 			   - first_frag->fr_address
   2706   1.1  christos 			     - first_frag->fr_fix) >> 4);
   2707   1.1  christos 	}
   2708   1.1  christos       else
   2709   1.1  christos 	/* We don't know what the final addresses will be. We try our
   2710   1.1  christos 	   best to estimate.  */
   2711   1.1  christos 	switch (first_frag->fr_type)
   2712   1.1  christos 	  {
   2713   1.1  christos 	  default:
   2714   1.1  christos 	    break;
   2715   1.1  christos 
   2716   1.1  christos 	  case rs_space:
   2717   1.1  christos 	    as_fatal (_("Only constant space allocation is supported"));
   2718   1.1  christos 	    break;
   2719   1.1  christos 
   2720   1.1  christos 	  case rs_align:
   2721   1.1  christos 	  case rs_align_code:
   2722   1.1  christos 	  case rs_align_test:
   2723   1.1  christos 	    /* Take alignment into account.  Assume the worst case
   2724   1.1  christos 	       before relaxation.  */
   2725   1.1  christos 	    s_index += 3 * ((1 << first_frag->fr_offset) >> 4);
   2726   1.1  christos 	    break;
   2727   1.1  christos 
   2728   1.1  christos 	  case rs_org:
   2729   1.1  christos 	    if (first_frag->fr_symbol)
   2730   1.1  christos 	      {
   2731   1.1  christos 		as_fatal (_("Only constant offsets are supported"));
   2732   1.1  christos 		break;
   2733   1.1  christos 	      }
   2734   1.6  christos 	    /* Fall through.  */
   2735   1.1  christos 	  case rs_fill:
   2736   1.1  christos 	    s_index += 3 * (first_frag->fr_offset >> 4);
   2737   1.1  christos 	    break;
   2738   1.1  christos 	  }
   2739   1.1  christos 
   2740   1.1  christos       /* Add in the full size of the frag converted to instruction slots.  */
   2741   1.1  christos       s_index += 3 * (first_frag->fr_fix >> 4);
   2742   1.1  christos       /* Subtract away the initial part before first_addr.  */
   2743   1.1  christos       s_index -= (3 * ((first_addr >> 4) - (start_addr >> 4))
   2744   1.1  christos 		+ ((first_addr & 0x3) - (start_addr & 0x3)));
   2745   1.1  christos 
   2746   1.1  christos       /* Move to the beginning of the next frag.  */
   2747   1.1  christos       first_frag = first_frag->fr_next;
   2748   1.1  christos       first_addr = (unsigned long) &first_frag->fr_literal;
   2749   1.1  christos 
   2750   1.1  christos       /* This can happen if there is section switching in the middle of a
   2751   1.1  christos 	 function, causing the frag chain for the function to be broken.
   2752   1.1  christos 	 It is too difficult to recover safely from this problem, so we just
   2753   1.1  christos 	 exit with an error.  */
   2754   1.1  christos       if (first_frag == NULL)
   2755   1.1  christos 	as_fatal (_("Section switching in code is not supported."));
   2756   1.1  christos     }
   2757   1.1  christos 
   2758   1.1  christos   /* Add in the used part of the last frag.  */
   2759   1.1  christos   s_index += (3 * ((slot_addr >> 4) - (first_addr >> 4))
   2760   1.1  christos 	    + ((slot_addr & 0x3) - (first_addr & 0x3)));
   2761   1.1  christos   return s_index;
   2762   1.1  christos }
   2763   1.1  christos 
   2764   1.1  christos /* Optimize unwind record directives.  */
   2765   1.1  christos 
   2766   1.1  christos static unw_rec_list *
   2767   1.1  christos optimize_unw_records (unw_rec_list *list)
   2768   1.1  christos {
   2769   1.1  christos   if (!list)
   2770   1.1  christos     return NULL;
   2771   1.1  christos 
   2772   1.1  christos   /* If the only unwind record is ".prologue" or ".prologue" followed
   2773   1.1  christos      by ".body", then we can optimize the unwind directives away.  */
   2774   1.1  christos   if (list->r.type == prologue
   2775   1.1  christos       && (list->next->r.type == endp
   2776   1.1  christos 	  || (list->next->r.type == body && list->next->next->r.type == endp)))
   2777   1.1  christos     return NULL;
   2778   1.1  christos 
   2779   1.1  christos   return list;
   2780   1.1  christos }
   2781   1.1  christos 
   2782   1.1  christos /* Given a complete record list, process any records which have
   2783   1.1  christos    unresolved fields, (ie length counts for a prologue).  After
   2784   1.1  christos    this has been run, all necessary information should be available
   2785   1.1  christos    within each record to generate an image.  */
   2786   1.1  christos 
   2787   1.1  christos static void
   2788   1.1  christos fixup_unw_records (unw_rec_list *list, int before_relax)
   2789   1.1  christos {
   2790   1.1  christos   unw_rec_list *ptr, *region = 0;
   2791   1.1  christos   unsigned long first_addr = 0, rlen = 0, t;
   2792   1.1  christos   fragS *first_frag = 0;
   2793   1.1  christos 
   2794   1.1  christos   for (ptr = list; ptr; ptr = ptr->next)
   2795   1.1  christos     {
   2796   1.1  christos       if (ptr->slot_number == SLOT_NUM_NOT_SET)
   2797   1.6  christos 	as_bad (_("Insn slot not set in unwind record."));
   2798   1.1  christos       t = slot_index (ptr->slot_number, ptr->slot_frag,
   2799   1.1  christos 		      first_addr, first_frag, before_relax);
   2800   1.1  christos       switch (ptr->r.type)
   2801   1.1  christos 	{
   2802   1.1  christos 	case prologue:
   2803   1.1  christos 	case prologue_gr:
   2804   1.1  christos 	case body:
   2805   1.1  christos 	  {
   2806   1.1  christos 	    unw_rec_list *last;
   2807   1.1  christos 	    int size;
   2808   1.1  christos 	    unsigned long last_addr = 0;
   2809   1.1  christos 	    fragS *last_frag = NULL;
   2810   1.1  christos 
   2811   1.1  christos 	    first_addr = ptr->slot_number;
   2812   1.1  christos 	    first_frag = ptr->slot_frag;
   2813   1.1  christos 	    /* Find either the next body/prologue start, or the end of
   2814   1.1  christos 	       the function, and determine the size of the region.  */
   2815   1.1  christos 	    for (last = ptr->next; last != NULL; last = last->next)
   2816   1.1  christos 	      if (last->r.type == prologue || last->r.type == prologue_gr
   2817   1.1  christos 		  || last->r.type == body || last->r.type == endp)
   2818   1.1  christos 		{
   2819   1.1  christos 		  last_addr = last->slot_number;
   2820   1.1  christos 		  last_frag = last->slot_frag;
   2821   1.1  christos 		  break;
   2822   1.1  christos 		}
   2823   1.1  christos 	    size = slot_index (last_addr, last_frag, first_addr, first_frag,
   2824   1.1  christos 			       before_relax);
   2825   1.1  christos 	    rlen = ptr->r.record.r.rlen = size;
   2826   1.1  christos 	    if (ptr->r.type == body)
   2827   1.1  christos 	      /* End of region.  */
   2828   1.1  christos 	      region = 0;
   2829   1.1  christos 	    else
   2830   1.1  christos 	      region = ptr;
   2831   1.1  christos 	    break;
   2832   1.1  christos 	  }
   2833   1.1  christos 	case epilogue:
   2834   1.1  christos 	  if (t < rlen)
   2835   1.1  christos 	    ptr->r.record.b.t = rlen - 1 - t;
   2836   1.1  christos 	  else
   2837   1.1  christos 	    /* This happens when a memory-stack-less procedure uses a
   2838   1.1  christos 	       ".restore sp" directive at the end of a region to pop
   2839   1.1  christos 	       the frame state.  */
   2840   1.1  christos 	    ptr->r.record.b.t = 0;
   2841   1.1  christos 	  break;
   2842   1.1  christos 
   2843   1.1  christos 	case mem_stack_f:
   2844   1.1  christos 	case mem_stack_v:
   2845   1.1  christos 	case rp_when:
   2846   1.1  christos 	case pfs_when:
   2847   1.1  christos 	case preds_when:
   2848   1.1  christos 	case unat_when:
   2849   1.1  christos 	case lc_when:
   2850   1.1  christos 	case fpsr_when:
   2851   1.1  christos 	case priunat_when_gr:
   2852   1.1  christos 	case priunat_when_mem:
   2853   1.1  christos 	case bsp_when:
   2854   1.1  christos 	case bspstore_when:
   2855   1.1  christos 	case rnat_when:
   2856   1.1  christos 	  ptr->r.record.p.t = t;
   2857   1.1  christos 	  break;
   2858   1.1  christos 
   2859   1.1  christos 	case spill_reg:
   2860   1.1  christos 	case spill_sprel:
   2861   1.1  christos 	case spill_psprel:
   2862   1.1  christos 	case spill_reg_p:
   2863   1.1  christos 	case spill_sprel_p:
   2864   1.1  christos 	case spill_psprel_p:
   2865   1.1  christos 	  ptr->r.record.x.t = t;
   2866   1.1  christos 	  break;
   2867   1.1  christos 
   2868   1.1  christos 	case frgr_mem:
   2869   1.1  christos 	  if (!region)
   2870   1.1  christos 	    {
   2871   1.1  christos 	      as_bad (_("frgr_mem record before region record!"));
   2872   1.1  christos 	      return;
   2873   1.1  christos 	    }
   2874   1.1  christos 	  region->r.record.r.mask.fr_mem |= ptr->r.record.p.frmask;
   2875   1.1  christos 	  region->r.record.r.mask.gr_mem |= ptr->r.record.p.grmask;
   2876   1.1  christos 	  set_imask (region, ptr->r.record.p.frmask, t, 1);
   2877   1.1  christos 	  set_imask (region, ptr->r.record.p.grmask, t, 2);
   2878   1.1  christos 	  break;
   2879   1.1  christos 	case fr_mem:
   2880   1.1  christos 	  if (!region)
   2881   1.1  christos 	    {
   2882   1.1  christos 	      as_bad (_("fr_mem record before region record!"));
   2883   1.1  christos 	      return;
   2884   1.1  christos 	    }
   2885   1.1  christos 	  region->r.record.r.mask.fr_mem |= ptr->r.record.p.frmask;
   2886   1.1  christos 	  set_imask (region, ptr->r.record.p.frmask, t, 1);
   2887   1.1  christos 	  break;
   2888   1.1  christos 	case gr_mem:
   2889   1.1  christos 	  if (!region)
   2890   1.1  christos 	    {
   2891   1.1  christos 	      as_bad (_("gr_mem record before region record!"));
   2892   1.1  christos 	      return;
   2893   1.1  christos 	    }
   2894   1.1  christos 	  region->r.record.r.mask.gr_mem |= ptr->r.record.p.grmask;
   2895   1.1  christos 	  set_imask (region, ptr->r.record.p.grmask, t, 2);
   2896   1.1  christos 	  break;
   2897   1.1  christos 	case br_mem:
   2898   1.1  christos 	  if (!region)
   2899   1.1  christos 	    {
   2900   1.1  christos 	      as_bad (_("br_mem record before region record!"));
   2901   1.1  christos 	      return;
   2902   1.1  christos 	    }
   2903   1.1  christos 	  region->r.record.r.mask.br_mem |= ptr->r.record.p.brmask;
   2904   1.1  christos 	  set_imask (region, ptr->r.record.p.brmask, t, 3);
   2905   1.1  christos 	  break;
   2906   1.1  christos 
   2907   1.1  christos 	case gr_gr:
   2908   1.1  christos 	  if (!region)
   2909   1.1  christos 	    {
   2910   1.1  christos 	      as_bad (_("gr_gr record before region record!"));
   2911   1.1  christos 	      return;
   2912   1.1  christos 	    }
   2913   1.1  christos 	  set_imask (region, ptr->r.record.p.grmask, t, 2);
   2914   1.1  christos 	  break;
   2915   1.1  christos 	case br_gr:
   2916   1.1  christos 	  if (!region)
   2917   1.1  christos 	    {
   2918   1.1  christos 	      as_bad (_("br_gr record before region record!"));
   2919   1.1  christos 	      return;
   2920   1.1  christos 	    }
   2921   1.1  christos 	  set_imask (region, ptr->r.record.p.brmask, t, 3);
   2922   1.1  christos 	  break;
   2923   1.1  christos 
   2924   1.1  christos 	default:
   2925   1.1  christos 	  break;
   2926   1.1  christos 	}
   2927   1.1  christos     }
   2928   1.1  christos }
   2929   1.1  christos 
   2930   1.1  christos /* Estimate the size of a frag before relaxing.  We only have one type of frag
   2931   1.1  christos    to handle here, which is the unwind info frag.  */
   2932   1.1  christos 
   2933   1.1  christos int
   2934   1.1  christos ia64_estimate_size_before_relax (fragS *frag,
   2935   1.1  christos 				 asection *segtype ATTRIBUTE_UNUSED)
   2936   1.1  christos {
   2937   1.1  christos   unw_rec_list *list;
   2938   1.1  christos   int len, size, pad;
   2939   1.1  christos 
   2940   1.1  christos   /* ??? This code is identical to the first part of ia64_convert_frag.  */
   2941   1.1  christos   list = (unw_rec_list *) frag->fr_opcode;
   2942   1.1  christos   fixup_unw_records (list, 0);
   2943   1.1  christos 
   2944   1.1  christos   len = calc_record_size (list);
   2945   1.1  christos   /* pad to pointer-size boundary.  */
   2946   1.1  christos   pad = len % md.pointer_size;
   2947   1.1  christos   if (pad != 0)
   2948   1.1  christos     len += md.pointer_size - pad;
   2949   1.1  christos   /* Add 8 for the header.  */
   2950   1.1  christos   size = len + 8;
   2951   1.1  christos   /* Add a pointer for the personality offset.  */
   2952   1.1  christos   if (frag->fr_offset)
   2953   1.1  christos     size += md.pointer_size;
   2954   1.1  christos 
   2955   1.1  christos   /* fr_var carries the max_chars that we created the fragment with.
   2956   1.1  christos      We must, of course, have allocated enough memory earlier.  */
   2957   1.1  christos   gas_assert (frag->fr_var >= size);
   2958   1.1  christos 
   2959   1.1  christos   return frag->fr_fix + size;
   2960   1.1  christos }
   2961   1.1  christos 
   2962   1.1  christos /* This function converts a rs_machine_dependent variant frag into a
   2963   1.3  christos   normal fill frag with the unwind image from the record list.  */
   2964   1.1  christos void
   2965   1.1  christos ia64_convert_frag (fragS *frag)
   2966   1.1  christos {
   2967   1.1  christos   unw_rec_list *list;
   2968   1.1  christos   int len, size, pad;
   2969   1.1  christos   valueT flag_value;
   2970   1.1  christos 
   2971   1.1  christos   /* ??? This code is identical to ia64_estimate_size_before_relax.  */
   2972   1.1  christos   list = (unw_rec_list *) frag->fr_opcode;
   2973   1.1  christos   fixup_unw_records (list, 0);
   2974   1.1  christos 
   2975   1.1  christos   len = calc_record_size (list);
   2976   1.1  christos   /* pad to pointer-size boundary.  */
   2977   1.1  christos   pad = len % md.pointer_size;
   2978   1.1  christos   if (pad != 0)
   2979   1.1  christos     len += md.pointer_size - pad;
   2980   1.1  christos   /* Add 8 for the header.  */
   2981   1.1  christos   size = len + 8;
   2982   1.1  christos   /* Add a pointer for the personality offset.  */
   2983   1.1  christos   if (frag->fr_offset)
   2984   1.1  christos     size += md.pointer_size;
   2985   1.1  christos 
   2986   1.1  christos   /* fr_var carries the max_chars that we created the fragment with.
   2987   1.1  christos      We must, of course, have allocated enough memory earlier.  */
   2988   1.1  christos   gas_assert (frag->fr_var >= size);
   2989   1.1  christos 
   2990   1.1  christos   /* Initialize the header area. fr_offset is initialized with
   2991   1.1  christos      unwind.personality_routine.  */
   2992   1.1  christos   if (frag->fr_offset)
   2993   1.1  christos     {
   2994   1.1  christos       if (md.flags & EF_IA_64_ABI64)
   2995   1.1  christos 	flag_value = (bfd_vma) 3 << 32;
   2996   1.1  christos       else
   2997   1.1  christos 	/* 32-bit unwind info block.  */
   2998   1.1  christos 	flag_value = (bfd_vma) 0x1003 << 32;
   2999   1.1  christos     }
   3000   1.1  christos   else
   3001   1.1  christos     flag_value = 0;
   3002   1.1  christos 
   3003   1.1  christos  md_number_to_chars (frag->fr_literal,
   3004   1.1  christos 		     (((bfd_vma) 1 << 48) /* Version.  */
   3005   1.1  christos 		      | flag_value        /* U & E handler flags.  */
   3006   1.1  christos 		      | (len / md.pointer_size)), /* Length.  */
   3007   1.1  christos 		     8);
   3008   1.1  christos 
   3009   1.1  christos   /* Skip the header.  */
   3010   1.1  christos   vbyte_mem_ptr = frag->fr_literal + 8;
   3011   1.1  christos   process_unw_records (list, output_vbyte_mem);
   3012   1.1  christos 
   3013   1.1  christos   /* Fill the padding bytes with zeros.  */
   3014   1.1  christos   if (pad != 0)
   3015   1.1  christos     md_number_to_chars (frag->fr_literal + len + 8 - md.pointer_size + pad, 0,
   3016   1.1  christos 			md.pointer_size - pad);
   3017   1.1  christos   /* Fill the unwind personality with zeros.  */
   3018   1.1  christos   if (frag->fr_offset)
   3019   1.1  christos     md_number_to_chars (frag->fr_literal + size - md.pointer_size, 0,
   3020   1.1  christos 			md.pointer_size);
   3021   1.1  christos 
   3022   1.1  christos   frag->fr_fix += size;
   3023   1.1  christos   frag->fr_type = rs_fill;
   3024   1.1  christos   frag->fr_var = 0;
   3025   1.1  christos   frag->fr_offset = 0;
   3026   1.1  christos }
   3027   1.1  christos 
   3028   1.1  christos static int
   3029   1.1  christos parse_predicate_and_operand (expressionS *e, unsigned *qp, const char *po)
   3030   1.1  christos {
   3031   1.1  christos   int sep = parse_operand_and_eval (e, ',');
   3032   1.1  christos 
   3033   1.1  christos   *qp = e->X_add_number - REG_P;
   3034   1.1  christos   if (e->X_op != O_register || *qp > 63)
   3035   1.1  christos     {
   3036   1.1  christos       as_bad (_("First operand to .%s must be a predicate"), po);
   3037   1.1  christos       *qp = 0;
   3038   1.1  christos     }
   3039   1.1  christos   else if (*qp == 0)
   3040   1.1  christos     as_warn (_("Pointless use of p0 as first operand to .%s"), po);
   3041   1.1  christos   if (sep == ',')
   3042   1.1  christos     sep = parse_operand_and_eval (e, ',');
   3043   1.1  christos   else
   3044   1.1  christos     e->X_op = O_absent;
   3045   1.1  christos   return sep;
   3046   1.1  christos }
   3047   1.1  christos 
   3048   1.1  christos static void
   3049   1.1  christos convert_expr_to_ab_reg (const expressionS *e,
   3050   1.1  christos 			unsigned int *ab,
   3051   1.1  christos 			unsigned int *regp,
   3052   1.1  christos 			const char *po,
   3053   1.1  christos 			int n)
   3054   1.1  christos {
   3055   1.1  christos   unsigned int reg = e->X_add_number;
   3056   1.1  christos 
   3057   1.1  christos   *ab = *regp = 0; /* Anything valid is good here.  */
   3058   1.1  christos 
   3059   1.1  christos   if (e->X_op != O_register)
   3060   1.1  christos     reg = REG_GR; /* Anything invalid is good here.  */
   3061   1.1  christos 
   3062   1.1  christos   if (reg >= (REG_GR + 4) && reg <= (REG_GR + 7))
   3063   1.1  christos     {
   3064   1.1  christos       *ab = 0;
   3065   1.1  christos       *regp = reg - REG_GR;
   3066   1.1  christos     }
   3067   1.1  christos   else if ((reg >= (REG_FR + 2) && reg <= (REG_FR + 5))
   3068   1.1  christos 	   || (reg >= (REG_FR + 16) && reg <= (REG_FR + 31)))
   3069   1.1  christos     {
   3070   1.1  christos       *ab = 1;
   3071   1.1  christos       *regp = reg - REG_FR;
   3072   1.1  christos     }
   3073   1.1  christos   else if (reg >= (REG_BR + 1) && reg <= (REG_BR + 5))
   3074   1.1  christos     {
   3075   1.1  christos       *ab = 2;
   3076   1.1  christos       *regp = reg - REG_BR;
   3077   1.1  christos     }
   3078   1.1  christos   else
   3079   1.1  christos     {
   3080   1.1  christos       *ab = 3;
   3081   1.1  christos       switch (reg)
   3082   1.1  christos 	{
   3083   1.1  christos 	case REG_PR:		*regp =  0; break;
   3084   1.1  christos 	case REG_PSP:		*regp =  1; break;
   3085   1.1  christos 	case REG_PRIUNAT:	*regp =  2; break;
   3086   1.1  christos 	case REG_BR + 0:	*regp =  3; break;
   3087   1.1  christos 	case REG_AR + AR_BSP:	*regp =  4; break;
   3088   1.1  christos 	case REG_AR + AR_BSPSTORE: *regp = 5; break;
   3089   1.1  christos 	case REG_AR + AR_RNAT:	*regp =  6; break;
   3090   1.1  christos 	case REG_AR + AR_UNAT:	*regp =  7; break;
   3091   1.1  christos 	case REG_AR + AR_FPSR:	*regp =  8; break;
   3092   1.1  christos 	case REG_AR + AR_PFS:	*regp =  9; break;
   3093   1.1  christos 	case REG_AR + AR_LC:	*regp = 10; break;
   3094   1.1  christos 
   3095   1.1  christos 	default:
   3096   1.1  christos 	  as_bad (_("Operand %d to .%s must be a preserved register"), n, po);
   3097   1.1  christos 	  break;
   3098   1.1  christos 	}
   3099   1.1  christos     }
   3100   1.1  christos }
   3101   1.1  christos 
   3102   1.1  christos static void
   3103   1.1  christos convert_expr_to_xy_reg (const expressionS *e,
   3104   1.1  christos 			unsigned int *xy,
   3105   1.1  christos 			unsigned int *regp,
   3106   1.1  christos 			const char *po,
   3107   1.1  christos 			int n)
   3108   1.1  christos {
   3109   1.1  christos   unsigned int reg = e->X_add_number;
   3110   1.1  christos 
   3111   1.1  christos   *xy = *regp = 0; /* Anything valid is good here.  */
   3112   1.1  christos 
   3113   1.1  christos   if (e->X_op != O_register)
   3114   1.1  christos     reg = REG_GR; /* Anything invalid is good here.  */
   3115   1.1  christos 
   3116   1.1  christos   if (reg >= (REG_GR + 1) && reg <= (REG_GR + 127))
   3117   1.1  christos     {
   3118   1.1  christos       *xy = 0;
   3119   1.1  christos       *regp = reg - REG_GR;
   3120   1.1  christos     }
   3121   1.1  christos   else if (reg >= (REG_FR + 2) && reg <= (REG_FR + 127))
   3122   1.1  christos     {
   3123   1.1  christos       *xy = 1;
   3124   1.1  christos       *regp = reg - REG_FR;
   3125   1.1  christos     }
   3126   1.1  christos   else if (reg >= REG_BR && reg <= (REG_BR + 7))
   3127   1.1  christos     {
   3128   1.1  christos       *xy = 2;
   3129   1.1  christos       *regp = reg - REG_BR;
   3130   1.1  christos     }
   3131   1.1  christos   else
   3132   1.1  christos     as_bad (_("Operand %d to .%s must be a writable register"), n, po);
   3133   1.1  christos }
   3134   1.1  christos 
   3135   1.1  christos static void
   3136   1.1  christos dot_align (int arg)
   3137   1.1  christos {
   3138   1.1  christos   /* The current frag is an alignment frag.  */
   3139   1.1  christos   align_frag = frag_now;
   3140   1.1  christos   s_align_bytes (arg);
   3141   1.1  christos }
   3142   1.1  christos 
   3143   1.1  christos static void
   3144   1.1  christos dot_radix (int dummy ATTRIBUTE_UNUSED)
   3145   1.1  christos {
   3146   1.1  christos   char *radix;
   3147   1.1  christos   int ch;
   3148   1.1  christos 
   3149   1.1  christos   SKIP_WHITESPACE ();
   3150   1.1  christos 
   3151   1.1  christos   if (is_it_end_of_statement ())
   3152   1.1  christos     return;
   3153   1.3  christos   ch = get_symbol_name (&radix);
   3154   1.1  christos   ia64_canonicalize_symbol_name (radix);
   3155   1.1  christos   if (strcasecmp (radix, "C"))
   3156   1.1  christos     as_bad (_("Radix `%s' unsupported or invalid"), radix);
   3157   1.3  christos   (void) restore_line_pointer (ch);
   3158   1.1  christos   demand_empty_rest_of_line ();
   3159   1.1  christos }
   3160   1.1  christos 
   3161   1.1  christos /* Helper function for .loc directives.  If the assembler is not generating
   3162   1.1  christos    line number info, then we need to remember which instructions have a .loc
   3163   1.1  christos    directive, and only call dwarf2_gen_line_info for those instructions.  */
   3164   1.1  christos 
   3165   1.1  christos static void
   3166   1.1  christos dot_loc (int x)
   3167   1.1  christos {
   3168   1.1  christos   CURR_SLOT.loc_directive_seen = 1;
   3169   1.1  christos   dwarf2_directive_loc (x);
   3170   1.1  christos }
   3171   1.1  christos 
   3172   1.9  christos /* .sbss, .srodata etc. are macros that expand into ".section SECNAME".  */
   3173   1.1  christos static void
   3174   1.1  christos dot_special_section (int which)
   3175   1.1  christos {
   3176   1.1  christos   set_section ((char *) special_section_name[which]);
   3177   1.1  christos }
   3178   1.1  christos 
   3179   1.1  christos /* Return -1 for warning and 0 for error.  */
   3180   1.1  christos 
   3181   1.1  christos static int
   3182   1.1  christos unwind_diagnostic (const char * region, const char *directive)
   3183   1.1  christos {
   3184   1.1  christos   if (md.unwind_check == unwind_check_warning)
   3185   1.1  christos     {
   3186   1.1  christos       as_warn (_(".%s outside of %s"), directive, region);
   3187   1.1  christos       return -1;
   3188   1.1  christos     }
   3189   1.1  christos   else
   3190   1.1  christos     {
   3191   1.1  christos       as_bad (_(".%s outside of %s"), directive, region);
   3192   1.1  christos       ignore_rest_of_line ();
   3193   1.1  christos       return 0;
   3194   1.1  christos     }
   3195   1.1  christos }
   3196   1.1  christos 
   3197   1.1  christos /* Return 1 if a directive is in a procedure, -1 if a directive isn't in
   3198   1.1  christos    a procedure but the unwind directive check is set to warning, 0 if
   3199   1.1  christos    a directive isn't in a procedure and the unwind directive check is set
   3200   1.1  christos    to error.  */
   3201   1.1  christos 
   3202   1.1  christos static int
   3203   1.1  christos in_procedure (const char *directive)
   3204   1.1  christos {
   3205   1.1  christos   if (unwind.proc_pending.sym
   3206   1.1  christos       && (!unwind.saved_text_seg || strcmp (directive, "endp") == 0))
   3207   1.1  christos     return 1;
   3208   1.1  christos   return unwind_diagnostic ("procedure", directive);
   3209   1.1  christos }
   3210   1.1  christos 
   3211   1.1  christos /* Return 1 if a directive is in a prologue, -1 if a directive isn't in
   3212   1.1  christos    a prologue but the unwind directive check is set to warning, 0 if
   3213   1.1  christos    a directive isn't in a prologue and the unwind directive check is set
   3214   1.1  christos    to error.  */
   3215   1.1  christos 
   3216   1.1  christos static int
   3217   1.1  christos in_prologue (const char *directive)
   3218   1.1  christos {
   3219   1.1  christos   int in = in_procedure (directive);
   3220   1.1  christos 
   3221   1.1  christos   if (in > 0 && !unwind.prologue)
   3222   1.1  christos     in = unwind_diagnostic ("prologue", directive);
   3223   1.1  christos   check_pending_save ();
   3224   1.1  christos   return in;
   3225   1.1  christos }
   3226   1.1  christos 
   3227   1.1  christos /* Return 1 if a directive is in a body, -1 if a directive isn't in
   3228   1.1  christos    a body but the unwind directive check is set to warning, 0 if
   3229   1.1  christos    a directive isn't in a body and the unwind directive check is set
   3230   1.1  christos    to error.  */
   3231   1.1  christos 
   3232   1.1  christos static int
   3233   1.1  christos in_body (const char *directive)
   3234   1.1  christos {
   3235   1.1  christos   int in = in_procedure (directive);
   3236   1.1  christos 
   3237   1.1  christos   if (in > 0 && !unwind.body)
   3238   1.1  christos     in = unwind_diagnostic ("body region", directive);
   3239   1.1  christos   return in;
   3240   1.1  christos }
   3241   1.1  christos 
   3242   1.1  christos static void
   3243   1.1  christos add_unwind_entry (unw_rec_list *ptr, int sep)
   3244   1.1  christos {
   3245   1.1  christos   if (ptr)
   3246   1.1  christos     {
   3247   1.1  christos       if (unwind.tail)
   3248   1.1  christos 	unwind.tail->next = ptr;
   3249   1.1  christos       else
   3250   1.1  christos 	unwind.list = ptr;
   3251   1.1  christos       unwind.tail = ptr;
   3252   1.1  christos 
   3253   1.1  christos       /* The current entry can in fact be a chain of unwind entries.  */
   3254   1.1  christos       if (unwind.current_entry == NULL)
   3255   1.1  christos 	unwind.current_entry = ptr;
   3256   1.1  christos     }
   3257   1.1  christos 
   3258   1.1  christos   /* The current entry can in fact be a chain of unwind entries.  */
   3259   1.1  christos   if (unwind.current_entry == NULL)
   3260   1.1  christos     unwind.current_entry = ptr;
   3261   1.1  christos 
   3262   1.1  christos   if (sep == ',')
   3263   1.1  christos     {
   3264   1.3  christos       char *name;
   3265   1.1  christos       /* Parse a tag permitted for the current directive.  */
   3266   1.1  christos       int ch;
   3267   1.1  christos 
   3268   1.1  christos       SKIP_WHITESPACE ();
   3269   1.3  christos       ch = get_symbol_name (&name);
   3270   1.1  christos       /* FIXME: For now, just issue a warning that this isn't implemented.  */
   3271   1.1  christos       {
   3272   1.1  christos 	static int warned;
   3273   1.1  christos 
   3274   1.1  christos 	if (!warned)
   3275   1.1  christos 	  {
   3276   1.1  christos 	    warned = 1;
   3277   1.1  christos 	    as_warn (_("Tags on unwind pseudo-ops aren't supported, yet"));
   3278   1.1  christos 	  }
   3279   1.1  christos       }
   3280   1.3  christos       (void) restore_line_pointer (ch);
   3281   1.1  christos     }
   3282   1.1  christos   if (sep != NOT_A_CHAR)
   3283   1.1  christos     demand_empty_rest_of_line ();
   3284   1.1  christos }
   3285   1.1  christos 
   3286   1.1  christos static void
   3287   1.1  christos dot_fframe (int dummy ATTRIBUTE_UNUSED)
   3288   1.1  christos {
   3289   1.1  christos   expressionS e;
   3290   1.1  christos   int sep;
   3291   1.1  christos 
   3292   1.1  christos   if (!in_prologue ("fframe"))
   3293   1.1  christos     return;
   3294   1.1  christos 
   3295   1.1  christos   sep = parse_operand_and_eval (&e, ',');
   3296   1.1  christos 
   3297   1.1  christos   if (e.X_op != O_constant)
   3298   1.1  christos     {
   3299   1.1  christos       as_bad (_("First operand to .fframe must be a constant"));
   3300   1.1  christos       e.X_add_number = 0;
   3301   1.1  christos     }
   3302   1.1  christos   add_unwind_entry (output_mem_stack_f (e.X_add_number), sep);
   3303   1.1  christos }
   3304   1.1  christos 
   3305   1.1  christos static void
   3306   1.1  christos dot_vframe (int dummy ATTRIBUTE_UNUSED)
   3307   1.1  christos {
   3308   1.1  christos   expressionS e;
   3309   1.1  christos   unsigned reg;
   3310   1.1  christos   int sep;
   3311   1.1  christos 
   3312   1.1  christos   if (!in_prologue ("vframe"))
   3313   1.1  christos     return;
   3314   1.1  christos 
   3315   1.1  christos   sep = parse_operand_and_eval (&e, ',');
   3316   1.1  christos   reg = e.X_add_number - REG_GR;
   3317   1.1  christos   if (e.X_op != O_register || reg > 127)
   3318   1.1  christos     {
   3319   1.1  christos       as_bad (_("First operand to .vframe must be a general register"));
   3320   1.1  christos       reg = 0;
   3321   1.1  christos     }
   3322   1.1  christos   add_unwind_entry (output_mem_stack_v (), sep);
   3323   1.1  christos   if (! (unwind.prologue_mask & 2))
   3324   1.1  christos     add_unwind_entry (output_psp_gr (reg), NOT_A_CHAR);
   3325   1.1  christos   else if (reg != unwind.prologue_gr
   3326   1.3  christos 		  + (unsigned) popcount (unwind.prologue_mask & -(2 << 1)))
   3327   1.1  christos     as_warn (_("Operand of .vframe contradicts .prologue"));
   3328   1.1  christos }
   3329   1.1  christos 
   3330   1.1  christos static void
   3331   1.1  christos dot_vframesp (int psp)
   3332   1.1  christos {
   3333   1.1  christos   expressionS e;
   3334   1.1  christos   int sep;
   3335   1.1  christos 
   3336   1.1  christos   if (psp)
   3337   1.1  christos     as_warn (_(".vframepsp is meaningless, assuming .vframesp was meant"));
   3338   1.1  christos 
   3339   1.1  christos   if (!in_prologue ("vframesp"))
   3340   1.1  christos     return;
   3341   1.1  christos 
   3342   1.1  christos   sep = parse_operand_and_eval (&e, ',');
   3343   1.1  christos   if (e.X_op != O_constant)
   3344   1.1  christos     {
   3345   1.1  christos       as_bad (_("Operand to .vframesp must be a constant (sp-relative offset)"));
   3346   1.1  christos       e.X_add_number = 0;
   3347   1.1  christos     }
   3348   1.1  christos   add_unwind_entry (output_mem_stack_v (), sep);
   3349   1.1  christos   add_unwind_entry (output_psp_sprel (e.X_add_number), NOT_A_CHAR);
   3350   1.1  christos }
   3351   1.1  christos 
   3352   1.1  christos static void
   3353   1.1  christos dot_save (int dummy ATTRIBUTE_UNUSED)
   3354   1.1  christos {
   3355   1.1  christos   expressionS e1, e2;
   3356   1.1  christos   unsigned reg1, reg2;
   3357   1.1  christos   int sep;
   3358   1.1  christos 
   3359   1.1  christos   if (!in_prologue ("save"))
   3360   1.1  christos     return;
   3361   1.1  christos 
   3362   1.1  christos   sep = parse_operand_and_eval (&e1, ',');
   3363   1.1  christos   if (sep == ',')
   3364   1.1  christos     sep = parse_operand_and_eval (&e2, ',');
   3365   1.1  christos   else
   3366   1.1  christos     e2.X_op = O_absent;
   3367   1.1  christos 
   3368   1.1  christos   reg1 = e1.X_add_number;
   3369   1.6  christos   /* Make sure it's a valid ar.xxx reg, OR its br0, aka 'rp'.  */
   3370   1.1  christos   if (e1.X_op != O_register)
   3371   1.1  christos     {
   3372   1.1  christos       as_bad (_("First operand to .save not a register"));
   3373   1.1  christos       reg1 = REG_PR; /* Anything valid is good here.  */
   3374   1.1  christos     }
   3375   1.1  christos   reg2 = e2.X_add_number - REG_GR;
   3376   1.1  christos   if (e2.X_op != O_register || reg2 > 127)
   3377   1.1  christos     {
   3378   1.1  christos       as_bad (_("Second operand to .save not a valid register"));
   3379   1.1  christos       reg2 = 0;
   3380   1.1  christos     }
   3381   1.1  christos   switch (reg1)
   3382   1.1  christos     {
   3383   1.1  christos     case REG_AR + AR_BSP:
   3384   1.1  christos       add_unwind_entry (output_bsp_when (), sep);
   3385   1.1  christos       add_unwind_entry (output_bsp_gr (reg2), NOT_A_CHAR);
   3386   1.1  christos       break;
   3387   1.1  christos     case REG_AR + AR_BSPSTORE:
   3388   1.1  christos       add_unwind_entry (output_bspstore_when (), sep);
   3389   1.1  christos       add_unwind_entry (output_bspstore_gr (reg2), NOT_A_CHAR);
   3390   1.1  christos       break;
   3391   1.1  christos     case REG_AR + AR_RNAT:
   3392   1.1  christos       add_unwind_entry (output_rnat_when (), sep);
   3393   1.1  christos       add_unwind_entry (output_rnat_gr (reg2), NOT_A_CHAR);
   3394   1.1  christos       break;
   3395   1.1  christos     case REG_AR + AR_UNAT:
   3396   1.1  christos       add_unwind_entry (output_unat_when (), sep);
   3397   1.1  christos       add_unwind_entry (output_unat_gr (reg2), NOT_A_CHAR);
   3398   1.1  christos       break;
   3399   1.1  christos     case REG_AR + AR_FPSR:
   3400   1.1  christos       add_unwind_entry (output_fpsr_when (), sep);
   3401   1.1  christos       add_unwind_entry (output_fpsr_gr (reg2), NOT_A_CHAR);
   3402   1.1  christos       break;
   3403   1.1  christos     case REG_AR + AR_PFS:
   3404   1.1  christos       add_unwind_entry (output_pfs_when (), sep);
   3405   1.1  christos       if (! (unwind.prologue_mask & 4))
   3406   1.1  christos 	add_unwind_entry (output_pfs_gr (reg2), NOT_A_CHAR);
   3407   1.1  christos       else if (reg2 != unwind.prologue_gr
   3408   1.3  christos 		       + (unsigned) popcount (unwind.prologue_mask & -(4 << 1)))
   3409   1.1  christos 	as_warn (_("Second operand of .save contradicts .prologue"));
   3410   1.1  christos       break;
   3411   1.1  christos     case REG_AR + AR_LC:
   3412   1.1  christos       add_unwind_entry (output_lc_when (), sep);
   3413   1.1  christos       add_unwind_entry (output_lc_gr (reg2), NOT_A_CHAR);
   3414   1.1  christos       break;
   3415   1.1  christos     case REG_BR:
   3416   1.1  christos       add_unwind_entry (output_rp_when (), sep);
   3417   1.1  christos       if (! (unwind.prologue_mask & 8))
   3418   1.1  christos 	add_unwind_entry (output_rp_gr (reg2), NOT_A_CHAR);
   3419   1.1  christos       else if (reg2 != unwind.prologue_gr)
   3420   1.1  christos 	as_warn (_("Second operand of .save contradicts .prologue"));
   3421   1.1  christos       break;
   3422   1.1  christos     case REG_PR:
   3423   1.1  christos       add_unwind_entry (output_preds_when (), sep);
   3424   1.1  christos       if (! (unwind.prologue_mask & 1))
   3425   1.1  christos 	add_unwind_entry (output_preds_gr (reg2), NOT_A_CHAR);
   3426   1.1  christos       else if (reg2 != unwind.prologue_gr
   3427   1.3  christos 		       + (unsigned) popcount (unwind.prologue_mask & -(1 << 1)))
   3428   1.1  christos 	as_warn (_("Second operand of .save contradicts .prologue"));
   3429   1.1  christos       break;
   3430   1.1  christos     case REG_PRIUNAT:
   3431   1.1  christos       add_unwind_entry (output_priunat_when_gr (), sep);
   3432   1.1  christos       add_unwind_entry (output_priunat_gr (reg2), NOT_A_CHAR);
   3433   1.1  christos       break;
   3434   1.1  christos     default:
   3435   1.1  christos       as_bad (_("First operand to .save not a valid register"));
   3436   1.1  christos       add_unwind_entry (NULL, sep);
   3437   1.1  christos       break;
   3438   1.1  christos     }
   3439   1.1  christos }
   3440   1.1  christos 
   3441   1.1  christos static void
   3442   1.1  christos dot_restore (int dummy ATTRIBUTE_UNUSED)
   3443   1.1  christos {
   3444   1.1  christos   expressionS e1;
   3445   1.1  christos   unsigned long ecount;	/* # of _additional_ regions to pop */
   3446   1.1  christos   int sep;
   3447   1.1  christos 
   3448   1.1  christos   if (!in_body ("restore"))
   3449   1.1  christos     return;
   3450   1.1  christos 
   3451   1.1  christos   sep = parse_operand_and_eval (&e1, ',');
   3452   1.1  christos   if (e1.X_op != O_register || e1.X_add_number != REG_GR + 12)
   3453   1.1  christos     as_bad (_("First operand to .restore must be stack pointer (sp)"));
   3454   1.1  christos 
   3455   1.1  christos   if (sep == ',')
   3456   1.1  christos     {
   3457   1.1  christos       expressionS e2;
   3458   1.1  christos 
   3459   1.1  christos       sep = parse_operand_and_eval (&e2, ',');
   3460   1.1  christos       if (e2.X_op != O_constant || e2.X_add_number < 0)
   3461   1.1  christos 	{
   3462   1.1  christos 	  as_bad (_("Second operand to .restore must be a constant >= 0"));
   3463   1.1  christos 	  e2.X_add_number = 0;
   3464   1.1  christos 	}
   3465   1.1  christos       ecount = e2.X_add_number;
   3466   1.1  christos     }
   3467   1.1  christos   else
   3468   1.1  christos     ecount = unwind.prologue_count - 1;
   3469   1.1  christos 
   3470   1.1  christos   if (ecount >= unwind.prologue_count)
   3471   1.1  christos     {
   3472   1.1  christos       as_bad (_("Epilogue count of %lu exceeds number of nested prologues (%u)"),
   3473   1.1  christos 	      ecount + 1, unwind.prologue_count);
   3474   1.1  christos       ecount = 0;
   3475   1.1  christos     }
   3476   1.1  christos 
   3477   1.1  christos   add_unwind_entry (output_epilogue (ecount), sep);
   3478   1.1  christos 
   3479   1.1  christos   if (ecount < unwind.prologue_count)
   3480   1.1  christos     unwind.prologue_count -= ecount + 1;
   3481   1.1  christos   else
   3482   1.1  christos     unwind.prologue_count = 0;
   3483   1.1  christos }
   3484   1.1  christos 
   3485   1.1  christos static void
   3486   1.1  christos dot_restorereg (int pred)
   3487   1.1  christos {
   3488   1.1  christos   unsigned int qp, ab, reg;
   3489   1.1  christos   expressionS e;
   3490   1.1  christos   int sep;
   3491   1.1  christos   const char * const po = pred ? "restorereg.p" : "restorereg";
   3492   1.1  christos 
   3493   1.1  christos   if (!in_procedure (po))
   3494   1.1  christos     return;
   3495   1.1  christos 
   3496   1.1  christos   if (pred)
   3497   1.1  christos     sep = parse_predicate_and_operand (&e, &qp, po);
   3498   1.1  christos   else
   3499   1.1  christos     {
   3500   1.1  christos       sep = parse_operand_and_eval (&e, ',');
   3501   1.1  christos       qp = 0;
   3502   1.1  christos     }
   3503   1.1  christos   convert_expr_to_ab_reg (&e, &ab, &reg, po, 1 + pred);
   3504   1.1  christos 
   3505   1.1  christos   add_unwind_entry (output_spill_reg (ab, reg, 0, 0, qp), sep);
   3506   1.1  christos }
   3507   1.1  christos 
   3508   1.5  christos static const char *special_linkonce_name[] =
   3509   1.1  christos   {
   3510   1.1  christos     ".gnu.linkonce.ia64unw.", ".gnu.linkonce.ia64unwi."
   3511   1.1  christos   };
   3512   1.1  christos 
   3513   1.1  christos static void
   3514   1.1  christos start_unwind_section (const segT text_seg, int sec_index)
   3515   1.1  christos {
   3516   1.1  christos   /*
   3517   1.1  christos     Use a slightly ugly scheme to derive the unwind section names from
   3518   1.1  christos     the text section name:
   3519   1.1  christos 
   3520   1.1  christos     text sect.  unwind table sect.
   3521   1.1  christos     name:       name:                      comments:
   3522   1.1  christos     ----------  -----------------          --------------------------------
   3523   1.1  christos     .text       .IA_64.unwind
   3524   1.1  christos     .text.foo   .IA_64.unwind.text.foo
   3525   1.1  christos     .foo        .IA_64.unwind.foo
   3526   1.1  christos     .gnu.linkonce.t.foo
   3527   1.1  christos 		.gnu.linkonce.ia64unw.foo
   3528   1.1  christos     _info       .IA_64.unwind_info         gas issues error message (ditto)
   3529   1.1  christos     _infoFOO    .IA_64.unwind_infoFOO      gas issues error message (ditto)
   3530   1.1  christos 
   3531   1.1  christos     This mapping is done so that:
   3532   1.1  christos 
   3533   1.1  christos 	(a) An object file with unwind info only in .text will use
   3534   1.1  christos 	    unwind section names .IA_64.unwind and .IA_64.unwind_info.
   3535   1.1  christos 	    This follows the letter of the ABI and also ensures backwards
   3536   1.1  christos 	    compatibility with older toolchains.
   3537   1.1  christos 
   3538   1.1  christos 	(b) An object file with unwind info in multiple text sections
   3539   1.1  christos 	    will use separate unwind sections for each text section.
   3540   1.1  christos 	    This allows us to properly set the "sh_info" and "sh_link"
   3541   1.1  christos 	    fields in SHT_IA_64_UNWIND as required by the ABI and also
   3542   1.1  christos 	    lets GNU ld support programs with multiple segments
   3543   1.1  christos 	    containing unwind info (as might be the case for certain
   3544   1.1  christos 	    embedded applications).
   3545   1.1  christos 
   3546   1.1  christos 	(c) An error is issued if there would be a name clash.
   3547   1.1  christos   */
   3548   1.1  christos 
   3549   1.1  christos   const char *text_name, *sec_text_name;
   3550   1.1  christos   char *sec_name;
   3551   1.1  christos   const char *prefix = special_section_name [sec_index];
   3552   1.1  christos   const char *suffix;
   3553   1.1  christos 
   3554   1.1  christos   sec_text_name = segment_name (text_seg);
   3555   1.1  christos   text_name = sec_text_name;
   3556   1.8  christos   if (startswith (text_name, "_info"))
   3557   1.1  christos     {
   3558   1.1  christos       as_bad (_("Illegal section name `%s' (causes unwind section name clash)"),
   3559   1.1  christos 	      text_name);
   3560   1.1  christos       ignore_rest_of_line ();
   3561   1.1  christos       return;
   3562   1.1  christos     }
   3563   1.1  christos   if (strcmp (text_name, ".text") == 0)
   3564   1.1  christos     text_name = "";
   3565   1.1  christos 
   3566   1.1  christos   /* Build the unwind section name by appending the (possibly stripped)
   3567   1.1  christos      text section name to the unwind prefix.  */
   3568   1.1  christos   suffix = text_name;
   3569   1.8  christos   if (startswith (text_name, ".gnu.linkonce.t."))
   3570   1.1  christos     {
   3571   1.1  christos       prefix = special_linkonce_name [sec_index - SPECIAL_SECTION_UNWIND];
   3572   1.1  christos       suffix += sizeof (".gnu.linkonce.t.") - 1;
   3573   1.1  christos     }
   3574   1.1  christos 
   3575  1.10  christos   sec_name = concat (prefix, suffix, (const char *) NULL);
   3576   1.1  christos 
   3577   1.1  christos   /* Handle COMDAT group.  */
   3578   1.1  christos   if ((text_seg->flags & SEC_LINK_ONCE) != 0
   3579   1.1  christos       && (elf_section_flags (text_seg) & SHF_GROUP) != 0)
   3580   1.1  christos     {
   3581   1.1  christos       char *section;
   3582   1.1  christos       const char *group_name = elf_group_name (text_seg);
   3583   1.1  christos 
   3584   1.1  christos       if (group_name == NULL)
   3585   1.1  christos 	{
   3586   1.1  christos 	  as_bad (_("Group section `%s' has no group signature"),
   3587   1.1  christos 		  sec_text_name);
   3588   1.1  christos 	  ignore_rest_of_line ();
   3589   1.5  christos 	  free (sec_name);
   3590   1.1  christos 	  return;
   3591   1.1  christos 	}
   3592   1.5  christos 
   3593   1.5  christos       /* We have to construct a fake section directive.  */
   3594  1.10  christos       section = concat (sec_name, ",\"aG\",@progbits,", group_name,
   3595  1.10  christos 			",comdat", (const char *) NULL);
   3596   1.1  christos       set_section (section);
   3597   1.5  christos       free (section);
   3598   1.1  christos     }
   3599   1.1  christos   else
   3600   1.1  christos     {
   3601   1.1  christos       set_section (sec_name);
   3602   1.7  christos       bfd_set_section_flags (now_seg, SEC_LOAD | SEC_ALLOC | SEC_READONLY);
   3603   1.1  christos     }
   3604   1.1  christos 
   3605   1.1  christos   elf_linked_to_section (now_seg) = text_seg;
   3606   1.5  christos   free (sec_name);
   3607   1.1  christos }
   3608   1.1  christos 
   3609   1.1  christos static void
   3610   1.1  christos generate_unwind_image (const segT text_seg)
   3611   1.1  christos {
   3612   1.1  christos   int size, pad;
   3613   1.1  christos   unw_rec_list *list;
   3614   1.1  christos 
   3615   1.1  christos   /* Mark the end of the unwind info, so that we can compute the size of the
   3616   1.1  christos      last unwind region.  */
   3617   1.1  christos   add_unwind_entry (output_endp (), NOT_A_CHAR);
   3618   1.1  christos 
   3619   1.1  christos   /* Force out pending instructions, to make sure all unwind records have
   3620   1.1  christos      a valid slot_number field.  */
   3621   1.1  christos   ia64_flush_insns ();
   3622   1.1  christos 
   3623   1.1  christos   /* Generate the unwind record.  */
   3624   1.1  christos   list = optimize_unw_records (unwind.list);
   3625   1.1  christos   fixup_unw_records (list, 1);
   3626   1.1  christos   size = calc_record_size (list);
   3627   1.1  christos 
   3628   1.1  christos   if (size > 0 || unwind.force_unwind_entry)
   3629   1.1  christos     {
   3630   1.1  christos       unwind.force_unwind_entry = 0;
   3631   1.1  christos       /* pad to pointer-size boundary.  */
   3632   1.1  christos       pad = size % md.pointer_size;
   3633   1.1  christos       if (pad != 0)
   3634   1.1  christos 	size += md.pointer_size - pad;
   3635   1.1  christos       /* Add 8 for the header.  */
   3636   1.1  christos       size += 8;
   3637   1.1  christos       /* Add a pointer for the personality offset.  */
   3638   1.1  christos       if (unwind.personality_routine)
   3639   1.1  christos 	size += md.pointer_size;
   3640   1.1  christos     }
   3641   1.1  christos 
   3642   1.1  christos   /* If there are unwind records, switch sections, and output the info.  */
   3643   1.1  christos   if (size != 0)
   3644   1.1  christos     {
   3645   1.1  christos       expressionS exp;
   3646   1.1  christos       bfd_reloc_code_real_type reloc;
   3647   1.1  christos 
   3648   1.1  christos       start_unwind_section (text_seg, SPECIAL_SECTION_UNWIND_INFO);
   3649   1.1  christos 
   3650   1.1  christos       /* Make sure the section has 4 byte alignment for ILP32 and
   3651   1.1  christos 	 8 byte alignment for LP64.  */
   3652   1.1  christos       frag_align (md.pointer_size_shift, 0, 0);
   3653   1.1  christos       record_alignment (now_seg, md.pointer_size_shift);
   3654   1.1  christos 
   3655   1.1  christos       /* Set expression which points to start of unwind descriptor area.  */
   3656   1.1  christos       unwind.info = expr_build_dot ();
   3657   1.3  christos 
   3658   1.1  christos       frag_var (rs_machine_dependent, size, size, 0, 0,
   3659  1.10  christos 		(intptr_t) unwind.personality_routine,
   3660   1.1  christos 		(char *) list);
   3661   1.1  christos 
   3662   1.1  christos       /* Add the personality address to the image.  */
   3663   1.1  christos       if (unwind.personality_routine != 0)
   3664   1.1  christos 	{
   3665   1.1  christos 	  exp.X_op = O_symbol;
   3666   1.1  christos 	  exp.X_add_symbol = unwind.personality_routine;
   3667   1.1  christos 	  exp.X_add_number = 0;
   3668   1.1  christos 
   3669   1.1  christos 	  if (md.flags & EF_IA_64_BE)
   3670   1.1  christos 	    {
   3671   1.1  christos 	      if (md.flags & EF_IA_64_ABI64)
   3672   1.1  christos 		reloc = BFD_RELOC_IA64_LTOFF_FPTR64MSB;
   3673   1.1  christos 	      else
   3674   1.1  christos 		reloc = BFD_RELOC_IA64_LTOFF_FPTR32MSB;
   3675   1.1  christos 	    }
   3676   1.1  christos 	  else
   3677   1.1  christos 	    {
   3678   1.1  christos 	      if (md.flags & EF_IA_64_ABI64)
   3679   1.1  christos 		reloc = BFD_RELOC_IA64_LTOFF_FPTR64LSB;
   3680   1.1  christos 	      else
   3681   1.1  christos 		reloc = BFD_RELOC_IA64_LTOFF_FPTR32LSB;
   3682   1.1  christos 	    }
   3683   1.1  christos 
   3684   1.1  christos 	  fix_new_exp (frag_now, frag_now_fix () - md.pointer_size,
   3685   1.1  christos 		       md.pointer_size, &exp, 0, reloc);
   3686   1.1  christos 	  unwind.personality_routine = 0;
   3687   1.1  christos 	}
   3688   1.1  christos     }
   3689   1.1  christos 
   3690   1.1  christos   free_saved_prologue_counts ();
   3691   1.1  christos   unwind.list = unwind.tail = unwind.current_entry = NULL;
   3692   1.1  christos }
   3693   1.1  christos 
   3694   1.1  christos static void
   3695   1.1  christos dot_handlerdata (int dummy ATTRIBUTE_UNUSED)
   3696   1.1  christos {
   3697   1.1  christos   if (!in_procedure ("handlerdata"))
   3698   1.1  christos     return;
   3699   1.1  christos   unwind.force_unwind_entry = 1;
   3700   1.1  christos 
   3701   1.1  christos   /* Remember which segment we're in so we can switch back after .endp */
   3702   1.1  christos   unwind.saved_text_seg = now_seg;
   3703   1.1  christos   unwind.saved_text_subseg = now_subseg;
   3704   1.1  christos 
   3705   1.1  christos   /* Generate unwind info into unwind-info section and then leave that
   3706   1.1  christos      section as the currently active one so dataXX directives go into
   3707   1.1  christos      the language specific data area of the unwind info block.  */
   3708   1.1  christos   generate_unwind_image (now_seg);
   3709   1.1  christos   demand_empty_rest_of_line ();
   3710   1.1  christos }
   3711   1.1  christos 
   3712   1.1  christos static void
   3713   1.1  christos dot_unwentry (int dummy ATTRIBUTE_UNUSED)
   3714   1.1  christos {
   3715   1.1  christos   if (!in_procedure ("unwentry"))
   3716   1.1  christos     return;
   3717   1.1  christos   unwind.force_unwind_entry = 1;
   3718   1.1  christos   demand_empty_rest_of_line ();
   3719   1.1  christos }
   3720   1.1  christos 
   3721   1.1  christos static void
   3722   1.1  christos dot_altrp (int dummy ATTRIBUTE_UNUSED)
   3723   1.1  christos {
   3724   1.1  christos   expressionS e;
   3725   1.1  christos   unsigned reg;
   3726   1.1  christos 
   3727   1.1  christos   if (!in_prologue ("altrp"))
   3728   1.1  christos     return;
   3729   1.1  christos 
   3730   1.1  christos   parse_operand_and_eval (&e, 0);
   3731   1.1  christos   reg = e.X_add_number - REG_BR;
   3732   1.1  christos   if (e.X_op != O_register || reg > 7)
   3733   1.1  christos     {
   3734   1.1  christos       as_bad (_("First operand to .altrp not a valid branch register"));
   3735   1.1  christos       reg = 0;
   3736   1.1  christos     }
   3737   1.1  christos   add_unwind_entry (output_rp_br (reg), 0);
   3738   1.1  christos }
   3739   1.1  christos 
   3740   1.1  christos static void
   3741   1.1  christos dot_savemem (int psprel)
   3742   1.1  christos {
   3743   1.1  christos   expressionS e1, e2;
   3744   1.1  christos   int sep;
   3745   1.1  christos   int reg1, val;
   3746   1.1  christos   const char * const po = psprel ? "savepsp" : "savesp";
   3747   1.1  christos 
   3748   1.1  christos   if (!in_prologue (po))
   3749   1.1  christos     return;
   3750   1.1  christos 
   3751   1.1  christos   sep = parse_operand_and_eval (&e1, ',');
   3752   1.1  christos   if (sep == ',')
   3753   1.1  christos     sep = parse_operand_and_eval (&e2, ',');
   3754   1.1  christos   else
   3755   1.1  christos     e2.X_op = O_absent;
   3756   1.1  christos 
   3757   1.1  christos   reg1 = e1.X_add_number;
   3758   1.1  christos   val = e2.X_add_number;
   3759   1.1  christos 
   3760   1.6  christos   /* Make sure it's a valid ar.xxx reg, OR its br0, aka 'rp'.  */
   3761   1.1  christos   if (e1.X_op != O_register)
   3762   1.1  christos     {
   3763   1.1  christos       as_bad (_("First operand to .%s not a register"), po);
   3764   1.1  christos       reg1 = REG_PR; /* Anything valid is good here.  */
   3765   1.1  christos     }
   3766   1.1  christos   if (e2.X_op != O_constant)
   3767   1.1  christos     {
   3768   1.1  christos       as_bad (_("Second operand to .%s not a constant"), po);
   3769   1.1  christos       val = 0;
   3770   1.1  christos     }
   3771   1.1  christos 
   3772   1.1  christos   switch (reg1)
   3773   1.1  christos     {
   3774   1.1  christos     case REG_AR + AR_BSP:
   3775   1.1  christos       add_unwind_entry (output_bsp_when (), sep);
   3776   1.1  christos       add_unwind_entry ((psprel
   3777   1.1  christos 			 ? output_bsp_psprel
   3778   1.1  christos 			 : output_bsp_sprel) (val), NOT_A_CHAR);
   3779   1.1  christos       break;
   3780   1.1  christos     case REG_AR + AR_BSPSTORE:
   3781   1.1  christos       add_unwind_entry (output_bspstore_when (), sep);
   3782   1.1  christos       add_unwind_entry ((psprel
   3783   1.1  christos 			 ? output_bspstore_psprel
   3784   1.1  christos 			 : output_bspstore_sprel) (val), NOT_A_CHAR);
   3785   1.1  christos       break;
   3786   1.1  christos     case REG_AR + AR_RNAT:
   3787   1.1  christos       add_unwind_entry (output_rnat_when (), sep);
   3788   1.1  christos       add_unwind_entry ((psprel
   3789   1.1  christos 			 ? output_rnat_psprel
   3790   1.1  christos 			 : output_rnat_sprel) (val), NOT_A_CHAR);
   3791   1.1  christos       break;
   3792   1.1  christos     case REG_AR + AR_UNAT:
   3793   1.1  christos       add_unwind_entry (output_unat_when (), sep);
   3794   1.1  christos       add_unwind_entry ((psprel
   3795   1.1  christos 			 ? output_unat_psprel
   3796   1.1  christos 			 : output_unat_sprel) (val), NOT_A_CHAR);
   3797   1.1  christos       break;
   3798   1.1  christos     case REG_AR + AR_FPSR:
   3799   1.1  christos       add_unwind_entry (output_fpsr_when (), sep);
   3800   1.1  christos       add_unwind_entry ((psprel
   3801   1.1  christos 			 ? output_fpsr_psprel
   3802   1.1  christos 			 : output_fpsr_sprel) (val), NOT_A_CHAR);
   3803   1.1  christos       break;
   3804   1.1  christos     case REG_AR + AR_PFS:
   3805   1.1  christos       add_unwind_entry (output_pfs_when (), sep);
   3806   1.1  christos       add_unwind_entry ((psprel
   3807   1.1  christos 			 ? output_pfs_psprel
   3808   1.1  christos 			 : output_pfs_sprel) (val), NOT_A_CHAR);
   3809   1.1  christos       break;
   3810   1.1  christos     case REG_AR + AR_LC:
   3811   1.1  christos       add_unwind_entry (output_lc_when (), sep);
   3812   1.1  christos       add_unwind_entry ((psprel
   3813   1.1  christos 			 ? output_lc_psprel
   3814   1.1  christos 			 : output_lc_sprel) (val), NOT_A_CHAR);
   3815   1.1  christos       break;
   3816   1.1  christos     case REG_BR:
   3817   1.1  christos       add_unwind_entry (output_rp_when (), sep);
   3818   1.1  christos       add_unwind_entry ((psprel
   3819   1.1  christos 			 ? output_rp_psprel
   3820   1.1  christos 			 : output_rp_sprel) (val), NOT_A_CHAR);
   3821   1.1  christos       break;
   3822   1.1  christos     case REG_PR:
   3823   1.1  christos       add_unwind_entry (output_preds_when (), sep);
   3824   1.1  christos       add_unwind_entry ((psprel
   3825   1.1  christos 			 ? output_preds_psprel
   3826   1.1  christos 			 : output_preds_sprel) (val), NOT_A_CHAR);
   3827   1.1  christos       break;
   3828   1.1  christos     case REG_PRIUNAT:
   3829   1.1  christos       add_unwind_entry (output_priunat_when_mem (), sep);
   3830   1.1  christos       add_unwind_entry ((psprel
   3831   1.1  christos 			 ? output_priunat_psprel
   3832   1.1  christos 			 : output_priunat_sprel) (val), NOT_A_CHAR);
   3833   1.1  christos       break;
   3834   1.1  christos     default:
   3835   1.1  christos       as_bad (_("First operand to .%s not a valid register"), po);
   3836   1.1  christos       add_unwind_entry (NULL, sep);
   3837   1.1  christos       break;
   3838   1.1  christos     }
   3839   1.1  christos }
   3840   1.1  christos 
   3841   1.1  christos static void
   3842   1.1  christos dot_saveg (int dummy ATTRIBUTE_UNUSED)
   3843   1.1  christos {
   3844   1.1  christos   expressionS e;
   3845   1.1  christos   unsigned grmask;
   3846   1.1  christos   int sep;
   3847   1.1  christos 
   3848   1.1  christos   if (!in_prologue ("save.g"))
   3849   1.1  christos     return;
   3850   1.1  christos 
   3851   1.1  christos   sep = parse_operand_and_eval (&e, ',');
   3852   1.1  christos 
   3853   1.1  christos   grmask = e.X_add_number;
   3854   1.1  christos   if (e.X_op != O_constant
   3855   1.1  christos       || e.X_add_number <= 0
   3856   1.1  christos       || e.X_add_number > 0xf)
   3857   1.1  christos     {
   3858   1.1  christos       as_bad (_("First operand to .save.g must be a positive 4-bit constant"));
   3859   1.1  christos       grmask = 0;
   3860   1.1  christos     }
   3861   1.1  christos 
   3862   1.1  christos   if (sep == ',')
   3863   1.1  christos     {
   3864   1.1  christos       unsigned reg;
   3865   1.1  christos       int n = popcount (grmask);
   3866   1.1  christos 
   3867   1.1  christos       parse_operand_and_eval (&e, 0);
   3868   1.1  christos       reg = e.X_add_number - REG_GR;
   3869   1.1  christos       if (e.X_op != O_register || reg > 127)
   3870   1.1  christos 	{
   3871   1.1  christos 	  as_bad (_("Second operand to .save.g must be a general register"));
   3872   1.1  christos 	  reg = 0;
   3873   1.1  christos 	}
   3874   1.1  christos       else if (reg > 128U - n)
   3875   1.1  christos 	{
   3876   1.1  christos 	  as_bad (_("Second operand to .save.g must be the first of %d general registers"), n);
   3877   1.1  christos 	  reg = 0;
   3878   1.1  christos 	}
   3879   1.1  christos       add_unwind_entry (output_gr_gr (grmask, reg), 0);
   3880   1.1  christos     }
   3881   1.1  christos   else
   3882   1.1  christos     add_unwind_entry (output_gr_mem (grmask), 0);
   3883   1.1  christos }
   3884   1.1  christos 
   3885   1.1  christos static void
   3886   1.1  christos dot_savef (int dummy ATTRIBUTE_UNUSED)
   3887   1.1  christos {
   3888   1.1  christos   expressionS e;
   3889   1.1  christos 
   3890   1.1  christos   if (!in_prologue ("save.f"))
   3891   1.1  christos     return;
   3892   1.1  christos 
   3893   1.1  christos   parse_operand_and_eval (&e, 0);
   3894   1.1  christos 
   3895   1.1  christos   if (e.X_op != O_constant
   3896   1.1  christos       || e.X_add_number <= 0
   3897   1.1  christos       || e.X_add_number > 0xfffff)
   3898   1.1  christos     {
   3899   1.1  christos       as_bad (_("Operand to .save.f must be a positive 20-bit constant"));
   3900   1.1  christos       e.X_add_number = 0;
   3901   1.1  christos     }
   3902   1.1  christos   add_unwind_entry (output_fr_mem (e.X_add_number), 0);
   3903   1.1  christos }
   3904   1.1  christos 
   3905   1.1  christos static void
   3906   1.1  christos dot_saveb (int dummy ATTRIBUTE_UNUSED)
   3907   1.1  christos {
   3908   1.1  christos   expressionS e;
   3909   1.1  christos   unsigned brmask;
   3910   1.1  christos   int sep;
   3911   1.1  christos 
   3912   1.1  christos   if (!in_prologue ("save.b"))
   3913   1.1  christos     return;
   3914   1.1  christos 
   3915   1.1  christos   sep = parse_operand_and_eval (&e, ',');
   3916   1.1  christos 
   3917   1.1  christos   brmask = e.X_add_number;
   3918   1.1  christos   if (e.X_op != O_constant
   3919   1.1  christos       || e.X_add_number <= 0
   3920   1.1  christos       || e.X_add_number > 0x1f)
   3921   1.1  christos     {
   3922   1.1  christos       as_bad (_("First operand to .save.b must be a positive 5-bit constant"));
   3923   1.1  christos       brmask = 0;
   3924   1.1  christos     }
   3925   1.1  christos 
   3926   1.1  christos   if (sep == ',')
   3927   1.1  christos     {
   3928   1.1  christos       unsigned reg;
   3929   1.1  christos       int n = popcount (brmask);
   3930   1.1  christos 
   3931   1.1  christos       parse_operand_and_eval (&e, 0);
   3932   1.1  christos       reg = e.X_add_number - REG_GR;
   3933   1.1  christos       if (e.X_op != O_register || reg > 127)
   3934   1.1  christos 	{
   3935   1.1  christos 	  as_bad (_("Second operand to .save.b must be a general register"));
   3936   1.1  christos 	  reg = 0;
   3937   1.1  christos 	}
   3938   1.1  christos       else if (reg > 128U - n)
   3939   1.1  christos 	{
   3940   1.1  christos 	  as_bad (_("Second operand to .save.b must be the first of %d general registers"), n);
   3941   1.1  christos 	  reg = 0;
   3942   1.1  christos 	}
   3943   1.1  christos       add_unwind_entry (output_br_gr (brmask, reg), 0);
   3944   1.1  christos     }
   3945   1.1  christos   else
   3946   1.1  christos     add_unwind_entry (output_br_mem (brmask), 0);
   3947   1.1  christos }
   3948   1.1  christos 
   3949   1.1  christos static void
   3950   1.1  christos dot_savegf (int dummy ATTRIBUTE_UNUSED)
   3951   1.1  christos {
   3952   1.1  christos   expressionS e1, e2;
   3953   1.1  christos 
   3954   1.1  christos   if (!in_prologue ("save.gf"))
   3955   1.1  christos     return;
   3956   1.1  christos 
   3957   1.1  christos   if (parse_operand_and_eval (&e1, ',') == ',')
   3958   1.1  christos     parse_operand_and_eval (&e2, 0);
   3959   1.1  christos   else
   3960   1.1  christos     e2.X_op = O_absent;
   3961   1.1  christos 
   3962   1.1  christos   if (e1.X_op != O_constant
   3963   1.1  christos       || e1.X_add_number < 0
   3964   1.1  christos       || e1.X_add_number > 0xf)
   3965   1.1  christos     {
   3966   1.1  christos       as_bad (_("First operand to .save.gf must be a non-negative 4-bit constant"));
   3967   1.1  christos       e1.X_op = O_absent;
   3968   1.1  christos       e1.X_add_number = 0;
   3969   1.1  christos     }
   3970   1.1  christos   if (e2.X_op != O_constant
   3971   1.1  christos       || e2.X_add_number < 0
   3972   1.1  christos       || e2.X_add_number > 0xfffff)
   3973   1.1  christos     {
   3974   1.1  christos       as_bad (_("Second operand to .save.gf must be a non-negative 20-bit constant"));
   3975   1.1  christos       e2.X_op = O_absent;
   3976   1.1  christos       e2.X_add_number = 0;
   3977   1.1  christos     }
   3978   1.1  christos   if (e1.X_op == O_constant
   3979   1.1  christos       && e2.X_op == O_constant
   3980   1.1  christos       && e1.X_add_number == 0
   3981   1.1  christos       && e2.X_add_number == 0)
   3982   1.1  christos     as_bad (_("Operands to .save.gf may not be both zero"));
   3983   1.1  christos 
   3984   1.1  christos   add_unwind_entry (output_frgr_mem (e1.X_add_number, e2.X_add_number), 0);
   3985   1.1  christos }
   3986   1.1  christos 
   3987   1.1  christos static void
   3988   1.1  christos dot_spill (int dummy ATTRIBUTE_UNUSED)
   3989   1.1  christos {
   3990   1.1  christos   expressionS e;
   3991   1.1  christos 
   3992   1.1  christos   if (!in_prologue ("spill"))
   3993   1.1  christos     return;
   3994   1.1  christos 
   3995   1.1  christos   parse_operand_and_eval (&e, 0);
   3996   1.1  christos 
   3997   1.1  christos   if (e.X_op != O_constant)
   3998   1.1  christos     {
   3999   1.1  christos       as_bad (_("Operand to .spill must be a constant"));
   4000   1.1  christos       e.X_add_number = 0;
   4001   1.1  christos     }
   4002   1.1  christos   add_unwind_entry (output_spill_base (e.X_add_number), 0);
   4003   1.1  christos }
   4004   1.1  christos 
   4005   1.1  christos static void
   4006   1.1  christos dot_spillreg (int pred)
   4007   1.1  christos {
   4008   1.1  christos   int sep;
   4009   1.1  christos   unsigned int qp, ab, xy, reg, treg;
   4010   1.1  christos   expressionS e;
   4011   1.1  christos   const char * const po = pred ? "spillreg.p" : "spillreg";
   4012   1.1  christos 
   4013   1.1  christos   if (!in_procedure (po))
   4014   1.1  christos     return;
   4015   1.1  christos 
   4016   1.1  christos   if (pred)
   4017   1.1  christos     sep = parse_predicate_and_operand (&e, &qp, po);
   4018   1.1  christos   else
   4019   1.1  christos     {
   4020   1.1  christos       sep = parse_operand_and_eval (&e, ',');
   4021   1.1  christos       qp = 0;
   4022   1.1  christos     }
   4023   1.1  christos   convert_expr_to_ab_reg (&e, &ab, &reg, po, 1 + pred);
   4024   1.1  christos 
   4025   1.1  christos   if (sep == ',')
   4026   1.1  christos     sep = parse_operand_and_eval (&e, ',');
   4027   1.1  christos   else
   4028   1.1  christos     e.X_op = O_absent;
   4029   1.1  christos   convert_expr_to_xy_reg (&e, &xy, &treg, po, 2 + pred);
   4030   1.1  christos 
   4031   1.1  christos   add_unwind_entry (output_spill_reg (ab, reg, treg, xy, qp), sep);
   4032   1.1  christos }
   4033   1.1  christos 
   4034   1.1  christos static void
   4035   1.1  christos dot_spillmem (int psprel)
   4036   1.1  christos {
   4037   1.1  christos   expressionS e;
   4038   1.1  christos   int pred = (psprel < 0), sep;
   4039   1.1  christos   unsigned int qp, ab, reg;
   4040   1.1  christos   const char * po;
   4041   1.1  christos 
   4042   1.1  christos   if (pred)
   4043   1.1  christos     {
   4044   1.1  christos       psprel = ~psprel;
   4045   1.1  christos       po = psprel ? "spillpsp.p" : "spillsp.p";
   4046   1.1  christos     }
   4047   1.1  christos   else
   4048   1.1  christos     po = psprel ? "spillpsp" : "spillsp";
   4049   1.1  christos 
   4050   1.1  christos   if (!in_procedure (po))
   4051   1.1  christos     return;
   4052   1.1  christos 
   4053   1.1  christos   if (pred)
   4054   1.1  christos     sep = parse_predicate_and_operand (&e, &qp, po);
   4055   1.1  christos   else
   4056   1.1  christos     {
   4057   1.1  christos       sep = parse_operand_and_eval (&e, ',');
   4058   1.1  christos       qp = 0;
   4059   1.1  christos     }
   4060   1.1  christos   convert_expr_to_ab_reg (&e, &ab, &reg, po, 1 + pred);
   4061   1.1  christos 
   4062   1.1  christos   if (sep == ',')
   4063   1.1  christos     sep = parse_operand_and_eval (&e, ',');
   4064   1.1  christos   else
   4065   1.1  christos     e.X_op = O_absent;
   4066   1.1  christos   if (e.X_op != O_constant)
   4067   1.1  christos     {
   4068   1.1  christos       as_bad (_("Operand %d to .%s must be a constant"), 2 + pred, po);
   4069   1.1  christos       e.X_add_number = 0;
   4070   1.1  christos     }
   4071   1.1  christos 
   4072   1.1  christos   if (psprel)
   4073   1.1  christos     add_unwind_entry (output_spill_psprel (ab, reg, e.X_add_number, qp), sep);
   4074   1.1  christos   else
   4075   1.1  christos     add_unwind_entry (output_spill_sprel (ab, reg, e.X_add_number, qp), sep);
   4076   1.1  christos }
   4077   1.1  christos 
   4078   1.1  christos static unsigned int
   4079   1.1  christos get_saved_prologue_count (unsigned long lbl)
   4080   1.1  christos {
   4081   1.1  christos   label_prologue_count *lpc = unwind.saved_prologue_counts;
   4082   1.1  christos 
   4083   1.1  christos   while (lpc != NULL && lpc->label_number != lbl)
   4084   1.1  christos     lpc = lpc->next;
   4085   1.1  christos 
   4086   1.1  christos   if (lpc != NULL)
   4087   1.1  christos     return lpc->prologue_count;
   4088   1.1  christos 
   4089   1.1  christos   as_bad (_("Missing .label_state %ld"), lbl);
   4090   1.1  christos   return 1;
   4091   1.1  christos }
   4092   1.1  christos 
   4093   1.1  christos static void
   4094   1.1  christos save_prologue_count (unsigned long lbl, unsigned int count)
   4095   1.1  christos {
   4096   1.1  christos   label_prologue_count *lpc = unwind.saved_prologue_counts;
   4097   1.1  christos 
   4098   1.1  christos   while (lpc != NULL && lpc->label_number != lbl)
   4099   1.1  christos     lpc = lpc->next;
   4100   1.1  christos 
   4101   1.1  christos   if (lpc != NULL)
   4102   1.1  christos     lpc->prologue_count = count;
   4103   1.1  christos   else
   4104   1.1  christos     {
   4105   1.5  christos       label_prologue_count *new_lpc = XNEW (label_prologue_count);
   4106   1.1  christos 
   4107   1.1  christos       new_lpc->next = unwind.saved_prologue_counts;
   4108   1.1  christos       new_lpc->label_number = lbl;
   4109   1.1  christos       new_lpc->prologue_count = count;
   4110   1.1  christos       unwind.saved_prologue_counts = new_lpc;
   4111   1.1  christos     }
   4112   1.1  christos }
   4113   1.1  christos 
   4114   1.1  christos static void
   4115   1.5  christos free_saved_prologue_counts (void)
   4116   1.1  christos {
   4117   1.1  christos   label_prologue_count *lpc = unwind.saved_prologue_counts;
   4118   1.1  christos   label_prologue_count *next;
   4119   1.1  christos 
   4120   1.1  christos   while (lpc != NULL)
   4121   1.1  christos     {
   4122   1.1  christos       next = lpc->next;
   4123   1.1  christos       free (lpc);
   4124   1.1  christos       lpc = next;
   4125   1.1  christos     }
   4126   1.1  christos 
   4127   1.1  christos   unwind.saved_prologue_counts = NULL;
   4128   1.1  christos }
   4129   1.1  christos 
   4130   1.1  christos static void
   4131   1.1  christos dot_label_state (int dummy ATTRIBUTE_UNUSED)
   4132   1.1  christos {
   4133   1.1  christos   expressionS e;
   4134   1.1  christos 
   4135   1.1  christos   if (!in_body ("label_state"))
   4136   1.1  christos     return;
   4137   1.1  christos 
   4138   1.1  christos   parse_operand_and_eval (&e, 0);
   4139   1.1  christos   if (e.X_op == O_constant)
   4140   1.1  christos     save_prologue_count (e.X_add_number, unwind.prologue_count);
   4141   1.1  christos   else
   4142   1.1  christos     {
   4143   1.1  christos       as_bad (_("Operand to .label_state must be a constant"));
   4144   1.1  christos       e.X_add_number = 0;
   4145   1.1  christos     }
   4146   1.1  christos   add_unwind_entry (output_label_state (e.X_add_number), 0);
   4147   1.1  christos }
   4148   1.1  christos 
   4149   1.1  christos static void
   4150   1.1  christos dot_copy_state (int dummy ATTRIBUTE_UNUSED)
   4151   1.1  christos {
   4152   1.1  christos   expressionS e;
   4153   1.1  christos 
   4154   1.1  christos   if (!in_body ("copy_state"))
   4155   1.1  christos     return;
   4156   1.1  christos 
   4157   1.1  christos   parse_operand_and_eval (&e, 0);
   4158   1.1  christos   if (e.X_op == O_constant)
   4159   1.1  christos     unwind.prologue_count = get_saved_prologue_count (e.X_add_number);
   4160   1.1  christos   else
   4161   1.1  christos     {
   4162   1.1  christos       as_bad (_("Operand to .copy_state must be a constant"));
   4163   1.1  christos       e.X_add_number = 0;
   4164   1.1  christos     }
   4165   1.1  christos   add_unwind_entry (output_copy_state (e.X_add_number), 0);
   4166   1.1  christos }
   4167   1.1  christos 
   4168   1.1  christos static void
   4169   1.1  christos dot_unwabi (int dummy ATTRIBUTE_UNUSED)
   4170   1.1  christos {
   4171   1.1  christos   expressionS e1, e2;
   4172   1.1  christos   unsigned char sep;
   4173   1.1  christos 
   4174   1.1  christos   if (!in_prologue ("unwabi"))
   4175   1.1  christos     return;
   4176   1.1  christos 
   4177   1.1  christos   sep = parse_operand_and_eval (&e1, ',');
   4178   1.1  christos   if (sep == ',')
   4179   1.1  christos     parse_operand_and_eval (&e2, 0);
   4180   1.1  christos   else
   4181   1.1  christos     e2.X_op = O_absent;
   4182   1.1  christos 
   4183   1.1  christos   if (e1.X_op != O_constant)
   4184   1.1  christos     {
   4185   1.1  christos       as_bad (_("First operand to .unwabi must be a constant"));
   4186   1.1  christos       e1.X_add_number = 0;
   4187   1.1  christos     }
   4188   1.1  christos 
   4189   1.1  christos   if (e2.X_op != O_constant)
   4190   1.1  christos     {
   4191   1.1  christos       as_bad (_("Second operand to .unwabi must be a constant"));
   4192   1.1  christos       e2.X_add_number = 0;
   4193   1.1  christos     }
   4194   1.1  christos 
   4195   1.1  christos   add_unwind_entry (output_unwabi (e1.X_add_number, e2.X_add_number), 0);
   4196   1.1  christos }
   4197   1.1  christos 
   4198   1.1  christos static void
   4199   1.1  christos dot_personality (int dummy ATTRIBUTE_UNUSED)
   4200   1.1  christos {
   4201  1.10  christos   char *name, c;
   4202   1.3  christos 
   4203   1.1  christos   if (!in_procedure ("personality"))
   4204   1.1  christos     return;
   4205   1.1  christos   SKIP_WHITESPACE ();
   4206   1.3  christos   c = get_symbol_name (&name);
   4207   1.1  christos   unwind.personality_routine = symbol_find_or_make (name);
   4208   1.1  christos   unwind.force_unwind_entry = 1;
   4209  1.10  christos   restore_line_pointer (c);
   4210  1.10  christos   SKIP_WHITESPACE ();
   4211   1.1  christos   demand_empty_rest_of_line ();
   4212   1.1  christos }
   4213   1.1  christos 
   4214   1.1  christos static void
   4215   1.1  christos dot_proc (int dummy ATTRIBUTE_UNUSED)
   4216   1.1  christos {
   4217  1.10  christos   char *name, c;
   4218   1.1  christos   symbolS *sym;
   4219   1.1  christos   proc_pending *pending, *last_pending;
   4220   1.1  christos 
   4221   1.1  christos   if (unwind.proc_pending.sym)
   4222   1.1  christos     {
   4223   1.1  christos       (md.unwind_check == unwind_check_warning
   4224   1.1  christos        ? as_warn
   4225   1.1  christos        : as_bad) (_("Missing .endp after previous .proc"));
   4226   1.1  christos       while (unwind.proc_pending.next)
   4227   1.1  christos 	{
   4228   1.1  christos 	  pending = unwind.proc_pending.next;
   4229   1.1  christos 	  unwind.proc_pending.next = pending->next;
   4230   1.1  christos 	  free (pending);
   4231   1.1  christos 	}
   4232   1.1  christos     }
   4233   1.1  christos   last_pending = NULL;
   4234   1.1  christos 
   4235   1.1  christos   /* Parse names of main and alternate entry points and mark them as
   4236   1.1  christos      function symbols:  */
   4237   1.1  christos   while (1)
   4238   1.1  christos     {
   4239   1.1  christos       SKIP_WHITESPACE ();
   4240   1.3  christos       c = get_symbol_name (&name);
   4241   1.1  christos       if (!*name)
   4242   1.1  christos 	as_bad (_("Empty argument of .proc"));
   4243   1.1  christos       else
   4244   1.1  christos 	{
   4245   1.1  christos 	  sym = symbol_find_or_make (name);
   4246   1.1  christos 	  if (S_IS_DEFINED (sym))
   4247   1.1  christos 	    as_bad (_("`%s' was already defined"), name);
   4248   1.1  christos 	  else if (!last_pending)
   4249   1.1  christos 	    {
   4250   1.1  christos 	      unwind.proc_pending.sym = sym;
   4251   1.1  christos 	      last_pending = &unwind.proc_pending;
   4252   1.1  christos 	    }
   4253   1.1  christos 	  else
   4254   1.1  christos 	    {
   4255   1.5  christos 	      pending = XNEW (proc_pending);
   4256   1.1  christos 	      pending->sym = sym;
   4257   1.1  christos 	      last_pending = last_pending->next = pending;
   4258   1.1  christos 	    }
   4259   1.1  christos 	  symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
   4260   1.1  christos 	}
   4261  1.10  christos       restore_line_pointer (c);
   4262  1.10  christos       SKIP_WHITESPACE ();
   4263   1.1  christos       if (*input_line_pointer != ',')
   4264   1.1  christos 	break;
   4265   1.1  christos       ++input_line_pointer;
   4266   1.1  christos     }
   4267   1.1  christos   if (!last_pending)
   4268   1.1  christos     {
   4269   1.1  christos       unwind.proc_pending.sym = expr_build_dot ();
   4270   1.1  christos       last_pending = &unwind.proc_pending;
   4271   1.1  christos     }
   4272   1.1  christos   last_pending->next = NULL;
   4273   1.1  christos   demand_empty_rest_of_line ();
   4274   1.5  christos   do_align (4, NULL, 0, 0);
   4275   1.1  christos 
   4276   1.1  christos   unwind.prologue = 0;
   4277   1.1  christos   unwind.prologue_count = 0;
   4278   1.1  christos   unwind.body = 0;
   4279   1.1  christos   unwind.insn = 0;
   4280   1.1  christos   unwind.list = unwind.tail = unwind.current_entry = NULL;
   4281   1.1  christos   unwind.personality_routine = 0;
   4282   1.1  christos }
   4283   1.1  christos 
   4284   1.1  christos static void
   4285   1.1  christos dot_body (int dummy ATTRIBUTE_UNUSED)
   4286   1.1  christos {
   4287   1.1  christos   if (!in_procedure ("body"))
   4288   1.1  christos     return;
   4289   1.1  christos   if (!unwind.prologue && !unwind.body && unwind.insn)
   4290   1.1  christos     as_warn (_("Initial .body should precede any instructions"));
   4291   1.1  christos   check_pending_save ();
   4292   1.1  christos 
   4293   1.1  christos   unwind.prologue = 0;
   4294   1.1  christos   unwind.prologue_mask = 0;
   4295   1.1  christos   unwind.body = 1;
   4296   1.1  christos 
   4297   1.1  christos   add_unwind_entry (output_body (), 0);
   4298   1.1  christos }
   4299   1.1  christos 
   4300   1.1  christos static void
   4301   1.1  christos dot_prologue (int dummy ATTRIBUTE_UNUSED)
   4302   1.1  christos {
   4303   1.1  christos   unsigned mask = 0, grsave = 0;
   4304   1.1  christos 
   4305   1.1  christos   if (!in_procedure ("prologue"))
   4306   1.1  christos     return;
   4307   1.1  christos   if (unwind.prologue)
   4308   1.1  christos     {
   4309   1.1  christos       as_bad (_(".prologue within prologue"));
   4310   1.1  christos       ignore_rest_of_line ();
   4311   1.1  christos       return;
   4312   1.1  christos     }
   4313   1.1  christos   if (!unwind.body && unwind.insn)
   4314   1.1  christos     as_warn (_("Initial .prologue should precede any instructions"));
   4315   1.1  christos 
   4316   1.1  christos   if (!is_it_end_of_statement ())
   4317   1.1  christos     {
   4318   1.1  christos       expressionS e;
   4319   1.1  christos       int n, sep = parse_operand_and_eval (&e, ',');
   4320   1.1  christos 
   4321   1.1  christos       if (e.X_op != O_constant
   4322   1.1  christos 	  || e.X_add_number < 0
   4323   1.1  christos 	  || e.X_add_number > 0xf)
   4324   1.1  christos 	as_bad (_("First operand to .prologue must be a positive 4-bit constant"));
   4325   1.1  christos       else if (e.X_add_number == 0)
   4326   1.1  christos 	as_warn (_("Pointless use of zero first operand to .prologue"));
   4327   1.1  christos       else
   4328   1.1  christos 	mask = e.X_add_number;
   4329   1.5  christos 
   4330   1.5  christos       n = popcount (mask);
   4331   1.1  christos 
   4332   1.1  christos       if (sep == ',')
   4333   1.1  christos 	parse_operand_and_eval (&e, 0);
   4334   1.1  christos       else
   4335   1.1  christos 	e.X_op = O_absent;
   4336   1.5  christos 
   4337   1.1  christos       if (e.X_op == O_constant
   4338   1.1  christos 	  && e.X_add_number >= 0
   4339   1.1  christos 	  && e.X_add_number < 128)
   4340   1.1  christos 	{
   4341   1.1  christos 	  if (md.unwind_check == unwind_check_error)
   4342   1.1  christos 	    as_warn (_("Using a constant as second operand to .prologue is deprecated"));
   4343   1.1  christos 	  grsave = e.X_add_number;
   4344   1.1  christos 	}
   4345   1.1  christos       else if (e.X_op != O_register
   4346   1.1  christos 	       || (grsave = e.X_add_number - REG_GR) > 127)
   4347   1.1  christos 	{
   4348   1.1  christos 	  as_bad (_("Second operand to .prologue must be a general register"));
   4349   1.1  christos 	  grsave = 0;
   4350   1.1  christos 	}
   4351   1.1  christos       else if (grsave > 128U - n)
   4352   1.1  christos 	{
   4353   1.1  christos 	  as_bad (_("Second operand to .prologue must be the first of %d general registers"), n);
   4354   1.1  christos 	  grsave = 0;
   4355   1.1  christos 	}
   4356   1.1  christos     }
   4357   1.1  christos 
   4358   1.1  christos   if (mask)
   4359   1.1  christos     add_unwind_entry (output_prologue_gr (mask, grsave), 0);
   4360   1.1  christos   else
   4361   1.1  christos     add_unwind_entry (output_prologue (), 0);
   4362   1.1  christos 
   4363   1.1  christos   unwind.prologue = 1;
   4364   1.1  christos   unwind.prologue_mask = mask;
   4365   1.1  christos   unwind.prologue_gr = grsave;
   4366   1.1  christos   unwind.body = 0;
   4367   1.1  christos   ++unwind.prologue_count;
   4368   1.1  christos }
   4369   1.1  christos 
   4370   1.1  christos static void
   4371   1.1  christos dot_endp (int dummy ATTRIBUTE_UNUSED)
   4372   1.1  christos {
   4373   1.1  christos   expressionS e;
   4374   1.1  christos   int bytes_per_address;
   4375   1.1  christos   long where;
   4376   1.1  christos   segT saved_seg;
   4377   1.1  christos   subsegT saved_subseg;
   4378   1.1  christos   proc_pending *pending;
   4379   1.1  christos   int unwind_check = md.unwind_check;
   4380   1.1  christos 
   4381   1.1  christos   md.unwind_check = unwind_check_error;
   4382   1.1  christos   if (!in_procedure ("endp"))
   4383   1.1  christos     return;
   4384   1.1  christos   md.unwind_check = unwind_check;
   4385   1.1  christos 
   4386   1.1  christos   if (unwind.saved_text_seg)
   4387   1.1  christos     {
   4388   1.1  christos       saved_seg = unwind.saved_text_seg;
   4389   1.1  christos       saved_subseg = unwind.saved_text_subseg;
   4390   1.1  christos       unwind.saved_text_seg = NULL;
   4391   1.1  christos     }
   4392   1.1  christos   else
   4393   1.1  christos     {
   4394   1.1  christos       saved_seg = now_seg;
   4395   1.1  christos       saved_subseg = now_subseg;
   4396   1.1  christos     }
   4397   1.1  christos 
   4398   1.1  christos   insn_group_break (1, 0, 0);
   4399   1.1  christos 
   4400   1.1  christos   /* If there wasn't a .handlerdata, we haven't generated an image yet.  */
   4401   1.1  christos   if (!unwind.info)
   4402   1.1  christos     generate_unwind_image (saved_seg);
   4403   1.1  christos 
   4404   1.1  christos   if (unwind.info || unwind.force_unwind_entry)
   4405   1.1  christos     {
   4406   1.1  christos       symbolS *proc_end;
   4407   1.1  christos 
   4408   1.8  christos       subseg_set (md.last_text_seg, md.last_text_subseg);
   4409   1.1  christos       proc_end = expr_build_dot ();
   4410   1.1  christos 
   4411   1.1  christos       start_unwind_section (saved_seg, SPECIAL_SECTION_UNWIND);
   4412   1.1  christos 
   4413   1.1  christos       /* Make sure that section has 4 byte alignment for ILP32 and
   4414   1.1  christos          8 byte alignment for LP64.  */
   4415   1.1  christos       record_alignment (now_seg, md.pointer_size_shift);
   4416   1.1  christos 
   4417   1.1  christos       /* Need space for 3 pointers for procedure start, procedure end,
   4418   1.1  christos 	 and unwind info.  */
   4419   1.1  christos       memset (frag_more (3 * md.pointer_size), 0, 3 * md.pointer_size);
   4420   1.1  christos       where = frag_now_fix () - (3 * md.pointer_size);
   4421   1.1  christos       bytes_per_address = bfd_arch_bits_per_address (stdoutput) / 8;
   4422   1.1  christos 
   4423   1.1  christos       /* Issue the values of  a) Proc Begin, b) Proc End, c) Unwind Record.  */
   4424   1.1  christos       e.X_op = O_pseudo_fixup;
   4425   1.1  christos       e.X_op_symbol = pseudo_func[FUNC_SEG_RELATIVE].u.sym;
   4426   1.1  christos       e.X_add_number = 0;
   4427   1.1  christos       if (!S_IS_LOCAL (unwind.proc_pending.sym)
   4428   1.1  christos 	  && S_IS_DEFINED (unwind.proc_pending.sym))
   4429   1.8  christos 	e.X_add_symbol
   4430   1.8  christos 	  = symbol_temp_new (S_GET_SEGMENT (unwind.proc_pending.sym),
   4431   1.8  christos 			     symbol_get_frag (unwind.proc_pending.sym),
   4432   1.8  christos 			     S_GET_VALUE (unwind.proc_pending.sym));
   4433   1.1  christos       else
   4434   1.1  christos 	e.X_add_symbol = unwind.proc_pending.sym;
   4435   1.3  christos       ia64_cons_fix_new (frag_now, where, bytes_per_address, &e,
   4436   1.3  christos 			 BFD_RELOC_NONE);
   4437   1.1  christos 
   4438   1.1  christos       e.X_op = O_pseudo_fixup;
   4439   1.1  christos       e.X_op_symbol = pseudo_func[FUNC_SEG_RELATIVE].u.sym;
   4440   1.1  christos       e.X_add_number = 0;
   4441   1.1  christos       e.X_add_symbol = proc_end;
   4442   1.1  christos       ia64_cons_fix_new (frag_now, where + bytes_per_address,
   4443   1.3  christos 			 bytes_per_address, &e, BFD_RELOC_NONE);
   4444   1.1  christos 
   4445   1.1  christos       if (unwind.info)
   4446   1.1  christos 	{
   4447   1.1  christos 	  e.X_op = O_pseudo_fixup;
   4448   1.1  christos 	  e.X_op_symbol = pseudo_func[FUNC_SEG_RELATIVE].u.sym;
   4449   1.1  christos 	  e.X_add_number = 0;
   4450   1.1  christos 	  e.X_add_symbol = unwind.info;
   4451   1.1  christos 	  ia64_cons_fix_new (frag_now, where + (bytes_per_address * 2),
   4452   1.3  christos 			     bytes_per_address, &e, BFD_RELOC_NONE);
   4453   1.1  christos 	}
   4454   1.1  christos     }
   4455   1.1  christos   subseg_set (saved_seg, saved_subseg);
   4456   1.1  christos 
   4457   1.1  christos   /* Set symbol sizes.  */
   4458   1.1  christos   pending = &unwind.proc_pending;
   4459   1.1  christos   if (S_GET_NAME (pending->sym))
   4460   1.1  christos     {
   4461   1.1  christos       do
   4462   1.1  christos 	{
   4463   1.1  christos 	  symbolS *sym = pending->sym;
   4464   1.1  christos 
   4465   1.1  christos 	  if (!S_IS_DEFINED (sym))
   4466   1.1  christos 	    as_bad (_("`%s' was not defined within procedure"), S_GET_NAME (sym));
   4467   1.1  christos 	  else if (S_GET_SIZE (sym) == 0
   4468   1.1  christos 		   && symbol_get_obj (sym)->size == NULL)
   4469   1.1  christos 	    {
   4470   1.1  christos 	      fragS *frag = symbol_get_frag (sym);
   4471   1.1  christos 
   4472   1.1  christos 	      if (frag)
   4473   1.1  christos 		{
   4474   1.1  christos 		  if (frag == frag_now && SEG_NORMAL (now_seg))
   4475   1.1  christos 		    S_SET_SIZE (sym, frag_now_fix () - S_GET_VALUE (sym));
   4476   1.1  christos 		  else
   4477   1.1  christos 		    {
   4478  1.10  christos 		      OBJ_SYMFIELD_TYPE *obj = symbol_get_obj (sym);
   4479  1.10  christos 		      obj->size = notes_alloc (sizeof (*obj->size));
   4480  1.10  christos 		      obj->size->X_op = O_subtract;
   4481  1.10  christos 		      obj->size->X_add_symbol
   4482   1.1  christos 			= symbol_new (FAKE_LABEL_NAME, now_seg,
   4483   1.8  christos 				      frag_now, frag_now_fix ());
   4484  1.10  christos 		      obj->size->X_op_symbol = sym;
   4485  1.10  christos 		      obj->size->X_add_number = 0;
   4486   1.1  christos 		    }
   4487   1.1  christos 		}
   4488   1.1  christos 	    }
   4489   1.1  christos 	} while ((pending = pending->next) != NULL);
   4490   1.1  christos     }
   4491   1.1  christos 
   4492   1.1  christos   /* Parse names of main and alternate entry points.  */
   4493   1.1  christos   while (1)
   4494   1.1  christos     {
   4495  1.10  christos       char *name, c;
   4496   1.1  christos 
   4497   1.1  christos       SKIP_WHITESPACE ();
   4498   1.3  christos       c = get_symbol_name (&name);
   4499   1.1  christos       if (!*name)
   4500   1.1  christos 	(md.unwind_check == unwind_check_warning
   4501   1.1  christos 	 ? as_warn
   4502   1.1  christos 	 : as_bad) (_("Empty argument of .endp"));
   4503   1.1  christos       else
   4504   1.1  christos 	{
   4505   1.1  christos 	  symbolS *sym = symbol_find (name);
   4506   1.1  christos 
   4507   1.1  christos 	  for (pending = &unwind.proc_pending; pending; pending = pending->next)
   4508   1.1  christos 	    {
   4509   1.1  christos 	      if (sym == pending->sym)
   4510   1.1  christos 		{
   4511   1.1  christos 		  pending->sym = NULL;
   4512   1.1  christos 		  break;
   4513   1.1  christos 		}
   4514   1.1  christos 	    }
   4515   1.1  christos 	  if (!sym || !pending)
   4516   1.1  christos 	    as_warn (_("`%s' was not specified with previous .proc"), name);
   4517   1.1  christos 	}
   4518  1.10  christos       restore_line_pointer (c);
   4519  1.10  christos       SKIP_WHITESPACE ();
   4520   1.1  christos       if (*input_line_pointer != ',')
   4521   1.1  christos 	break;
   4522   1.1  christos       ++input_line_pointer;
   4523   1.1  christos     }
   4524   1.1  christos   demand_empty_rest_of_line ();
   4525   1.1  christos 
   4526   1.1  christos   /* Deliberately only checking for the main entry point here; the
   4527   1.1  christos      language spec even says all arguments to .endp are ignored.  */
   4528   1.1  christos   if (unwind.proc_pending.sym
   4529   1.1  christos       && S_GET_NAME (unwind.proc_pending.sym)
   4530   1.1  christos       && strcmp (S_GET_NAME (unwind.proc_pending.sym), FAKE_LABEL_NAME))
   4531   1.1  christos     as_warn (_("`%s' should be an operand to this .endp"),
   4532   1.1  christos 	     S_GET_NAME (unwind.proc_pending.sym));
   4533   1.1  christos   while (unwind.proc_pending.next)
   4534   1.1  christos     {
   4535   1.1  christos       pending = unwind.proc_pending.next;
   4536   1.1  christos       unwind.proc_pending.next = pending->next;
   4537   1.1  christos       free (pending);
   4538   1.1  christos     }
   4539   1.1  christos   unwind.proc_pending.sym = unwind.info = NULL;
   4540   1.1  christos }
   4541   1.1  christos 
   4542   1.1  christos static void
   4543   1.1  christos dot_template (int template_val)
   4544   1.1  christos {
   4545   1.1  christos   CURR_SLOT.user_template = template_val;
   4546   1.1  christos }
   4547   1.1  christos 
   4548   1.1  christos static void
   4549   1.1  christos dot_regstk (int dummy ATTRIBUTE_UNUSED)
   4550   1.1  christos {
   4551   1.1  christos   int ins, locs, outs, rots;
   4552   1.1  christos 
   4553   1.1  christos   if (is_it_end_of_statement ())
   4554   1.1  christos     ins = locs = outs = rots = 0;
   4555   1.1  christos   else
   4556   1.1  christos     {
   4557   1.1  christos       ins = get_absolute_expression ();
   4558   1.1  christos       if (*input_line_pointer++ != ',')
   4559   1.1  christos 	goto err;
   4560   1.1  christos       locs = get_absolute_expression ();
   4561   1.1  christos       if (*input_line_pointer++ != ',')
   4562   1.1  christos 	goto err;
   4563   1.1  christos       outs = get_absolute_expression ();
   4564   1.1  christos       if (*input_line_pointer++ != ',')
   4565   1.1  christos 	goto err;
   4566   1.1  christos       rots = get_absolute_expression ();
   4567   1.1  christos     }
   4568   1.1  christos   set_regstack (ins, locs, outs, rots);
   4569   1.1  christos   return;
   4570   1.1  christos 
   4571   1.1  christos  err:
   4572   1.1  christos   as_bad (_("Comma expected"));
   4573   1.1  christos   ignore_rest_of_line ();
   4574   1.1  christos }
   4575   1.1  christos 
   4576   1.1  christos static void
   4577   1.1  christos dot_rot (int type)
   4578   1.1  christos {
   4579   1.1  christos   offsetT num_regs;
   4580   1.1  christos   valueT num_alloced = 0;
   4581   1.1  christos   struct dynreg **drpp, *dr;
   4582   1.1  christos   int ch, base_reg = 0;
   4583   1.1  christos   char *name, *start;
   4584   1.1  christos   size_t len;
   4585   1.1  christos 
   4586   1.1  christos   switch (type)
   4587   1.1  christos     {
   4588   1.1  christos     case DYNREG_GR: base_reg = REG_GR + 32; break;
   4589   1.1  christos     case DYNREG_FR: base_reg = REG_FR + 32; break;
   4590   1.1  christos     case DYNREG_PR: base_reg = REG_P + 16; break;
   4591   1.1  christos     default: break;
   4592   1.1  christos     }
   4593   1.1  christos 
   4594   1.1  christos   /* First, remove existing names from hash table.  */
   4595   1.1  christos   for (dr = md.dynreg[type]; dr && dr->num_regs; dr = dr->next)
   4596   1.1  christos     {
   4597   1.8  christos       str_hash_delete (md.dynreg_hash, dr->name);
   4598   1.1  christos       /* FIXME: Free dr->name.  */
   4599   1.1  christos       dr->num_regs = 0;
   4600   1.1  christos     }
   4601   1.1  christos 
   4602   1.1  christos   drpp = &md.dynreg[type];
   4603   1.1  christos   while (1)
   4604   1.1  christos     {
   4605   1.3  christos       ch = get_symbol_name (&start);
   4606   1.1  christos       len = strlen (ia64_canonicalize_symbol_name (start));
   4607  1.10  christos       restore_line_pointer (ch);
   4608   1.1  christos 
   4609  1.10  christos       SKIP_WHITESPACE ();
   4610   1.1  christos       if (*input_line_pointer != '[')
   4611   1.1  christos 	{
   4612   1.1  christos 	  as_bad (_("Expected '['"));
   4613   1.1  christos 	  goto err;
   4614   1.1  christos 	}
   4615   1.1  christos       ++input_line_pointer;	/* skip '[' */
   4616   1.1  christos 
   4617   1.1  christos       num_regs = get_absolute_expression ();
   4618   1.1  christos 
   4619   1.1  christos       if (*input_line_pointer++ != ']')
   4620   1.1  christos 	{
   4621   1.1  christos 	  as_bad (_("Expected ']'"));
   4622   1.1  christos 	  goto err;
   4623   1.1  christos 	}
   4624   1.1  christos       if (num_regs <= 0)
   4625   1.1  christos 	{
   4626   1.1  christos 	  as_bad (_("Number of elements must be positive"));
   4627   1.1  christos 	  goto err;
   4628   1.1  christos 	}
   4629   1.1  christos       SKIP_WHITESPACE ();
   4630   1.1  christos 
   4631   1.1  christos       num_alloced += num_regs;
   4632   1.1  christos       switch (type)
   4633   1.1  christos 	{
   4634   1.1  christos 	case DYNREG_GR:
   4635   1.1  christos 	  if (num_alloced > md.rot.num_regs)
   4636   1.1  christos 	    {
   4637   1.1  christos 	      as_bad (_("Used more than the declared %d rotating registers"),
   4638   1.1  christos 		      md.rot.num_regs);
   4639   1.1  christos 	      goto err;
   4640   1.1  christos 	    }
   4641   1.1  christos 	  break;
   4642   1.1  christos 	case DYNREG_FR:
   4643   1.1  christos 	  if (num_alloced > 96)
   4644   1.1  christos 	    {
   4645   1.1  christos 	      as_bad (_("Used more than the available 96 rotating registers"));
   4646   1.1  christos 	      goto err;
   4647   1.1  christos 	    }
   4648   1.1  christos 	  break;
   4649   1.1  christos 	case DYNREG_PR:
   4650   1.1  christos 	  if (num_alloced > 48)
   4651   1.1  christos 	    {
   4652   1.1  christos 	      as_bad (_("Used more than the available 48 rotating registers"));
   4653   1.1  christos 	      goto err;
   4654   1.1  christos 	    }
   4655   1.1  christos 	  break;
   4656   1.1  christos 
   4657   1.1  christos 	default:
   4658   1.1  christos 	  break;
   4659   1.1  christos 	}
   4660   1.1  christos 
   4661   1.1  christos       if (!*drpp)
   4662   1.9  christos 	*drpp = notes_calloc (1, sizeof (**drpp));
   4663   1.1  christos 
   4664   1.9  christos       name = notes_memdup (start, len, len + 1);
   4665   1.1  christos 
   4666   1.1  christos       dr = *drpp;
   4667   1.1  christos       dr->name = name;
   4668   1.1  christos       dr->num_regs = num_regs;
   4669   1.1  christos       dr->base = base_reg;
   4670   1.1  christos       drpp = &dr->next;
   4671   1.1  christos       base_reg += num_regs;
   4672   1.1  christos 
   4673   1.8  christos       if (str_hash_insert (md.dynreg_hash, name, dr, 0) != NULL)
   4674   1.1  christos 	{
   4675   1.1  christos 	  as_bad (_("Attempt to redefine register set `%s'"), name);
   4676   1.1  christos 	  goto err;
   4677   1.1  christos 	}
   4678   1.1  christos 
   4679   1.1  christos       if (*input_line_pointer != ',')
   4680   1.1  christos 	break;
   4681   1.1  christos       ++input_line_pointer;	/* skip comma */
   4682   1.1  christos       SKIP_WHITESPACE ();
   4683   1.1  christos     }
   4684   1.1  christos   demand_empty_rest_of_line ();
   4685   1.1  christos   return;
   4686   1.1  christos 
   4687   1.1  christos  err:
   4688   1.1  christos   ignore_rest_of_line ();
   4689   1.1  christos }
   4690   1.1  christos 
   4691   1.1  christos static void
   4692   1.1  christos dot_byteorder (int byteorder)
   4693   1.1  christos {
   4694   1.1  christos   segment_info_type *seginfo = seg_info (now_seg);
   4695   1.1  christos 
   4696   1.1  christos   if (byteorder == -1)
   4697   1.1  christos     {
   4698   1.1  christos       if (seginfo->tc_segment_info_data.endian == 0)
   4699   1.1  christos 	seginfo->tc_segment_info_data.endian = default_big_endian ? 1 : 2;
   4700   1.1  christos       byteorder = seginfo->tc_segment_info_data.endian == 1;
   4701   1.1  christos     }
   4702   1.1  christos   else
   4703   1.1  christos     seginfo->tc_segment_info_data.endian = byteorder ? 1 : 2;
   4704   1.1  christos 
   4705   1.1  christos   if (target_big_endian != byteorder)
   4706   1.1  christos     {
   4707   1.1  christos       target_big_endian = byteorder;
   4708   1.1  christos       if (target_big_endian)
   4709   1.1  christos 	{
   4710   1.1  christos 	  ia64_number_to_chars = number_to_chars_bigendian;
   4711   1.1  christos 	  ia64_float_to_chars = ia64_float_to_chars_bigendian;
   4712   1.1  christos 	}
   4713   1.1  christos       else
   4714   1.1  christos 	{
   4715   1.1  christos 	  ia64_number_to_chars = number_to_chars_littleendian;
   4716   1.1  christos 	  ia64_float_to_chars = ia64_float_to_chars_littleendian;
   4717   1.1  christos 	}
   4718   1.1  christos     }
   4719   1.1  christos }
   4720   1.1  christos 
   4721   1.1  christos static void
   4722   1.1  christos dot_psr (int dummy ATTRIBUTE_UNUSED)
   4723   1.1  christos {
   4724   1.1  christos   char *option;
   4725   1.1  christos   int ch;
   4726   1.1  christos 
   4727   1.1  christos   while (1)
   4728   1.1  christos     {
   4729   1.3  christos       ch = get_symbol_name (&option);
   4730   1.1  christos       if (strcmp (option, "lsb") == 0)
   4731   1.1  christos 	md.flags &= ~EF_IA_64_BE;
   4732   1.1  christos       else if (strcmp (option, "msb") == 0)
   4733   1.1  christos 	md.flags |= EF_IA_64_BE;
   4734   1.1  christos       else if (strcmp (option, "abi32") == 0)
   4735   1.1  christos 	md.flags &= ~EF_IA_64_ABI64;
   4736   1.1  christos       else if (strcmp (option, "abi64") == 0)
   4737   1.1  christos 	md.flags |= EF_IA_64_ABI64;
   4738   1.1  christos       else
   4739   1.1  christos 	as_bad (_("Unknown psr option `%s'"), option);
   4740  1.10  christos       restore_line_pointer (ch);
   4741   1.1  christos 
   4742  1.10  christos       SKIP_WHITESPACE ();
   4743   1.1  christos       if (*input_line_pointer != ',')
   4744   1.1  christos 	break;
   4745   1.1  christos 
   4746   1.1  christos       ++input_line_pointer;
   4747   1.1  christos       SKIP_WHITESPACE ();
   4748   1.1  christos     }
   4749   1.1  christos   demand_empty_rest_of_line ();
   4750   1.1  christos }
   4751   1.1  christos 
   4752   1.1  christos static void
   4753   1.1  christos dot_ln (int dummy ATTRIBUTE_UNUSED)
   4754   1.1  christos {
   4755   1.1  christos   new_logical_line (0, get_absolute_expression ());
   4756   1.1  christos   demand_empty_rest_of_line ();
   4757   1.1  christos }
   4758   1.1  christos 
   4759   1.1  christos static void
   4760   1.1  christos cross_section (int ref, void (*builder) (int), int ua)
   4761   1.1  christos {
   4762   1.1  christos   char *start, *end;
   4763   1.1  christos   int saved_auto_align;
   4764   1.1  christos   unsigned int section_count;
   4765   1.8  christos   const char *name;
   4766   1.1  christos 
   4767   1.1  christos   start = input_line_pointer;
   4768   1.8  christos   name = obj_elf_section_name ();
   4769   1.8  christos   if (name == NULL)
   4770   1.8  christos     return;
   4771   1.1  christos   end = input_line_pointer;
   4772   1.1  christos   if (*input_line_pointer != ',')
   4773   1.1  christos     {
   4774   1.1  christos       as_bad (_("Comma expected after section name"));
   4775   1.1  christos       ignore_rest_of_line ();
   4776   1.1  christos       return;
   4777   1.1  christos     }
   4778   1.1  christos   *end = '\0';
   4779   1.1  christos   end = input_line_pointer + 1;		/* skip comma */
   4780   1.1  christos   input_line_pointer = start;
   4781   1.1  christos   md.keep_pending_output = 1;
   4782   1.1  christos   section_count = bfd_count_sections (stdoutput);
   4783   1.1  christos   obj_elf_section (0);
   4784   1.1  christos   if (section_count != bfd_count_sections (stdoutput))
   4785   1.1  christos     as_warn (_("Creating sections with .xdataN/.xrealN/.xstringZ is deprecated."));
   4786   1.1  christos   input_line_pointer = end;
   4787   1.1  christos   saved_auto_align = md.auto_align;
   4788   1.1  christos   if (ua)
   4789   1.1  christos     md.auto_align = 0;
   4790   1.1  christos   (*builder) (ref);
   4791   1.1  christos   if (ua)
   4792   1.1  christos     md.auto_align = saved_auto_align;
   4793   1.1  christos   obj_elf_previous (0);
   4794   1.1  christos   md.keep_pending_output = 0;
   4795   1.1  christos }
   4796   1.1  christos 
   4797   1.1  christos static void
   4798   1.1  christos dot_xdata (int size)
   4799   1.1  christos {
   4800   1.1  christos   cross_section (size, cons, 0);
   4801   1.1  christos }
   4802   1.1  christos 
   4803   1.1  christos /* Why doesn't float_cons() call md_cons_align() the way cons() does?  */
   4804   1.1  christos 
   4805   1.1  christos static void
   4806   1.1  christos stmt_float_cons (int kind)
   4807   1.1  christos {
   4808   1.1  christos   size_t alignment;
   4809   1.1  christos 
   4810   1.1  christos   switch (kind)
   4811   1.1  christos     {
   4812   1.1  christos     case 'd':
   4813   1.5  christos       alignment = 3;
   4814   1.1  christos       break;
   4815   1.1  christos 
   4816   1.1  christos     case 'x':
   4817   1.1  christos     case 'X':
   4818   1.5  christos       alignment = 4;
   4819   1.1  christos       break;
   4820   1.1  christos 
   4821   1.1  christos     case 'f':
   4822   1.1  christos     default:
   4823   1.5  christos       alignment = 2;
   4824   1.1  christos       break;
   4825   1.1  christos     }
   4826   1.5  christos   do_align (alignment, NULL, 0, 0);
   4827   1.1  christos   float_cons (kind);
   4828   1.1  christos }
   4829   1.1  christos 
   4830   1.1  christos static void
   4831   1.1  christos stmt_cons_ua (int size)
   4832   1.1  christos {
   4833   1.1  christos   int saved_auto_align = md.auto_align;
   4834   1.1  christos 
   4835   1.1  christos   md.auto_align = 0;
   4836   1.1  christos   cons (size);
   4837   1.1  christos   md.auto_align = saved_auto_align;
   4838   1.1  christos }
   4839   1.1  christos 
   4840   1.1  christos static void
   4841   1.1  christos dot_xfloat_cons (int kind)
   4842   1.1  christos {
   4843   1.1  christos   cross_section (kind, stmt_float_cons, 0);
   4844   1.1  christos }
   4845   1.1  christos 
   4846   1.1  christos static void
   4847   1.1  christos dot_xstringer (int zero)
   4848   1.1  christos {
   4849   1.1  christos   cross_section (zero, stringer, 0);
   4850   1.1  christos }
   4851   1.1  christos 
   4852   1.1  christos static void
   4853   1.1  christos dot_xdata_ua (int size)
   4854   1.1  christos {
   4855   1.1  christos   cross_section (size, cons, 1);
   4856   1.1  christos }
   4857   1.1  christos 
   4858   1.1  christos static void
   4859   1.1  christos dot_xfloat_cons_ua (int kind)
   4860   1.1  christos {
   4861   1.1  christos   cross_section (kind, float_cons, 1);
   4862   1.1  christos }
   4863   1.1  christos 
   4864   1.1  christos /* .reg.val <regname>,value */
   4865   1.1  christos 
   4866   1.1  christos static void
   4867   1.1  christos dot_reg_val (int dummy ATTRIBUTE_UNUSED)
   4868   1.1  christos {
   4869   1.1  christos   expressionS reg;
   4870   1.1  christos 
   4871   1.1  christos   expression_and_evaluate (&reg);
   4872   1.1  christos   if (reg.X_op != O_register)
   4873   1.1  christos     {
   4874   1.1  christos       as_bad (_("Register name expected"));
   4875   1.1  christos       ignore_rest_of_line ();
   4876   1.1  christos     }
   4877   1.1  christos   else if (*input_line_pointer++ != ',')
   4878   1.1  christos     {
   4879   1.1  christos       as_bad (_("Comma expected"));
   4880   1.1  christos       ignore_rest_of_line ();
   4881   1.1  christos     }
   4882   1.1  christos   else
   4883   1.1  christos     {
   4884   1.1  christos       valueT value = get_absolute_expression ();
   4885   1.1  christos       int regno = reg.X_add_number;
   4886   1.1  christos       if (regno <= REG_GR || regno > REG_GR + 127)
   4887   1.1  christos 	as_warn (_("Register value annotation ignored"));
   4888   1.1  christos       else
   4889   1.1  christos 	{
   4890   1.1  christos 	  gr_values[regno - REG_GR].known = 1;
   4891   1.1  christos 	  gr_values[regno - REG_GR].value = value;
   4892   1.1  christos 	  gr_values[regno - REG_GR].path = md.path;
   4893   1.1  christos 	}
   4894   1.1  christos     }
   4895   1.1  christos   demand_empty_rest_of_line ();
   4896   1.1  christos }
   4897   1.1  christos 
   4898   1.1  christos /*
   4899   1.1  christos   .serialize.data
   4900   1.1  christos   .serialize.instruction
   4901   1.1  christos  */
   4902   1.1  christos static void
   4903   1.1  christos dot_serialize (int type)
   4904   1.1  christos {
   4905   1.1  christos   insn_group_break (0, 0, 0);
   4906   1.1  christos   if (type)
   4907   1.1  christos     instruction_serialization ();
   4908   1.1  christos   else
   4909   1.1  christos     data_serialization ();
   4910   1.1  christos   insn_group_break (0, 0, 0);
   4911   1.1  christos   demand_empty_rest_of_line ();
   4912   1.1  christos }
   4913   1.1  christos 
   4914   1.1  christos /* select dv checking mode
   4915   1.1  christos    .auto
   4916   1.1  christos    .explicit
   4917   1.1  christos    .default
   4918   1.1  christos 
   4919   1.1  christos    A stop is inserted when changing modes
   4920   1.1  christos  */
   4921   1.1  christos 
   4922   1.1  christos static void
   4923   1.1  christos dot_dv_mode (int type)
   4924   1.1  christos {
   4925   1.1  christos   if (md.manual_bundling)
   4926   1.1  christos     as_warn (_("Directive invalid within a bundle"));
   4927   1.1  christos 
   4928   1.1  christos   if (type == 'E' || type == 'A')
   4929   1.1  christos     md.mode_explicitly_set = 0;
   4930   1.1  christos   else
   4931   1.1  christos     md.mode_explicitly_set = 1;
   4932   1.1  christos 
   4933   1.1  christos   md.detect_dv = 1;
   4934   1.1  christos   switch (type)
   4935   1.1  christos     {
   4936   1.1  christos     case 'A':
   4937   1.1  christos     case 'a':
   4938   1.1  christos       if (md.explicit_mode)
   4939   1.1  christos 	insn_group_break (1, 0, 0);
   4940   1.1  christos       md.explicit_mode = 0;
   4941   1.1  christos       break;
   4942   1.1  christos     case 'E':
   4943   1.1  christos     case 'e':
   4944   1.1  christos       if (!md.explicit_mode)
   4945   1.1  christos 	insn_group_break (1, 0, 0);
   4946   1.1  christos       md.explicit_mode = 1;
   4947   1.1  christos       break;
   4948   1.1  christos     default:
   4949   1.1  christos     case 'd':
   4950   1.1  christos       if (md.explicit_mode != md.default_explicit_mode)
   4951   1.1  christos 	insn_group_break (1, 0, 0);
   4952   1.1  christos       md.explicit_mode = md.default_explicit_mode;
   4953   1.1  christos       md.mode_explicitly_set = 0;
   4954   1.1  christos       break;
   4955   1.1  christos     }
   4956   1.1  christos }
   4957   1.1  christos 
   4958   1.1  christos static void
   4959   1.1  christos print_prmask (valueT mask)
   4960   1.1  christos {
   4961   1.1  christos   int regno;
   4962   1.5  christos   const char *comma = "";
   4963   1.1  christos   for (regno = 0; regno < 64; regno++)
   4964   1.1  christos     {
   4965   1.1  christos       if (mask & ((valueT) 1 << regno))
   4966   1.1  christos 	{
   4967   1.1  christos 	  fprintf (stderr, "%s p%d", comma, regno);
   4968   1.1  christos 	  comma = ",";
   4969   1.1  christos 	}
   4970   1.1  christos     }
   4971   1.1  christos }
   4972   1.1  christos 
   4973   1.1  christos /*
   4974   1.1  christos   .pred.rel.clear [p1 [,p2 [,...]]]     (also .pred.rel "clear" or @clear)
   4975   1.1  christos   .pred.rel.imply p1, p2                (also .pred.rel "imply" or @imply)
   4976   1.1  christos   .pred.rel.mutex p1, p2 [,...]         (also .pred.rel "mutex" or @mutex)
   4977   1.1  christos   .pred.safe_across_calls p1 [, p2 [,...]]
   4978   1.1  christos  */
   4979   1.1  christos 
   4980   1.1  christos static void
   4981   1.1  christos dot_pred_rel (int type)
   4982   1.1  christos {
   4983   1.1  christos   valueT mask = 0;
   4984   1.1  christos   int count = 0;
   4985   1.1  christos   int p1 = -1, p2 = -1;
   4986   1.1  christos 
   4987   1.1  christos   if (type == 0)
   4988   1.1  christos     {
   4989   1.1  christos       if (*input_line_pointer == '"')
   4990   1.1  christos 	{
   4991   1.1  christos 	  int len;
   4992   1.1  christos 	  char *form = demand_copy_C_string (&len);
   4993   1.1  christos 
   4994   1.1  christos 	  if (strcmp (form, "mutex") == 0)
   4995   1.1  christos 	    type = 'm';
   4996   1.1  christos 	  else if (strcmp (form, "clear") == 0)
   4997   1.1  christos 	    type = 'c';
   4998   1.1  christos 	  else if (strcmp (form, "imply") == 0)
   4999   1.1  christos 	    type = 'i';
   5000   1.9  christos 	  notes_free (form);
   5001   1.1  christos 	}
   5002   1.1  christos       else if (*input_line_pointer == '@')
   5003   1.1  christos 	{
   5004   1.3  christos 	  char *form;
   5005   1.3  christos 	  char c;
   5006   1.3  christos 
   5007   1.3  christos 	  ++input_line_pointer;
   5008   1.3  christos 	  c = get_symbol_name (&form);
   5009   1.1  christos 
   5010   1.1  christos 	  if (strcmp (form, "mutex") == 0)
   5011   1.1  christos 	    type = 'm';
   5012   1.1  christos 	  else if (strcmp (form, "clear") == 0)
   5013   1.1  christos 	    type = 'c';
   5014   1.1  christos 	  else if (strcmp (form, "imply") == 0)
   5015   1.1  christos 	    type = 'i';
   5016   1.3  christos 	  (void) restore_line_pointer (c);
   5017   1.1  christos 	}
   5018   1.1  christos       else
   5019   1.1  christos 	{
   5020   1.1  christos 	  as_bad (_("Missing predicate relation type"));
   5021   1.1  christos 	  ignore_rest_of_line ();
   5022   1.1  christos 	  return;
   5023   1.1  christos 	}
   5024   1.1  christos       if (type == 0)
   5025   1.1  christos 	{
   5026   1.1  christos 	  as_bad (_("Unrecognized predicate relation type"));
   5027   1.1  christos 	  ignore_rest_of_line ();
   5028   1.1  christos 	  return;
   5029   1.1  christos 	}
   5030   1.1  christos       if (*input_line_pointer == ',')
   5031   1.1  christos 	++input_line_pointer;
   5032   1.1  christos       SKIP_WHITESPACE ();
   5033   1.1  christos     }
   5034   1.1  christos 
   5035   1.1  christos   while (1)
   5036   1.1  christos     {
   5037   1.1  christos       valueT bits = 1;
   5038   1.1  christos       int sep, regno;
   5039   1.1  christos       expressionS pr, *pr1, *pr2;
   5040   1.1  christos 
   5041   1.1  christos       sep = parse_operand_and_eval (&pr, ',');
   5042   1.1  christos       if (pr.X_op == O_register
   5043   1.1  christos 	  && pr.X_add_number >= REG_P
   5044   1.1  christos 	  && pr.X_add_number <= REG_P + 63)
   5045   1.1  christos 	{
   5046   1.1  christos 	  regno = pr.X_add_number - REG_P;
   5047   1.1  christos 	  bits <<= regno;
   5048   1.1  christos 	  count++;
   5049   1.1  christos 	  if (p1 == -1)
   5050   1.1  christos 	    p1 = regno;
   5051   1.1  christos 	  else if (p2 == -1)
   5052   1.1  christos 	    p2 = regno;
   5053   1.1  christos 	}
   5054   1.1  christos       else if (type != 'i'
   5055   1.1  christos 	  && pr.X_op == O_subtract
   5056   1.1  christos 	  && (pr1 = symbol_get_value_expression (pr.X_add_symbol))
   5057   1.1  christos 	  && pr1->X_op == O_register
   5058   1.1  christos 	  && pr1->X_add_number >= REG_P
   5059   1.1  christos 	  && pr1->X_add_number <= REG_P + 63
   5060   1.1  christos 	  && (pr2 = symbol_get_value_expression (pr.X_op_symbol))
   5061   1.1  christos 	  && pr2->X_op == O_register
   5062   1.1  christos 	  && pr2->X_add_number >= REG_P
   5063   1.1  christos 	  && pr2->X_add_number <= REG_P + 63)
   5064   1.1  christos 	{
   5065   1.1  christos 	  /* It's a range.  */
   5066   1.1  christos 	  int stop;
   5067   1.1  christos 
   5068   1.1  christos 	  regno = pr1->X_add_number - REG_P;
   5069   1.1  christos 	  stop = pr2->X_add_number - REG_P;
   5070   1.1  christos 	  if (regno >= stop)
   5071   1.1  christos 	    {
   5072   1.1  christos 	      as_bad (_("Bad register range"));
   5073   1.1  christos 	      ignore_rest_of_line ();
   5074   1.1  christos 	      return;
   5075   1.1  christos 	    }
   5076   1.1  christos 	  bits = ((bits << stop) << 1) - (bits << regno);
   5077   1.1  christos 	  count += stop - regno + 1;
   5078   1.1  christos 	}
   5079   1.1  christos       else
   5080   1.1  christos 	{
   5081   1.1  christos 	  as_bad (_("Predicate register expected"));
   5082   1.1  christos 	  ignore_rest_of_line ();
   5083   1.1  christos 	  return;
   5084   1.1  christos 	}
   5085   1.1  christos       if (mask & bits)
   5086   1.1  christos 	as_warn (_("Duplicate predicate register ignored"));
   5087   1.1  christos       mask |= bits;
   5088   1.1  christos       if (sep != ',')
   5089   1.1  christos 	break;
   5090   1.1  christos     }
   5091   1.1  christos 
   5092   1.1  christos   switch (type)
   5093   1.1  christos     {
   5094   1.1  christos     case 'c':
   5095   1.1  christos       if (count == 0)
   5096   1.1  christos 	mask = ~(valueT) 0;
   5097   1.1  christos       clear_qp_mutex (mask);
   5098  1.10  christos       clear_qp_implies (mask, 0);
   5099   1.1  christos       break;
   5100   1.1  christos     case 'i':
   5101   1.1  christos       if (count != 2 || p1 == -1 || p2 == -1)
   5102   1.1  christos 	as_bad (_("Predicate source and target required"));
   5103   1.1  christos       else if (p1 == 0 || p2 == 0)
   5104   1.1  christos 	as_bad (_("Use of p0 is not valid in this context"));
   5105   1.1  christos       else
   5106   1.1  christos 	add_qp_imply (p1, p2);
   5107   1.1  christos       break;
   5108   1.1  christos     case 'm':
   5109   1.1  christos       if (count < 2)
   5110   1.1  christos 	{
   5111   1.1  christos 	  as_bad (_("At least two PR arguments expected"));
   5112   1.1  christos 	  break;
   5113   1.1  christos 	}
   5114   1.1  christos       else if (mask & 1)
   5115   1.1  christos 	{
   5116   1.1  christos 	  as_bad (_("Use of p0 is not valid in this context"));
   5117   1.1  christos 	  break;
   5118   1.1  christos 	}
   5119   1.1  christos       add_qp_mutex (mask);
   5120   1.1  christos       break;
   5121   1.1  christos     case 's':
   5122   1.1  christos       /* note that we don't override any existing relations */
   5123   1.1  christos       if (count == 0)
   5124   1.1  christos 	{
   5125   1.1  christos 	  as_bad (_("At least one PR argument expected"));
   5126   1.1  christos 	  break;
   5127   1.1  christos 	}
   5128   1.1  christos       if (md.debug_dv)
   5129   1.1  christos 	{
   5130   1.1  christos 	  fprintf (stderr, "Safe across calls: ");
   5131   1.1  christos 	  print_prmask (mask);
   5132   1.1  christos 	  fprintf (stderr, "\n");
   5133   1.1  christos 	}
   5134   1.1  christos       qp_safe_across_calls = mask;
   5135   1.1  christos       break;
   5136   1.1  christos     }
   5137   1.1  christos   demand_empty_rest_of_line ();
   5138   1.1  christos }
   5139   1.1  christos 
   5140   1.1  christos /* .entry label [, label [, ...]]
   5141   1.1  christos    Hint to DV code that the given labels are to be considered entry points.
   5142   1.1  christos    Otherwise, only global labels are considered entry points.  */
   5143   1.1  christos 
   5144   1.1  christos static void
   5145   1.1  christos dot_entry (int dummy ATTRIBUTE_UNUSED)
   5146   1.1  christos {
   5147   1.1  christos   char *name;
   5148   1.1  christos   int c;
   5149   1.1  christos   symbolS *symbolP;
   5150   1.1  christos 
   5151   1.1  christos   do
   5152   1.1  christos     {
   5153   1.3  christos       c = get_symbol_name (&name);
   5154   1.1  christos       symbolP = symbol_find_or_make (name);
   5155   1.1  christos 
   5156   1.8  christos       if (str_hash_insert (md.entry_hash, S_GET_NAME (symbolP), symbolP, 0))
   5157   1.8  christos 	as_bad (_("duplicate entry hint %s"), name);
   5158   1.1  christos 
   5159  1.10  christos       restore_line_pointer (c);
   5160  1.10  christos       SKIP_WHITESPACE ();
   5161   1.1  christos       c = *input_line_pointer;
   5162   1.1  christos       if (c == ',')
   5163   1.1  christos 	{
   5164   1.1  christos 	  input_line_pointer++;
   5165   1.1  christos 	  SKIP_WHITESPACE ();
   5166   1.1  christos 	  if (*input_line_pointer == '\n')
   5167   1.1  christos 	    c = '\n';
   5168   1.1  christos 	}
   5169   1.1  christos     }
   5170   1.1  christos   while (c == ',');
   5171   1.1  christos 
   5172   1.1  christos   demand_empty_rest_of_line ();
   5173   1.1  christos }
   5174   1.1  christos 
   5175   1.1  christos /* .mem.offset offset, base
   5176   1.1  christos    "base" is used to distinguish between offsets from a different base.  */
   5177   1.1  christos 
   5178   1.1  christos static void
   5179   1.1  christos dot_mem_offset (int dummy ATTRIBUTE_UNUSED)
   5180   1.1  christos {
   5181   1.1  christos   md.mem_offset.hint = 1;
   5182   1.1  christos   md.mem_offset.offset = get_absolute_expression ();
   5183   1.1  christos   if (*input_line_pointer != ',')
   5184   1.1  christos     {
   5185   1.1  christos       as_bad (_("Comma expected"));
   5186   1.1  christos       ignore_rest_of_line ();
   5187   1.1  christos       return;
   5188   1.1  christos     }
   5189   1.1  christos   ++input_line_pointer;
   5190   1.1  christos   md.mem_offset.base = get_absolute_expression ();
   5191   1.1  christos   demand_empty_rest_of_line ();
   5192   1.1  christos }
   5193   1.1  christos 
   5194   1.1  christos /* ia64-specific pseudo-ops:  */
   5195   1.1  christos const pseudo_typeS md_pseudo_table[] =
   5196   1.1  christos   {
   5197   1.1  christos     { "radix", dot_radix, 0 },
   5198   1.1  christos     { "lcomm", s_lcomm_bytes, 1 },
   5199   1.1  christos     { "loc", dot_loc, 0 },
   5200   1.1  christos     { "sbss", dot_special_section, SPECIAL_SECTION_SBSS },
   5201   1.1  christos     { "sdata", dot_special_section, SPECIAL_SECTION_SDATA },
   5202   1.1  christos     { "rodata", dot_special_section, SPECIAL_SECTION_RODATA },
   5203   1.1  christos     { "comment", dot_special_section, SPECIAL_SECTION_COMMENT },
   5204   1.1  christos     { "ia_64.unwind", dot_special_section, SPECIAL_SECTION_UNWIND },
   5205   1.1  christos     { "ia_64.unwind_info", dot_special_section, SPECIAL_SECTION_UNWIND_INFO },
   5206   1.1  christos     { "init_array", dot_special_section, SPECIAL_SECTION_INIT_ARRAY },
   5207   1.1  christos     { "fini_array", dot_special_section, SPECIAL_SECTION_FINI_ARRAY },
   5208   1.1  christos     { "proc", dot_proc, 0 },
   5209   1.1  christos     { "body", dot_body, 0 },
   5210   1.1  christos     { "prologue", dot_prologue, 0 },
   5211   1.1  christos     { "endp", dot_endp, 0 },
   5212   1.1  christos 
   5213   1.1  christos     { "fframe", dot_fframe, 0 },
   5214   1.1  christos     { "vframe", dot_vframe, 0 },
   5215   1.1  christos     { "vframesp", dot_vframesp, 0 },
   5216   1.1  christos     { "vframepsp", dot_vframesp, 1 },
   5217   1.1  christos     { "save", dot_save, 0 },
   5218   1.1  christos     { "restore", dot_restore, 0 },
   5219   1.1  christos     { "restorereg", dot_restorereg, 0 },
   5220   1.1  christos     { "restorereg.p", dot_restorereg, 1 },
   5221   1.1  christos     { "handlerdata", dot_handlerdata, 0 },
   5222   1.1  christos     { "unwentry", dot_unwentry, 0 },
   5223   1.1  christos     { "altrp", dot_altrp, 0 },
   5224   1.1  christos     { "savesp", dot_savemem, 0 },
   5225   1.1  christos     { "savepsp", dot_savemem, 1 },
   5226   1.1  christos     { "save.g", dot_saveg, 0 },
   5227   1.1  christos     { "save.f", dot_savef, 0 },
   5228   1.1  christos     { "save.b", dot_saveb, 0 },
   5229   1.1  christos     { "save.gf", dot_savegf, 0 },
   5230   1.1  christos     { "spill", dot_spill, 0 },
   5231   1.1  christos     { "spillreg", dot_spillreg, 0 },
   5232   1.1  christos     { "spillsp", dot_spillmem, 0 },
   5233   1.1  christos     { "spillpsp", dot_spillmem, 1 },
   5234   1.1  christos     { "spillreg.p", dot_spillreg, 1 },
   5235   1.1  christos     { "spillsp.p", dot_spillmem, ~0 },
   5236   1.1  christos     { "spillpsp.p", dot_spillmem, ~1 },
   5237   1.1  christos     { "label_state", dot_label_state, 0 },
   5238   1.1  christos     { "copy_state", dot_copy_state, 0 },
   5239   1.1  christos     { "unwabi", dot_unwabi, 0 },
   5240   1.1  christos     { "personality", dot_personality, 0 },
   5241   1.1  christos     { "mii", dot_template, 0x0 },
   5242   1.1  christos     { "mli", dot_template, 0x2 }, /* old format, for compatibility */
   5243   1.1  christos     { "mlx", dot_template, 0x2 },
   5244   1.1  christos     { "mmi", dot_template, 0x4 },
   5245   1.1  christos     { "mfi", dot_template, 0x6 },
   5246   1.1  christos     { "mmf", dot_template, 0x7 },
   5247   1.1  christos     { "mib", dot_template, 0x8 },
   5248   1.1  christos     { "mbb", dot_template, 0x9 },
   5249   1.1  christos     { "bbb", dot_template, 0xb },
   5250   1.1  christos     { "mmb", dot_template, 0xc },
   5251   1.1  christos     { "mfb", dot_template, 0xe },
   5252   1.1  christos     { "align", dot_align, 0 },
   5253   1.1  christos     { "regstk", dot_regstk, 0 },
   5254   1.1  christos     { "rotr", dot_rot, DYNREG_GR },
   5255   1.1  christos     { "rotf", dot_rot, DYNREG_FR },
   5256   1.1  christos     { "rotp", dot_rot, DYNREG_PR },
   5257   1.1  christos     { "lsb", dot_byteorder, 0 },
   5258   1.1  christos     { "msb", dot_byteorder, 1 },
   5259   1.1  christos     { "psr", dot_psr, 0 },
   5260   1.1  christos     { "alias", dot_alias, 0 },
   5261   1.1  christos     { "secalias", dot_alias, 1 },
   5262   1.1  christos     { "ln", dot_ln, 0 },		/* source line info (for debugging) */
   5263   1.1  christos 
   5264   1.1  christos     { "xdata1", dot_xdata, 1 },
   5265   1.1  christos     { "xdata2", dot_xdata, 2 },
   5266   1.1  christos     { "xdata4", dot_xdata, 4 },
   5267   1.1  christos     { "xdata8", dot_xdata, 8 },
   5268   1.1  christos     { "xdata16", dot_xdata, 16 },
   5269   1.1  christos     { "xreal4", dot_xfloat_cons, 'f' },
   5270   1.1  christos     { "xreal8", dot_xfloat_cons, 'd' },
   5271   1.1  christos     { "xreal10", dot_xfloat_cons, 'x' },
   5272   1.1  christos     { "xreal16", dot_xfloat_cons, 'X' },
   5273   1.1  christos     { "xstring", dot_xstringer, 8 + 0 },
   5274   1.1  christos     { "xstringz", dot_xstringer, 8 + 1 },
   5275   1.1  christos 
   5276   1.1  christos     /* unaligned versions:  */
   5277   1.1  christos     { "xdata2.ua", dot_xdata_ua, 2 },
   5278   1.1  christos     { "xdata4.ua", dot_xdata_ua, 4 },
   5279   1.1  christos     { "xdata8.ua", dot_xdata_ua, 8 },
   5280   1.1  christos     { "xdata16.ua", dot_xdata_ua, 16 },
   5281   1.1  christos     { "xreal4.ua", dot_xfloat_cons_ua, 'f' },
   5282   1.1  christos     { "xreal8.ua", dot_xfloat_cons_ua, 'd' },
   5283   1.1  christos     { "xreal10.ua", dot_xfloat_cons_ua, 'x' },
   5284   1.1  christos     { "xreal16.ua", dot_xfloat_cons_ua, 'X' },
   5285   1.1  christos 
   5286   1.1  christos     /* annotations/DV checking support */
   5287   1.1  christos     { "entry", dot_entry, 0 },
   5288   1.1  christos     { "mem.offset", dot_mem_offset, 0 },
   5289   1.1  christos     { "pred.rel", dot_pred_rel, 0 },
   5290   1.1  christos     { "pred.rel.clear", dot_pred_rel, 'c' },
   5291   1.1  christos     { "pred.rel.imply", dot_pred_rel, 'i' },
   5292   1.1  christos     { "pred.rel.mutex", dot_pred_rel, 'm' },
   5293   1.1  christos     { "pred.safe_across_calls", dot_pred_rel, 's' },
   5294   1.1  christos     { "reg.val", dot_reg_val, 0 },
   5295   1.1  christos     { "serialize.data", dot_serialize, 0 },
   5296   1.1  christos     { "serialize.instruction", dot_serialize, 1 },
   5297   1.1  christos     { "auto", dot_dv_mode, 'a' },
   5298   1.1  christos     { "explicit", dot_dv_mode, 'e' },
   5299   1.1  christos     { "default", dot_dv_mode, 'd' },
   5300   1.1  christos 
   5301   1.1  christos     /* ??? These are needed to make gas/testsuite/gas/elf/ehopt.s work.
   5302   1.1  christos        IA-64 aligns data allocation pseudo-ops by default, so we have to
   5303   1.1  christos        tell it that these ones are supposed to be unaligned.  Long term,
   5304   1.1  christos        should rewrite so that only IA-64 specific data allocation pseudo-ops
   5305   1.1  christos        are aligned by default.  */
   5306   1.1  christos     {"2byte", stmt_cons_ua, 2},
   5307   1.1  christos     {"4byte", stmt_cons_ua, 4},
   5308   1.1  christos     {"8byte", stmt_cons_ua, 8},
   5309   1.1  christos 
   5310   1.1  christos #ifdef TE_VMS
   5311   1.1  christos     {"vms_common", obj_elf_vms_common, 0},
   5312   1.1  christos #endif
   5313   1.1  christos 
   5314   1.1  christos     { NULL, 0, 0 }
   5315   1.1  christos   };
   5316   1.1  christos 
   5317   1.1  christos static const struct pseudo_opcode
   5318   1.1  christos   {
   5319   1.1  christos     const char *name;
   5320   1.1  christos     void (*handler) (int);
   5321   1.1  christos     int arg;
   5322   1.1  christos   }
   5323   1.1  christos pseudo_opcode[] =
   5324   1.1  christos   {
   5325   1.1  christos     /* these are more like pseudo-ops, but don't start with a dot */
   5326   1.1  christos     { "data1", cons, 1 },
   5327   1.1  christos     { "data2", cons, 2 },
   5328   1.1  christos     { "data4", cons, 4 },
   5329   1.1  christos     { "data8", cons, 8 },
   5330   1.1  christos     { "data16", cons, 16 },
   5331   1.1  christos     { "real4", stmt_float_cons, 'f' },
   5332   1.1  christos     { "real8", stmt_float_cons, 'd' },
   5333   1.1  christos     { "real10", stmt_float_cons, 'x' },
   5334   1.1  christos     { "real16", stmt_float_cons, 'X' },
   5335   1.1  christos     { "string", stringer, 8 + 0 },
   5336   1.1  christos     { "stringz", stringer, 8 + 1 },
   5337   1.1  christos 
   5338   1.1  christos     /* unaligned versions:  */
   5339   1.1  christos     { "data2.ua", stmt_cons_ua, 2 },
   5340   1.1  christos     { "data4.ua", stmt_cons_ua, 4 },
   5341   1.1  christos     { "data8.ua", stmt_cons_ua, 8 },
   5342   1.1  christos     { "data16.ua", stmt_cons_ua, 16 },
   5343   1.1  christos     { "real4.ua", float_cons, 'f' },
   5344   1.1  christos     { "real8.ua", float_cons, 'd' },
   5345   1.1  christos     { "real10.ua", float_cons, 'x' },
   5346   1.1  christos     { "real16.ua", float_cons, 'X' },
   5347   1.1  christos   };
   5348   1.1  christos 
   5349   1.1  christos /* Declare a register by creating a symbol for it and entering it in
   5350   1.1  christos    the symbol table.  */
   5351   1.1  christos 
   5352   1.1  christos static symbolS *
   5353   1.1  christos declare_register (const char *name, unsigned int regnum)
   5354   1.1  christos {
   5355   1.1  christos   symbolS *sym;
   5356   1.1  christos 
   5357   1.8  christos   sym = symbol_create (name, reg_section, &zero_address_frag, regnum);
   5358   1.1  christos 
   5359   1.8  christos   if (str_hash_insert (md.reg_hash, S_GET_NAME (sym), sym, 0) != NULL)
   5360   1.8  christos     as_fatal (_("duplicate %s"), name);
   5361   1.1  christos 
   5362   1.1  christos   return sym;
   5363   1.1  christos }
   5364   1.1  christos 
   5365   1.1  christos static void
   5366   1.1  christos declare_register_set (const char *prefix,
   5367   1.1  christos 		      unsigned int num_regs,
   5368   1.1  christos 		      unsigned int base_regnum)
   5369   1.1  christos {
   5370   1.1  christos   char name[8];
   5371   1.1  christos   unsigned int i;
   5372   1.1  christos 
   5373   1.1  christos   for (i = 0; i < num_regs; ++i)
   5374   1.1  christos     {
   5375   1.1  christos       snprintf (name, sizeof (name), "%s%u", prefix, i);
   5376   1.1  christos       declare_register (name, base_regnum + i);
   5377   1.1  christos     }
   5378   1.1  christos }
   5379   1.1  christos 
   5380   1.1  christos static unsigned int
   5381   1.1  christos operand_width (enum ia64_opnd opnd)
   5382   1.1  christos {
   5383   1.1  christos   const struct ia64_operand *odesc = &elf64_ia64_operands[opnd];
   5384   1.1  christos   unsigned int bits = 0;
   5385   1.1  christos   int i;
   5386   1.1  christos 
   5387   1.1  christos   bits = 0;
   5388   1.1  christos   for (i = 0; i < NELEMS (odesc->field) && odesc->field[i].bits; ++i)
   5389   1.1  christos     bits += odesc->field[i].bits;
   5390   1.1  christos 
   5391   1.1  christos   return bits;
   5392   1.1  christos }
   5393   1.1  christos 
   5394   1.1  christos static enum operand_match_result
   5395   1.1  christos operand_match (const struct ia64_opcode *idesc, int res_index, expressionS *e)
   5396   1.1  christos {
   5397   1.1  christos   enum ia64_opnd opnd = idesc->operands[res_index];
   5398   1.1  christos   int bits, relocatable = 0;
   5399   1.1  christos   struct insn_fix *fix;
   5400   1.1  christos   bfd_signed_vma val;
   5401   1.1  christos 
   5402   1.1  christos   switch (opnd)
   5403   1.1  christos     {
   5404   1.1  christos       /* constants:  */
   5405   1.1  christos 
   5406   1.1  christos     case IA64_OPND_AR_CCV:
   5407   1.1  christos       if (e->X_op == O_register && e->X_add_number == REG_AR + 32)
   5408   1.1  christos 	return OPERAND_MATCH;
   5409   1.1  christos       break;
   5410   1.1  christos 
   5411   1.1  christos     case IA64_OPND_AR_CSD:
   5412   1.1  christos       if (e->X_op == O_register && e->X_add_number == REG_AR + 25)
   5413   1.1  christos 	return OPERAND_MATCH;
   5414   1.1  christos       break;
   5415   1.1  christos 
   5416   1.1  christos     case IA64_OPND_AR_PFS:
   5417   1.1  christos       if (e->X_op == O_register && e->X_add_number == REG_AR + 64)
   5418   1.1  christos 	return OPERAND_MATCH;
   5419   1.1  christos       break;
   5420   1.1  christos 
   5421   1.1  christos     case IA64_OPND_GR0:
   5422   1.1  christos       if (e->X_op == O_register && e->X_add_number == REG_GR + 0)
   5423   1.1  christos 	return OPERAND_MATCH;
   5424   1.1  christos       break;
   5425   1.1  christos 
   5426   1.1  christos     case IA64_OPND_IP:
   5427   1.1  christos       if (e->X_op == O_register && e->X_add_number == REG_IP)
   5428   1.1  christos 	return OPERAND_MATCH;
   5429   1.1  christos       break;
   5430   1.1  christos 
   5431   1.1  christos     case IA64_OPND_PR:
   5432   1.1  christos       if (e->X_op == O_register && e->X_add_number == REG_PR)
   5433   1.1  christos 	return OPERAND_MATCH;
   5434   1.1  christos       break;
   5435   1.1  christos 
   5436   1.1  christos     case IA64_OPND_PR_ROT:
   5437   1.1  christos       if (e->X_op == O_register && e->X_add_number == REG_PR_ROT)
   5438   1.1  christos 	return OPERAND_MATCH;
   5439   1.1  christos       break;
   5440   1.1  christos 
   5441   1.1  christos     case IA64_OPND_PSR:
   5442   1.1  christos       if (e->X_op == O_register && e->X_add_number == REG_PSR)
   5443   1.1  christos 	return OPERAND_MATCH;
   5444   1.1  christos       break;
   5445   1.1  christos 
   5446   1.1  christos     case IA64_OPND_PSR_L:
   5447   1.1  christos       if (e->X_op == O_register && e->X_add_number == REG_PSR_L)
   5448   1.1  christos 	return OPERAND_MATCH;
   5449   1.1  christos       break;
   5450   1.1  christos 
   5451   1.1  christos     case IA64_OPND_PSR_UM:
   5452   1.1  christos       if (e->X_op == O_register && e->X_add_number == REG_PSR_UM)
   5453   1.1  christos 	return OPERAND_MATCH;
   5454   1.1  christos       break;
   5455   1.1  christos 
   5456   1.1  christos     case IA64_OPND_C1:
   5457   1.1  christos       if (e->X_op == O_constant)
   5458   1.1  christos 	{
   5459   1.1  christos 	  if (e->X_add_number == 1)
   5460   1.1  christos 	    return OPERAND_MATCH;
   5461   1.1  christos 	  else
   5462   1.1  christos 	    return OPERAND_OUT_OF_RANGE;
   5463   1.1  christos 	}
   5464   1.1  christos       break;
   5465   1.1  christos 
   5466   1.1  christos     case IA64_OPND_C8:
   5467   1.1  christos       if (e->X_op == O_constant)
   5468   1.1  christos 	{
   5469   1.1  christos 	  if (e->X_add_number == 8)
   5470   1.1  christos 	    return OPERAND_MATCH;
   5471   1.1  christos 	  else
   5472   1.1  christos 	    return OPERAND_OUT_OF_RANGE;
   5473   1.1  christos 	}
   5474   1.1  christos       break;
   5475   1.1  christos 
   5476   1.1  christos     case IA64_OPND_C16:
   5477   1.1  christos       if (e->X_op == O_constant)
   5478   1.1  christos 	{
   5479   1.1  christos 	  if (e->X_add_number == 16)
   5480   1.1  christos 	    return OPERAND_MATCH;
   5481   1.1  christos 	  else
   5482   1.1  christos 	    return OPERAND_OUT_OF_RANGE;
   5483   1.1  christos 	}
   5484   1.1  christos       break;
   5485   1.1  christos 
   5486   1.1  christos       /* register operands:  */
   5487   1.1  christos 
   5488   1.1  christos     case IA64_OPND_AR3:
   5489   1.1  christos       if (e->X_op == O_register && e->X_add_number >= REG_AR
   5490   1.1  christos 	  && e->X_add_number < REG_AR + 128)
   5491   1.1  christos 	return OPERAND_MATCH;
   5492   1.1  christos       break;
   5493   1.1  christos 
   5494   1.1  christos     case IA64_OPND_B1:
   5495   1.1  christos     case IA64_OPND_B2:
   5496   1.1  christos       if (e->X_op == O_register && e->X_add_number >= REG_BR
   5497   1.1  christos 	  && e->X_add_number < REG_BR + 8)
   5498   1.1  christos 	return OPERAND_MATCH;
   5499   1.1  christos       break;
   5500   1.1  christos 
   5501   1.1  christos     case IA64_OPND_CR3:
   5502   1.1  christos       if (e->X_op == O_register && e->X_add_number >= REG_CR
   5503   1.1  christos 	  && e->X_add_number < REG_CR + 128)
   5504   1.1  christos 	return OPERAND_MATCH;
   5505   1.1  christos       break;
   5506   1.1  christos 
   5507   1.1  christos     case IA64_OPND_DAHR3:
   5508   1.1  christos       if (e->X_op == O_register && e->X_add_number >= REG_DAHR
   5509   1.1  christos 	  && e->X_add_number < REG_DAHR + 8)
   5510   1.1  christos 	return OPERAND_MATCH;
   5511   1.1  christos       break;
   5512   1.1  christos 
   5513   1.1  christos     case IA64_OPND_F1:
   5514   1.1  christos     case IA64_OPND_F2:
   5515   1.1  christos     case IA64_OPND_F3:
   5516   1.1  christos     case IA64_OPND_F4:
   5517   1.1  christos       if (e->X_op == O_register && e->X_add_number >= REG_FR
   5518   1.1  christos 	  && e->X_add_number < REG_FR + 128)
   5519   1.1  christos 	return OPERAND_MATCH;
   5520   1.1  christos       break;
   5521   1.1  christos 
   5522   1.1  christos     case IA64_OPND_P1:
   5523   1.1  christos     case IA64_OPND_P2:
   5524   1.1  christos       if (e->X_op == O_register && e->X_add_number >= REG_P
   5525   1.1  christos 	  && e->X_add_number < REG_P + 64)
   5526   1.1  christos 	return OPERAND_MATCH;
   5527   1.1  christos       break;
   5528   1.1  christos 
   5529   1.1  christos     case IA64_OPND_R1:
   5530   1.1  christos     case IA64_OPND_R2:
   5531   1.1  christos     case IA64_OPND_R3:
   5532   1.1  christos       if (e->X_op == O_register && e->X_add_number >= REG_GR
   5533   1.1  christos 	  && e->X_add_number < REG_GR + 128)
   5534   1.1  christos 	return OPERAND_MATCH;
   5535   1.1  christos       break;
   5536   1.1  christos 
   5537   1.1  christos     case IA64_OPND_R3_2:
   5538   1.1  christos       if (e->X_op == O_register && e->X_add_number >= REG_GR)
   5539   1.1  christos 	{
   5540   1.1  christos 	  if (e->X_add_number < REG_GR + 4)
   5541   1.1  christos 	    return OPERAND_MATCH;
   5542   1.1  christos 	  else if (e->X_add_number < REG_GR + 128)
   5543   1.1  christos 	    return OPERAND_OUT_OF_RANGE;
   5544   1.1  christos 	}
   5545   1.1  christos       break;
   5546   1.1  christos 
   5547   1.1  christos       /* indirect operands:  */
   5548   1.1  christos     case IA64_OPND_CPUID_R3:
   5549   1.1  christos     case IA64_OPND_DBR_R3:
   5550   1.1  christos     case IA64_OPND_DTR_R3:
   5551   1.1  christos     case IA64_OPND_ITR_R3:
   5552   1.1  christos     case IA64_OPND_IBR_R3:
   5553   1.1  christos     case IA64_OPND_MSR_R3:
   5554   1.1  christos     case IA64_OPND_PKR_R3:
   5555   1.1  christos     case IA64_OPND_PMC_R3:
   5556   1.1  christos     case IA64_OPND_PMD_R3:
   5557   1.1  christos     case IA64_OPND_DAHR_R3:
   5558   1.1  christos     case IA64_OPND_RR_R3:
   5559   1.1  christos       if (e->X_op == O_index && e->X_op_symbol
   5560   1.1  christos 	  && (S_GET_VALUE (e->X_op_symbol) - IND_CPUID
   5561   1.1  christos 	      == opnd - IA64_OPND_CPUID_R3))
   5562   1.1  christos 	return OPERAND_MATCH;
   5563   1.1  christos       break;
   5564   1.1  christos 
   5565   1.1  christos     case IA64_OPND_MR3:
   5566   1.1  christos       if (e->X_op == O_index && !e->X_op_symbol)
   5567   1.1  christos 	return OPERAND_MATCH;
   5568   1.1  christos       break;
   5569   1.1  christos 
   5570   1.1  christos       /* immediate operands:  */
   5571   1.1  christos     case IA64_OPND_CNT2a:
   5572   1.1  christos     case IA64_OPND_LEN4:
   5573   1.1  christos     case IA64_OPND_LEN6:
   5574   1.1  christos       bits = operand_width (idesc->operands[res_index]);
   5575   1.1  christos       if (e->X_op == O_constant)
   5576   1.1  christos 	{
   5577   1.1  christos 	  if ((bfd_vma) (e->X_add_number - 1) < ((bfd_vma) 1 << bits))
   5578   1.1  christos 	    return OPERAND_MATCH;
   5579   1.1  christos 	  else
   5580   1.1  christos 	    return OPERAND_OUT_OF_RANGE;
   5581   1.1  christos 	}
   5582   1.1  christos       break;
   5583   1.1  christos 
   5584   1.1  christos     case IA64_OPND_CNT2b:
   5585   1.1  christos       if (e->X_op == O_constant)
   5586   1.1  christos 	{
   5587   1.1  christos 	  if ((bfd_vma) (e->X_add_number - 1) < 3)
   5588   1.1  christos 	    return OPERAND_MATCH;
   5589   1.1  christos 	  else
   5590   1.1  christos 	    return OPERAND_OUT_OF_RANGE;
   5591   1.1  christos 	}
   5592   1.1  christos       break;
   5593   1.1  christos 
   5594   1.1  christos     case IA64_OPND_CNT2c:
   5595   1.1  christos       val = e->X_add_number;
   5596   1.1  christos       if (e->X_op == O_constant)
   5597   1.1  christos 	{
   5598   1.1  christos 	  if ((val == 0 || val == 7 || val == 15 || val == 16))
   5599   1.1  christos 	    return OPERAND_MATCH;
   5600   1.1  christos 	  else
   5601   1.1  christos 	    return OPERAND_OUT_OF_RANGE;
   5602   1.1  christos 	}
   5603   1.1  christos       break;
   5604   1.1  christos 
   5605   1.1  christos     case IA64_OPND_SOR:
   5606   1.1  christos       /* SOR must be an integer multiple of 8 */
   5607   1.1  christos       if (e->X_op == O_constant && e->X_add_number & 0x7)
   5608   1.1  christos 	return OPERAND_OUT_OF_RANGE;
   5609   1.6  christos       /* Fall through.  */
   5610   1.1  christos     case IA64_OPND_SOF:
   5611   1.1  christos     case IA64_OPND_SOL:
   5612   1.1  christos       if (e->X_op == O_constant)
   5613   1.1  christos 	{
   5614   1.1  christos 	  if ((bfd_vma) e->X_add_number <= 96)
   5615   1.1  christos 	    return OPERAND_MATCH;
   5616   1.1  christos 	  else
   5617   1.1  christos 	    return OPERAND_OUT_OF_RANGE;
   5618   1.1  christos 	}
   5619   1.1  christos       break;
   5620   1.1  christos 
   5621   1.1  christos     case IA64_OPND_IMMU62:
   5622   1.1  christos       if (e->X_op == O_constant)
   5623   1.1  christos 	{
   5624   1.1  christos 	  if ((bfd_vma) e->X_add_number < ((bfd_vma) 1 << 62))
   5625   1.1  christos 	    return OPERAND_MATCH;
   5626   1.1  christos 	  else
   5627   1.1  christos 	    return OPERAND_OUT_OF_RANGE;
   5628   1.1  christos 	}
   5629   1.1  christos       else
   5630   1.1  christos 	{
   5631   1.1  christos 	  /* FIXME -- need 62-bit relocation type */
   5632   1.1  christos 	  as_bad (_("62-bit relocation not yet implemented"));
   5633   1.1  christos 	}
   5634   1.1  christos       break;
   5635   1.1  christos 
   5636   1.1  christos     case IA64_OPND_IMMU64:
   5637   1.1  christos       if (e->X_op == O_symbol || e->X_op == O_pseudo_fixup
   5638   1.1  christos 	  || e->X_op == O_subtract)
   5639   1.1  christos 	{
   5640   1.1  christos 	  fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups;
   5641   1.1  christos 	  fix->code = BFD_RELOC_IA64_IMM64;
   5642   1.1  christos 	  if (e->X_op != O_subtract)
   5643   1.1  christos 	    {
   5644   1.1  christos 	      fix->code = ia64_gen_real_reloc_type (e->X_op_symbol, fix->code);
   5645   1.1  christos 	      if (e->X_op == O_pseudo_fixup)
   5646   1.1  christos 		e->X_op = O_symbol;
   5647   1.1  christos 	    }
   5648   1.1  christos 
   5649   1.1  christos 	  fix->opnd = idesc->operands[res_index];
   5650   1.1  christos 	  fix->expr = *e;
   5651   1.1  christos 	  fix->is_pcrel = 0;
   5652   1.1  christos 	  ++CURR_SLOT.num_fixups;
   5653   1.1  christos 	  return OPERAND_MATCH;
   5654   1.1  christos 	}
   5655   1.1  christos       else if (e->X_op == O_constant)
   5656   1.1  christos 	return OPERAND_MATCH;
   5657   1.1  christos       break;
   5658   1.1  christos 
   5659   1.1  christos     case IA64_OPND_IMMU5b:
   5660   1.1  christos       if (e->X_op == O_constant)
   5661   1.1  christos 	{
   5662   1.1  christos 	  val = e->X_add_number;
   5663   1.1  christos 	  if (val >= 32 && val <= 63)
   5664   1.1  christos 	    return OPERAND_MATCH;
   5665   1.1  christos 	  else
   5666   1.1  christos 	    return OPERAND_OUT_OF_RANGE;
   5667   1.1  christos 	}
   5668   1.1  christos       break;
   5669   1.1  christos 
   5670   1.1  christos     case IA64_OPND_CCNT5:
   5671   1.1  christos     case IA64_OPND_CNT5:
   5672   1.1  christos     case IA64_OPND_CNT6:
   5673   1.1  christos     case IA64_OPND_CPOS6a:
   5674   1.1  christos     case IA64_OPND_CPOS6b:
   5675   1.1  christos     case IA64_OPND_CPOS6c:
   5676   1.1  christos     case IA64_OPND_IMMU2:
   5677   1.1  christos     case IA64_OPND_IMMU7a:
   5678   1.1  christos     case IA64_OPND_IMMU7b:
   5679   1.1  christos     case IA64_OPND_IMMU16:
   5680   1.1  christos     case IA64_OPND_IMMU19:
   5681   1.1  christos     case IA64_OPND_IMMU21:
   5682   1.1  christos     case IA64_OPND_IMMU24:
   5683   1.1  christos     case IA64_OPND_MBTYPE4:
   5684   1.1  christos     case IA64_OPND_MHTYPE8:
   5685   1.1  christos     case IA64_OPND_POS6:
   5686   1.1  christos       bits = operand_width (idesc->operands[res_index]);
   5687   1.1  christos       if (e->X_op == O_constant)
   5688   1.1  christos 	{
   5689   1.1  christos 	  if ((bfd_vma) e->X_add_number < ((bfd_vma) 1 << bits))
   5690   1.1  christos 	    return OPERAND_MATCH;
   5691   1.1  christos 	  else
   5692   1.1  christos 	    return OPERAND_OUT_OF_RANGE;
   5693   1.1  christos 	}
   5694   1.1  christos       break;
   5695   1.1  christos 
   5696   1.1  christos     case IA64_OPND_IMMU9:
   5697   1.1  christos       bits = operand_width (idesc->operands[res_index]);
   5698   1.1  christos       if (e->X_op == O_constant)
   5699   1.1  christos 	{
   5700   1.1  christos 	  if ((bfd_vma) e->X_add_number < ((bfd_vma) 1 << bits))
   5701   1.1  christos 	    {
   5702   1.1  christos 	      int lobits = e->X_add_number & 0x3;
   5703   1.1  christos 	      if (((bfd_vma) e->X_add_number & 0x3C) != 0 && lobits == 0)
   5704   1.1  christos 		e->X_add_number |= (bfd_vma) 0x3;
   5705   1.1  christos 	      return OPERAND_MATCH;
   5706   1.1  christos 	    }
   5707   1.1  christos 	  else
   5708   1.1  christos 	    return OPERAND_OUT_OF_RANGE;
   5709   1.1  christos 	}
   5710   1.1  christos       break;
   5711   1.1  christos 
   5712   1.1  christos     case IA64_OPND_IMM44:
   5713   1.1  christos       /* least 16 bits must be zero */
   5714   1.1  christos       if ((e->X_add_number & 0xffff) != 0)
   5715   1.1  christos 	/* XXX technically, this is wrong: we should not be issuing warning
   5716   1.1  christos 	   messages until we're sure this instruction pattern is going to
   5717   1.1  christos 	   be used! */
   5718   1.1  christos 	as_warn (_("lower 16 bits of mask ignored"));
   5719   1.1  christos 
   5720   1.1  christos       if (e->X_op == O_constant)
   5721   1.1  christos 	{
   5722   1.1  christos 	  if (((e->X_add_number >= 0
   5723   1.1  christos 		&& (bfd_vma) e->X_add_number < ((bfd_vma) 1 << 44))
   5724   1.1  christos 	       || (e->X_add_number < 0
   5725   1.1  christos 		   && (bfd_vma) -e->X_add_number <= ((bfd_vma) 1 << 44))))
   5726   1.1  christos 	    {
   5727   1.1  christos 	      /* sign-extend */
   5728   1.1  christos 	      if (e->X_add_number >= 0
   5729   1.1  christos 		  && (e->X_add_number & ((bfd_vma) 1 << 43)) != 0)
   5730   1.1  christos 		{
   5731   1.1  christos 		  e->X_add_number |= ~(((bfd_vma) 1 << 44) - 1);
   5732   1.1  christos 		}
   5733   1.1  christos 	      return OPERAND_MATCH;
   5734   1.1  christos 	    }
   5735   1.1  christos 	  else
   5736   1.1  christos 	    return OPERAND_OUT_OF_RANGE;
   5737   1.1  christos 	}
   5738   1.1  christos       break;
   5739   1.1  christos 
   5740   1.1  christos     case IA64_OPND_IMM17:
   5741   1.1  christos       /* bit 0 is a don't care (pr0 is hardwired to 1) */
   5742   1.1  christos       if (e->X_op == O_constant)
   5743   1.1  christos 	{
   5744   1.1  christos 	  if (((e->X_add_number >= 0
   5745   1.1  christos 		&& (bfd_vma) e->X_add_number < ((bfd_vma) 1 << 17))
   5746   1.1  christos 	       || (e->X_add_number < 0
   5747   1.1  christos 		   && (bfd_vma) -e->X_add_number <= ((bfd_vma) 1 << 17))))
   5748   1.1  christos 	    {
   5749   1.1  christos 	      /* sign-extend */
   5750   1.1  christos 	      if (e->X_add_number >= 0
   5751   1.1  christos 		  && (e->X_add_number & ((bfd_vma) 1 << 16)) != 0)
   5752   1.1  christos 		{
   5753   1.1  christos 		  e->X_add_number |= ~(((bfd_vma) 1 << 17) - 1);
   5754   1.1  christos 		}
   5755   1.1  christos 	      return OPERAND_MATCH;
   5756   1.1  christos 	    }
   5757   1.1  christos 	  else
   5758   1.1  christos 	    return OPERAND_OUT_OF_RANGE;
   5759   1.1  christos 	}
   5760   1.1  christos       break;
   5761   1.1  christos 
   5762   1.1  christos     case IA64_OPND_IMM14:
   5763   1.1  christos     case IA64_OPND_IMM22:
   5764   1.1  christos       relocatable = 1;
   5765   1.6  christos       /* Fall through.  */
   5766   1.1  christos     case IA64_OPND_IMM1:
   5767   1.1  christos     case IA64_OPND_IMM8:
   5768   1.1  christos     case IA64_OPND_IMM8U4:
   5769   1.1  christos     case IA64_OPND_IMM8M1:
   5770   1.1  christos     case IA64_OPND_IMM8M1U4:
   5771   1.1  christos     case IA64_OPND_IMM8M1U8:
   5772   1.1  christos     case IA64_OPND_IMM9a:
   5773   1.1  christos     case IA64_OPND_IMM9b:
   5774   1.1  christos       bits = operand_width (idesc->operands[res_index]);
   5775   1.1  christos       if (relocatable && (e->X_op == O_symbol
   5776   1.1  christos 			  || e->X_op == O_subtract
   5777   1.1  christos 			  || e->X_op == O_pseudo_fixup))
   5778   1.1  christos 	{
   5779   1.1  christos 	  fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups;
   5780   1.1  christos 
   5781   1.1  christos 	  if (idesc->operands[res_index] == IA64_OPND_IMM14)
   5782   1.1  christos 	    fix->code = BFD_RELOC_IA64_IMM14;
   5783   1.1  christos 	  else
   5784   1.1  christos 	    fix->code = BFD_RELOC_IA64_IMM22;
   5785   1.1  christos 
   5786   1.1  christos 	  if (e->X_op != O_subtract)
   5787   1.1  christos 	    {
   5788   1.1  christos 	      fix->code = ia64_gen_real_reloc_type (e->X_op_symbol, fix->code);
   5789   1.1  christos 	      if (e->X_op == O_pseudo_fixup)
   5790   1.1  christos 		e->X_op = O_symbol;
   5791   1.1  christos 	    }
   5792   1.1  christos 
   5793   1.1  christos 	  fix->opnd = idesc->operands[res_index];
   5794   1.1  christos 	  fix->expr = *e;
   5795   1.1  christos 	  fix->is_pcrel = 0;
   5796   1.1  christos 	  ++CURR_SLOT.num_fixups;
   5797   1.1  christos 	  return OPERAND_MATCH;
   5798   1.1  christos 	}
   5799   1.1  christos       else if (e->X_op != O_constant
   5800   1.1  christos 	       && ! (e->X_op == O_big && opnd == IA64_OPND_IMM8M1U8))
   5801   1.1  christos 	return OPERAND_MISMATCH;
   5802   1.1  christos 
   5803   1.1  christos       if (opnd == IA64_OPND_IMM8M1U4)
   5804   1.1  christos 	{
   5805   1.1  christos 	  /* Zero is not valid for unsigned compares that take an adjusted
   5806   1.1  christos 	     constant immediate range.  */
   5807   1.1  christos 	  if (e->X_add_number == 0)
   5808   1.1  christos 	    return OPERAND_OUT_OF_RANGE;
   5809   1.1  christos 
   5810   1.1  christos 	  /* Sign-extend 32-bit unsigned numbers, so that the following range
   5811   1.1  christos 	     checks will work.  */
   5812   1.1  christos 	  val = e->X_add_number;
   5813   1.7  christos 	  if ((val & (~(bfd_vma) 0 << 32)) == 0)
   5814   1.7  christos 	    val = (val ^ ((bfd_vma) 1 << 31)) - ((bfd_vma) 1 << 31);
   5815   1.1  christos 
   5816   1.1  christos 	  /* Check for 0x100000000.  This is valid because
   5817   1.1  christos 	     0x100000000-1 is the same as ((uint32_t) -1).  */
   5818   1.1  christos 	  if (val == ((bfd_signed_vma) 1 << 32))
   5819   1.1  christos 	    return OPERAND_MATCH;
   5820   1.1  christos 
   5821   1.1  christos 	  val = val - 1;
   5822   1.1  christos 	}
   5823   1.1  christos       else if (opnd == IA64_OPND_IMM8M1U8)
   5824   1.1  christos 	{
   5825   1.1  christos 	  /* Zero is not valid for unsigned compares that take an adjusted
   5826   1.1  christos 	     constant immediate range.  */
   5827   1.1  christos 	  if (e->X_add_number == 0)
   5828   1.1  christos 	    return OPERAND_OUT_OF_RANGE;
   5829   1.1  christos 
   5830   1.1  christos 	  /* Check for 0x10000000000000000.  */
   5831   1.1  christos 	  if (e->X_op == O_big)
   5832   1.1  christos 	    {
   5833   1.1  christos 	      if (generic_bignum[0] == 0
   5834   1.1  christos 		  && generic_bignum[1] == 0
   5835   1.1  christos 		  && generic_bignum[2] == 0
   5836   1.1  christos 		  && generic_bignum[3] == 0
   5837   1.1  christos 		  && generic_bignum[4] == 1)
   5838   1.1  christos 		return OPERAND_MATCH;
   5839   1.1  christos 	      else
   5840   1.1  christos 		return OPERAND_OUT_OF_RANGE;
   5841   1.1  christos 	    }
   5842   1.1  christos 	  else
   5843   1.1  christos 	    val = e->X_add_number - 1;
   5844   1.1  christos 	}
   5845   1.1  christos       else if (opnd == IA64_OPND_IMM8M1)
   5846   1.1  christos 	val = e->X_add_number - 1;
   5847   1.1  christos       else if (opnd == IA64_OPND_IMM8U4)
   5848   1.1  christos 	{
   5849   1.1  christos 	  /* Sign-extend 32-bit unsigned numbers, so that the following range
   5850   1.1  christos 	     checks will work.  */
   5851   1.1  christos 	  val = e->X_add_number;
   5852   1.7  christos 	  if ((val & (~(bfd_vma) 0 << 32)) == 0)
   5853   1.7  christos 	    val = (val ^ ((bfd_vma) 1 << 31)) - ((bfd_vma) 1 << 31);
   5854   1.1  christos 	}
   5855   1.1  christos       else
   5856   1.1  christos 	val = e->X_add_number;
   5857   1.1  christos 
   5858   1.1  christos       if ((val >= 0 && (bfd_vma) val < ((bfd_vma) 1 << (bits - 1)))
   5859   1.1  christos 	  || (val < 0 && (bfd_vma) -val <= ((bfd_vma) 1 << (bits - 1))))
   5860   1.1  christos 	return OPERAND_MATCH;
   5861   1.1  christos       else
   5862   1.1  christos 	return OPERAND_OUT_OF_RANGE;
   5863   1.1  christos 
   5864   1.1  christos     case IA64_OPND_INC3:
   5865   1.1  christos       /* +/- 1, 4, 8, 16 */
   5866   1.1  christos       val = e->X_add_number;
   5867   1.1  christos       if (val < 0)
   5868   1.1  christos 	val = -val;
   5869   1.1  christos       if (e->X_op == O_constant)
   5870   1.1  christos 	{
   5871   1.1  christos 	  if ((val == 1 || val == 4 || val == 8 || val == 16))
   5872   1.1  christos 	    return OPERAND_MATCH;
   5873   1.1  christos 	  else
   5874   1.1  christos 	    return OPERAND_OUT_OF_RANGE;
   5875   1.1  christos 	}
   5876   1.1  christos       break;
   5877   1.1  christos 
   5878   1.1  christos     case IA64_OPND_TGT25:
   5879   1.1  christos     case IA64_OPND_TGT25b:
   5880   1.1  christos     case IA64_OPND_TGT25c:
   5881   1.1  christos     case IA64_OPND_TGT64:
   5882   1.1  christos       if (e->X_op == O_symbol)
   5883   1.1  christos 	{
   5884   1.1  christos 	  fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups;
   5885   1.1  christos 	  if (opnd == IA64_OPND_TGT25)
   5886   1.1  christos 	    fix->code = BFD_RELOC_IA64_PCREL21F;
   5887   1.1  christos 	  else if (opnd == IA64_OPND_TGT25b)
   5888   1.1  christos 	    fix->code = BFD_RELOC_IA64_PCREL21M;
   5889   1.1  christos 	  else if (opnd == IA64_OPND_TGT25c)
   5890   1.1  christos 	    fix->code = BFD_RELOC_IA64_PCREL21B;
   5891   1.1  christos 	  else if (opnd == IA64_OPND_TGT64)
   5892   1.1  christos 	    fix->code = BFD_RELOC_IA64_PCREL60B;
   5893   1.1  christos 	  else
   5894   1.1  christos 	    abort ();
   5895   1.1  christos 
   5896   1.1  christos 	  fix->code = ia64_gen_real_reloc_type (e->X_op_symbol, fix->code);
   5897   1.1  christos 	  fix->opnd = idesc->operands[res_index];
   5898   1.1  christos 	  fix->expr = *e;
   5899   1.1  christos 	  fix->is_pcrel = 1;
   5900   1.1  christos 	  ++CURR_SLOT.num_fixups;
   5901   1.1  christos 	  return OPERAND_MATCH;
   5902   1.1  christos 	}
   5903   1.6  christos       /* Fall through.  */
   5904   1.1  christos     case IA64_OPND_TAG13:
   5905   1.1  christos     case IA64_OPND_TAG13b:
   5906   1.1  christos       switch (e->X_op)
   5907   1.1  christos 	{
   5908   1.1  christos 	case O_constant:
   5909   1.1  christos 	  return OPERAND_MATCH;
   5910   1.1  christos 
   5911   1.1  christos 	case O_symbol:
   5912   1.1  christos 	  fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups;
   5913   1.1  christos 	  /* There are no external relocs for TAG13/TAG13b fields, so we
   5914   1.1  christos 	     create a dummy reloc.  This will not live past md_apply_fix.  */
   5915   1.1  christos 	  fix->code = BFD_RELOC_UNUSED;
   5916   1.1  christos 	  fix->code = ia64_gen_real_reloc_type (e->X_op_symbol, fix->code);
   5917   1.1  christos 	  fix->opnd = idesc->operands[res_index];
   5918   1.1  christos 	  fix->expr = *e;
   5919   1.1  christos 	  fix->is_pcrel = 1;
   5920   1.1  christos 	  ++CURR_SLOT.num_fixups;
   5921   1.1  christos 	  return OPERAND_MATCH;
   5922   1.1  christos 
   5923   1.1  christos 	default:
   5924   1.1  christos 	  break;
   5925   1.1  christos 	}
   5926   1.1  christos       break;
   5927   1.1  christos 
   5928   1.1  christos     case IA64_OPND_LDXMOV:
   5929   1.1  christos       fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups;
   5930   1.1  christos       fix->code = BFD_RELOC_IA64_LDXMOV;
   5931   1.1  christos       fix->opnd = idesc->operands[res_index];
   5932   1.1  christos       fix->expr = *e;
   5933   1.1  christos       fix->is_pcrel = 0;
   5934   1.1  christos       ++CURR_SLOT.num_fixups;
   5935   1.1  christos       return OPERAND_MATCH;
   5936   1.1  christos 
   5937   1.1  christos     case IA64_OPND_STRD5b:
   5938   1.1  christos       if (e->X_op == O_constant)
   5939   1.1  christos 	{
   5940   1.1  christos 	  /* 5-bit signed scaled by 64 */
   5941   1.3  christos 	  if ((e->X_add_number <=  	( 0xf  << 6 ))
   5942   1.1  christos 	       && (e->X_add_number >=  -( 0x10 << 6 )))
   5943   1.1  christos 	    {
   5944   1.3  christos 
   5945   1.1  christos 	      /* Must be a multiple of 64 */
   5946   1.1  christos 	      if ((e->X_add_number & 0x3f) != 0)
   5947   1.1  christos 	        as_warn (_("stride must be a multiple of 64; lower 6 bits ignored"));
   5948   1.1  christos 
   5949   1.1  christos 	      e->X_add_number &= ~ 0x3f;
   5950   1.1  christos 	      return OPERAND_MATCH;
   5951   1.1  christos 	    }
   5952   1.1  christos 	  else
   5953   1.1  christos 	    return OPERAND_OUT_OF_RANGE;
   5954   1.1  christos 	}
   5955   1.1  christos       break;
   5956   1.1  christos     case IA64_OPND_CNT6a:
   5957   1.1  christos       if (e->X_op == O_constant)
   5958   1.1  christos 	{
   5959   1.1  christos 	  /* 6-bit unsigned biased by 1 -- count 0 is meaningless */
   5960   1.3  christos 	  if ((e->X_add_number     <=   64)
   5961   1.1  christos 	       && (e->X_add_number > 0) )
   5962   1.1  christos 	    {
   5963   1.1  christos 	      return OPERAND_MATCH;
   5964   1.1  christos 	    }
   5965   1.1  christos 	  else
   5966   1.1  christos 	    return OPERAND_OUT_OF_RANGE;
   5967   1.1  christos 	}
   5968   1.1  christos       break;
   5969   1.1  christos 
   5970   1.1  christos     default:
   5971   1.1  christos       break;
   5972   1.1  christos     }
   5973   1.1  christos   return OPERAND_MISMATCH;
   5974   1.1  christos }
   5975   1.1  christos 
   5976   1.1  christos static int
   5977   1.1  christos parse_operand (expressionS *e, int more)
   5978   1.1  christos {
   5979   1.1  christos   int sep = '\0';
   5980   1.1  christos 
   5981   1.1  christos   memset (e, 0, sizeof (*e));
   5982   1.1  christos   e->X_op = O_absent;
   5983   1.1  christos   SKIP_WHITESPACE ();
   5984   1.1  christos   expression (e);
   5985   1.9  christos   resolve_register (e);
   5986   1.1  christos   sep = *input_line_pointer;
   5987   1.1  christos   if (more && (sep == ',' || sep == more))
   5988   1.1  christos     ++input_line_pointer;
   5989   1.1  christos   return sep;
   5990   1.1  christos }
   5991   1.1  christos 
   5992   1.1  christos static int
   5993   1.1  christos parse_operand_and_eval (expressionS *e, int more)
   5994   1.1  christos {
   5995   1.1  christos   int sep = parse_operand (e, more);
   5996   1.1  christos   resolve_expression (e);
   5997   1.1  christos   return sep;
   5998   1.1  christos }
   5999   1.1  christos 
   6000   1.1  christos static int
   6001   1.1  christos parse_operand_maybe_eval (expressionS *e, int more, enum ia64_opnd op)
   6002   1.1  christos {
   6003   1.1  christos   int sep = parse_operand (e, more);
   6004   1.1  christos   switch (op)
   6005   1.1  christos     {
   6006   1.1  christos     case IA64_OPND_IMM14:
   6007   1.1  christos     case IA64_OPND_IMM22:
   6008   1.1  christos     case IA64_OPND_IMMU64:
   6009   1.1  christos     case IA64_OPND_TGT25:
   6010   1.1  christos     case IA64_OPND_TGT25b:
   6011   1.1  christos     case IA64_OPND_TGT25c:
   6012   1.1  christos     case IA64_OPND_TGT64:
   6013   1.1  christos     case IA64_OPND_TAG13:
   6014   1.1  christos     case IA64_OPND_TAG13b:
   6015   1.1  christos     case IA64_OPND_LDXMOV:
   6016   1.1  christos       break;
   6017   1.1  christos     default:
   6018   1.1  christos       resolve_expression (e);
   6019   1.1  christos       break;
   6020   1.1  christos     }
   6021   1.1  christos   return sep;
   6022   1.1  christos }
   6023   1.1  christos 
   6024   1.1  christos /* Returns the next entry in the opcode table that matches the one in
   6025   1.1  christos    IDESC, and frees the entry in IDESC.  If no matching entry is
   6026   1.1  christos    found, NULL is returned instead.  */
   6027   1.1  christos 
   6028   1.1  christos static struct ia64_opcode *
   6029   1.1  christos get_next_opcode (struct ia64_opcode *idesc)
   6030   1.1  christos {
   6031   1.1  christos   struct ia64_opcode *next = ia64_find_next_opcode (idesc);
   6032   1.1  christos   ia64_free_opcode (idesc);
   6033   1.1  christos   return next;
   6034   1.1  christos }
   6035   1.1  christos 
   6036   1.1  christos /* Parse the operands for the opcode and find the opcode variant that
   6037   1.1  christos    matches the specified operands, or NULL if no match is possible.  */
   6038   1.1  christos 
   6039   1.1  christos static struct ia64_opcode *
   6040   1.1  christos parse_operands (struct ia64_opcode *idesc)
   6041   1.1  christos {
   6042   1.1  christos   int i = 0, highest_unmatched_operand, num_operands = 0, num_outputs = 0;
   6043   1.1  christos   int error_pos, out_of_range_pos, curr_out_of_range_pos, sep = 0;
   6044   1.1  christos   int reg1, reg2;
   6045   1.1  christos   char reg_class;
   6046   1.1  christos   enum ia64_opnd expected_operand = IA64_OPND_NIL;
   6047   1.1  christos   enum operand_match_result result;
   6048   1.1  christos   char mnemonic[129];
   6049   1.1  christos   char *first_arg = 0, *end, *saved_input_pointer;
   6050   1.1  christos   unsigned int sof;
   6051   1.1  christos 
   6052   1.1  christos   gas_assert (strlen (idesc->name) <= 128);
   6053   1.1  christos 
   6054   1.1  christos   strcpy (mnemonic, idesc->name);
   6055   1.1  christos   if (idesc->operands[2] == IA64_OPND_SOF
   6056   1.1  christos       || idesc->operands[1] == IA64_OPND_SOF)
   6057   1.1  christos     {
   6058   1.1  christos       /* To make the common idiom "alloc loc?=ar.pfs,0,1,0,0" work, we
   6059   1.1  christos 	 can't parse the first operand until we have parsed the
   6060   1.1  christos 	 remaining operands of the "alloc" instruction.  */
   6061   1.1  christos       SKIP_WHITESPACE ();
   6062   1.1  christos       first_arg = input_line_pointer;
   6063   1.1  christos       end = strchr (input_line_pointer, '=');
   6064   1.1  christos       if (!end)
   6065   1.1  christos 	{
   6066   1.1  christos 	  as_bad (_("Expected separator `='"));
   6067   1.1  christos 	  return 0;
   6068   1.1  christos 	}
   6069   1.1  christos       input_line_pointer = end + 1;
   6070   1.1  christos       ++i;
   6071   1.1  christos       ++num_outputs;
   6072   1.1  christos     }
   6073   1.1  christos 
   6074   1.1  christos   for (; ; ++i)
   6075   1.1  christos     {
   6076   1.3  christos       if (i < NELEMS (CURR_SLOT.opnd))
   6077   1.1  christos 	{
   6078   1.8  christos 	  enum ia64_opnd op = IA64_OPND_NIL;
   6079   1.8  christos 	  if (i < NELEMS (idesc->operands))
   6080   1.8  christos 	    op = idesc->operands[i];
   6081   1.8  christos 	  sep = parse_operand_maybe_eval (CURR_SLOT.opnd + i, '=', op);
   6082   1.1  christos 	  if (CURR_SLOT.opnd[i].X_op == O_absent)
   6083   1.1  christos 	    break;
   6084   1.1  christos 	}
   6085   1.1  christos       else
   6086   1.1  christos 	{
   6087   1.1  christos 	  expressionS dummy;
   6088   1.1  christos 
   6089   1.1  christos 	  sep = parse_operand (&dummy, '=');
   6090   1.1  christos 	  if (dummy.X_op == O_absent)
   6091   1.1  christos 	    break;
   6092   1.1  christos 	}
   6093   1.1  christos 
   6094   1.1  christos       ++num_operands;
   6095   1.1  christos 
   6096   1.1  christos       if (sep != '=' && sep != ',')
   6097   1.1  christos 	break;
   6098   1.1  christos 
   6099   1.1  christos       if (sep == '=')
   6100   1.1  christos 	{
   6101   1.1  christos 	  if (num_outputs > 0)
   6102   1.1  christos 	    as_bad (_("Duplicate equal sign (=) in instruction"));
   6103   1.1  christos 	  else
   6104   1.1  christos 	    num_outputs = i + 1;
   6105   1.1  christos 	}
   6106   1.1  christos     }
   6107   1.1  christos   if (sep != '\0')
   6108   1.1  christos     {
   6109   1.1  christos       as_bad (_("Illegal operand separator `%c'"), sep);
   6110   1.1  christos       return 0;
   6111   1.1  christos     }
   6112   1.1  christos 
   6113   1.1  christos   if (idesc->operands[2] == IA64_OPND_SOF
   6114   1.1  christos       || idesc->operands[1] == IA64_OPND_SOF)
   6115   1.1  christos     {
   6116   1.1  christos       /* Map alloc r1=ar.pfs,i,l,o,r to alloc r1=ar.pfs,(i+l+o),(i+l),r.
   6117   1.1  christos 	 Note, however, that due to that mapping operand numbers in error
   6118   1.1  christos 	 messages for any of the constant operands will not be correct.  */
   6119   1.1  christos       know (strcmp (idesc->name, "alloc") == 0);
   6120   1.1  christos       /* The first operand hasn't been parsed/initialized, yet (but
   6121   1.1  christos 	 num_operands intentionally doesn't account for that).  */
   6122   1.1  christos       i = num_operands > 4 ? 2 : 1;
   6123   1.1  christos #define FORCE_CONST(n) (CURR_SLOT.opnd[n].X_op == O_constant \
   6124   1.1  christos 			? CURR_SLOT.opnd[n].X_add_number \
   6125   1.1  christos 			: 0)
   6126   1.1  christos       sof = set_regstack (FORCE_CONST(i),
   6127   1.1  christos 			  FORCE_CONST(i + 1),
   6128   1.1  christos 			  FORCE_CONST(i + 2),
   6129   1.1  christos 			  FORCE_CONST(i + 3));
   6130   1.1  christos #undef FORCE_CONST
   6131   1.1  christos 
   6132   1.1  christos       /* now we can parse the first arg:  */
   6133   1.1  christos       saved_input_pointer = input_line_pointer;
   6134   1.1  christos       input_line_pointer = first_arg;
   6135   1.1  christos       sep = parse_operand_maybe_eval (CURR_SLOT.opnd + 0, '=',
   6136   1.1  christos 				      idesc->operands[0]);
   6137   1.1  christos       if (sep != '=')
   6138   1.1  christos 	--num_outputs;	/* force error */
   6139   1.1  christos       input_line_pointer = saved_input_pointer;
   6140   1.1  christos 
   6141   1.1  christos       CURR_SLOT.opnd[i].X_add_number = sof;
   6142   1.1  christos       if (CURR_SLOT.opnd[i + 1].X_op == O_constant
   6143   1.1  christos 	  && CURR_SLOT.opnd[i + 2].X_op == O_constant)
   6144   1.1  christos 	CURR_SLOT.opnd[i + 1].X_add_number
   6145   1.1  christos 	  = sof - CURR_SLOT.opnd[i + 2].X_add_number;
   6146   1.1  christos       else
   6147   1.1  christos 	CURR_SLOT.opnd[i + 1].X_op = O_illegal;
   6148   1.1  christos       CURR_SLOT.opnd[i + 2] = CURR_SLOT.opnd[i + 3];
   6149   1.1  christos     }
   6150   1.1  christos 
   6151   1.1  christos   highest_unmatched_operand = -4;
   6152   1.1  christos   curr_out_of_range_pos = -1;
   6153   1.1  christos   error_pos = 0;
   6154   1.1  christos   for (; idesc; idesc = get_next_opcode (idesc))
   6155   1.1  christos     {
   6156   1.1  christos       if (num_outputs != idesc->num_outputs)
   6157   1.1  christos 	continue;		/* mismatch in # of outputs */
   6158   1.1  christos       if (highest_unmatched_operand < 0)
   6159   1.1  christos 	highest_unmatched_operand |= 1;
   6160   1.1  christos       if (num_operands > NELEMS (idesc->operands)
   6161   1.1  christos 	  || (num_operands < NELEMS (idesc->operands)
   6162   1.1  christos 	   && idesc->operands[num_operands])
   6163   1.1  christos 	  || (num_operands > 0 && !idesc->operands[num_operands - 1]))
   6164   1.1  christos 	continue;		/* mismatch in number of arguments */
   6165   1.1  christos       if (highest_unmatched_operand < 0)
   6166   1.1  christos 	highest_unmatched_operand |= 2;
   6167   1.1  christos 
   6168   1.1  christos       CURR_SLOT.num_fixups = 0;
   6169   1.1  christos 
   6170   1.1  christos       /* Try to match all operands.  If we see an out-of-range operand,
   6171   1.1  christos 	 then continue trying to match the rest of the operands, since if
   6172   1.1  christos 	 the rest match, then this idesc will give the best error message.  */
   6173   1.1  christos 
   6174   1.1  christos       out_of_range_pos = -1;
   6175   1.1  christos       for (i = 0; i < num_operands && idesc->operands[i]; ++i)
   6176   1.1  christos 	{
   6177   1.1  christos 	  result = operand_match (idesc, i, CURR_SLOT.opnd + i);
   6178   1.1  christos 	  if (result != OPERAND_MATCH)
   6179   1.1  christos 	    {
   6180   1.1  christos 	      if (result != OPERAND_OUT_OF_RANGE)
   6181   1.1  christos 		break;
   6182   1.1  christos 	      if (out_of_range_pos < 0)
   6183   1.1  christos 		/* remember position of the first out-of-range operand: */
   6184   1.1  christos 		out_of_range_pos = i;
   6185   1.1  christos 	    }
   6186   1.1  christos 	}
   6187   1.1  christos 
   6188   1.1  christos       /* If we did not match all operands, or if at least one operand was
   6189   1.1  christos 	 out-of-range, then this idesc does not match.  Keep track of which
   6190   1.1  christos 	 idesc matched the most operands before failing.  If we have two
   6191   1.1  christos 	 idescs that failed at the same position, and one had an out-of-range
   6192   1.1  christos 	 operand, then prefer the out-of-range operand.  Thus if we have
   6193   1.1  christos 	 "add r0=0x1000000,r1" we get an error saying the constant is out
   6194   1.1  christos 	 of range instead of an error saying that the constant should have been
   6195   1.1  christos 	 a register.  */
   6196   1.1  christos 
   6197   1.1  christos       if (i != num_operands || out_of_range_pos >= 0)
   6198   1.1  christos 	{
   6199   1.1  christos 	  if (i > highest_unmatched_operand
   6200   1.1  christos 	      || (i == highest_unmatched_operand
   6201   1.1  christos 		  && out_of_range_pos > curr_out_of_range_pos))
   6202   1.1  christos 	    {
   6203   1.1  christos 	      highest_unmatched_operand = i;
   6204   1.1  christos 	      if (out_of_range_pos >= 0)
   6205   1.1  christos 		{
   6206   1.1  christos 		  expected_operand = idesc->operands[out_of_range_pos];
   6207   1.1  christos 		  error_pos = out_of_range_pos;
   6208   1.1  christos 		}
   6209   1.1  christos 	      else
   6210   1.1  christos 		{
   6211   1.1  christos 		  expected_operand = idesc->operands[i];
   6212   1.1  christos 		  error_pos = i;
   6213   1.1  christos 		}
   6214   1.1  christos 	      curr_out_of_range_pos = out_of_range_pos;
   6215   1.1  christos 	    }
   6216   1.1  christos 	  continue;
   6217   1.1  christos 	}
   6218   1.1  christos 
   6219   1.1  christos       break;
   6220   1.1  christos     }
   6221   1.1  christos   if (!idesc)
   6222   1.1  christos     {
   6223   1.1  christos       if (expected_operand)
   6224   1.1  christos 	as_bad (_("Operand %u of `%s' should be %s"),
   6225   1.1  christos 		error_pos + 1, mnemonic,
   6226   1.1  christos 		elf64_ia64_operands[expected_operand].desc);
   6227   1.1  christos       else if (highest_unmatched_operand < 0 && !(highest_unmatched_operand & 1))
   6228   1.1  christos 	as_bad (_("Wrong number of output operands"));
   6229   1.1  christos       else if (highest_unmatched_operand < 0 && !(highest_unmatched_operand & 2))
   6230   1.1  christos 	as_bad (_("Wrong number of input operands"));
   6231   1.1  christos       else
   6232   1.1  christos 	as_bad (_("Operand mismatch"));
   6233   1.1  christos       return 0;
   6234   1.1  christos     }
   6235   1.1  christos 
   6236   1.1  christos   /* Check that the instruction doesn't use
   6237   1.1  christos      - r0, f0, or f1 as output operands
   6238   1.1  christos      - the same predicate twice as output operands
   6239   1.1  christos      - r0 as address of a base update load or store
   6240   1.1  christos      - the same GR as output and address of a base update load
   6241   1.1  christos      - two even- or two odd-numbered FRs as output operands of a floating
   6242   1.1  christos        point parallel load.
   6243   1.1  christos      At most two (conflicting) output (or output-like) operands can exist,
   6244   1.1  christos      (floating point parallel loads have three outputs, but the base register,
   6245   1.1  christos      if updated, cannot conflict with the actual outputs).  */
   6246   1.1  christos   reg2 = reg1 = -1;
   6247   1.1  christos   for (i = 0; i < num_operands; ++i)
   6248   1.1  christos     {
   6249   1.1  christos       int regno = 0;
   6250   1.1  christos 
   6251   1.1  christos       reg_class = 0;
   6252   1.1  christos       switch (idesc->operands[i])
   6253   1.1  christos 	{
   6254   1.1  christos 	case IA64_OPND_R1:
   6255   1.1  christos 	case IA64_OPND_R2:
   6256   1.1  christos 	case IA64_OPND_R3:
   6257   1.1  christos 	  if (i < num_outputs)
   6258   1.1  christos 	    {
   6259   1.1  christos 	      if (CURR_SLOT.opnd[i].X_add_number == REG_GR)
   6260   1.1  christos 		reg_class = 'r';
   6261   1.1  christos 	      else if (reg1 < 0)
   6262   1.1  christos 		reg1 = CURR_SLOT.opnd[i].X_add_number;
   6263   1.1  christos 	      else if (reg2 < 0)
   6264   1.1  christos 		reg2 = CURR_SLOT.opnd[i].X_add_number;
   6265   1.1  christos 	    }
   6266   1.1  christos 	  break;
   6267   1.1  christos 	case IA64_OPND_P1:
   6268   1.1  christos 	case IA64_OPND_P2:
   6269   1.1  christos 	  if (i < num_outputs)
   6270   1.1  christos 	    {
   6271   1.1  christos 	      if (reg1 < 0)
   6272   1.1  christos 		reg1 = CURR_SLOT.opnd[i].X_add_number;
   6273   1.1  christos 	      else if (reg2 < 0)
   6274   1.1  christos 		reg2 = CURR_SLOT.opnd[i].X_add_number;
   6275   1.1  christos 	    }
   6276   1.1  christos 	  break;
   6277   1.1  christos 	case IA64_OPND_F1:
   6278   1.1  christos 	case IA64_OPND_F2:
   6279   1.1  christos 	case IA64_OPND_F3:
   6280   1.1  christos 	case IA64_OPND_F4:
   6281   1.1  christos 	  if (i < num_outputs)
   6282   1.1  christos 	    {
   6283   1.1  christos 	      if (CURR_SLOT.opnd[i].X_add_number >= REG_FR
   6284   1.1  christos 		  && CURR_SLOT.opnd[i].X_add_number <= REG_FR + 1)
   6285   1.1  christos 		{
   6286   1.1  christos 		  reg_class = 'f';
   6287   1.1  christos 		  regno = CURR_SLOT.opnd[i].X_add_number - REG_FR;
   6288   1.1  christos 		}
   6289   1.1  christos 	      else if (reg1 < 0)
   6290   1.1  christos 		reg1 = CURR_SLOT.opnd[i].X_add_number;
   6291   1.1  christos 	      else if (reg2 < 0)
   6292   1.1  christos 		reg2 = CURR_SLOT.opnd[i].X_add_number;
   6293   1.1  christos 	    }
   6294   1.1  christos 	  break;
   6295   1.1  christos 	case IA64_OPND_MR3:
   6296   1.1  christos 	  if (idesc->flags & IA64_OPCODE_POSTINC)
   6297   1.1  christos 	    {
   6298   1.1  christos 	      if (CURR_SLOT.opnd[i].X_add_number == REG_GR)
   6299   1.1  christos 		reg_class = 'm';
   6300   1.1  christos 	      else if (reg1 < 0)
   6301   1.1  christos 		reg1 = CURR_SLOT.opnd[i].X_add_number;
   6302   1.1  christos 	      else if (reg2 < 0)
   6303   1.1  christos 		reg2 = CURR_SLOT.opnd[i].X_add_number;
   6304   1.1  christos 	    }
   6305   1.1  christos 	  break;
   6306   1.1  christos 	default:
   6307   1.1  christos 	  break;
   6308   1.1  christos 	}
   6309   1.1  christos       switch (reg_class)
   6310   1.1  christos 	{
   6311   1.1  christos 	case 0:
   6312   1.1  christos 	  break;
   6313   1.1  christos 	default:
   6314   1.1  christos 	  as_warn (_("Invalid use of `%c%d' as output operand"), reg_class, regno);
   6315   1.1  christos 	  break;
   6316   1.1  christos 	case 'm':
   6317   1.1  christos 	  as_warn (_("Invalid use of `r%d' as base update address operand"), regno);
   6318   1.1  christos 	  break;
   6319   1.1  christos 	}
   6320   1.1  christos     }
   6321   1.1  christos   if (reg1 == reg2)
   6322   1.1  christos     {
   6323   1.1  christos       if (reg1 >= REG_GR && reg1 <= REG_GR + 127)
   6324   1.1  christos 	{
   6325   1.1  christos 	  reg1 -= REG_GR;
   6326   1.1  christos 	  reg_class = 'r';
   6327   1.1  christos 	}
   6328   1.1  christos       else if (reg1 >= REG_P && reg1 <= REG_P + 63)
   6329   1.1  christos 	{
   6330   1.1  christos 	  reg1 -= REG_P;
   6331   1.1  christos 	  reg_class = 'p';
   6332   1.1  christos 	}
   6333   1.1  christos       else if (reg1 >= REG_FR && reg1 <= REG_FR + 127)
   6334   1.1  christos 	{
   6335   1.1  christos 	  reg1 -= REG_FR;
   6336   1.1  christos 	  reg_class = 'f';
   6337   1.1  christos 	}
   6338   1.1  christos       else
   6339   1.1  christos 	reg_class = 0;
   6340   1.1  christos       if (reg_class)
   6341   1.1  christos 	as_warn (_("Invalid duplicate use of `%c%d'"), reg_class, reg1);
   6342   1.1  christos     }
   6343   1.1  christos   else if (((reg1 >= REG_FR && reg1 <= REG_FR + 31
   6344   1.1  christos 	     && reg2 >= REG_FR && reg2 <= REG_FR + 31)
   6345   1.1  christos 	    || (reg1 >= REG_FR + 32 && reg1 <= REG_FR + 127
   6346   1.1  christos 	     && reg2 >= REG_FR + 32 && reg2 <= REG_FR + 127))
   6347   1.1  christos 	   && ! ((reg1 ^ reg2) & 1))
   6348   1.1  christos     as_warn (_("Invalid simultaneous use of `f%d' and `f%d'"),
   6349   1.1  christos 	     reg1 - REG_FR, reg2 - REG_FR);
   6350   1.1  christos   else if ((reg1 >= REG_FR && reg1 <= REG_FR + 31
   6351   1.1  christos 	    && reg2 >= REG_FR + 32 && reg2 <= REG_FR + 127)
   6352   1.1  christos 	   || (reg1 >= REG_FR + 32 && reg1 <= REG_FR + 127
   6353   1.1  christos 	    && reg2 >= REG_FR && reg2 <= REG_FR + 31))
   6354   1.1  christos     as_warn (_("Dangerous simultaneous use of `f%d' and `f%d'"),
   6355   1.1  christos 	     reg1 - REG_FR, reg2 - REG_FR);
   6356   1.1  christos   return idesc;
   6357   1.1  christos }
   6358   1.1  christos 
   6359   1.1  christos static void
   6360   1.1  christos build_insn (struct slot *slot, bfd_vma *insnp)
   6361   1.1  christos {
   6362   1.1  christos   const struct ia64_operand *odesc, *o2desc;
   6363   1.1  christos   struct ia64_opcode *idesc = slot->idesc;
   6364   1.1  christos   bfd_vma insn;
   6365   1.1  christos   bfd_signed_vma val;
   6366   1.1  christos   const char *err;
   6367   1.1  christos   int i;
   6368   1.1  christos 
   6369   1.1  christos   insn = idesc->opcode | slot->qp_regno;
   6370   1.1  christos 
   6371   1.1  christos   for (i = 0; i < NELEMS (idesc->operands) && idesc->operands[i]; ++i)
   6372   1.1  christos     {
   6373   1.1  christos       if (slot->opnd[i].X_op == O_register
   6374   1.1  christos 	  || slot->opnd[i].X_op == O_constant
   6375   1.1  christos 	  || slot->opnd[i].X_op == O_index)
   6376   1.1  christos 	val = slot->opnd[i].X_add_number;
   6377   1.1  christos       else if (slot->opnd[i].X_op == O_big)
   6378   1.1  christos 	{
   6379   1.1  christos 	  /* This must be the value 0x10000000000000000.  */
   6380   1.1  christos 	  gas_assert (idesc->operands[i] == IA64_OPND_IMM8M1U8);
   6381   1.1  christos 	  val = 0;
   6382   1.1  christos 	}
   6383   1.1  christos       else
   6384   1.1  christos 	val = 0;
   6385   1.1  christos 
   6386   1.1  christos       switch (idesc->operands[i])
   6387   1.1  christos 	{
   6388   1.1  christos 	case IA64_OPND_IMMU64:
   6389   1.1  christos 	  *insnp++ = (val >> 22) & 0x1ffffffffffLL;
   6390   1.1  christos 	  insn |= (((val & 0x7f) << 13) | (((val >> 7) & 0x1ff) << 27)
   6391   1.1  christos 		   | (((val >> 16) & 0x1f) << 22) | (((val >> 21) & 0x1) << 21)
   6392   1.1  christos 		   | (((val >> 63) & 0x1) << 36));
   6393   1.1  christos 	  continue;
   6394   1.1  christos 
   6395   1.1  christos 	case IA64_OPND_IMMU62:
   6396   1.1  christos 	  val &= 0x3fffffffffffffffULL;
   6397   1.1  christos 	  if (val != slot->opnd[i].X_add_number)
   6398   1.1  christos 	    as_warn (_("Value truncated to 62 bits"));
   6399   1.1  christos 	  *insnp++ = (val >> 21) & 0x1ffffffffffLL;
   6400   1.1  christos 	  insn |= (((val & 0xfffff) << 6) | (((val >> 20) & 0x1) << 36));
   6401   1.1  christos 	  continue;
   6402   1.1  christos 
   6403   1.1  christos 	case IA64_OPND_TGT64:
   6404   1.1  christos 	  val >>= 4;
   6405   1.1  christos 	  *insnp++ = ((val >> 20) & 0x7fffffffffLL) << 2;
   6406   1.1  christos 	  insn |= ((((val >> 59) & 0x1) << 36)
   6407   1.1  christos 		   | (((val >> 0) & 0xfffff) << 13));
   6408   1.1  christos 	  continue;
   6409   1.1  christos 
   6410   1.1  christos 	case IA64_OPND_AR3:
   6411   1.1  christos 	  val -= REG_AR;
   6412   1.1  christos 	  break;
   6413   1.1  christos 
   6414   1.1  christos 	case IA64_OPND_B1:
   6415   1.1  christos 	case IA64_OPND_B2:
   6416   1.1  christos 	  val -= REG_BR;
   6417   1.1  christos 	  break;
   6418   1.1  christos 
   6419   1.1  christos 	case IA64_OPND_CR3:
   6420   1.1  christos 	  val -= REG_CR;
   6421   1.1  christos 	  break;
   6422   1.1  christos 
   6423   1.1  christos 	case IA64_OPND_DAHR3:
   6424   1.1  christos 	  val -= REG_DAHR;
   6425   1.1  christos 	  break;
   6426   1.1  christos 
   6427   1.1  christos 	case IA64_OPND_F1:
   6428   1.1  christos 	case IA64_OPND_F2:
   6429   1.1  christos 	case IA64_OPND_F3:
   6430   1.1  christos 	case IA64_OPND_F4:
   6431   1.1  christos 	  val -= REG_FR;
   6432   1.1  christos 	  break;
   6433   1.1  christos 
   6434   1.1  christos 	case IA64_OPND_P1:
   6435   1.1  christos 	case IA64_OPND_P2:
   6436   1.1  christos 	  val -= REG_P;
   6437   1.1  christos 	  break;
   6438   1.1  christos 
   6439   1.1  christos 	case IA64_OPND_R1:
   6440   1.1  christos 	case IA64_OPND_R2:
   6441   1.1  christos 	case IA64_OPND_R3:
   6442   1.1  christos 	case IA64_OPND_R3_2:
   6443   1.1  christos 	case IA64_OPND_CPUID_R3:
   6444   1.1  christos 	case IA64_OPND_DBR_R3:
   6445   1.1  christos 	case IA64_OPND_DTR_R3:
   6446   1.1  christos 	case IA64_OPND_ITR_R3:
   6447   1.1  christos 	case IA64_OPND_IBR_R3:
   6448   1.1  christos 	case IA64_OPND_MR3:
   6449   1.1  christos 	case IA64_OPND_MSR_R3:
   6450   1.1  christos 	case IA64_OPND_PKR_R3:
   6451   1.1  christos 	case IA64_OPND_PMC_R3:
   6452   1.1  christos 	case IA64_OPND_PMD_R3:
   6453   1.1  christos 	case IA64_OPND_DAHR_R3:
   6454   1.1  christos 	case IA64_OPND_RR_R3:
   6455   1.1  christos 	  val -= REG_GR;
   6456   1.1  christos 	  break;
   6457   1.1  christos 
   6458   1.1  christos 	default:
   6459   1.1  christos 	  break;
   6460   1.1  christos 	}
   6461   1.1  christos 
   6462   1.1  christos       odesc = elf64_ia64_operands + idesc->operands[i];
   6463   1.1  christos       err = (*odesc->insert) (odesc, val, &insn);
   6464   1.1  christos       if (err)
   6465   1.1  christos 	as_bad_where (slot->src_file, slot->src_line,
   6466   1.1  christos 		      _("Bad operand value: %s"), err);
   6467   1.1  christos       if (idesc->flags & IA64_OPCODE_PSEUDO)
   6468   1.1  christos 	{
   6469   1.1  christos 	  if ((idesc->flags & IA64_OPCODE_F2_EQ_F3)
   6470   1.1  christos 	      && odesc == elf64_ia64_operands + IA64_OPND_F3)
   6471   1.1  christos 	    {
   6472   1.1  christos 	      o2desc = elf64_ia64_operands + IA64_OPND_F2;
   6473   1.1  christos 	      (*o2desc->insert) (o2desc, val, &insn);
   6474   1.1  christos 	    }
   6475   1.1  christos 	  if ((idesc->flags & IA64_OPCODE_LEN_EQ_64MCNT)
   6476   1.1  christos 	      && (odesc == elf64_ia64_operands + IA64_OPND_CPOS6a
   6477   1.1  christos 		  || odesc == elf64_ia64_operands + IA64_OPND_POS6))
   6478   1.1  christos 	    {
   6479   1.1  christos 	      o2desc = elf64_ia64_operands + IA64_OPND_LEN6;
   6480   1.1  christos 	      (*o2desc->insert) (o2desc, 64 - val, &insn);
   6481   1.1  christos 	    }
   6482   1.1  christos 	}
   6483   1.1  christos     }
   6484   1.1  christos   *insnp = insn;
   6485   1.1  christos }
   6486   1.1  christos 
   6487   1.1  christos static void
   6488   1.1  christos emit_one_bundle (void)
   6489   1.1  christos {
   6490   1.1  christos   int manual_bundling_off = 0, manual_bundling = 0;
   6491   1.1  christos   enum ia64_unit required_unit, insn_unit = 0;
   6492   1.1  christos   enum ia64_insn_type type[3], insn_type;
   6493   1.1  christos   unsigned int template_val, orig_template;
   6494   1.1  christos   bfd_vma insn[3] = { -1, -1, -1 };
   6495   1.1  christos   struct ia64_opcode *idesc;
   6496   1.1  christos   int end_of_insn_group = 0, user_template = -1;
   6497   1.1  christos   int n, i, j, first, curr, last_slot;
   6498   1.1  christos   bfd_vma t0 = 0, t1 = 0;
   6499   1.1  christos   struct label_fix *lfix;
   6500   1.8  christos   bool mark_label;
   6501   1.1  christos   struct insn_fix *ifix;
   6502   1.1  christos   char mnemonic[16];
   6503   1.1  christos   fixS *fix;
   6504   1.1  christos   char *f;
   6505   1.1  christos   int addr_mod;
   6506   1.1  christos 
   6507   1.1  christos   first = (md.curr_slot + NUM_SLOTS - md.num_slots_in_use) % NUM_SLOTS;
   6508   1.1  christos   know (first >= 0 && first < NUM_SLOTS);
   6509   1.1  christos   n = MIN (3, md.num_slots_in_use);
   6510   1.1  christos 
   6511   1.1  christos   /* Determine template: user user_template if specified, best match
   6512   1.1  christos      otherwise:  */
   6513   1.1  christos 
   6514   1.1  christos   if (md.slot[first].user_template >= 0)
   6515   1.1  christos     user_template = template_val = md.slot[first].user_template;
   6516   1.1  christos   else
   6517   1.1  christos     {
   6518   1.1  christos       /* Auto select appropriate template.  */
   6519   1.1  christos       memset (type, 0, sizeof (type));
   6520   1.1  christos       curr = first;
   6521   1.1  christos       for (i = 0; i < n; ++i)
   6522   1.1  christos 	{
   6523   1.1  christos 	  if (md.slot[curr].label_fixups && i != 0)
   6524   1.1  christos 	    break;
   6525   1.1  christos 	  type[i] = md.slot[curr].idesc->type;
   6526   1.1  christos 	  curr = (curr + 1) % NUM_SLOTS;
   6527   1.1  christos 	}
   6528   1.1  christos       template_val = best_template[type[0]][type[1]][type[2]];
   6529   1.1  christos     }
   6530   1.1  christos 
   6531   1.1  christos   /* initialize instructions with appropriate nops:  */
   6532   1.1  christos   for (i = 0; i < 3; ++i)
   6533   1.1  christos     insn[i] = nop[ia64_templ_desc[template_val].exec_unit[i]];
   6534   1.1  christos 
   6535   1.1  christos   f = frag_more (16);
   6536   1.1  christos 
   6537   1.1  christos   /* Check to see if this bundle is at an offset that is a multiple of 16-bytes
   6538   1.1  christos      from the start of the frag.  */
   6539   1.1  christos   addr_mod = frag_now_fix () & 15;
   6540   1.1  christos   if (frag_now->has_code && frag_now->insn_addr != addr_mod)
   6541   1.1  christos     as_bad (_("instruction address is not a multiple of 16"));
   6542   1.1  christos   frag_now->insn_addr = addr_mod;
   6543   1.1  christos   frag_now->has_code = 1;
   6544   1.1  christos 
   6545   1.1  christos   /* now fill in slots with as many insns as possible:  */
   6546   1.1  christos   curr = first;
   6547   1.1  christos   idesc = md.slot[curr].idesc;
   6548   1.1  christos   end_of_insn_group = 0;
   6549   1.1  christos   last_slot = -1;
   6550   1.1  christos   for (i = 0; i < 3 && md.num_slots_in_use > 0; ++i)
   6551   1.1  christos     {
   6552   1.1  christos       /* If we have unwind records, we may need to update some now.  */
   6553   1.1  christos       unw_rec_list *ptr = md.slot[curr].unwind_record;
   6554   1.1  christos       unw_rec_list *end_ptr = NULL;
   6555   1.1  christos 
   6556   1.1  christos       if (ptr)
   6557   1.1  christos 	{
   6558   1.1  christos 	  /* Find the last prologue/body record in the list for the current
   6559   1.1  christos 	     insn, and set the slot number for all records up to that point.
   6560   1.1  christos 	     This needs to be done now, because prologue/body records refer to
   6561   1.1  christos 	     the current point, not the point after the instruction has been
   6562   1.1  christos 	     issued.  This matters because there may have been nops emitted
   6563   1.1  christos 	     meanwhile.  Any non-prologue non-body record followed by a
   6564   1.1  christos 	     prologue/body record must also refer to the current point.  */
   6565   1.1  christos 	  unw_rec_list *last_ptr;
   6566   1.1  christos 
   6567   1.1  christos 	  for (j = 1; end_ptr == NULL && j < md.num_slots_in_use; ++j)
   6568   1.1  christos 	    end_ptr = md.slot[(curr + j) % NUM_SLOTS].unwind_record;
   6569   1.1  christos 	  for (last_ptr = NULL; ptr != end_ptr; ptr = ptr->next)
   6570   1.1  christos 	    if (ptr->r.type == prologue || ptr->r.type == prologue_gr
   6571   1.1  christos 		|| ptr->r.type == body)
   6572   1.1  christos 	      last_ptr = ptr;
   6573   1.1  christos 	  if (last_ptr)
   6574   1.1  christos 	    {
   6575   1.1  christos 	      /* Make last_ptr point one after the last prologue/body
   6576   1.1  christos 		 record.  */
   6577   1.1  christos 	      last_ptr = last_ptr->next;
   6578   1.1  christos 	      for (ptr = md.slot[curr].unwind_record; ptr != last_ptr;
   6579   1.1  christos 		   ptr = ptr->next)
   6580   1.1  christos 		{
   6581   1.1  christos 		  ptr->slot_number = (unsigned long) f + i;
   6582   1.1  christos 		  ptr->slot_frag = frag_now;
   6583   1.1  christos 		}
   6584   1.1  christos 	      /* Remove the initialized records, so that we won't accidentally
   6585   1.1  christos 		 update them again if we insert a nop and continue.  */
   6586   1.1  christos 	      md.slot[curr].unwind_record = last_ptr;
   6587   1.1  christos 	    }
   6588   1.1  christos 	}
   6589   1.1  christos 
   6590   1.1  christos       manual_bundling_off = md.slot[curr].manual_bundling_off;
   6591   1.1  christos       if (md.slot[curr].manual_bundling_on)
   6592   1.1  christos 	{
   6593   1.1  christos 	  if (curr == first)
   6594   1.1  christos 	    manual_bundling = 1;
   6595   1.1  christos 	  else
   6596   1.1  christos 	  break; /* Need to start a new bundle.  */
   6597   1.1  christos 	}
   6598   1.1  christos 
   6599   1.1  christos       /* If this instruction specifies a template, then it must be the first
   6600   1.1  christos 	 instruction of a bundle.  */
   6601   1.1  christos       if (curr != first && md.slot[curr].user_template >= 0)
   6602   1.1  christos 	break;
   6603   1.1  christos 
   6604   1.1  christos       if (idesc->flags & IA64_OPCODE_SLOT2)
   6605   1.1  christos 	{
   6606   1.1  christos 	  if (manual_bundling && !manual_bundling_off)
   6607   1.1  christos 	    {
   6608   1.1  christos 	      as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
   6609   1.1  christos 			    _("`%s' must be last in bundle"), idesc->name);
   6610   1.1  christos 	      if (i < 2)
   6611   1.1  christos 		manual_bundling = -1; /* Suppress meaningless post-loop errors.  */
   6612   1.1  christos 	    }
   6613   1.1  christos 	  i = 2;
   6614   1.1  christos 	}
   6615   1.1  christos       if (idesc->flags & IA64_OPCODE_LAST)
   6616   1.1  christos 	{
   6617   1.1  christos 	  int required_slot;
   6618   1.1  christos 	  unsigned int required_template;
   6619   1.1  christos 
   6620   1.1  christos 	  /* If we need a stop bit after an M slot, our only choice is
   6621   1.1  christos 	     template 5 (M;;MI).  If we need a stop bit after a B
   6622   1.1  christos 	     slot, our only choice is to place it at the end of the
   6623   1.1  christos 	     bundle, because the only available templates are MIB,
   6624   1.1  christos 	     MBB, BBB, MMB, and MFB.  We don't handle anything other
   6625   1.1  christos 	     than M and B slots because these are the only kind of
   6626   1.1  christos 	     instructions that can have the IA64_OPCODE_LAST bit set.  */
   6627   1.1  christos 	  required_template = template_val;
   6628   1.1  christos 	  switch (idesc->type)
   6629   1.1  christos 	    {
   6630   1.1  christos 	    case IA64_TYPE_M:
   6631   1.1  christos 	      required_slot = 0;
   6632   1.1  christos 	      required_template = 5;
   6633   1.1  christos 	      break;
   6634   1.1  christos 
   6635   1.1  christos 	    case IA64_TYPE_B:
   6636   1.1  christos 	      required_slot = 2;
   6637   1.1  christos 	      break;
   6638   1.1  christos 
   6639   1.1  christos 	    default:
   6640   1.1  christos 	      as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
   6641   1.1  christos 			    _("Internal error: don't know how to force %s to end of instruction group"),
   6642   1.1  christos 			    idesc->name);
   6643   1.1  christos 	      required_slot = i;
   6644   1.1  christos 	      break;
   6645   1.1  christos 	    }
   6646   1.1  christos 	  if (manual_bundling
   6647   1.1  christos 	      && (i > required_slot
   6648   1.1  christos 		  || (required_slot == 2 && !manual_bundling_off)
   6649   1.1  christos 		  || (user_template >= 0
   6650   1.1  christos 		      /* Changing from MMI to M;MI is OK.  */
   6651   1.1  christos 		      && (template_val ^ required_template) > 1)))
   6652   1.1  christos 	    {
   6653   1.1  christos 	      as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
   6654   1.1  christos 			    _("`%s' must be last in instruction group"),
   6655   1.1  christos 			    idesc->name);
   6656   1.1  christos 	      if (i < 2 && required_slot == 2 && !manual_bundling_off)
   6657   1.1  christos 		manual_bundling = -1; /* Suppress meaningless post-loop errors.  */
   6658   1.1  christos 	    }
   6659   1.1  christos 	  if (required_slot < i)
   6660   1.1  christos 	    /* Can't fit this instruction.  */
   6661   1.1  christos 	    break;
   6662   1.1  christos 
   6663   1.1  christos 	  i = required_slot;
   6664   1.1  christos 	  if (required_template != template_val)
   6665   1.1  christos 	    {
   6666   1.1  christos 	      /* If we switch the template, we need to reset the NOPs
   6667   1.1  christos 	         after slot i.  The slot-types of the instructions ahead
   6668   1.1  christos 	         of i never change, so we don't need to worry about
   6669   1.1  christos 	         changing NOPs in front of this slot.  */
   6670   1.1  christos 	      for (j = i; j < 3; ++j)
   6671   1.1  christos 	        insn[j] = nop[ia64_templ_desc[required_template].exec_unit[j]];
   6672   1.1  christos 
   6673   1.1  christos 	      /* We just picked a template that includes the stop bit in the
   6674   1.1  christos 		 middle, so we don't need another one emitted later.  */
   6675   1.1  christos 	      md.slot[curr].end_of_insn_group = 0;
   6676   1.1  christos 	    }
   6677   1.1  christos 	  template_val = required_template;
   6678   1.1  christos 	}
   6679   1.1  christos       if (curr != first && md.slot[curr].label_fixups)
   6680   1.1  christos 	{
   6681   1.1  christos 	  if (manual_bundling)
   6682   1.1  christos 	    {
   6683   1.1  christos 	      as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
   6684   1.1  christos 			    _("Label must be first in a bundle"));
   6685   1.1  christos 	      manual_bundling = -1; /* Suppress meaningless post-loop errors.  */
   6686   1.1  christos 	    }
   6687   1.1  christos 	  /* This insn must go into the first slot of a bundle.  */
   6688   1.1  christos 	  break;
   6689   1.1  christos 	}
   6690   1.1  christos 
   6691   1.1  christos       if (end_of_insn_group && md.num_slots_in_use >= 1)
   6692   1.1  christos 	{
   6693   1.1  christos 	  /* We need an instruction group boundary in the middle of a
   6694   1.1  christos 	     bundle.  See if we can switch to an other template with
   6695   1.1  christos 	     an appropriate boundary.  */
   6696   1.1  christos 
   6697   1.1  christos 	  orig_template = template_val;
   6698   1.1  christos 	  if (i == 1 && (user_template == 4
   6699   1.1  christos 			 || (user_template < 0
   6700   1.1  christos 			     && (ia64_templ_desc[template_val].exec_unit[0]
   6701   1.1  christos 				 == IA64_UNIT_M))))
   6702   1.1  christos 	    {
   6703   1.1  christos 	      template_val = 5;
   6704   1.1  christos 	      end_of_insn_group = 0;
   6705   1.1  christos 	    }
   6706   1.1  christos 	  else if (i == 2 && (user_template == 0
   6707   1.1  christos 			      || (user_template < 0
   6708   1.1  christos 				  && (ia64_templ_desc[template_val].exec_unit[1]
   6709   1.1  christos 				      == IA64_UNIT_I)))
   6710   1.1  christos 		   /* This test makes sure we don't switch the template if
   6711   1.1  christos 		      the next instruction is one that needs to be first in
   6712   1.1  christos 		      an instruction group.  Since all those instructions are
   6713   1.1  christos 		      in the M group, there is no way such an instruction can
   6714   1.1  christos 		      fit in this bundle even if we switch the template.  The
   6715   1.1  christos 		      reason we have to check for this is that otherwise we
   6716   1.1  christos 		      may end up generating "MI;;I M.." which has the deadly
   6717   1.1  christos 		      effect that the second M instruction is no longer the
   6718   1.1  christos 		      first in the group! --davidm 99/12/16  */
   6719   1.1  christos 		   && (idesc->flags & IA64_OPCODE_FIRST) == 0)
   6720   1.1  christos 	    {
   6721   1.1  christos 	      template_val = 1;
   6722   1.1  christos 	      end_of_insn_group = 0;
   6723   1.1  christos 	    }
   6724   1.1  christos 	  else if (i == 1
   6725   1.1  christos 		   && user_template == 0
   6726   1.1  christos 		   && !(idesc->flags & IA64_OPCODE_FIRST))
   6727   1.1  christos 	    /* Use the next slot.  */
   6728   1.1  christos 	    continue;
   6729   1.1  christos 	  else if (curr != first)
   6730   1.1  christos 	    /* can't fit this insn */
   6731   1.1  christos 	    break;
   6732   1.1  christos 
   6733   1.1  christos 	  if (template_val != orig_template)
   6734   1.1  christos 	    /* if we switch the template, we need to reset the NOPs
   6735   1.1  christos 	       after slot i.  The slot-types of the instructions ahead
   6736   1.1  christos 	       of i never change, so we don't need to worry about
   6737   1.1  christos 	       changing NOPs in front of this slot.  */
   6738   1.1  christos 	    for (j = i; j < 3; ++j)
   6739   1.1  christos 	      insn[j] = nop[ia64_templ_desc[template_val].exec_unit[j]];
   6740   1.1  christos 	}
   6741   1.1  christos       required_unit = ia64_templ_desc[template_val].exec_unit[i];
   6742   1.1  christos 
   6743   1.1  christos       /* resolve dynamic opcodes such as "break", "hint", and "nop":  */
   6744   1.1  christos       if (idesc->type == IA64_TYPE_DYN)
   6745   1.1  christos 	{
   6746   1.1  christos 	  enum ia64_opnd opnd1, opnd2;
   6747   1.1  christos 
   6748   1.1  christos 	  if ((strcmp (idesc->name, "nop") == 0)
   6749   1.1  christos 	      || (strcmp (idesc->name, "break") == 0))
   6750   1.1  christos 	    insn_unit = required_unit;
   6751   1.1  christos 	  else if (strcmp (idesc->name, "hint") == 0)
   6752   1.1  christos 	    {
   6753   1.1  christos 	      insn_unit = required_unit;
   6754   1.1  christos 	      if (required_unit == IA64_UNIT_B)
   6755   1.1  christos 		{
   6756   1.1  christos 		  switch (md.hint_b)
   6757   1.1  christos 		    {
   6758   1.1  christos 		    case hint_b_ok:
   6759   1.1  christos 		      break;
   6760   1.1  christos 		    case hint_b_warning:
   6761   1.1  christos 		      as_warn (_("hint in B unit may be treated as nop"));
   6762   1.1  christos 		      break;
   6763   1.1  christos 		    case hint_b_error:
   6764   1.1  christos 		      /* When manual bundling is off and there is no
   6765   1.1  christos 			 user template, we choose a different unit so
   6766   1.1  christos 			 that hint won't go into the current slot. We
   6767   1.1  christos 			 will fill the current bundle with nops and
   6768   1.1  christos 			 try to put hint into the next bundle.  */
   6769   1.1  christos 		      if (!manual_bundling && user_template < 0)
   6770   1.1  christos 			insn_unit = IA64_UNIT_I;
   6771   1.1  christos 		      else
   6772   1.1  christos 			as_bad (_("hint in B unit can't be used"));
   6773   1.1  christos 		      break;
   6774   1.1  christos 		    }
   6775   1.1  christos 		}
   6776   1.1  christos 	    }
   6777   1.1  christos 	  else if (strcmp (idesc->name, "chk.s") == 0
   6778   1.1  christos 	      || strcmp (idesc->name, "mov") == 0)
   6779   1.1  christos 	    {
   6780   1.1  christos 	      insn_unit = IA64_UNIT_M;
   6781   1.1  christos 	      if (required_unit == IA64_UNIT_I
   6782   1.1  christos 		  || (required_unit == IA64_UNIT_F && template_val == 6))
   6783   1.1  christos 		insn_unit = IA64_UNIT_I;
   6784   1.1  christos 	    }
   6785   1.1  christos 	  else
   6786   1.1  christos 	    as_fatal (_("emit_one_bundle: unexpected dynamic op"));
   6787   1.1  christos 
   6788   1.1  christos 	  snprintf (mnemonic, sizeof (mnemonic), "%s.%c",
   6789   1.1  christos 		    idesc->name, "?imbfxx"[insn_unit]);
   6790   1.1  christos 	  opnd1 = idesc->operands[0];
   6791   1.1  christos 	  opnd2 = idesc->operands[1];
   6792   1.1  christos 	  ia64_free_opcode (idesc);
   6793   1.1  christos 	  idesc = ia64_find_opcode (mnemonic);
   6794   1.1  christos 	  /* moves to/from ARs have collisions */
   6795   1.1  christos 	  if (opnd1 == IA64_OPND_AR3 || opnd2 == IA64_OPND_AR3)
   6796   1.1  christos 	    {
   6797   1.1  christos 	      while (idesc != NULL
   6798   1.1  christos 		     && (idesc->operands[0] != opnd1
   6799   1.1  christos 			 || idesc->operands[1] != opnd2))
   6800   1.1  christos 		idesc = get_next_opcode (idesc);
   6801   1.1  christos 	    }
   6802   1.1  christos 	  md.slot[curr].idesc = idesc;
   6803   1.1  christos 	}
   6804   1.1  christos       else
   6805   1.1  christos 	{
   6806   1.1  christos 	  insn_type = idesc->type;
   6807   1.1  christos 	  insn_unit = IA64_UNIT_NIL;
   6808   1.1  christos 	  switch (insn_type)
   6809   1.1  christos 	    {
   6810   1.1  christos 	    case IA64_TYPE_A:
   6811   1.1  christos 	      if (required_unit == IA64_UNIT_I || required_unit == IA64_UNIT_M)
   6812   1.1  christos 		insn_unit = required_unit;
   6813   1.1  christos 	      break;
   6814   1.1  christos 	    case IA64_TYPE_X: insn_unit = IA64_UNIT_L; break;
   6815   1.1  christos 	    case IA64_TYPE_I: insn_unit = IA64_UNIT_I; break;
   6816   1.1  christos 	    case IA64_TYPE_M: insn_unit = IA64_UNIT_M; break;
   6817   1.1  christos 	    case IA64_TYPE_B: insn_unit = IA64_UNIT_B; break;
   6818   1.1  christos 	    case IA64_TYPE_F: insn_unit = IA64_UNIT_F; break;
   6819   1.1  christos 	    default:				       break;
   6820   1.1  christos 	    }
   6821   1.1  christos 	}
   6822   1.1  christos 
   6823   1.1  christos       if (insn_unit != required_unit)
   6824   1.1  christos 	continue;		/* Try next slot.  */
   6825   1.1  christos 
   6826   1.1  christos       /* Now is a good time to fix up the labels for this insn.  */
   6827   1.8  christos       mark_label = false;
   6828   1.1  christos       for (lfix = md.slot[curr].label_fixups; lfix; lfix = lfix->next)
   6829   1.1  christos 	{
   6830   1.1  christos 	  S_SET_VALUE (lfix->sym, frag_now_fix () - 16);
   6831   1.1  christos 	  symbol_set_frag (lfix->sym, frag_now);
   6832   1.1  christos 	  mark_label |= lfix->dw2_mark_labels;
   6833   1.1  christos 	}
   6834   1.1  christos       for (lfix = md.slot[curr].tag_fixups; lfix; lfix = lfix->next)
   6835   1.1  christos 	{
   6836   1.1  christos 	  S_SET_VALUE (lfix->sym, frag_now_fix () - 16 + i);
   6837   1.1  christos 	  symbol_set_frag (lfix->sym, frag_now);
   6838   1.1  christos 	}
   6839   1.1  christos 
   6840   1.1  christos       if (debug_type == DEBUG_DWARF2
   6841   1.1  christos 	  || md.slot[curr].loc_directive_seen
   6842   1.1  christos 	  || mark_label)
   6843   1.1  christos 	{
   6844   1.1  christos 	  bfd_vma addr = frag_now->fr_address + frag_now_fix () - 16 + i;
   6845   1.1  christos 
   6846   1.1  christos 	  md.slot[curr].loc_directive_seen = 0;
   6847   1.1  christos 	  if (mark_label)
   6848   1.1  christos 	    md.slot[curr].debug_line.flags |= DWARF2_FLAG_BASIC_BLOCK;
   6849   1.1  christos 
   6850   1.1  christos 	  dwarf2_gen_line_info (addr, &md.slot[curr].debug_line);
   6851   1.1  christos 	}
   6852   1.1  christos 
   6853   1.1  christos       build_insn (md.slot + curr, insn + i);
   6854   1.1  christos 
   6855   1.1  christos       ptr = md.slot[curr].unwind_record;
   6856   1.1  christos       if (ptr)
   6857   1.1  christos 	{
   6858   1.1  christos 	  /* Set slot numbers for all remaining unwind records belonging to the
   6859   1.1  christos 	     current insn.  There can not be any prologue/body unwind records
   6860   1.1  christos 	     here.  */
   6861   1.1  christos 	  for (; ptr != end_ptr; ptr = ptr->next)
   6862   1.1  christos 	    {
   6863   1.1  christos 	      ptr->slot_number = (unsigned long) f + i;
   6864   1.1  christos 	      ptr->slot_frag = frag_now;
   6865   1.1  christos 	    }
   6866   1.1  christos 	  md.slot[curr].unwind_record = NULL;
   6867   1.1  christos 	}
   6868   1.1  christos 
   6869   1.1  christos       for (j = 0; j < md.slot[curr].num_fixups; ++j)
   6870   1.1  christos 	{
   6871   1.8  christos 	  unsigned long where;
   6872   1.8  christos 
   6873   1.1  christos 	  ifix = md.slot[curr].fixup + j;
   6874   1.8  christos 	  where = frag_now_fix () - 16 + i;
   6875   1.8  christos #ifdef TE_HPUX
   6876   1.8  christos 	  /* Relocations for instructions specify the slot in the
   6877   1.8  christos 	     bottom two bits of r_offset.  The IA64 HP-UX linker
   6878   1.8  christos 	     expects PCREL60B relocations to specify slot 2 of an
   6879   1.8  christos 	     instruction.  gas generates PCREL60B against slot 1.  */
   6880   1.8  christos 	  if (ifix->code == BFD_RELOC_IA64_PCREL60B)
   6881   1.8  christos 	    {
   6882   1.8  christos 	      know (i == 1);
   6883   1.8  christos 	      ++where;
   6884   1.8  christos 	    }
   6885   1.8  christos #endif
   6886   1.8  christos 
   6887   1.8  christos 	  fix = fix_new_exp (frag_now, where, 8,
   6888   1.1  christos 			     &ifix->expr, ifix->is_pcrel, ifix->code);
   6889   1.1  christos 	  fix->tc_fix_data.opnd = ifix->opnd;
   6890   1.1  christos 	  fix->fx_file = md.slot[curr].src_file;
   6891   1.1  christos 	  fix->fx_line = md.slot[curr].src_line;
   6892   1.1  christos 	}
   6893   1.1  christos 
   6894   1.1  christos       end_of_insn_group = md.slot[curr].end_of_insn_group;
   6895   1.1  christos 
   6896   1.3  christos       /* This adjustment to "i" must occur after the fix, otherwise the fix
   6897   1.3  christos 	 is assigned to the wrong slot, and the VMS linker complains.  */
   6898   1.3  christos       if (required_unit == IA64_UNIT_L)
   6899   1.3  christos 	{
   6900   1.3  christos 	  know (i == 1);
   6901   1.3  christos 	  /* skip one slot for long/X-unit instructions */
   6902   1.3  christos 	  ++i;
   6903   1.3  christos 	}
   6904   1.3  christos       --md.num_slots_in_use;
   6905   1.3  christos       last_slot = i;
   6906   1.3  christos 
   6907   1.1  christos       /* clear slot:  */
   6908   1.1  christos       ia64_free_opcode (md.slot[curr].idesc);
   6909   1.1  christos       memset (md.slot + curr, 0, sizeof (md.slot[curr]));
   6910   1.1  christos       md.slot[curr].user_template = -1;
   6911   1.1  christos 
   6912   1.1  christos       if (manual_bundling_off)
   6913   1.1  christos 	{
   6914   1.1  christos 	  manual_bundling = 0;
   6915   1.1  christos 	  break;
   6916   1.1  christos 	}
   6917   1.1  christos       curr = (curr + 1) % NUM_SLOTS;
   6918   1.1  christos       idesc = md.slot[curr].idesc;
   6919   1.1  christos     }
   6920   1.1  christos 
   6921   1.1  christos   /* A user template was specified, but the first following instruction did
   6922   1.1  christos      not fit.  This can happen with or without manual bundling.  */
   6923   1.1  christos   if (md.num_slots_in_use > 0 && last_slot < 0)
   6924   1.1  christos     {
   6925   1.1  christos       as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
   6926   1.1  christos 		    _("`%s' does not fit into %s template"),
   6927   1.1  christos 		    idesc->name, ia64_templ_desc[template_val].name);
   6928   1.1  christos       /* Drop first insn so we don't livelock.  */
   6929   1.1  christos       --md.num_slots_in_use;
   6930   1.1  christos       know (curr == first);
   6931   1.1  christos       ia64_free_opcode (md.slot[curr].idesc);
   6932   1.1  christos       memset (md.slot + curr, 0, sizeof (md.slot[curr]));
   6933   1.1  christos       md.slot[curr].user_template = -1;
   6934   1.1  christos     }
   6935   1.1  christos   else if (manual_bundling > 0)
   6936   1.1  christos     {
   6937   1.1  christos       if (md.num_slots_in_use > 0)
   6938   1.1  christos 	{
   6939   1.1  christos 	  if (last_slot >= 2)
   6940   1.1  christos 	    as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
   6941   1.1  christos 			  _("`%s' does not fit into bundle"), idesc->name);
   6942   1.1  christos 	  else
   6943   1.1  christos 	    {
   6944   1.1  christos 	      const char *where;
   6945   1.1  christos 
   6946   1.1  christos 	      if (template_val == 2)
   6947   1.1  christos 		where = "X slot";
   6948   1.1  christos 	      else if (last_slot == 0)
   6949   1.1  christos 		where = "slots 2 or 3";
   6950   1.1  christos 	      else
   6951   1.1  christos 		where = "slot 3";
   6952   1.1  christos 	      as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
   6953   1.1  christos 			    _("`%s' can't go in %s of %s template"),
   6954   1.1  christos 			    idesc->name, where, ia64_templ_desc[template_val].name);
   6955   1.1  christos 	    }
   6956   1.1  christos 	}
   6957   1.1  christos       else
   6958   1.1  christos 	as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
   6959   1.1  christos 		      _("Missing '}' at end of file"));
   6960   1.1  christos     }
   6961   1.3  christos 
   6962   1.1  christos   know (md.num_slots_in_use < NUM_SLOTS);
   6963   1.1  christos 
   6964   1.1  christos   t0 = end_of_insn_group | (template_val << 1) | (insn[0] << 5) | (insn[1] << 46);
   6965   1.1  christos   t1 = ((insn[1] >> 18) & 0x7fffff) | (insn[2] << 23);
   6966   1.1  christos 
   6967   1.1  christos   number_to_chars_littleendian (f + 0, t0, 8);
   6968   1.1  christos   number_to_chars_littleendian (f + 8, t1, 8);
   6969   1.1  christos }
   6970   1.1  christos 
   6971   1.1  christos int
   6972   1.5  christos md_parse_option (int c, const char *arg)
   6973   1.1  christos {
   6974   1.1  christos 
   6975   1.1  christos   switch (c)
   6976   1.1  christos     {
   6977   1.1  christos     /* Switches from the Intel assembler.  */
   6978   1.1  christos     case 'm':
   6979   1.1  christos       if (strcmp (arg, "ilp64") == 0
   6980   1.1  christos 	  || strcmp (arg, "lp64") == 0
   6981   1.1  christos 	  || strcmp (arg, "p64") == 0)
   6982   1.1  christos 	{
   6983   1.1  christos 	  md.flags |= EF_IA_64_ABI64;
   6984   1.1  christos 	}
   6985   1.1  christos       else if (strcmp (arg, "ilp32") == 0)
   6986   1.1  christos 	{
   6987   1.1  christos 	  md.flags &= ~EF_IA_64_ABI64;
   6988   1.1  christos 	}
   6989   1.1  christos       else if (strcmp (arg, "le") == 0)
   6990   1.1  christos 	{
   6991   1.1  christos 	  md.flags &= ~EF_IA_64_BE;
   6992   1.1  christos 	  default_big_endian = 0;
   6993   1.1  christos 	}
   6994   1.1  christos       else if (strcmp (arg, "be") == 0)
   6995   1.1  christos 	{
   6996   1.1  christos 	  md.flags |= EF_IA_64_BE;
   6997   1.1  christos 	  default_big_endian = 1;
   6998   1.1  christos 	}
   6999   1.8  christos       else if (startswith (arg, "unwind-check="))
   7000   1.1  christos 	{
   7001   1.1  christos 	  arg += 13;
   7002   1.1  christos 	  if (strcmp (arg, "warning") == 0)
   7003   1.1  christos 	    md.unwind_check = unwind_check_warning;
   7004   1.1  christos 	  else if (strcmp (arg, "error") == 0)
   7005   1.1  christos 	    md.unwind_check = unwind_check_error;
   7006   1.1  christos 	  else
   7007   1.1  christos 	    return 0;
   7008   1.1  christos 	}
   7009   1.8  christos       else if (startswith (arg, "hint.b="))
   7010   1.1  christos 	{
   7011   1.1  christos 	  arg += 7;
   7012   1.1  christos 	  if (strcmp (arg, "ok") == 0)
   7013   1.1  christos 	    md.hint_b = hint_b_ok;
   7014   1.1  christos 	  else if (strcmp (arg, "warning") == 0)
   7015   1.1  christos 	    md.hint_b = hint_b_warning;
   7016   1.1  christos 	  else if (strcmp (arg, "error") == 0)
   7017   1.1  christos 	    md.hint_b = hint_b_error;
   7018   1.1  christos 	  else
   7019   1.1  christos 	    return 0;
   7020   1.1  christos 	}
   7021   1.8  christos       else if (startswith (arg, "tune="))
   7022   1.1  christos 	{
   7023   1.1  christos 	  arg += 5;
   7024   1.1  christos 	  if (strcmp (arg, "itanium1") == 0)
   7025   1.1  christos 	    md.tune = itanium1;
   7026   1.1  christos 	  else if (strcmp (arg, "itanium2") == 0)
   7027   1.1  christos 	    md.tune = itanium2;
   7028   1.1  christos 	  else
   7029   1.1  christos 	    return 0;
   7030   1.1  christos 	}
   7031   1.1  christos       else
   7032   1.1  christos 	return 0;
   7033   1.1  christos       break;
   7034   1.1  christos 
   7035   1.1  christos     case 'N':
   7036   1.1  christos       if (strcmp (arg, "so") == 0)
   7037   1.1  christos 	{
   7038   1.1  christos 	  /* Suppress signon message.  */
   7039   1.1  christos 	}
   7040   1.1  christos       else if (strcmp (arg, "pi") == 0)
   7041   1.1  christos 	{
   7042   1.1  christos 	  /* Reject privileged instructions.  FIXME */
   7043   1.1  christos 	}
   7044   1.1  christos       else if (strcmp (arg, "us") == 0)
   7045   1.1  christos 	{
   7046   1.1  christos 	  /* Allow union of signed and unsigned range.  FIXME */
   7047   1.1  christos 	}
   7048   1.1  christos       else if (strcmp (arg, "close_fcalls") == 0)
   7049   1.1  christos 	{
   7050   1.1  christos 	  /* Do not resolve global function calls.  */
   7051   1.1  christos 	}
   7052   1.1  christos       else
   7053   1.1  christos 	return 0;
   7054   1.1  christos       break;
   7055   1.1  christos 
   7056   1.1  christos     case 'C':
   7057   1.1  christos       /* temp[="prefix"]  Insert temporary labels into the object file
   7058   1.1  christos 			  symbol table prefixed by "prefix".
   7059   1.1  christos 			  Default prefix is ":temp:".
   7060   1.1  christos        */
   7061   1.1  christos       break;
   7062   1.1  christos 
   7063   1.1  christos     case 'a':
   7064   1.1  christos       /* indirect=<tgt>	Assume unannotated indirect branches behavior
   7065   1.1  christos 			according to <tgt> --
   7066   1.1  christos 			exit:	branch out from the current context (default)
   7067   1.1  christos 			labels:	all labels in context may be branch targets
   7068   1.1  christos        */
   7069   1.8  christos       if (!startswith (arg, "indirect="))
   7070   1.1  christos         return 0;
   7071   1.1  christos       break;
   7072   1.1  christos 
   7073   1.1  christos     case 'x':
   7074   1.1  christos       /* -X conflicts with an ignored option, use -x instead */
   7075   1.1  christos       md.detect_dv = 1;
   7076   1.1  christos       if (!arg || strcmp (arg, "explicit") == 0)
   7077   1.1  christos 	{
   7078   1.1  christos 	  /* set default mode to explicit */
   7079   1.1  christos 	  md.default_explicit_mode = 1;
   7080   1.1  christos 	  break;
   7081   1.1  christos 	}
   7082   1.1  christos       else if (strcmp (arg, "auto") == 0)
   7083   1.1  christos 	{
   7084   1.1  christos 	  md.default_explicit_mode = 0;
   7085   1.1  christos 	}
   7086   1.1  christos       else if (strcmp (arg, "none") == 0)
   7087   1.1  christos 	{
   7088   1.1  christos 	  md.detect_dv = 0;
   7089   1.1  christos 	}
   7090   1.1  christos       else if (strcmp (arg, "debug") == 0)
   7091   1.1  christos 	{
   7092   1.1  christos 	  md.debug_dv = 1;
   7093   1.1  christos 	}
   7094   1.1  christos       else if (strcmp (arg, "debugx") == 0)
   7095   1.1  christos 	{
   7096   1.1  christos 	  md.default_explicit_mode = 1;
   7097   1.1  christos 	  md.debug_dv = 1;
   7098   1.1  christos 	}
   7099   1.1  christos       else if (strcmp (arg, "debugn") == 0)
   7100   1.1  christos 	{
   7101   1.1  christos 	  md.debug_dv = 1;
   7102   1.1  christos 	  md.detect_dv = 0;
   7103   1.1  christos 	}
   7104   1.1  christos       else
   7105   1.1  christos 	{
   7106   1.1  christos 	  as_bad (_("Unrecognized option '-x%s'"), arg);
   7107   1.1  christos 	}
   7108   1.1  christos       break;
   7109   1.1  christos 
   7110   1.1  christos     case 'S':
   7111   1.1  christos       /* nops		Print nops statistics.  */
   7112   1.1  christos       break;
   7113   1.1  christos 
   7114   1.1  christos     /* GNU specific switches for gcc.  */
   7115   1.1  christos     case OPTION_MCONSTANT_GP:
   7116   1.1  christos       md.flags |= EF_IA_64_CONS_GP;
   7117   1.1  christos       break;
   7118   1.1  christos 
   7119   1.1  christos     case OPTION_MAUTO_PIC:
   7120   1.1  christos       md.flags |= EF_IA_64_NOFUNCDESC_CONS_GP;
   7121   1.1  christos       break;
   7122   1.1  christos 
   7123   1.1  christos     default:
   7124   1.1  christos       return 0;
   7125   1.1  christos     }
   7126   1.1  christos 
   7127   1.1  christos   return 1;
   7128   1.1  christos }
   7129   1.1  christos 
   7130   1.1  christos void
   7131   1.1  christos md_show_usage (FILE *stream)
   7132   1.1  christos {
   7133   1.1  christos   fputs (_("\
   7134   1.1  christos IA-64 options:\n\
   7135   1.1  christos   --mconstant-gp	  mark output file as using the constant-GP model\n\
   7136   1.1  christos 			  (sets ELF header flag EF_IA_64_CONS_GP)\n\
   7137   1.1  christos   --mauto-pic		  mark output file as using the constant-GP model\n\
   7138   1.1  christos 			  without function descriptors (sets ELF header flag\n\
   7139   1.1  christos 			  EF_IA_64_NOFUNCDESC_CONS_GP)\n\
   7140   1.1  christos   -milp32|-milp64|-mlp64|-mp64	select data model (default -mlp64)\n\
   7141   1.1  christos   -mle | -mbe		  select little- or big-endian byte order (default -mle)\n\
   7142   1.1  christos   -mtune=[itanium1|itanium2]\n\
   7143   1.1  christos 			  tune for a specific CPU (default -mtune=itanium2)\n\
   7144   1.1  christos   -munwind-check=[warning|error]\n\
   7145   1.1  christos 			  unwind directive check (default -munwind-check=warning)\n\
   7146   1.1  christos   -mhint.b=[ok|warning|error]\n\
   7147   1.1  christos 			  hint.b check (default -mhint.b=error)\n\
   7148   1.1  christos   -x | -xexplicit	  turn on dependency violation checking\n"), stream);
   7149   1.1  christos   /* Note for translators: "automagically" can be translated as "automatically" here.  */
   7150   1.1  christos   fputs (_("\
   7151   1.1  christos   -xauto		  automagically remove dependency violations (default)\n\
   7152   1.1  christos   -xnone		  turn off dependency violation checking\n\
   7153   1.1  christos   -xdebug		  debug dependency violation checker\n\
   7154   1.1  christos   -xdebugn		  debug dependency violation checker but turn off\n\
   7155   1.1  christos 			  dependency violation checking\n\
   7156   1.1  christos   -xdebugx		  debug dependency violation checker and turn on\n\
   7157   1.1  christos 			  dependency violation checking\n"),
   7158   1.1  christos 	stream);
   7159   1.1  christos }
   7160   1.1  christos 
   7161   1.1  christos void
   7162   1.1  christos ia64_after_parse_args (void)
   7163   1.1  christos {
   7164   1.1  christos   if (debug_type == DEBUG_STABS)
   7165   1.1  christos     as_fatal (_("--gstabs is not supported for ia64"));
   7166   1.1  christos }
   7167   1.1  christos 
   7168   1.1  christos /* Return true if TYPE fits in TEMPL at SLOT.  */
   7169   1.1  christos 
   7170   1.1  christos static int
   7171   1.1  christos match (int templ, int type, int slot)
   7172   1.1  christos {
   7173   1.1  christos   enum ia64_unit unit;
   7174   1.1  christos   int result;
   7175   1.1  christos 
   7176   1.1  christos   unit = ia64_templ_desc[templ].exec_unit[slot];
   7177   1.1  christos   switch (type)
   7178   1.1  christos     {
   7179   1.1  christos     case IA64_TYPE_DYN: result = 1; break; /* for nop and break */
   7180   1.1  christos     case IA64_TYPE_A:
   7181   1.1  christos       result = (unit == IA64_UNIT_I || unit == IA64_UNIT_M);
   7182   1.1  christos       break;
   7183   1.1  christos     case IA64_TYPE_X:	result = (unit == IA64_UNIT_L); break;
   7184   1.1  christos     case IA64_TYPE_I:	result = (unit == IA64_UNIT_I); break;
   7185   1.1  christos     case IA64_TYPE_M:	result = (unit == IA64_UNIT_M); break;
   7186   1.1  christos     case IA64_TYPE_B:	result = (unit == IA64_UNIT_B); break;
   7187   1.1  christos     case IA64_TYPE_F:	result = (unit == IA64_UNIT_F); break;
   7188   1.1  christos     default:		result = 0; break;
   7189   1.1  christos     }
   7190   1.1  christos   return result;
   7191   1.1  christos }
   7192   1.1  christos 
   7193   1.1  christos /* For Itanium 1, add a bit of extra goodness if a nop of type F or B would fit
   7194   1.1  christos    in TEMPL at SLOT.  For Itanium 2, add a bit of extra goodness if a nop of
   7195   1.1  christos    type M or I would fit in TEMPL at SLOT.  */
   7196   1.1  christos 
   7197   1.1  christos static inline int
   7198   1.1  christos extra_goodness (int templ, int slot)
   7199   1.1  christos {
   7200   1.1  christos   switch (md.tune)
   7201   1.1  christos     {
   7202   1.1  christos     case itanium1:
   7203   1.1  christos       if (slot == 1 && match (templ, IA64_TYPE_F, slot))
   7204   1.1  christos 	return 2;
   7205   1.1  christos       else if (slot == 2 && match (templ, IA64_TYPE_B, slot))
   7206   1.1  christos 	return 1;
   7207   1.1  christos       else
   7208   1.1  christos 	return 0;
   7209   1.1  christos       break;
   7210   1.1  christos     case itanium2:
   7211   1.1  christos       if (match (templ, IA64_TYPE_M, slot)
   7212   1.1  christos 	  || match (templ, IA64_TYPE_I, slot))
   7213   1.1  christos 	/* Favor M- and I-unit NOPs.  We definitely want to avoid
   7214   1.1  christos 	   F-unit and B-unit may cause split-issue or less-than-optimal
   7215   1.1  christos 	   branch-prediction.  */
   7216   1.1  christos 	return 2;
   7217   1.1  christos       else
   7218   1.1  christos 	return 0;
   7219   1.1  christos       break;
   7220   1.1  christos     default:
   7221   1.1  christos       abort ();
   7222   1.1  christos       return 0;
   7223   1.1  christos     }
   7224   1.1  christos }
   7225   1.1  christos 
   7226   1.1  christos /* This function is called once, at assembler startup time.  It sets
   7227   1.1  christos    up all the tables, etc. that the MD part of the assembler will need
   7228   1.1  christos    that can be determined before arguments are parsed.  */
   7229   1.1  christos void
   7230   1.1  christos md_begin (void)
   7231   1.1  christos {
   7232   1.1  christos   int i, j, k, t, goodness, best, ok;
   7233   1.1  christos 
   7234   1.1  christos   md.auto_align = 1;
   7235   1.1  christos   md.explicit_mode = md.default_explicit_mode;
   7236   1.1  christos 
   7237   1.7  christos   bfd_set_section_alignment (text_section, 4);
   7238   1.1  christos 
   7239   1.1  christos   /* Make sure function pointers get initialized.  */
   7240   1.1  christos   target_big_endian = -1;
   7241   1.1  christos   dot_byteorder (default_big_endian);
   7242   1.1  christos 
   7243   1.8  christos   alias_hash = str_htab_create ();
   7244   1.8  christos   alias_name_hash = str_htab_create ();
   7245   1.8  christos   secalias_hash = str_htab_create ();
   7246   1.8  christos   secalias_name_hash = str_htab_create ();
   7247   1.1  christos 
   7248   1.1  christos   pseudo_func[FUNC_DTP_MODULE].u.sym =
   7249   1.8  christos     symbol_new (".<dtpmod>", undefined_section,
   7250   1.8  christos 		&zero_address_frag, FUNC_DTP_MODULE);
   7251   1.1  christos 
   7252   1.1  christos   pseudo_func[FUNC_DTP_RELATIVE].u.sym =
   7253   1.8  christos     symbol_new (".<dtprel>", undefined_section,
   7254   1.8  christos 		&zero_address_frag, FUNC_DTP_RELATIVE);
   7255   1.1  christos 
   7256   1.1  christos   pseudo_func[FUNC_FPTR_RELATIVE].u.sym =
   7257   1.8  christos     symbol_new (".<fptr>", undefined_section,
   7258   1.8  christos 		&zero_address_frag, FUNC_FPTR_RELATIVE);
   7259   1.1  christos 
   7260   1.1  christos   pseudo_func[FUNC_GP_RELATIVE].u.sym =
   7261   1.8  christos     symbol_new (".<gprel>", undefined_section,
   7262   1.8  christos 		&zero_address_frag, FUNC_GP_RELATIVE);
   7263   1.1  christos 
   7264   1.1  christos   pseudo_func[FUNC_LT_RELATIVE].u.sym =
   7265   1.8  christos     symbol_new (".<ltoff>", undefined_section,
   7266   1.8  christos 		&zero_address_frag, FUNC_LT_RELATIVE);
   7267   1.1  christos 
   7268   1.1  christos   pseudo_func[FUNC_LT_RELATIVE_X].u.sym =
   7269   1.8  christos     symbol_new (".<ltoffx>", undefined_section,
   7270   1.8  christos 		&zero_address_frag, FUNC_LT_RELATIVE_X);
   7271   1.1  christos 
   7272   1.1  christos   pseudo_func[FUNC_PC_RELATIVE].u.sym =
   7273   1.8  christos     symbol_new (".<pcrel>", undefined_section,
   7274   1.8  christos 		&zero_address_frag, FUNC_PC_RELATIVE);
   7275   1.1  christos 
   7276   1.1  christos   pseudo_func[FUNC_PLT_RELATIVE].u.sym =
   7277   1.8  christos     symbol_new (".<pltoff>", undefined_section,
   7278   1.8  christos 		&zero_address_frag, FUNC_PLT_RELATIVE);
   7279   1.1  christos 
   7280   1.1  christos   pseudo_func[FUNC_SEC_RELATIVE].u.sym =
   7281   1.8  christos     symbol_new (".<secrel>", undefined_section,
   7282   1.8  christos 		&zero_address_frag, FUNC_SEC_RELATIVE);
   7283   1.1  christos 
   7284   1.1  christos   pseudo_func[FUNC_SEG_RELATIVE].u.sym =
   7285   1.8  christos     symbol_new (".<segrel>", undefined_section,
   7286   1.8  christos 		&zero_address_frag, FUNC_SEG_RELATIVE);
   7287   1.1  christos 
   7288   1.1  christos   pseudo_func[FUNC_TP_RELATIVE].u.sym =
   7289   1.8  christos     symbol_new (".<tprel>", undefined_section,
   7290   1.8  christos 		&zero_address_frag, FUNC_TP_RELATIVE);
   7291   1.1  christos 
   7292   1.1  christos   pseudo_func[FUNC_LTV_RELATIVE].u.sym =
   7293   1.8  christos     symbol_new (".<ltv>", undefined_section,
   7294   1.8  christos 		&zero_address_frag, FUNC_LTV_RELATIVE);
   7295   1.1  christos 
   7296   1.1  christos   pseudo_func[FUNC_LT_FPTR_RELATIVE].u.sym =
   7297   1.8  christos     symbol_new (".<ltoff.fptr>", undefined_section,
   7298   1.8  christos 		&zero_address_frag, FUNC_LT_FPTR_RELATIVE);
   7299   1.1  christos 
   7300   1.1  christos   pseudo_func[FUNC_LT_DTP_MODULE].u.sym =
   7301   1.8  christos     symbol_new (".<ltoff.dtpmod>", undefined_section,
   7302   1.8  christos 		&zero_address_frag, FUNC_LT_DTP_MODULE);
   7303   1.1  christos 
   7304   1.1  christos   pseudo_func[FUNC_LT_DTP_RELATIVE].u.sym =
   7305   1.8  christos     symbol_new (".<ltoff.dptrel>", undefined_section,
   7306   1.8  christos 		&zero_address_frag, FUNC_LT_DTP_RELATIVE);
   7307   1.1  christos 
   7308   1.1  christos   pseudo_func[FUNC_LT_TP_RELATIVE].u.sym =
   7309   1.8  christos     symbol_new (".<ltoff.tprel>", undefined_section,
   7310   1.8  christos 		&zero_address_frag, FUNC_LT_TP_RELATIVE);
   7311   1.1  christos 
   7312   1.1  christos   pseudo_func[FUNC_IPLT_RELOC].u.sym =
   7313   1.8  christos     symbol_new (".<iplt>", undefined_section,
   7314   1.8  christos 		&zero_address_frag, FUNC_IPLT_RELOC);
   7315   1.1  christos 
   7316   1.1  christos #ifdef TE_VMS
   7317   1.1  christos   pseudo_func[FUNC_SLOTCOUNT_RELOC].u.sym =
   7318   1.8  christos     symbol_new (".<slotcount>", undefined_section,
   7319   1.8  christos 		&zero_address_frag, FUNC_SLOTCOUNT_RELOC);
   7320   1.1  christos #endif
   7321   1.1  christos 
   7322   1.1  christos  if (md.tune != itanium1)
   7323   1.1  christos    {
   7324   1.1  christos      /* Convert MFI NOPs bundles into MMI NOPs bundles.  */
   7325   1.1  christos      le_nop[0] = 0x8;
   7326   1.1  christos      le_nop_stop[0] = 0x9;
   7327   1.1  christos    }
   7328   1.1  christos 
   7329   1.1  christos   /* Compute the table of best templates.  We compute goodness as a
   7330   1.1  christos      base 4 value, in which each match counts for 3.  Match-failures
   7331   1.1  christos      result in NOPs and we use extra_goodness() to pick the execution
   7332   1.1  christos      units that are best suited for issuing the NOP.  */
   7333   1.1  christos   for (i = 0; i < IA64_NUM_TYPES; ++i)
   7334   1.1  christos     for (j = 0; j < IA64_NUM_TYPES; ++j)
   7335   1.1  christos       for (k = 0; k < IA64_NUM_TYPES; ++k)
   7336   1.1  christos 	{
   7337   1.1  christos 	  best = 0;
   7338   1.1  christos 	  for (t = 0; t < NELEMS (ia64_templ_desc); ++t)
   7339   1.1  christos 	    {
   7340   1.1  christos 	      goodness = 0;
   7341   1.1  christos 	      if (match (t, i, 0))
   7342   1.1  christos 		{
   7343   1.1  christos 		  if (match (t, j, 1))
   7344   1.1  christos 		    {
   7345   1.1  christos 		      if ((t == 2 && j == IA64_TYPE_X) || match (t, k, 2))
   7346   1.1  christos 			goodness = 3 + 3 + 3;
   7347   1.1  christos 		      else
   7348   1.1  christos 			goodness = 3 + 3 + extra_goodness (t, 2);
   7349   1.1  christos 		    }
   7350   1.1  christos 		  else if (match (t, j, 2))
   7351   1.1  christos 		    goodness = 3 + 3 + extra_goodness (t, 1);
   7352   1.1  christos 		  else
   7353   1.1  christos 		    {
   7354   1.1  christos 		      goodness = 3;
   7355   1.1  christos 		      goodness += extra_goodness (t, 1);
   7356   1.1  christos 		      goodness += extra_goodness (t, 2);
   7357   1.1  christos 		    }
   7358   1.1  christos 		}
   7359   1.1  christos 	      else if (match (t, i, 1))
   7360   1.1  christos 		{
   7361   1.1  christos 		  if ((t == 2 && i == IA64_TYPE_X) || match (t, j, 2))
   7362   1.1  christos 		    goodness = 3 + 3;
   7363   1.1  christos 		  else
   7364   1.1  christos 		    goodness = 3 + extra_goodness (t, 2);
   7365   1.1  christos 		}
   7366   1.1  christos 	      else if (match (t, i, 2))
   7367   1.1  christos 		goodness = 3 + extra_goodness (t, 1);
   7368   1.1  christos 
   7369   1.1  christos 	      if (goodness > best)
   7370   1.1  christos 		{
   7371   1.1  christos 		  best = goodness;
   7372   1.1  christos 		  best_template[i][j][k] = t;
   7373   1.1  christos 		}
   7374   1.1  christos 	    }
   7375   1.1  christos 	}
   7376   1.1  christos 
   7377   1.1  christos #ifdef DEBUG_TEMPLATES
   7378   1.1  christos   /* For debugging changes to the best_template calculations.  We don't care
   7379   1.1  christos      about combinations with invalid instructions, so start the loops at 1.  */
   7380   1.1  christos   for (i = 0; i < IA64_NUM_TYPES; ++i)
   7381   1.1  christos     for (j = 0; j < IA64_NUM_TYPES; ++j)
   7382   1.1  christos       for (k = 0; k < IA64_NUM_TYPES; ++k)
   7383   1.1  christos 	{
   7384   1.1  christos 	  char type_letter[IA64_NUM_TYPES] = { 'n', 'a', 'i', 'm', 'b', 'f',
   7385   1.1  christos 					       'x', 'd' };
   7386   1.1  christos 	  fprintf (stderr, "%c%c%c %s\n", type_letter[i], type_letter[j],
   7387   1.1  christos 		   type_letter[k],
   7388   1.1  christos 		   ia64_templ_desc[best_template[i][j][k]].name);
   7389   1.1  christos 	}
   7390   1.1  christos #endif
   7391   1.1  christos 
   7392   1.1  christos   for (i = 0; i < NUM_SLOTS; ++i)
   7393   1.1  christos     md.slot[i].user_template = -1;
   7394   1.1  christos 
   7395   1.8  christos   md.pseudo_hash = str_htab_create ();
   7396   1.1  christos   for (i = 0; i < NELEMS (pseudo_opcode); ++i)
   7397   1.8  christos     if (str_hash_insert (md.pseudo_hash, pseudo_opcode[i].name,
   7398   1.8  christos 			 pseudo_opcode + i, 0) != NULL)
   7399   1.8  christos       as_fatal (_("duplicate %s"), pseudo_opcode[i].name);
   7400   1.8  christos 
   7401   1.8  christos   md.reg_hash = str_htab_create ();
   7402   1.8  christos   md.dynreg_hash = str_htab_create ();
   7403   1.8  christos   md.const_hash = str_htab_create ();
   7404   1.8  christos   md.entry_hash = str_htab_create ();
   7405   1.1  christos 
   7406   1.1  christos   /* general registers:  */
   7407   1.1  christos   declare_register_set ("r", 128, REG_GR);
   7408   1.1  christos   declare_register ("gp", REG_GR +  1);
   7409   1.1  christos   declare_register ("sp", REG_GR + 12);
   7410   1.1  christos   declare_register ("tp", REG_GR + 13);
   7411   1.1  christos   declare_register_set ("ret", 4, REG_GR + 8);
   7412   1.1  christos 
   7413   1.1  christos   /* floating point registers:  */
   7414   1.1  christos   declare_register_set ("f", 128, REG_FR);
   7415   1.1  christos   declare_register_set ("farg", 8, REG_FR + 8);
   7416   1.1  christos   declare_register_set ("fret", 8, REG_FR + 8);
   7417   1.1  christos 
   7418   1.1  christos   /* branch registers:  */
   7419   1.1  christos   declare_register_set ("b", 8, REG_BR);
   7420   1.1  christos   declare_register ("rp", REG_BR + 0);
   7421   1.1  christos 
   7422   1.1  christos   /* predicate registers:  */
   7423   1.1  christos   declare_register_set ("p", 64, REG_P);
   7424   1.1  christos   declare_register ("pr", REG_PR);
   7425   1.1  christos   declare_register ("pr.rot", REG_PR_ROT);
   7426   1.1  christos 
   7427   1.1  christos   /* application registers:  */
   7428   1.1  christos   declare_register_set ("ar", 128, REG_AR);
   7429   1.1  christos   for (i = 0; i < NELEMS (ar); ++i)
   7430   1.1  christos     declare_register (ar[i].name, REG_AR + ar[i].regnum);
   7431   1.1  christos 
   7432   1.1  christos   /* control registers:  */
   7433   1.1  christos   declare_register_set ("cr", 128, REG_CR);
   7434   1.1  christos   for (i = 0; i < NELEMS (cr); ++i)
   7435   1.1  christos     declare_register (cr[i].name, REG_CR + cr[i].regnum);
   7436   1.1  christos 
   7437   1.1  christos   /* dahr registers:  */
   7438   1.1  christos   declare_register_set ("dahr", 8, REG_DAHR);
   7439   1.1  christos 
   7440   1.1  christos   declare_register ("ip", REG_IP);
   7441   1.1  christos   declare_register ("cfm", REG_CFM);
   7442   1.1  christos   declare_register ("psr", REG_PSR);
   7443   1.1  christos   declare_register ("psr.l", REG_PSR_L);
   7444   1.1  christos   declare_register ("psr.um", REG_PSR_UM);
   7445   1.1  christos 
   7446   1.1  christos   for (i = 0; i < NELEMS (indirect_reg); ++i)
   7447   1.1  christos     {
   7448   1.1  christos       unsigned int regnum = indirect_reg[i].regnum;
   7449   1.1  christos 
   7450   1.1  christos       md.indregsym[regnum - IND_CPUID] = declare_register (indirect_reg[i].name, regnum);
   7451   1.1  christos     }
   7452   1.1  christos 
   7453   1.1  christos   /* pseudo-registers used to specify unwind info:  */
   7454   1.1  christos   declare_register ("psp", REG_PSP);
   7455   1.1  christos 
   7456   1.1  christos   for (i = 0; i < NELEMS (const_bits); ++i)
   7457   1.8  christos     if (str_hash_insert (md.const_hash, const_bits[i].name, const_bits + i, 0))
   7458   1.8  christos       as_fatal (_("duplicate %s"), const_bits[i].name);
   7459   1.1  christos 
   7460   1.1  christos   /* Set the architecture and machine depending on defaults and command line
   7461   1.1  christos      options.  */
   7462   1.1  christos   if (md.flags & EF_IA_64_ABI64)
   7463   1.1  christos     ok = bfd_set_arch_mach (stdoutput, bfd_arch_ia64, bfd_mach_ia64_elf64);
   7464   1.1  christos   else
   7465   1.1  christos     ok = bfd_set_arch_mach (stdoutput, bfd_arch_ia64, bfd_mach_ia64_elf32);
   7466   1.1  christos 
   7467   1.1  christos   if (! ok)
   7468   1.1  christos      as_warn (_("Could not set architecture and machine"));
   7469   1.1  christos 
   7470   1.1  christos   /* Set the pointer size and pointer shift size depending on md.flags */
   7471   1.1  christos 
   7472   1.1  christos   if (md.flags & EF_IA_64_ABI64)
   7473   1.1  christos     {
   7474   1.1  christos       md.pointer_size = 8;         /* pointers are 8 bytes */
   7475   1.1  christos       md.pointer_size_shift = 3;   /* alignment is 8 bytes = 2^2 */
   7476   1.1  christos     }
   7477   1.1  christos   else
   7478   1.1  christos     {
   7479   1.1  christos       md.pointer_size = 4;         /* pointers are 4 bytes */
   7480   1.1  christos       md.pointer_size_shift = 2;   /* alignment is 4 bytes = 2^2 */
   7481   1.1  christos     }
   7482   1.1  christos 
   7483   1.1  christos   md.mem_offset.hint = 0;
   7484   1.1  christos   md.path = 0;
   7485   1.1  christos   md.maxpaths = 0;
   7486   1.1  christos   md.entry_labels = NULL;
   7487   1.1  christos }
   7488   1.1  christos 
   7489   1.1  christos /* Set the default options in md.  Cannot do this in md_begin because
   7490   1.1  christos    that is called after md_parse_option which is where we set the
   7491   1.1  christos    options in md based on command line options.  */
   7492   1.1  christos 
   7493   1.1  christos void
   7494   1.1  christos ia64_init (int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED)
   7495   1.1  christos {
   7496   1.1  christos   md.flags = MD_FLAGS_DEFAULT;
   7497   1.1  christos #ifndef TE_VMS
   7498   1.1  christos   /* Don't turn on dependency checking for VMS, doesn't work.  */
   7499   1.1  christos   md.detect_dv = 1;
   7500   1.1  christos #endif
   7501   1.1  christos   /* FIXME: We should change it to unwind_check_error someday.  */
   7502   1.1  christos   md.unwind_check = unwind_check_warning;
   7503   1.1  christos   md.hint_b = hint_b_error;
   7504   1.1  christos   md.tune = itanium2;
   7505   1.1  christos }
   7506   1.1  christos 
   7507   1.1  christos /* Return a string for the target object file format.  */
   7508   1.1  christos 
   7509   1.1  christos const char *
   7510   1.1  christos ia64_target_format (void)
   7511   1.1  christos {
   7512   1.1  christos   if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
   7513   1.1  christos     {
   7514   1.1  christos       if (md.flags & EF_IA_64_BE)
   7515   1.1  christos 	{
   7516   1.1  christos 	  if (md.flags & EF_IA_64_ABI64)
   7517   1.1  christos #if defined(TE_AIX50)
   7518   1.1  christos 	    return "elf64-ia64-aix-big";
   7519   1.1  christos #elif defined(TE_HPUX)
   7520   1.1  christos 	    return "elf64-ia64-hpux-big";
   7521   1.1  christos #else
   7522   1.1  christos 	    return "elf64-ia64-big";
   7523   1.1  christos #endif
   7524   1.1  christos 	  else
   7525   1.1  christos #if defined(TE_AIX50)
   7526   1.1  christos 	    return "elf32-ia64-aix-big";
   7527   1.1  christos #elif defined(TE_HPUX)
   7528   1.1  christos 	    return "elf32-ia64-hpux-big";
   7529   1.1  christos #else
   7530   1.1  christos 	    return "elf32-ia64-big";
   7531   1.1  christos #endif
   7532   1.1  christos 	}
   7533   1.1  christos       else
   7534   1.1  christos 	{
   7535   1.1  christos 	  if (md.flags & EF_IA_64_ABI64)
   7536   1.1  christos #if defined (TE_AIX50)
   7537   1.1  christos 	    return "elf64-ia64-aix-little";
   7538   1.1  christos #elif defined (TE_VMS)
   7539   1.1  christos 	  {
   7540   1.1  christos 	    md.flags |= EF_IA_64_ARCHVER_1;
   7541   1.1  christos 	    return "elf64-ia64-vms";
   7542   1.1  christos 	  }
   7543   1.1  christos #else
   7544   1.1  christos 	    return "elf64-ia64-little";
   7545   1.1  christos #endif
   7546   1.1  christos 	  else
   7547   1.1  christos #ifdef TE_AIX50
   7548   1.1  christos 	    return "elf32-ia64-aix-little";
   7549   1.1  christos #else
   7550   1.1  christos 	    return "elf32-ia64-little";
   7551   1.1  christos #endif
   7552   1.1  christos 	}
   7553   1.1  christos     }
   7554   1.1  christos   else
   7555   1.1  christos     return "unknown-format";
   7556   1.1  christos }
   7557   1.1  christos 
   7558   1.1  christos void
   7559   1.9  christos ia64_md_finish (void)
   7560   1.1  christos {
   7561   1.1  christos   /* terminate insn group upon reaching end of file:  */
   7562   1.1  christos   insn_group_break (1, 0, 0);
   7563   1.1  christos 
   7564   1.1  christos   /* emits slots we haven't written yet:  */
   7565   1.1  christos   ia64_flush_insns ();
   7566   1.1  christos 
   7567   1.1  christos   bfd_set_private_flags (stdoutput, md.flags);
   7568   1.1  christos 
   7569   1.1  christos   md.mem_offset.hint = 0;
   7570   1.1  christos }
   7571   1.1  christos 
   7572   1.1  christos void
   7573   1.1  christos ia64_start_line (void)
   7574   1.1  christos {
   7575   1.1  christos   static int first;
   7576   1.1  christos 
   7577   1.1  christos   if (!first) {
   7578   1.1  christos     /* Make sure we don't reference input_line_pointer[-1] when that's
   7579   1.1  christos        not valid.  */
   7580   1.1  christos     first = 1;
   7581   1.1  christos     return;
   7582   1.1  christos   }
   7583   1.1  christos 
   7584   1.1  christos   if (md.qp.X_op == O_register)
   7585   1.1  christos     as_bad (_("qualifying predicate not followed by instruction"));
   7586   1.1  christos   md.qp.X_op = O_absent;
   7587   1.1  christos 
   7588   1.1  christos   if (ignore_input ())
   7589   1.1  christos     return;
   7590   1.1  christos 
   7591   1.1  christos   if (input_line_pointer[0] == ';' && input_line_pointer[-1] == ';')
   7592   1.1  christos     {
   7593   1.1  christos       if (md.detect_dv && !md.explicit_mode)
   7594   1.1  christos 	{
   7595   1.1  christos 	  static int warned;
   7596   1.1  christos 
   7597   1.1  christos 	  if (!warned)
   7598   1.1  christos 	    {
   7599   1.1  christos 	      warned = 1;
   7600   1.1  christos 	      as_warn (_("Explicit stops are ignored in auto mode"));
   7601   1.1  christos 	    }
   7602   1.1  christos 	}
   7603   1.1  christos       else
   7604   1.1  christos 	insn_group_break (1, 0, 0);
   7605   1.1  christos     }
   7606   1.1  christos   else if (input_line_pointer[-1] == '{')
   7607   1.1  christos     {
   7608   1.1  christos       if (md.manual_bundling)
   7609   1.1  christos 	as_warn (_("Found '{' when manual bundling is already turned on"));
   7610   1.1  christos       else
   7611   1.1  christos 	CURR_SLOT.manual_bundling_on = 1;
   7612   1.1  christos       md.manual_bundling = 1;
   7613   1.1  christos 
   7614   1.1  christos       /* Bundling is only acceptable in explicit mode
   7615   1.1  christos 	 or when in default automatic mode.  */
   7616   1.1  christos       if (md.detect_dv && !md.explicit_mode)
   7617   1.1  christos 	{
   7618   1.1  christos 	  if (!md.mode_explicitly_set
   7619   1.1  christos 	      && !md.default_explicit_mode)
   7620   1.1  christos 	    dot_dv_mode ('E');
   7621   1.1  christos 	  else
   7622   1.1  christos 	    as_warn (_("Found '{' after explicit switch to automatic mode"));
   7623   1.1  christos 	}
   7624   1.1  christos     }
   7625   1.1  christos   else if (input_line_pointer[-1] == '}')
   7626   1.1  christos     {
   7627   1.1  christos       if (!md.manual_bundling)
   7628   1.1  christos 	as_warn (_("Found '}' when manual bundling is off"));
   7629   1.1  christos       else
   7630   1.1  christos 	PREV_SLOT.manual_bundling_off = 1;
   7631   1.1  christos       md.manual_bundling = 0;
   7632   1.1  christos 
   7633   1.1  christos       /* switch back to automatic mode, if applicable */
   7634   1.1  christos       if (md.detect_dv
   7635   1.1  christos 	  && md.explicit_mode
   7636   1.1  christos 	  && !md.mode_explicitly_set
   7637   1.1  christos 	  && !md.default_explicit_mode)
   7638   1.1  christos 	dot_dv_mode ('A');
   7639   1.1  christos     }
   7640   1.1  christos }
   7641   1.1  christos 
   7642   1.1  christos /* This is a hook for ia64_frob_label, so that it can distinguish tags from
   7643   1.1  christos    labels.  */
   7644   1.1  christos static int defining_tag = 0;
   7645   1.1  christos 
   7646   1.1  christos int
   7647   1.1  christos ia64_unrecognized_line (int ch)
   7648   1.1  christos {
   7649   1.1  christos   switch (ch)
   7650   1.1  christos     {
   7651   1.1  christos     case '(':
   7652   1.1  christos       expression_and_evaluate (&md.qp);
   7653   1.1  christos       if (*input_line_pointer++ != ')')
   7654   1.1  christos 	{
   7655   1.1  christos 	  as_bad (_("Expected ')'"));
   7656   1.1  christos 	  return 0;
   7657   1.1  christos 	}
   7658   1.1  christos       if (md.qp.X_op != O_register)
   7659   1.1  christos 	{
   7660   1.1  christos 	  as_bad (_("Qualifying predicate expected"));
   7661   1.1  christos 	  return 0;
   7662   1.1  christos 	}
   7663   1.1  christos       if (md.qp.X_add_number < REG_P || md.qp.X_add_number >= REG_P + 64)
   7664   1.1  christos 	{
   7665   1.1  christos 	  as_bad (_("Predicate register expected"));
   7666   1.1  christos 	  return 0;
   7667   1.1  christos 	}
   7668   1.1  christos       return 1;
   7669   1.1  christos 
   7670   1.1  christos     case '[':
   7671   1.1  christos       {
   7672   1.1  christos 	char *s;
   7673   1.1  christos 	char c;
   7674   1.1  christos 	symbolS *tag;
   7675   1.1  christos 	int temp;
   7676   1.1  christos 
   7677   1.1  christos 	if (md.qp.X_op == O_register)
   7678   1.1  christos 	  {
   7679   1.1  christos 	    as_bad (_("Tag must come before qualifying predicate."));
   7680   1.1  christos 	    return 0;
   7681   1.1  christos 	  }
   7682   1.1  christos 
   7683   1.1  christos 	/* This implements just enough of read_a_source_file in read.c to
   7684   1.1  christos 	   recognize labels.  */
   7685   1.1  christos 	if (is_name_beginner (*input_line_pointer))
   7686   1.1  christos 	  {
   7687   1.3  christos 	    c = get_symbol_name (&s);
   7688   1.1  christos 	  }
   7689   1.1  christos 	else if (LOCAL_LABELS_FB
   7690   1.1  christos 		 && ISDIGIT (*input_line_pointer))
   7691   1.1  christos 	  {
   7692   1.1  christos 	    temp = 0;
   7693   1.1  christos 	    while (ISDIGIT (*input_line_pointer))
   7694   1.1  christos 	      temp = (temp * 10) + *input_line_pointer++ - '0';
   7695   1.1  christos 	    fb_label_instance_inc (temp);
   7696   1.1  christos 	    s = fb_label_name (temp, 0);
   7697   1.1  christos 	    c = *input_line_pointer;
   7698   1.1  christos 	  }
   7699   1.1  christos 	else
   7700   1.1  christos 	  {
   7701   1.1  christos 	    s = NULL;
   7702   1.1  christos 	    c = '\0';
   7703   1.1  christos 	  }
   7704   1.1  christos 	if (c != ':')
   7705   1.1  christos 	  {
   7706   1.1  christos 	    /* Put ':' back for error messages' sake.  */
   7707   1.1  christos 	    *input_line_pointer++ = ':';
   7708   1.1  christos 	    as_bad (_("Expected ':'"));
   7709   1.1  christos 	    return 0;
   7710   1.1  christos 	  }
   7711   1.1  christos 
   7712   1.1  christos 	defining_tag = 1;
   7713   1.1  christos 	tag = colon (s);
   7714   1.1  christos 	defining_tag = 0;
   7715   1.1  christos 	/* Put ':' back for error messages' sake.  */
   7716   1.1  christos 	*input_line_pointer++ = ':';
   7717   1.1  christos 	if (*input_line_pointer++ != ']')
   7718   1.1  christos 	  {
   7719   1.1  christos 	    as_bad (_("Expected ']'"));
   7720   1.1  christos 	    return 0;
   7721   1.1  christos 	  }
   7722   1.1  christos 	if (! tag)
   7723   1.1  christos 	  {
   7724   1.1  christos 	    as_bad (_("Tag name expected"));
   7725   1.1  christos 	    return 0;
   7726   1.1  christos 	  }
   7727   1.1  christos 	return 1;
   7728   1.1  christos       }
   7729   1.1  christos 
   7730   1.1  christos     default:
   7731   1.1  christos       break;
   7732   1.1  christos     }
   7733   1.1  christos 
   7734   1.1  christos   /* Not a valid line.  */
   7735   1.1  christos   return 0;
   7736   1.1  christos }
   7737   1.1  christos 
   7738   1.1  christos void
   7739   1.1  christos ia64_frob_label (struct symbol *sym)
   7740   1.1  christos {
   7741   1.1  christos   struct label_fix *fix;
   7742   1.1  christos 
   7743   1.1  christos   /* Tags need special handling since they are not bundle breaks like
   7744   1.1  christos      labels.  */
   7745   1.1  christos   if (defining_tag)
   7746   1.1  christos     {
   7747   1.5  christos       fix = XOBNEW (&notes, struct label_fix);
   7748   1.1  christos       fix->sym = sym;
   7749   1.1  christos       fix->next = CURR_SLOT.tag_fixups;
   7750   1.8  christos       fix->dw2_mark_labels = false;
   7751   1.1  christos       CURR_SLOT.tag_fixups = fix;
   7752   1.1  christos 
   7753   1.1  christos       return;
   7754   1.1  christos     }
   7755   1.1  christos 
   7756   1.7  christos   if (bfd_section_flags (now_seg) & SEC_CODE)
   7757   1.1  christos     {
   7758   1.1  christos       md.last_text_seg = now_seg;
   7759   1.8  christos       md.last_text_subseg = now_subseg;
   7760   1.5  christos       fix = XOBNEW (&notes, struct label_fix);
   7761   1.1  christos       fix->sym = sym;
   7762   1.1  christos       fix->next = CURR_SLOT.label_fixups;
   7763   1.1  christos       fix->dw2_mark_labels = dwarf2_loc_mark_labels;
   7764   1.1  christos       CURR_SLOT.label_fixups = fix;
   7765   1.1  christos 
   7766   1.1  christos       /* Keep track of how many code entry points we've seen.  */
   7767   1.1  christos       if (md.path == md.maxpaths)
   7768   1.1  christos 	{
   7769   1.1  christos 	  md.maxpaths += 20;
   7770   1.5  christos 	  md.entry_labels = XRESIZEVEC (const char *, md.entry_labels,
   7771   1.5  christos 					md.maxpaths);
   7772   1.1  christos 	}
   7773   1.1  christos       md.entry_labels[md.path++] = S_GET_NAME (sym);
   7774   1.1  christos     }
   7775   1.1  christos }
   7776   1.1  christos 
   7777   1.1  christos #ifdef TE_HPUX
   7778   1.1  christos /* The HP-UX linker will give unresolved symbol errors for symbols
   7779   1.1  christos    that are declared but unused.  This routine removes declared,
   7780   1.1  christos    unused symbols from an object.  */
   7781   1.1  christos int
   7782   1.1  christos ia64_frob_symbol (struct symbol *sym)
   7783   1.1  christos {
   7784   1.1  christos   if ((S_GET_SEGMENT (sym) == bfd_und_section_ptr && ! symbol_used_p (sym) &&
   7785   1.1  christos        ELF_ST_VISIBILITY (S_GET_OTHER (sym)) == STV_DEFAULT)
   7786   1.1  christos       || (S_GET_SEGMENT (sym) == bfd_abs_section_ptr
   7787   1.1  christos 	  && ! S_IS_EXTERNAL (sym)))
   7788   1.1  christos     return 1;
   7789   1.1  christos   return 0;
   7790   1.1  christos }
   7791   1.1  christos #endif
   7792   1.1  christos 
   7793   1.1  christos void
   7794   1.1  christos ia64_flush_pending_output (void)
   7795   1.1  christos {
   7796   1.1  christos   if (!md.keep_pending_output
   7797   1.7  christos       && bfd_section_flags (now_seg) & SEC_CODE)
   7798   1.1  christos     {
   7799   1.1  christos       /* ??? This causes many unnecessary stop bits to be emitted.
   7800   1.1  christos 	 Unfortunately, it isn't clear if it is safe to remove this.  */
   7801   1.1  christos       insn_group_break (1, 0, 0);
   7802   1.1  christos       ia64_flush_insns ();
   7803   1.1  christos     }
   7804   1.1  christos }
   7805   1.1  christos 
   7806   1.1  christos /* Do ia64-specific expression optimization.  All that's done here is
   7807   1.1  christos    to transform index expressions that are either due to the indexing
   7808   1.1  christos    of rotating registers or due to the indexing of indirect register
   7809   1.1  christos    sets.  */
   7810   1.1  christos int
   7811   1.1  christos ia64_optimize_expr (expressionS *l, operatorT op, expressionS *r)
   7812   1.1  christos {
   7813   1.1  christos   if (op != O_index)
   7814   1.1  christos     return 0;
   7815   1.1  christos   resolve_expression (l);
   7816   1.1  christos   if (l->X_op == O_register)
   7817   1.1  christos     {
   7818   1.1  christos       unsigned num_regs = l->X_add_number >> 16;
   7819   1.1  christos 
   7820   1.1  christos       resolve_expression (r);
   7821   1.1  christos       if (num_regs)
   7822   1.1  christos 	{
   7823   1.1  christos 	  /* Left side is a .rotX-allocated register.  */
   7824   1.1  christos 	  if (r->X_op != O_constant)
   7825   1.1  christos 	    {
   7826   1.1  christos 	      as_bad (_("Rotating register index must be a non-negative constant"));
   7827   1.1  christos 	      r->X_add_number = 0;
   7828   1.1  christos 	    }
   7829   1.1  christos 	  else if ((valueT) r->X_add_number >= num_regs)
   7830   1.1  christos 	    {
   7831   1.1  christos 	      as_bad (_("Index out of range 0..%u"), num_regs - 1);
   7832   1.1  christos 	      r->X_add_number = 0;
   7833   1.1  christos 	    }
   7834   1.1  christos 	  l->X_add_number = (l->X_add_number & 0xffff) + r->X_add_number;
   7835   1.1  christos 	  return 1;
   7836   1.1  christos 	}
   7837   1.1  christos       else if (l->X_add_number >= IND_CPUID && l->X_add_number <= IND_RR)
   7838   1.1  christos 	{
   7839   1.1  christos 	  if (r->X_op != O_register
   7840   1.1  christos 	      || r->X_add_number < REG_GR
   7841   1.1  christos 	      || r->X_add_number > REG_GR + 127)
   7842   1.1  christos 	    {
   7843   1.1  christos 	      as_bad (_("Indirect register index must be a general register"));
   7844   1.1  christos 	      r->X_add_number = REG_GR;
   7845   1.1  christos 	    }
   7846   1.1  christos 	  l->X_op = O_index;
   7847   1.1  christos 	  l->X_op_symbol = md.indregsym[l->X_add_number - IND_CPUID];
   7848   1.1  christos 	  l->X_add_number = r->X_add_number;
   7849   1.1  christos 	  return 1;
   7850   1.1  christos 	}
   7851   1.1  christos     }
   7852   1.1  christos   as_bad (_("Index can only be applied to rotating or indirect registers"));
   7853   1.1  christos   /* Fall back to some register use of which has as little as possible
   7854   1.1  christos      side effects, to minimize subsequent error messages.  */
   7855   1.1  christos   l->X_op = O_register;
   7856   1.1  christos   l->X_add_number = REG_GR + 3;
   7857   1.1  christos   return 1;
   7858   1.1  christos }
   7859   1.1  christos 
   7860   1.1  christos int
   7861   1.1  christos ia64_parse_name (char *name, expressionS *e, char *nextcharP)
   7862   1.1  christos {
   7863   1.1  christos   struct const_desc *cdesc;
   7864   1.1  christos   struct dynreg *dr = 0;
   7865   1.1  christos   unsigned int idx;
   7866   1.1  christos   struct symbol *sym;
   7867   1.1  christos   char *end;
   7868   1.1  christos 
   7869   1.1  christos   if (*name == '@')
   7870   1.1  christos     {
   7871   1.1  christos       enum pseudo_type pseudo_type = PSEUDO_FUNC_NONE;
   7872   1.1  christos 
   7873   1.1  christos       /* Find what relocation pseudo-function we're dealing with.  */
   7874   1.1  christos       for (idx = 0; idx < NELEMS (pseudo_func); ++idx)
   7875   1.1  christos 	if (pseudo_func[idx].name
   7876   1.1  christos 	    && pseudo_func[idx].name[0] == name[1]
   7877   1.1  christos 	    && strcmp (pseudo_func[idx].name + 1, name + 2) == 0)
   7878   1.1  christos 	  {
   7879   1.1  christos 	    pseudo_type = pseudo_func[idx].type;
   7880   1.1  christos 	    break;
   7881   1.1  christos 	  }
   7882   1.1  christos       switch (pseudo_type)
   7883   1.1  christos 	{
   7884   1.1  christos 	case PSEUDO_FUNC_RELOC:
   7885   1.1  christos 	  end = input_line_pointer;
   7886   1.1  christos 	  if (*nextcharP != '(')
   7887   1.1  christos 	    {
   7888   1.1  christos 	      as_bad (_("Expected '('"));
   7889   1.1  christos 	      break;
   7890   1.1  christos 	    }
   7891   1.1  christos 	  /* Skip '('.  */
   7892   1.1  christos 	  ++input_line_pointer;
   7893   1.1  christos 	  expression (e);
   7894   1.1  christos 	  if (*input_line_pointer != ')')
   7895   1.1  christos 	    {
   7896   1.1  christos 	      as_bad (_("Missing ')'"));
   7897   1.1  christos 	      goto done;
   7898   1.1  christos 	    }
   7899   1.1  christos 	  /* Skip ')'.  */
   7900   1.1  christos 	  ++input_line_pointer;
   7901   1.1  christos #ifdef TE_VMS
   7902   1.1  christos           if (idx == FUNC_SLOTCOUNT_RELOC)
   7903   1.1  christos             {
   7904   1.1  christos               /* @slotcount can accept any expression.  Canonicalize.  */
   7905   1.1  christos               e->X_add_symbol = make_expr_symbol (e);
   7906   1.1  christos               e->X_op = O_symbol;
   7907   1.1  christos               e->X_add_number = 0;
   7908   1.1  christos             }
   7909   1.1  christos #endif
   7910   1.1  christos 	  if (e->X_op != O_symbol)
   7911   1.1  christos 	    {
   7912   1.1  christos 	      if (e->X_op != O_pseudo_fixup)
   7913   1.1  christos 		{
   7914   1.1  christos 		  as_bad (_("Not a symbolic expression"));
   7915   1.1  christos 		  goto done;
   7916   1.1  christos 		}
   7917   1.1  christos 	      if (idx != FUNC_LT_RELATIVE)
   7918   1.1  christos 		{
   7919   1.1  christos 		  as_bad (_("Illegal combination of relocation functions"));
   7920   1.1  christos 		  goto done;
   7921   1.1  christos 		}
   7922   1.1  christos 	      switch (S_GET_VALUE (e->X_op_symbol))
   7923   1.1  christos 		{
   7924   1.1  christos 		case FUNC_FPTR_RELATIVE:
   7925   1.1  christos 		  idx = FUNC_LT_FPTR_RELATIVE; break;
   7926   1.1  christos 		case FUNC_DTP_MODULE:
   7927   1.1  christos 		  idx = FUNC_LT_DTP_MODULE; break;
   7928   1.1  christos 		case FUNC_DTP_RELATIVE:
   7929   1.1  christos 		  idx = FUNC_LT_DTP_RELATIVE; break;
   7930   1.1  christos 		case FUNC_TP_RELATIVE:
   7931   1.1  christos 		  idx = FUNC_LT_TP_RELATIVE; break;
   7932   1.1  christos 		default:
   7933   1.1  christos 		  as_bad (_("Illegal combination of relocation functions"));
   7934   1.1  christos 		  goto done;
   7935   1.1  christos 		}
   7936   1.1  christos 	    }
   7937   1.1  christos 	  /* Make sure gas doesn't get rid of local symbols that are used
   7938   1.1  christos 	     in relocs.  */
   7939   1.1  christos 	  e->X_op = O_pseudo_fixup;
   7940   1.1  christos 	  e->X_op_symbol = pseudo_func[idx].u.sym;
   7941   1.1  christos 	done:
   7942   1.1  christos 	  *nextcharP = *input_line_pointer;
   7943   1.1  christos 	  break;
   7944   1.1  christos 
   7945   1.1  christos 	case PSEUDO_FUNC_CONST:
   7946   1.1  christos 	  e->X_op = O_constant;
   7947   1.1  christos 	  e->X_add_number = pseudo_func[idx].u.ival;
   7948   1.1  christos 	  break;
   7949   1.1  christos 
   7950   1.1  christos 	case PSEUDO_FUNC_REG:
   7951   1.1  christos 	  e->X_op = O_register;
   7952   1.1  christos 	  e->X_add_number = pseudo_func[idx].u.ival;
   7953   1.1  christos 	  break;
   7954   1.1  christos 
   7955   1.1  christos 	default:
   7956   1.1  christos 	  return 0;
   7957   1.1  christos 	}
   7958   1.1  christos       return 1;
   7959   1.1  christos     }
   7960   1.1  christos 
   7961   1.1  christos   /* first see if NAME is a known register name:  */
   7962   1.8  christos   sym = str_hash_find (md.reg_hash, name);
   7963   1.1  christos   if (sym)
   7964   1.1  christos     {
   7965   1.1  christos       e->X_op = O_register;
   7966   1.1  christos       e->X_add_number = S_GET_VALUE (sym);
   7967   1.1  christos       return 1;
   7968   1.1  christos     }
   7969   1.1  christos 
   7970   1.8  christos   cdesc = str_hash_find (md.const_hash, name);
   7971   1.1  christos   if (cdesc)
   7972   1.1  christos     {
   7973   1.1  christos       e->X_op = O_constant;
   7974   1.1  christos       e->X_add_number = cdesc->value;
   7975   1.1  christos       return 1;
   7976   1.1  christos     }
   7977   1.1  christos 
   7978   1.1  christos   /* check for inN, locN, or outN:  */
   7979   1.1  christos   idx = 0;
   7980   1.1  christos   switch (name[0])
   7981   1.1  christos     {
   7982   1.1  christos     case 'i':
   7983   1.1  christos       if (name[1] == 'n' && ISDIGIT (name[2]))
   7984   1.1  christos 	{
   7985   1.1  christos 	  dr = &md.in;
   7986   1.1  christos 	  idx = 2;
   7987   1.1  christos 	}
   7988   1.1  christos       break;
   7989   1.1  christos 
   7990   1.1  christos     case 'l':
   7991   1.1  christos       if (name[1] == 'o' && name[2] == 'c' && ISDIGIT (name[3]))
   7992   1.1  christos 	{
   7993   1.1  christos 	  dr = &md.loc;
   7994   1.1  christos 	  idx = 3;
   7995   1.1  christos 	}
   7996   1.1  christos       break;
   7997   1.1  christos 
   7998   1.1  christos     case 'o':
   7999   1.1  christos       if (name[1] == 'u' && name[2] == 't' && ISDIGIT (name[3]))
   8000   1.1  christos 	{
   8001   1.1  christos 	  dr = &md.out;
   8002   1.1  christos 	  idx = 3;
   8003   1.1  christos 	}
   8004   1.1  christos       break;
   8005   1.1  christos 
   8006   1.1  christos     default:
   8007   1.1  christos       break;
   8008   1.1  christos     }
   8009   1.1  christos 
   8010   1.1  christos   /* Ignore register numbers with leading zeroes, except zero itself.  */
   8011   1.1  christos   if (dr && (name[idx] != '0' || name[idx + 1] == '\0'))
   8012   1.1  christos     {
   8013   1.1  christos       unsigned long regnum;
   8014   1.1  christos 
   8015   1.1  christos       /* The name is inN, locN, or outN; parse the register number.  */
   8016   1.1  christos       regnum = strtoul (name + idx, &end, 10);
   8017   1.1  christos       if (end > name + idx && *end == '\0' && regnum < 96)
   8018   1.1  christos 	{
   8019   1.1  christos 	  if (regnum >= dr->num_regs)
   8020   1.1  christos 	    {
   8021   1.1  christos 	      if (!dr->num_regs)
   8022   1.1  christos 		as_bad (_("No current frame"));
   8023   1.1  christos 	      else
   8024   1.1  christos 		as_bad (_("Register number out of range 0..%u"),
   8025   1.1  christos 			dr->num_regs - 1);
   8026   1.1  christos 	      regnum = 0;
   8027   1.1  christos 	    }
   8028   1.1  christos 	  e->X_op = O_register;
   8029   1.1  christos 	  e->X_add_number = dr->base + regnum;
   8030   1.1  christos 	  return 1;
   8031   1.1  christos 	}
   8032   1.1  christos     }
   8033   1.1  christos 
   8034   1.5  christos   end = xstrdup (name);
   8035   1.1  christos   name = ia64_canonicalize_symbol_name (end);
   8036   1.8  christos   if ((dr = str_hash_find (md.dynreg_hash, name)))
   8037   1.1  christos     {
   8038   1.1  christos       /* We've got ourselves the name of a rotating register set.
   8039   1.1  christos 	 Store the base register number in the low 16 bits of
   8040   1.1  christos 	 X_add_number and the size of the register set in the top 16
   8041   1.1  christos 	 bits.  */
   8042   1.1  christos       e->X_op = O_register;
   8043   1.1  christos       e->X_add_number = dr->base | (dr->num_regs << 16);
   8044   1.5  christos       free (end);
   8045   1.1  christos       return 1;
   8046   1.1  christos     }
   8047   1.5  christos   free (end);
   8048   1.1  christos   return 0;
   8049   1.1  christos }
   8050   1.1  christos 
   8051   1.1  christos /* Remove the '#' suffix that indicates a symbol as opposed to a register.  */
   8052   1.1  christos 
   8053   1.1  christos char *
   8054   1.1  christos ia64_canonicalize_symbol_name (char *name)
   8055   1.1  christos {
   8056   1.1  christos   size_t len = strlen (name), full = len;
   8057   1.1  christos 
   8058   1.1  christos   while (len > 0 && name[len - 1] == '#')
   8059   1.1  christos     --len;
   8060   1.1  christos   if (len <= 0)
   8061   1.1  christos     {
   8062   1.1  christos       if (full > 0)
   8063   1.1  christos 	as_bad (_("Standalone `#' is illegal"));
   8064   1.1  christos     }
   8065   1.1  christos   else if (len < full - 1)
   8066   1.1  christos     as_warn (_("Redundant `#' suffix operators"));
   8067   1.1  christos   name[len] = '\0';
   8068   1.1  christos   return name;
   8069   1.1  christos }
   8070   1.1  christos 
   8071   1.1  christos /* Return true if idesc is a conditional branch instruction.  This excludes
   8072   1.1  christos    the modulo scheduled branches, and br.ia.  Mod-sched branches are excluded
   8073   1.1  christos    because they always read/write resources regardless of the value of the
   8074   1.1  christos    qualifying predicate.  br.ia must always use p0, and hence is always
   8075   1.1  christos    taken.  Thus this function returns true for branches which can fall
   8076   1.1  christos    through, and which use no resources if they do fall through.  */
   8077   1.1  christos 
   8078   1.1  christos static int
   8079   1.1  christos is_conditional_branch (struct ia64_opcode *idesc)
   8080   1.1  christos {
   8081   1.1  christos   /* br is a conditional branch.  Everything that starts with br. except
   8082   1.1  christos      br.ia, br.c{loop,top,exit}, and br.w{top,exit} is a conditional branch.
   8083   1.1  christos      Everything that starts with brl is a conditional branch.  */
   8084   1.1  christos   return (idesc->name[0] == 'b' && idesc->name[1] == 'r'
   8085   1.1  christos 	  && (idesc->name[2] == '\0'
   8086   1.1  christos 	      || (idesc->name[2] == '.' && idesc->name[3] != 'i'
   8087   1.1  christos 		  && idesc->name[3] != 'c' && idesc->name[3] != 'w')
   8088   1.1  christos 	      || idesc->name[2] == 'l'
   8089   1.1  christos 	      /* br.cond, br.call, br.clr  */
   8090   1.1  christos 	      || (idesc->name[2] == '.' && idesc->name[3] == 'c'
   8091   1.1  christos 		  && (idesc->name[4] == 'a' || idesc->name[4] == 'o'
   8092   1.1  christos 		      || (idesc->name[4] == 'l' && idesc->name[5] == 'r')))));
   8093   1.1  christos }
   8094   1.1  christos 
   8095   1.1  christos /* Return whether the given opcode is a taken branch.  If there's any doubt,
   8096   1.1  christos    returns zero.  */
   8097   1.1  christos 
   8098   1.1  christos static int
   8099   1.1  christos is_taken_branch (struct ia64_opcode *idesc)
   8100   1.1  christos {
   8101   1.1  christos   return ((is_conditional_branch (idesc) && CURR_SLOT.qp_regno == 0)
   8102   1.8  christos 	  || startswith (idesc->name, "br.ia"));
   8103   1.1  christos }
   8104   1.1  christos 
   8105   1.1  christos /* Return whether the given opcode is an interruption or rfi.  If there's any
   8106   1.1  christos    doubt, returns zero.  */
   8107   1.1  christos 
   8108   1.1  christos static int
   8109   1.1  christos is_interruption_or_rfi (struct ia64_opcode *idesc)
   8110   1.1  christos {
   8111   1.1  christos   if (strcmp (idesc->name, "rfi") == 0)
   8112   1.1  christos     return 1;
   8113   1.1  christos   return 0;
   8114   1.1  christos }
   8115   1.1  christos 
   8116   1.1  christos /* Returns the index of the given dependency in the opcode's list of chks, or
   8117   1.1  christos    -1 if there is no dependency.  */
   8118   1.1  christos 
   8119   1.1  christos static int
   8120   1.1  christos depends_on (int depind, struct ia64_opcode *idesc)
   8121   1.1  christos {
   8122   1.1  christos   int i;
   8123   1.1  christos   const struct ia64_opcode_dependency *dep = idesc->dependencies;
   8124   1.1  christos   for (i = 0; i < dep->nchks; i++)
   8125   1.1  christos     {
   8126   1.1  christos       if (depind == DEP (dep->chks[i]))
   8127   1.1  christos 	return i;
   8128   1.1  christos     }
   8129   1.1  christos   return -1;
   8130   1.1  christos }
   8131   1.1  christos 
   8132   1.1  christos /* Determine a set of specific resources used for a particular resource
   8133   1.1  christos    class.  Returns the number of specific resources identified  For those
   8134   1.1  christos    cases which are not determinable statically, the resource returned is
   8135   1.1  christos    marked nonspecific.
   8136   1.1  christos 
   8137   1.1  christos    Meanings of value in 'NOTE':
   8138   1.1  christos    1) only read/write when the register number is explicitly encoded in the
   8139   1.1  christos    insn.
   8140   1.1  christos    2) only read CFM when accessing a rotating GR, FR, or PR.  mov pr only
   8141   1.1  christos    accesses CFM when qualifying predicate is in the rotating region.
   8142   1.1  christos    3) general register value is used to specify an indirect register; not
   8143   1.1  christos    determinable statically.
   8144   1.1  christos    4) only read the given resource when bits 7:0 of the indirect index
   8145   1.1  christos    register value does not match the register number of the resource; not
   8146   1.1  christos    determinable statically.
   8147   1.1  christos    5) all rules are implementation specific.
   8148   1.1  christos    6) only when both the index specified by the reader and the index specified
   8149   1.1  christos    by the writer have the same value in bits 63:61; not determinable
   8150   1.1  christos    statically.
   8151   1.1  christos    7) only access the specified resource when the corresponding mask bit is
   8152   1.1  christos    set
   8153   1.1  christos    8) PSR.dfh is only read when these insns reference FR32-127.  PSR.dfl is
   8154   1.1  christos    only read when these insns reference FR2-31
   8155   1.1  christos    9) PSR.mfl is only written when these insns write FR2-31.  PSR.mfh is only
   8156   1.1  christos    written when these insns write FR32-127
   8157   1.1  christos    10) The PSR.bn bit is only accessed when one of GR16-31 is specified in the
   8158   1.1  christos    instruction
   8159   1.1  christos    11) The target predicates are written independently of PR[qp], but source
   8160   1.1  christos    registers are only read if PR[qp] is true.  Since the state of PR[qp]
   8161   1.1  christos    cannot statically be determined, all source registers are marked used.
   8162   1.1  christos    12) This insn only reads the specified predicate register when that
   8163   1.1  christos    register is the PR[qp].
   8164   1.1  christos    13) This reference to ld-c only applies to the GR whose value is loaded
   8165   1.1  christos    with data returned from memory, not the post-incremented address register.
   8166   1.1  christos    14) The RSE resource includes the implementation-specific RSE internal
   8167   1.1  christos    state resources.  At least one (and possibly more) of these resources are
   8168   1.1  christos    read by each instruction listed in IC:rse-readers.  At least one (and
   8169   1.1  christos    possibly more) of these resources are written by each insn listed in
   8170   1.1  christos    IC:rse-writers.
   8171   1.1  christos    15+16) Represents reserved instructions, which the assembler does not
   8172   1.1  christos    generate.
   8173   1.1  christos    17) CR[TPR] has a RAW dependency only between mov-to-CR-TPR and
   8174   1.1  christos    mov-to-PSR-l or ssm instructions that set PSR.i, PSR.pp or PSR.up.
   8175   1.1  christos 
   8176   1.1  christos    Memory resources (i.e. locations in memory) are *not* marked or tracked by
   8177   1.1  christos    this code; there are no dependency violations based on memory access.
   8178   1.1  christos */
   8179   1.1  christos 
   8180   1.1  christos #define MAX_SPECS 256
   8181   1.1  christos #define DV_CHK 1
   8182   1.1  christos #define DV_REG 0
   8183   1.1  christos 
   8184   1.1  christos static int
   8185   1.1  christos specify_resource (const struct ia64_dependency *dep,
   8186   1.1  christos 		  struct ia64_opcode *idesc,
   8187   1.1  christos 		  /* is this a DV chk or a DV reg? */
   8188   1.1  christos 		  int type,
   8189   1.1  christos 		  /* returned specific resources */
   8190   1.1  christos 		  struct rsrc specs[MAX_SPECS],
   8191   1.1  christos 		  /* resource note for this insn's usage */
   8192   1.1  christos 		  int note,
   8193   1.1  christos 		  /* which execution path to examine */
   8194   1.1  christos 		  int path)
   8195   1.1  christos {
   8196   1.1  christos   int count = 0;
   8197   1.1  christos   int i;
   8198   1.1  christos   int rsrc_write = 0;
   8199   1.1  christos   struct rsrc tmpl;
   8200   1.1  christos 
   8201   1.1  christos   if (dep->mode == IA64_DV_WAW
   8202   1.1  christos       || (dep->mode == IA64_DV_RAW && type == DV_REG)
   8203   1.1  christos       || (dep->mode == IA64_DV_WAR && type == DV_CHK))
   8204   1.1  christos     rsrc_write = 1;
   8205   1.1  christos 
   8206   1.1  christos   /* template for any resources we identify */
   8207   1.1  christos   tmpl.dependency = dep;
   8208   1.1  christos   tmpl.note = note;
   8209   1.1  christos   tmpl.insn_srlz = tmpl.data_srlz = 0;
   8210   1.1  christos   tmpl.qp_regno = CURR_SLOT.qp_regno;
   8211   1.1  christos   tmpl.link_to_qp_branch = 1;
   8212   1.1  christos   tmpl.mem_offset.hint = 0;
   8213   1.1  christos   tmpl.mem_offset.offset = 0;
   8214   1.1  christos   tmpl.mem_offset.base = 0;
   8215   1.1  christos   tmpl.specific = 1;
   8216   1.1  christos   tmpl.index = -1;
   8217   1.1  christos   tmpl.cmp_type = CMP_NONE;
   8218   1.1  christos   tmpl.depind = 0;
   8219   1.1  christos   tmpl.file = NULL;
   8220   1.1  christos   tmpl.line = 0;
   8221   1.1  christos   tmpl.path = 0;
   8222   1.1  christos 
   8223   1.1  christos #define UNHANDLED \
   8224   1.1  christos as_warn (_("Unhandled dependency %s for %s (%s), note %d"), \
   8225   1.1  christos dep->name, idesc->name, (rsrc_write?"write":"read"), note)
   8226   1.1  christos #define KNOWN(REG) (gr_values[REG].known && gr_values[REG].path >= path)
   8227   1.1  christos 
   8228   1.1  christos   /* we don't need to track these */
   8229   1.1  christos   if (dep->semantics == IA64_DVS_NONE)
   8230   1.1  christos     return 0;
   8231   1.1  christos 
   8232   1.1  christos   switch (dep->specifier)
   8233   1.1  christos     {
   8234   1.1  christos     case IA64_RS_AR_K:
   8235   1.1  christos       if (note == 1)
   8236   1.1  christos 	{
   8237   1.1  christos 	  if (idesc->operands[!rsrc_write] == IA64_OPND_AR3)
   8238   1.1  christos 	    {
   8239   1.1  christos 	      int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR;
   8240   1.1  christos 	      if (regno >= 0 && regno <= 7)
   8241   1.1  christos 		{
   8242   1.1  christos 		  specs[count] = tmpl;
   8243   1.1  christos 		  specs[count++].index = regno;
   8244   1.1  christos 		}
   8245   1.1  christos 	    }
   8246   1.1  christos 	}
   8247   1.1  christos       else if (note == 0)
   8248   1.1  christos 	{
   8249   1.1  christos 	  for (i = 0; i < 8; i++)
   8250   1.1  christos 	    {
   8251   1.1  christos 	      specs[count] = tmpl;
   8252   1.1  christos 	      specs[count++].index = i;
   8253   1.1  christos 	    }
   8254   1.1  christos 	}
   8255   1.1  christos       else
   8256   1.1  christos 	{
   8257   1.1  christos 	  UNHANDLED;
   8258   1.1  christos 	}
   8259   1.1  christos       break;
   8260   1.1  christos 
   8261   1.1  christos     case IA64_RS_AR_UNAT:
   8262   1.1  christos       /* This is a mov =AR or mov AR= instruction.  */
   8263   1.1  christos       if (idesc->operands[!rsrc_write] == IA64_OPND_AR3)
   8264   1.1  christos 	{
   8265   1.1  christos 	  int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR;
   8266   1.1  christos 	  if (regno == AR_UNAT)
   8267   1.1  christos 	    {
   8268   1.1  christos 	      specs[count++] = tmpl;
   8269   1.1  christos 	    }
   8270   1.1  christos 	}
   8271   1.1  christos       else
   8272   1.1  christos 	{
   8273   1.1  christos 	  /* This is a spill/fill, or other instruction that modifies the
   8274   1.1  christos 	     unat register.  */
   8275   1.1  christos 
   8276   1.1  christos 	  /* Unless we can determine the specific bits used, mark the whole
   8277   1.1  christos 	     thing; bits 8:3 of the memory address indicate the bit used in
   8278   1.1  christos 	     UNAT.  The .mem.offset hint may be used to eliminate a small
   8279   1.1  christos 	     subset of conflicts.  */
   8280   1.1  christos 	  specs[count] = tmpl;
   8281   1.1  christos 	  if (md.mem_offset.hint)
   8282   1.1  christos 	    {
   8283   1.1  christos 	      if (md.debug_dv)
   8284   1.1  christos 		fprintf (stderr, "  Using hint for spill/fill\n");
   8285   1.1  christos 	      /* The index isn't actually used, just set it to something
   8286   1.1  christos 		 approximating the bit index.  */
   8287   1.1  christos 	      specs[count].index = (md.mem_offset.offset >> 3) & 0x3F;
   8288   1.1  christos 	      specs[count].mem_offset.hint = 1;
   8289   1.1  christos 	      specs[count].mem_offset.offset = md.mem_offset.offset;
   8290   1.1  christos 	      specs[count++].mem_offset.base = md.mem_offset.base;
   8291   1.1  christos 	    }
   8292   1.1  christos 	  else
   8293   1.1  christos 	    {
   8294   1.1  christos 	      specs[count++].specific = 0;
   8295   1.1  christos 	    }
   8296   1.1  christos 	}
   8297   1.1  christos       break;
   8298   1.1  christos 
   8299   1.1  christos     case IA64_RS_AR:
   8300   1.1  christos       if (note == 1)
   8301   1.1  christos 	{
   8302   1.1  christos 	  if (idesc->operands[!rsrc_write] == IA64_OPND_AR3)
   8303   1.1  christos 	    {
   8304   1.1  christos 	      int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR;
   8305   1.1  christos 	      if ((regno >= 8 && regno <= 15)
   8306   1.1  christos 		  || (regno >= 20 && regno <= 23)
   8307   1.1  christos 		  || (regno >= 31 && regno <= 39)
   8308   1.1  christos 		  || (regno >= 41 && regno <= 47)
   8309   1.1  christos 		  || (regno >= 67 && regno <= 111))
   8310   1.1  christos 		{
   8311   1.1  christos 		  specs[count] = tmpl;
   8312   1.1  christos 		  specs[count++].index = regno;
   8313   1.1  christos 		}
   8314   1.1  christos 	    }
   8315   1.1  christos 	}
   8316   1.1  christos       else
   8317   1.1  christos 	{
   8318   1.1  christos 	  UNHANDLED;
   8319   1.1  christos 	}
   8320   1.1  christos       break;
   8321   1.1  christos 
   8322   1.1  christos     case IA64_RS_ARb:
   8323   1.1  christos       if (note == 1)
   8324   1.1  christos 	{
   8325   1.1  christos 	  if (idesc->operands[!rsrc_write] == IA64_OPND_AR3)
   8326   1.1  christos 	    {
   8327   1.1  christos 	      int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR;
   8328   1.1  christos 	      if ((regno >= 48 && regno <= 63)
   8329   1.1  christos 		  || (regno >= 112 && regno <= 127))
   8330   1.1  christos 		{
   8331   1.1  christos 		  specs[count] = tmpl;
   8332   1.1  christos 		  specs[count++].index = regno;
   8333   1.1  christos 		}
   8334   1.1  christos 	    }
   8335   1.1  christos 	}
   8336   1.1  christos       else if (note == 0)
   8337   1.1  christos 	{
   8338   1.1  christos 	  for (i = 48; i < 64; i++)
   8339   1.1  christos 	    {
   8340   1.1  christos 	      specs[count] = tmpl;
   8341   1.1  christos 	      specs[count++].index = i;
   8342   1.1  christos 	    }
   8343   1.1  christos 	  for (i = 112; i < 128; i++)
   8344   1.1  christos 	    {
   8345   1.1  christos 	      specs[count] = tmpl;
   8346   1.1  christos 	      specs[count++].index = i;
   8347   1.1  christos 	    }
   8348   1.1  christos 	}
   8349   1.1  christos       else
   8350   1.1  christos 	{
   8351   1.1  christos 	  UNHANDLED;
   8352   1.1  christos 	}
   8353   1.1  christos       break;
   8354   1.1  christos 
   8355   1.1  christos     case IA64_RS_BR:
   8356   1.1  christos       if (note != 1)
   8357   1.1  christos 	{
   8358   1.1  christos 	  UNHANDLED;
   8359   1.1  christos 	}
   8360   1.1  christos       else
   8361   1.1  christos 	{
   8362   1.1  christos 	  if (rsrc_write)
   8363   1.1  christos 	    {
   8364   1.1  christos 	      for (i = 0; i < idesc->num_outputs; i++)
   8365   1.1  christos 		if (idesc->operands[i] == IA64_OPND_B1
   8366   1.1  christos 		    || idesc->operands[i] == IA64_OPND_B2)
   8367   1.1  christos 		  {
   8368   1.1  christos 		    specs[count] = tmpl;
   8369   1.1  christos 		    specs[count++].index =
   8370   1.1  christos 		      CURR_SLOT.opnd[i].X_add_number - REG_BR;
   8371   1.1  christos 		  }
   8372   1.1  christos 	    }
   8373   1.1  christos 	  else
   8374   1.1  christos 	    {
   8375   1.1  christos 	      for (i = idesc->num_outputs; i < NELEMS (idesc->operands); i++)
   8376   1.1  christos 		if (idesc->operands[i] == IA64_OPND_B1
   8377   1.1  christos 		    || idesc->operands[i] == IA64_OPND_B2)
   8378   1.1  christos 		  {
   8379   1.1  christos 		    specs[count] = tmpl;
   8380   1.1  christos 		    specs[count++].index =
   8381   1.1  christos 		      CURR_SLOT.opnd[i].X_add_number - REG_BR;
   8382   1.1  christos 		  }
   8383   1.1  christos 	    }
   8384   1.1  christos 	}
   8385   1.1  christos       break;
   8386   1.1  christos 
   8387   1.1  christos     case IA64_RS_CPUID: /* four or more registers */
   8388   1.1  christos       if (note == 3)
   8389   1.1  christos 	{
   8390   1.1  christos 	  if (idesc->operands[!rsrc_write] == IA64_OPND_CPUID_R3)
   8391   1.1  christos 	    {
   8392   1.1  christos 	      int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR;
   8393   1.1  christos 	      if (regno >= 0 && regno < NELEMS (gr_values)
   8394   1.1  christos 		  && KNOWN (regno))
   8395   1.1  christos 		{
   8396   1.1  christos 		  specs[count] = tmpl;
   8397   1.1  christos 		  specs[count++].index = gr_values[regno].value & 0xFF;
   8398   1.1  christos 		}
   8399   1.1  christos 	      else
   8400   1.1  christos 		{
   8401   1.1  christos 		  specs[count] = tmpl;
   8402   1.1  christos 		  specs[count++].specific = 0;
   8403   1.1  christos 		}
   8404   1.1  christos 	    }
   8405   1.1  christos 	}
   8406   1.1  christos       else
   8407   1.1  christos 	{
   8408   1.1  christos 	  UNHANDLED;
   8409   1.1  christos 	}
   8410   1.1  christos       break;
   8411   1.1  christos 
   8412   1.1  christos     case IA64_RS_DBR: /* four or more registers */
   8413   1.1  christos       if (note == 3)
   8414   1.1  christos 	{
   8415   1.1  christos 	  if (idesc->operands[!rsrc_write] == IA64_OPND_DBR_R3)
   8416   1.1  christos 	    {
   8417   1.1  christos 	      int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR;
   8418   1.1  christos 	      if (regno >= 0 && regno < NELEMS (gr_values)
   8419   1.1  christos 		  && KNOWN (regno))
   8420   1.1  christos 		{
   8421   1.1  christos 		  specs[count] = tmpl;
   8422   1.1  christos 		  specs[count++].index = gr_values[regno].value & 0xFF;
   8423   1.1  christos 		}
   8424   1.1  christos 	      else
   8425   1.1  christos 		{
   8426   1.1  christos 		  specs[count] = tmpl;
   8427   1.1  christos 		  specs[count++].specific = 0;
   8428   1.1  christos 		}
   8429   1.1  christos 	    }
   8430   1.1  christos 	}
   8431   1.1  christos       else if (note == 0 && !rsrc_write)
   8432   1.1  christos 	{
   8433   1.1  christos 	  specs[count] = tmpl;
   8434   1.1  christos 	  specs[count++].specific = 0;
   8435   1.1  christos 	}
   8436   1.1  christos       else
   8437   1.1  christos 	{
   8438   1.1  christos 	  UNHANDLED;
   8439   1.1  christos 	}
   8440   1.1  christos       break;
   8441   1.1  christos 
   8442   1.1  christos     case IA64_RS_IBR: /* four or more registers */
   8443   1.1  christos       if (note == 3)
   8444   1.1  christos 	{
   8445   1.1  christos 	  if (idesc->operands[!rsrc_write] == IA64_OPND_IBR_R3)
   8446   1.1  christos 	    {
   8447   1.1  christos 	      int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR;
   8448   1.1  christos 	      if (regno >= 0 && regno < NELEMS (gr_values)
   8449   1.1  christos 		  && KNOWN (regno))
   8450   1.1  christos 		{
   8451   1.1  christos 		  specs[count] = tmpl;
   8452   1.1  christos 		  specs[count++].index = gr_values[regno].value & 0xFF;
   8453   1.1  christos 		}
   8454   1.1  christos 	      else
   8455   1.1  christos 		{
   8456   1.1  christos 		  specs[count] = tmpl;
   8457   1.1  christos 		  specs[count++].specific = 0;
   8458   1.1  christos 		}
   8459   1.1  christos 	    }
   8460   1.1  christos 	}
   8461   1.1  christos       else
   8462   1.1  christos 	{
   8463   1.1  christos 	  UNHANDLED;
   8464   1.1  christos 	}
   8465   1.1  christos       break;
   8466   1.1  christos 
   8467   1.1  christos     case IA64_RS_MSR:
   8468   1.1  christos       if (note == 5)
   8469   1.1  christos 	{
   8470   1.1  christos 	  /* These are implementation specific.  Force all references to
   8471   1.1  christos 	     conflict with all other references.  */
   8472   1.1  christos 	  specs[count] = tmpl;
   8473   1.1  christos 	  specs[count++].specific = 0;
   8474   1.1  christos 	}
   8475   1.1  christos       else
   8476   1.1  christos 	{
   8477   1.1  christos 	  UNHANDLED;
   8478   1.1  christos 	}
   8479   1.1  christos       break;
   8480   1.1  christos 
   8481   1.1  christos     case IA64_RS_PKR: /* 16 or more registers */
   8482   1.1  christos       if (note == 3 || note == 4)
   8483   1.1  christos 	{
   8484   1.1  christos 	  if (idesc->operands[!rsrc_write] == IA64_OPND_PKR_R3)
   8485   1.1  christos 	    {
   8486   1.1  christos 	      int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR;
   8487   1.1  christos 	      if (regno >= 0 && regno < NELEMS (gr_values)
   8488   1.1  christos 		  && KNOWN (regno))
   8489   1.1  christos 		{
   8490   1.1  christos 		  if (note == 3)
   8491   1.1  christos 		    {
   8492   1.1  christos 		      specs[count] = tmpl;
   8493   1.1  christos 		      specs[count++].index = gr_values[regno].value & 0xFF;
   8494   1.1  christos 		    }
   8495   1.1  christos 		  else
   8496   1.1  christos 		    for (i = 0; i < NELEMS (gr_values); i++)
   8497   1.1  christos 		      {
   8498   1.1  christos 			/* Uses all registers *except* the one in R3.  */
   8499   1.1  christos 			if ((unsigned)i != (gr_values[regno].value & 0xFF))
   8500   1.1  christos 			  {
   8501   1.1  christos 			    specs[count] = tmpl;
   8502   1.1  christos 			    specs[count++].index = i;
   8503   1.1  christos 			  }
   8504   1.1  christos 		      }
   8505   1.1  christos 		}
   8506   1.1  christos 	      else
   8507   1.1  christos 		{
   8508   1.1  christos 		  specs[count] = tmpl;
   8509   1.1  christos 		  specs[count++].specific = 0;
   8510   1.1  christos 		}
   8511   1.1  christos 	    }
   8512   1.1  christos 	}
   8513   1.1  christos       else if (note == 0)
   8514   1.1  christos 	{
   8515   1.1  christos 	  /* probe et al.  */
   8516   1.1  christos 	  specs[count] = tmpl;
   8517   1.1  christos 	  specs[count++].specific = 0;
   8518   1.1  christos 	}
   8519   1.1  christos       break;
   8520   1.1  christos 
   8521   1.1  christos     case IA64_RS_PMC: /* four or more registers */
   8522   1.1  christos       if (note == 3)
   8523   1.1  christos 	{
   8524   1.1  christos 	  if (idesc->operands[!rsrc_write] == IA64_OPND_PMC_R3
   8525   1.1  christos 	      || (!rsrc_write && idesc->operands[1] == IA64_OPND_PMD_R3))
   8526   1.1  christos 
   8527   1.1  christos 	    {
   8528   1.1  christos 	      int reg_index = ((idesc->operands[1] == IA64_OPND_R3 && !rsrc_write)
   8529   1.1  christos 			       ? 1 : !rsrc_write);
   8530   1.1  christos 	      int regno = CURR_SLOT.opnd[reg_index].X_add_number - REG_GR;
   8531   1.1  christos 	      if (regno >= 0 && regno < NELEMS (gr_values)
   8532   1.1  christos 		  && KNOWN (regno))
   8533   1.1  christos 		{
   8534   1.1  christos 		  specs[count] = tmpl;
   8535   1.1  christos 		  specs[count++].index = gr_values[regno].value & 0xFF;
   8536   1.1  christos 		}
   8537   1.1  christos 	      else
   8538   1.1  christos 		{
   8539   1.1  christos 		  specs[count] = tmpl;
   8540   1.1  christos 		  specs[count++].specific = 0;
   8541   1.1  christos 		}
   8542   1.1  christos 	    }
   8543   1.1  christos 	}
   8544   1.1  christos       else
   8545   1.1  christos 	{
   8546   1.1  christos 	  UNHANDLED;
   8547   1.1  christos 	}
   8548   1.1  christos       break;
   8549   1.1  christos 
   8550   1.1  christos     case IA64_RS_PMD: /* four or more registers */
   8551   1.1  christos       if (note == 3)
   8552   1.1  christos 	{
   8553   1.1  christos 	  if (idesc->operands[!rsrc_write] == IA64_OPND_PMD_R3)
   8554   1.1  christos 	    {
   8555   1.1  christos 	      int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR;
   8556   1.1  christos 	      if (regno >= 0 && regno < NELEMS (gr_values)
   8557   1.1  christos 		  && KNOWN (regno))
   8558   1.1  christos 		{
   8559   1.1  christos 		  specs[count] = tmpl;
   8560   1.1  christos 		  specs[count++].index = gr_values[regno].value & 0xFF;
   8561   1.1  christos 		}
   8562   1.1  christos 	      else
   8563   1.1  christos 		{
   8564   1.1  christos 		  specs[count] = tmpl;
   8565   1.1  christos 		  specs[count++].specific = 0;
   8566   1.1  christos 		}
   8567   1.1  christos 	    }
   8568   1.1  christos 	}
   8569   1.1  christos       else
   8570   1.1  christos 	{
   8571   1.1  christos 	  UNHANDLED;
   8572   1.1  christos 	}
   8573   1.1  christos       break;
   8574   1.1  christos 
   8575   1.1  christos     case IA64_RS_RR: /* eight registers */
   8576   1.1  christos       if (note == 6)
   8577   1.1  christos 	{
   8578   1.1  christos 	  if (idesc->operands[!rsrc_write] == IA64_OPND_RR_R3)
   8579   1.1  christos 	    {
   8580   1.1  christos 	      int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR;
   8581   1.1  christos 	      if (regno >= 0 && regno < NELEMS (gr_values)
   8582   1.1  christos 		  && KNOWN (regno))
   8583   1.1  christos 		{
   8584   1.1  christos 		  specs[count] = tmpl;
   8585   1.1  christos 		  specs[count++].index = (gr_values[regno].value >> 61) & 0x7;
   8586   1.1  christos 		}
   8587   1.1  christos 	      else
   8588   1.1  christos 		{
   8589   1.1  christos 		  specs[count] = tmpl;
   8590   1.1  christos 		  specs[count++].specific = 0;
   8591   1.1  christos 		}
   8592   1.1  christos 	    }
   8593   1.1  christos 	}
   8594   1.1  christos       else if (note == 0 && !rsrc_write)
   8595   1.1  christos 	{
   8596   1.1  christos 	  specs[count] = tmpl;
   8597   1.1  christos 	  specs[count++].specific = 0;
   8598   1.1  christos 	}
   8599   1.1  christos       else
   8600   1.1  christos 	{
   8601   1.1  christos 	  UNHANDLED;
   8602   1.1  christos 	}
   8603   1.1  christos       break;
   8604   1.1  christos 
   8605   1.1  christos     case IA64_RS_CR_IRR:
   8606   1.1  christos       if (note == 0)
   8607   1.1  christos 	{
   8608   1.1  christos 	  /* handle mov-from-CR-IVR; it's a read that writes CR[IRR] */
   8609   1.1  christos 	  int regno = CURR_SLOT.opnd[1].X_add_number - REG_CR;
   8610   1.1  christos 	  if (rsrc_write
   8611   1.1  christos 	      && idesc->operands[1] == IA64_OPND_CR3
   8612   1.1  christos 	      && regno == CR_IVR)
   8613   1.1  christos 	    {
   8614   1.1  christos 	      for (i = 0; i < 4; i++)
   8615   1.1  christos 		{
   8616   1.1  christos 		  specs[count] = tmpl;
   8617   1.1  christos 		  specs[count++].index = CR_IRR0 + i;
   8618   1.1  christos 		}
   8619   1.1  christos 	    }
   8620   1.1  christos 	}
   8621   1.1  christos       else if (note == 1)
   8622   1.1  christos 	{
   8623   1.1  christos 	  int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_CR;
   8624   1.1  christos 	  if (idesc->operands[!rsrc_write] == IA64_OPND_CR3
   8625   1.1  christos 	      && regno >= CR_IRR0
   8626   1.1  christos 	      && regno <= CR_IRR3)
   8627   1.1  christos 	    {
   8628   1.1  christos 	      specs[count] = tmpl;
   8629   1.1  christos 	      specs[count++].index = regno;
   8630   1.1  christos 	    }
   8631   1.1  christos 	}
   8632   1.1  christos       else
   8633   1.1  christos 	{
   8634   1.1  christos 	  UNHANDLED;
   8635   1.1  christos 	}
   8636   1.1  christos       break;
   8637   1.1  christos 
   8638   1.1  christos     case IA64_RS_CR_IIB:
   8639   1.1  christos       if (note != 0)
   8640   1.1  christos 	{
   8641   1.1  christos 	  UNHANDLED;
   8642   1.1  christos 	}
   8643   1.1  christos       else
   8644   1.1  christos 	{
   8645   1.1  christos 	  int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_CR;
   8646   1.1  christos 	  if (idesc->operands[!rsrc_write] == IA64_OPND_CR3
   8647   1.1  christos 	      && (regno == CR_IIB0 || regno == CR_IIB1))
   8648   1.1  christos 	    {
   8649   1.1  christos 	      specs[count] = tmpl;
   8650   1.1  christos 	      specs[count++].index = regno;
   8651   1.1  christos 	    }
   8652   1.1  christos 	}
   8653   1.1  christos       break;
   8654   1.1  christos 
   8655   1.1  christos     case IA64_RS_CR_LRR:
   8656   1.1  christos       if (note != 1)
   8657   1.1  christos 	{
   8658   1.1  christos 	  UNHANDLED;
   8659   1.1  christos 	}
   8660   1.1  christos       else
   8661   1.1  christos 	{
   8662   1.1  christos 	  int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_CR;
   8663   1.1  christos 	  if (idesc->operands[!rsrc_write] == IA64_OPND_CR3
   8664   1.1  christos 	      && (regno == CR_LRR0 || regno == CR_LRR1))
   8665   1.1  christos 	    {
   8666   1.1  christos 	      specs[count] = tmpl;
   8667   1.1  christos 	      specs[count++].index = regno;
   8668   1.1  christos 	    }
   8669   1.1  christos 	}
   8670   1.1  christos       break;
   8671   1.1  christos 
   8672   1.1  christos     case IA64_RS_CR:
   8673   1.1  christos       if (note == 1)
   8674   1.1  christos 	{
   8675   1.1  christos 	  if (idesc->operands[!rsrc_write] == IA64_OPND_CR3)
   8676   1.1  christos 	    {
   8677   1.1  christos 	      specs[count] = tmpl;
   8678   1.1  christos 	      specs[count++].index =
   8679   1.1  christos 		CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_CR;
   8680   1.1  christos 	    }
   8681   1.1  christos 	}
   8682   1.1  christos       else
   8683   1.1  christos 	{
   8684   1.1  christos 	  UNHANDLED;
   8685   1.1  christos 	}
   8686   1.1  christos       break;
   8687   1.1  christos 
   8688   1.1  christos     case IA64_RS_DAHR:
   8689   1.1  christos       if (note == 0)
   8690   1.1  christos 	{
   8691   1.1  christos 	  if (idesc->operands[!rsrc_write] == IA64_OPND_DAHR3)
   8692   1.1  christos 	    {
   8693   1.1  christos 	      specs[count] = tmpl;
   8694   1.1  christos 	      specs[count++].index =
   8695   1.1  christos 		CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_DAHR;
   8696   1.1  christos 	    }
   8697   1.1  christos 	}
   8698   1.1  christos       else
   8699   1.1  christos 	{
   8700   1.1  christos 	  UNHANDLED;
   8701   1.1  christos 	}
   8702   1.1  christos       break;
   8703   1.1  christos 
   8704   1.1  christos     case IA64_RS_FR:
   8705   1.1  christos     case IA64_RS_FRb:
   8706   1.1  christos       if (note != 1)
   8707   1.1  christos 	{
   8708   1.1  christos 	  UNHANDLED;
   8709   1.1  christos 	}
   8710   1.1  christos       else if (rsrc_write)
   8711   1.1  christos 	{
   8712   1.1  christos 	  if (dep->specifier == IA64_RS_FRb
   8713   1.1  christos 	      && idesc->operands[0] == IA64_OPND_F1)
   8714   1.1  christos 	    {
   8715   1.1  christos 	      specs[count] = tmpl;
   8716   1.1  christos 	      specs[count++].index = CURR_SLOT.opnd[0].X_add_number - REG_FR;
   8717   1.1  christos 	    }
   8718   1.1  christos 	}
   8719   1.1  christos       else
   8720   1.1  christos 	{
   8721   1.1  christos 	  for (i = idesc->num_outputs; i < NELEMS (idesc->operands); i++)
   8722   1.1  christos 	    {
   8723   1.1  christos 	      if (idesc->operands[i] == IA64_OPND_F2
   8724   1.1  christos 		  || idesc->operands[i] == IA64_OPND_F3
   8725   1.1  christos 		  || idesc->operands[i] == IA64_OPND_F4)
   8726   1.1  christos 		{
   8727   1.1  christos 		  specs[count] = tmpl;
   8728   1.1  christos 		  specs[count++].index =
   8729   1.1  christos 		    CURR_SLOT.opnd[i].X_add_number - REG_FR;
   8730   1.1  christos 		}
   8731   1.1  christos 	    }
   8732   1.1  christos 	}
   8733   1.1  christos       break;
   8734   1.1  christos 
   8735   1.1  christos     case IA64_RS_GR:
   8736   1.1  christos       if (note == 13)
   8737   1.1  christos 	{
   8738   1.1  christos 	  /* This reference applies only to the GR whose value is loaded with
   8739   1.1  christos 	     data returned from memory.  */
   8740   1.1  christos 	  specs[count] = tmpl;
   8741   1.1  christos 	  specs[count++].index = CURR_SLOT.opnd[0].X_add_number - REG_GR;
   8742   1.1  christos 	}
   8743   1.1  christos       else if (note == 1)
   8744   1.1  christos 	{
   8745   1.1  christos 	  if (rsrc_write)
   8746   1.1  christos 	    {
   8747   1.1  christos 	      for (i = 0; i < idesc->num_outputs; i++)
   8748   1.1  christos 		if (idesc->operands[i] == IA64_OPND_R1
   8749   1.1  christos 		    || idesc->operands[i] == IA64_OPND_R2
   8750   1.1  christos 		    || idesc->operands[i] == IA64_OPND_R3)
   8751   1.1  christos 		  {
   8752   1.1  christos 		    specs[count] = tmpl;
   8753   1.1  christos 		    specs[count++].index =
   8754   1.1  christos 		      CURR_SLOT.opnd[i].X_add_number - REG_GR;
   8755   1.1  christos 		  }
   8756   1.1  christos 	      if (idesc->flags & IA64_OPCODE_POSTINC)
   8757   1.1  christos 		for (i = 0; i < NELEMS (idesc->operands); i++)
   8758   1.1  christos 		  if (idesc->operands[i] == IA64_OPND_MR3)
   8759   1.1  christos 		    {
   8760   1.1  christos 		      specs[count] = tmpl;
   8761   1.1  christos 		      specs[count++].index =
   8762   1.1  christos 			CURR_SLOT.opnd[i].X_add_number - REG_GR;
   8763   1.1  christos 		    }
   8764   1.1  christos 	    }
   8765   1.1  christos 	  else
   8766   1.1  christos 	    {
   8767   1.1  christos 	      /* Look for anything that reads a GR.  */
   8768   1.1  christos 	      for (i = 0; i < NELEMS (idesc->operands); i++)
   8769   1.1  christos 		{
   8770   1.1  christos 		  if (idesc->operands[i] == IA64_OPND_MR3
   8771   1.1  christos 		      || idesc->operands[i] == IA64_OPND_CPUID_R3
   8772   1.1  christos 		      || idesc->operands[i] == IA64_OPND_DBR_R3
   8773   1.1  christos 		      || idesc->operands[i] == IA64_OPND_IBR_R3
   8774   1.1  christos 		      || idesc->operands[i] == IA64_OPND_MSR_R3
   8775   1.1  christos 		      || idesc->operands[i] == IA64_OPND_PKR_R3
   8776   1.1  christos 		      || idesc->operands[i] == IA64_OPND_PMC_R3
   8777   1.1  christos 		      || idesc->operands[i] == IA64_OPND_PMD_R3
   8778   1.1  christos 		      || idesc->operands[i] == IA64_OPND_DAHR_R3
   8779   1.1  christos 		      || idesc->operands[i] == IA64_OPND_RR_R3
   8780   1.1  christos 		      || ((i >= idesc->num_outputs)
   8781   1.1  christos 			  && (idesc->operands[i] == IA64_OPND_R1
   8782   1.1  christos 			      || idesc->operands[i] == IA64_OPND_R2
   8783   1.1  christos 			      || idesc->operands[i] == IA64_OPND_R3
   8784   1.1  christos 			      /* addl source register.  */
   8785   1.1  christos 			      || idesc->operands[i] == IA64_OPND_R3_2)))
   8786   1.1  christos 		    {
   8787   1.1  christos 		      specs[count] = tmpl;
   8788   1.1  christos 		      specs[count++].index =
   8789   1.1  christos 			CURR_SLOT.opnd[i].X_add_number - REG_GR;
   8790   1.1  christos 		    }
   8791   1.1  christos 		}
   8792   1.1  christos 	    }
   8793   1.1  christos 	}
   8794   1.1  christos       else
   8795   1.1  christos 	{
   8796   1.1  christos 	  UNHANDLED;
   8797   1.1  christos 	}
   8798   1.1  christos       break;
   8799   1.1  christos 
   8800   1.1  christos       /* This is the same as IA64_RS_PRr, except that the register range is
   8801   1.1  christos 	 from 1 - 15, and there are no rotating register reads/writes here.  */
   8802   1.1  christos     case IA64_RS_PR:
   8803   1.1  christos       if (note == 0)
   8804   1.1  christos 	{
   8805   1.1  christos 	  for (i = 1; i < 16; i++)
   8806   1.1  christos 	    {
   8807   1.1  christos 	      specs[count] = tmpl;
   8808   1.1  christos 	      specs[count++].index = i;
   8809   1.1  christos 	    }
   8810   1.1  christos 	}
   8811   1.1  christos       else if (note == 7)
   8812   1.1  christos 	{
   8813   1.1  christos 	  valueT mask = 0;
   8814   1.1  christos 	  /* Mark only those registers indicated by the mask.  */
   8815   1.1  christos 	  if (rsrc_write)
   8816   1.1  christos 	    {
   8817   1.1  christos 	      mask = CURR_SLOT.opnd[2].X_add_number;
   8818   1.1  christos 	      for (i = 1; i < 16; i++)
   8819   1.1  christos 		if (mask & ((valueT) 1 << i))
   8820   1.1  christos 		  {
   8821   1.1  christos 		    specs[count] = tmpl;
   8822   1.1  christos 		    specs[count++].index = i;
   8823   1.1  christos 		  }
   8824   1.1  christos 	    }
   8825   1.1  christos 	  else
   8826   1.1  christos 	    {
   8827   1.1  christos 	      UNHANDLED;
   8828   1.1  christos 	    }
   8829   1.1  christos 	}
   8830   1.1  christos       else if (note == 11) /* note 11 implies note 1 as well */
   8831   1.1  christos 	{
   8832   1.1  christos 	  if (rsrc_write)
   8833   1.1  christos 	    {
   8834   1.1  christos 	      for (i = 0; i < idesc->num_outputs; i++)
   8835   1.1  christos 		{
   8836   1.1  christos 		  if (idesc->operands[i] == IA64_OPND_P1
   8837   1.1  christos 		      || idesc->operands[i] == IA64_OPND_P2)
   8838   1.1  christos 		    {
   8839   1.1  christos 		      int regno = CURR_SLOT.opnd[i].X_add_number - REG_P;
   8840   1.1  christos 		      if (regno >= 1 && regno < 16)
   8841   1.1  christos 			{
   8842   1.1  christos 			  specs[count] = tmpl;
   8843   1.1  christos 			  specs[count++].index = regno;
   8844   1.1  christos 			}
   8845   1.1  christos 		    }
   8846   1.1  christos 		}
   8847   1.1  christos 	    }
   8848   1.1  christos 	  else
   8849   1.1  christos 	    {
   8850   1.1  christos 	      UNHANDLED;
   8851   1.1  christos 	    }
   8852   1.1  christos 	}
   8853   1.1  christos       else if (note == 12)
   8854   1.1  christos 	{
   8855   1.1  christos 	  if (CURR_SLOT.qp_regno >= 1 && CURR_SLOT.qp_regno < 16)
   8856   1.1  christos 	    {
   8857   1.1  christos 	      specs[count] = tmpl;
   8858   1.1  christos 	      specs[count++].index = CURR_SLOT.qp_regno;
   8859   1.1  christos 	    }
   8860   1.1  christos 	}
   8861   1.1  christos       else if (note == 1)
   8862   1.1  christos 	{
   8863   1.1  christos 	  if (rsrc_write)
   8864   1.1  christos 	    {
   8865   1.1  christos 	      int p1 = CURR_SLOT.opnd[0].X_add_number - REG_P;
   8866   1.1  christos 	      int p2 = CURR_SLOT.opnd[1].X_add_number - REG_P;
   8867   1.1  christos 	      int or_andcm = strstr (idesc->name, "or.andcm") != NULL;
   8868   1.1  christos 	      int and_orcm = strstr (idesc->name, "and.orcm") != NULL;
   8869   1.1  christos 
   8870   1.1  christos 	      if ((idesc->operands[0] == IA64_OPND_P1
   8871   1.1  christos 		   || idesc->operands[0] == IA64_OPND_P2)
   8872   1.1  christos 		  && p1 >= 1 && p1 < 16)
   8873   1.1  christos 		{
   8874   1.1  christos 		  specs[count] = tmpl;
   8875   1.1  christos 		  specs[count].cmp_type =
   8876   1.1  christos 		    (or_andcm ? CMP_OR : (and_orcm ? CMP_AND : CMP_NONE));
   8877   1.1  christos 		  specs[count++].index = p1;
   8878   1.1  christos 		}
   8879   1.1  christos 	      if ((idesc->operands[1] == IA64_OPND_P1
   8880   1.1  christos 		   || idesc->operands[1] == IA64_OPND_P2)
   8881   1.1  christos 		  && p2 >= 1 && p2 < 16)
   8882   1.1  christos 		{
   8883   1.1  christos 		  specs[count] = tmpl;
   8884   1.1  christos 		  specs[count].cmp_type =
   8885   1.1  christos 		    (or_andcm ? CMP_AND : (and_orcm ? CMP_OR : CMP_NONE));
   8886   1.1  christos 		  specs[count++].index = p2;
   8887   1.1  christos 		}
   8888   1.1  christos 	    }
   8889   1.1  christos 	  else
   8890   1.1  christos 	    {
   8891   1.1  christos 	      if (CURR_SLOT.qp_regno >= 1 && CURR_SLOT.qp_regno < 16)
   8892   1.1  christos 		{
   8893   1.1  christos 		  specs[count] = tmpl;
   8894   1.1  christos 		  specs[count++].index = CURR_SLOT.qp_regno;
   8895   1.1  christos 		}
   8896   1.1  christos 	      if (idesc->operands[1] == IA64_OPND_PR)
   8897   1.1  christos 		{
   8898   1.1  christos 		  for (i = 1; i < 16; i++)
   8899   1.1  christos 		    {
   8900   1.1  christos 		      specs[count] = tmpl;
   8901   1.1  christos 		      specs[count++].index = i;
   8902   1.1  christos 		    }
   8903   1.1  christos 		}
   8904   1.1  christos 	    }
   8905   1.1  christos 	}
   8906   1.1  christos       else
   8907   1.1  christos 	{
   8908   1.1  christos 	  UNHANDLED;
   8909   1.1  christos 	}
   8910   1.1  christos       break;
   8911   1.1  christos 
   8912   1.1  christos       /* This is the general case for PRs.  IA64_RS_PR and IA64_RS_PR63 are
   8913   1.1  christos 	 simplified cases of this.  */
   8914   1.1  christos     case IA64_RS_PRr:
   8915   1.1  christos       if (note == 0)
   8916   1.1  christos 	{
   8917   1.1  christos 	  for (i = 16; i < 63; i++)
   8918   1.1  christos 	    {
   8919   1.1  christos 	      specs[count] = tmpl;
   8920   1.1  christos 	      specs[count++].index = i;
   8921   1.1  christos 	    }
   8922   1.1  christos 	}
   8923   1.1  christos       else if (note == 7)
   8924   1.1  christos 	{
   8925   1.1  christos 	  valueT mask = 0;
   8926   1.1  christos 	  /* Mark only those registers indicated by the mask.  */
   8927   1.1  christos 	  if (rsrc_write
   8928   1.1  christos 	      && idesc->operands[0] == IA64_OPND_PR)
   8929   1.1  christos 	    {
   8930   1.1  christos 	      mask = CURR_SLOT.opnd[2].X_add_number;
   8931   1.1  christos 	      if (mask & ((valueT) 1 << 16))
   8932   1.1  christos 		for (i = 16; i < 63; i++)
   8933   1.1  christos 		  {
   8934   1.1  christos 		    specs[count] = tmpl;
   8935   1.1  christos 		    specs[count++].index = i;
   8936   1.1  christos 		  }
   8937   1.1  christos 	    }
   8938   1.1  christos 	  else if (rsrc_write
   8939   1.1  christos 		   && idesc->operands[0] == IA64_OPND_PR_ROT)
   8940   1.1  christos 	    {
   8941   1.1  christos 	      for (i = 16; i < 63; i++)
   8942   1.1  christos 		{
   8943   1.1  christos 		  specs[count] = tmpl;
   8944   1.1  christos 		  specs[count++].index = i;
   8945   1.1  christos 		}
   8946   1.1  christos 	    }
   8947   1.1  christos 	  else
   8948   1.1  christos 	    {
   8949   1.1  christos 	      UNHANDLED;
   8950   1.1  christos 	    }
   8951   1.1  christos 	}
   8952   1.1  christos       else if (note == 11) /* note 11 implies note 1 as well */
   8953   1.1  christos 	{
   8954   1.1  christos 	  if (rsrc_write)
   8955   1.1  christos 	    {
   8956   1.1  christos 	      for (i = 0; i < idesc->num_outputs; i++)
   8957   1.1  christos 		{
   8958   1.1  christos 		  if (idesc->operands[i] == IA64_OPND_P1
   8959   1.1  christos 		      || idesc->operands[i] == IA64_OPND_P2)
   8960   1.1  christos 		    {
   8961   1.1  christos 		      int regno = CURR_SLOT.opnd[i].X_add_number - REG_P;
   8962   1.1  christos 		      if (regno >= 16 && regno < 63)
   8963   1.1  christos 			{
   8964   1.1  christos 			  specs[count] = tmpl;
   8965   1.1  christos 			  specs[count++].index = regno;
   8966   1.1  christos 			}
   8967   1.1  christos 		    }
   8968   1.1  christos 		}
   8969   1.1  christos 	    }
   8970   1.1  christos 	  else
   8971   1.1  christos 	    {
   8972   1.1  christos 	      UNHANDLED;
   8973   1.1  christos 	    }
   8974   1.1  christos 	}
   8975   1.1  christos       else if (note == 12)
   8976   1.1  christos 	{
   8977   1.1  christos 	  if (CURR_SLOT.qp_regno >= 16 && CURR_SLOT.qp_regno < 63)
   8978   1.1  christos 	    {
   8979   1.1  christos 	      specs[count] = tmpl;
   8980   1.1  christos 	      specs[count++].index = CURR_SLOT.qp_regno;
   8981   1.1  christos 	    }
   8982   1.1  christos 	}
   8983   1.1  christos       else if (note == 1)
   8984   1.1  christos 	{
   8985   1.1  christos 	  if (rsrc_write)
   8986   1.1  christos 	    {
   8987   1.1  christos 	      int p1 = CURR_SLOT.opnd[0].X_add_number - REG_P;
   8988   1.1  christos 	      int p2 = CURR_SLOT.opnd[1].X_add_number - REG_P;
   8989   1.1  christos 	      int or_andcm = strstr (idesc->name, "or.andcm") != NULL;
   8990   1.1  christos 	      int and_orcm = strstr (idesc->name, "and.orcm") != NULL;
   8991   1.1  christos 
   8992   1.1  christos 	      if ((idesc->operands[0] == IA64_OPND_P1
   8993   1.1  christos 		   || idesc->operands[0] == IA64_OPND_P2)
   8994   1.1  christos 		  && p1 >= 16 && p1 < 63)
   8995   1.1  christos 		{
   8996   1.1  christos 		  specs[count] = tmpl;
   8997   1.1  christos 		  specs[count].cmp_type =
   8998   1.1  christos 		    (or_andcm ? CMP_OR : (and_orcm ? CMP_AND : CMP_NONE));
   8999   1.1  christos 		  specs[count++].index = p1;
   9000   1.1  christos 		}
   9001   1.1  christos 	      if ((idesc->operands[1] == IA64_OPND_P1
   9002   1.1  christos 		   || idesc->operands[1] == IA64_OPND_P2)
   9003   1.1  christos 		  && p2 >= 16 && p2 < 63)
   9004   1.1  christos 		{
   9005   1.1  christos 		  specs[count] = tmpl;
   9006   1.1  christos 		  specs[count].cmp_type =
   9007   1.1  christos 		    (or_andcm ? CMP_AND : (and_orcm ? CMP_OR : CMP_NONE));
   9008   1.1  christos 		  specs[count++].index = p2;
   9009   1.1  christos 		}
   9010   1.1  christos 	    }
   9011   1.1  christos 	  else
   9012   1.1  christos 	    {
   9013   1.1  christos 	      if (CURR_SLOT.qp_regno >= 16 && CURR_SLOT.qp_regno < 63)
   9014   1.1  christos 		{
   9015   1.1  christos 		  specs[count] = tmpl;
   9016   1.1  christos 		  specs[count++].index = CURR_SLOT.qp_regno;
   9017   1.1  christos 		}
   9018   1.1  christos 	      if (idesc->operands[1] == IA64_OPND_PR)
   9019   1.1  christos 		{
   9020   1.1  christos 		  for (i = 16; i < 63; i++)
   9021   1.1  christos 		    {
   9022   1.1  christos 		      specs[count] = tmpl;
   9023   1.1  christos 		      specs[count++].index = i;
   9024   1.1  christos 		    }
   9025   1.1  christos 		}
   9026   1.1  christos 	    }
   9027   1.1  christos 	}
   9028   1.1  christos       else
   9029   1.1  christos 	{
   9030   1.1  christos 	  UNHANDLED;
   9031   1.1  christos 	}
   9032   1.1  christos       break;
   9033   1.1  christos 
   9034   1.1  christos     case IA64_RS_PSR:
   9035   1.1  christos       /* Verify that the instruction is using the PSR bit indicated in
   9036   1.1  christos 	 dep->regindex.  */
   9037   1.1  christos       if (note == 0)
   9038   1.1  christos 	{
   9039   1.1  christos 	  if (idesc->operands[!rsrc_write] == IA64_OPND_PSR_UM)
   9040   1.1  christos 	    {
   9041   1.1  christos 	      if (dep->regindex < 6)
   9042   1.1  christos 		{
   9043   1.1  christos 		  specs[count++] = tmpl;
   9044   1.1  christos 		}
   9045   1.1  christos 	    }
   9046   1.1  christos 	  else if (idesc->operands[!rsrc_write] == IA64_OPND_PSR)
   9047   1.1  christos 	    {
   9048   1.1  christos 	      if (dep->regindex < 32
   9049   1.1  christos 		  || dep->regindex == 35
   9050   1.1  christos 		  || dep->regindex == 36
   9051   1.1  christos 		  || (!rsrc_write && dep->regindex == PSR_CPL))
   9052   1.1  christos 		{
   9053   1.1  christos 		  specs[count++] = tmpl;
   9054   1.1  christos 		}
   9055   1.1  christos 	    }
   9056   1.1  christos 	  else if (idesc->operands[!rsrc_write] == IA64_OPND_PSR_L)
   9057   1.1  christos 	    {
   9058   1.1  christos 	      if (dep->regindex < 32
   9059   1.1  christos 		  || dep->regindex == 35
   9060   1.1  christos 		  || dep->regindex == 36
   9061   1.1  christos 		  || (rsrc_write && dep->regindex == PSR_CPL))
   9062   1.1  christos 		{
   9063   1.1  christos 		  specs[count++] = tmpl;
   9064   1.1  christos 		}
   9065   1.1  christos 	    }
   9066   1.1  christos 	  else
   9067   1.1  christos 	    {
   9068   1.1  christos 	      /* Several PSR bits have very specific dependencies.  */
   9069   1.1  christos 	      switch (dep->regindex)
   9070   1.1  christos 		{
   9071   1.1  christos 		default:
   9072   1.1  christos 		  specs[count++] = tmpl;
   9073   1.1  christos 		  break;
   9074   1.1  christos 		case PSR_IC:
   9075   1.1  christos 		  if (rsrc_write)
   9076   1.1  christos 		    {
   9077   1.1  christos 		      specs[count++] = tmpl;
   9078   1.1  christos 		    }
   9079   1.1  christos 		  else
   9080   1.1  christos 		    {
   9081   1.1  christos 		      /* Only certain CR accesses use PSR.ic */
   9082   1.1  christos 		      if (idesc->operands[0] == IA64_OPND_CR3
   9083   1.1  christos 			  || idesc->operands[1] == IA64_OPND_CR3)
   9084   1.1  christos 			{
   9085   1.1  christos 			  int reg_index =
   9086   1.1  christos 			    ((idesc->operands[0] == IA64_OPND_CR3)
   9087   1.1  christos 			     ? 0 : 1);
   9088   1.1  christos 			  int regno =
   9089   1.1  christos 			    CURR_SLOT.opnd[reg_index].X_add_number - REG_CR;
   9090   1.1  christos 
   9091   1.1  christos 			  switch (regno)
   9092   1.1  christos 			    {
   9093   1.1  christos 			    default:
   9094   1.1  christos 			      break;
   9095   1.1  christos 			    case CR_ITIR:
   9096   1.1  christos 			    case CR_IFS:
   9097   1.1  christos 			    case CR_IIM:
   9098   1.1  christos 			    case CR_IIP:
   9099   1.1  christos 			    case CR_IPSR:
   9100   1.1  christos 			    case CR_ISR:
   9101   1.1  christos 			    case CR_IFA:
   9102   1.1  christos 			    case CR_IHA:
   9103   1.1  christos 			    case CR_IIB0:
   9104   1.1  christos 			    case CR_IIB1:
   9105   1.1  christos 			    case CR_IIPA:
   9106   1.1  christos 			      specs[count++] = tmpl;
   9107   1.1  christos 			      break;
   9108   1.1  christos 			    }
   9109   1.1  christos 			}
   9110   1.1  christos 		    }
   9111   1.1  christos 		  break;
   9112   1.1  christos 		case PSR_CPL:
   9113   1.1  christos 		  if (rsrc_write)
   9114   1.1  christos 		    {
   9115   1.1  christos 		      specs[count++] = tmpl;
   9116   1.1  christos 		    }
   9117   1.1  christos 		  else
   9118   1.1  christos 		    {
   9119   1.1  christos 		      /* Only some AR accesses use cpl */
   9120   1.1  christos 		      if (idesc->operands[0] == IA64_OPND_AR3
   9121   1.1  christos 			  || idesc->operands[1] == IA64_OPND_AR3)
   9122   1.1  christos 			{
   9123   1.1  christos 			  int reg_index =
   9124   1.1  christos 			    ((idesc->operands[0] == IA64_OPND_AR3)
   9125   1.1  christos 			     ? 0 : 1);
   9126   1.1  christos 			  int regno =
   9127   1.1  christos 			    CURR_SLOT.opnd[reg_index].X_add_number - REG_AR;
   9128   1.1  christos 
   9129   1.1  christos 			  if (regno == AR_ITC
   9130   1.1  christos 			      || regno == AR_RUC
   9131   1.1  christos 			      || (reg_index == 0
   9132   1.1  christos 				  && (regno == AR_RSC
   9133   1.1  christos 				      || (regno >= AR_K0
   9134   1.1  christos 					  && regno <= AR_K7))))
   9135   1.1  christos 			    {
   9136   1.1  christos 			      specs[count++] = tmpl;
   9137   1.1  christos 			    }
   9138   1.1  christos 			}
   9139   1.1  christos 		      else
   9140   1.1  christos 			{
   9141   1.1  christos 			  specs[count++] = tmpl;
   9142   1.1  christos 			}
   9143   1.1  christos 		      break;
   9144   1.1  christos 		    }
   9145   1.1  christos 		}
   9146   1.1  christos 	    }
   9147   1.1  christos 	}
   9148   1.1  christos       else if (note == 7)
   9149   1.1  christos 	{
   9150   1.1  christos 	  valueT mask = 0;
   9151   1.1  christos 	  if (idesc->operands[0] == IA64_OPND_IMMU24)
   9152   1.1  christos 	    {
   9153   1.1  christos 	      mask = CURR_SLOT.opnd[0].X_add_number;
   9154   1.1  christos 	    }
   9155   1.1  christos 	  else
   9156   1.1  christos 	    {
   9157   1.1  christos 	      UNHANDLED;
   9158   1.1  christos 	    }
   9159   1.1  christos 	  if (mask & ((valueT) 1 << dep->regindex))
   9160   1.1  christos 	    {
   9161   1.1  christos 	      specs[count++] = tmpl;
   9162   1.1  christos 	    }
   9163   1.1  christos 	}
   9164   1.1  christos       else if (note == 8)
   9165   1.1  christos 	{
   9166   1.1  christos 	  int min = dep->regindex == PSR_DFL ? 2 : 32;
   9167   1.1  christos 	  int max = dep->regindex == PSR_DFL ? 31 : 127;
   9168   1.1  christos 	  /* dfh is read on FR32-127; dfl is read on FR2-31 */
   9169   1.1  christos 	  for (i = 0; i < NELEMS (idesc->operands); i++)
   9170   1.1  christos 	    {
   9171   1.1  christos 	      if (idesc->operands[i] == IA64_OPND_F1
   9172   1.1  christos 		  || idesc->operands[i] == IA64_OPND_F2
   9173   1.1  christos 		  || idesc->operands[i] == IA64_OPND_F3
   9174   1.1  christos 		  || idesc->operands[i] == IA64_OPND_F4)
   9175   1.1  christos 		{
   9176   1.1  christos 		  int reg = CURR_SLOT.opnd[i].X_add_number - REG_FR;
   9177   1.1  christos 		  if (reg >= min && reg <= max)
   9178   1.1  christos 		    {
   9179   1.1  christos 		      specs[count++] = tmpl;
   9180   1.1  christos 		    }
   9181   1.1  christos 		}
   9182   1.1  christos 	    }
   9183   1.1  christos 	}
   9184   1.1  christos       else if (note == 9)
   9185   1.1  christos 	{
   9186   1.1  christos 	  int min = dep->regindex == PSR_MFL ? 2 : 32;
   9187   1.1  christos 	  int max = dep->regindex == PSR_MFL ? 31 : 127;
   9188   1.1  christos 	  /* mfh is read on writes to FR32-127; mfl is read on writes to
   9189   1.1  christos 	     FR2-31 */
   9190   1.1  christos 	  for (i = 0; i < idesc->num_outputs; i++)
   9191   1.1  christos 	    {
   9192   1.1  christos 	      if (idesc->operands[i] == IA64_OPND_F1)
   9193   1.1  christos 		{
   9194   1.1  christos 		  int reg = CURR_SLOT.opnd[i].X_add_number - REG_FR;
   9195   1.1  christos 		  if (reg >= min && reg <= max)
   9196   1.1  christos 		    {
   9197   1.1  christos 		      specs[count++] = tmpl;
   9198   1.1  christos 		    }
   9199   1.1  christos 		}
   9200   1.1  christos 	    }
   9201   1.1  christos 	}
   9202   1.1  christos       else if (note == 10)
   9203   1.1  christos 	{
   9204   1.1  christos 	  for (i = 0; i < NELEMS (idesc->operands); i++)
   9205   1.1  christos 	    {
   9206   1.1  christos 	      if (idesc->operands[i] == IA64_OPND_R1
   9207   1.1  christos 		  || idesc->operands[i] == IA64_OPND_R2
   9208   1.1  christos 		  || idesc->operands[i] == IA64_OPND_R3)
   9209   1.1  christos 		{
   9210   1.1  christos 		  int regno = CURR_SLOT.opnd[i].X_add_number - REG_GR;
   9211   1.1  christos 		  if (regno >= 16 && regno <= 31)
   9212   1.1  christos 		    {
   9213   1.1  christos 		      specs[count++] = tmpl;
   9214   1.1  christos 		    }
   9215   1.1  christos 		}
   9216   1.1  christos 	    }
   9217   1.1  christos 	}
   9218   1.1  christos       else
   9219   1.1  christos 	{
   9220   1.1  christos 	  UNHANDLED;
   9221   1.1  christos 	}
   9222   1.1  christos       break;
   9223   1.1  christos 
   9224   1.1  christos     case IA64_RS_AR_FPSR:
   9225   1.1  christos       if (idesc->operands[!rsrc_write] == IA64_OPND_AR3)
   9226   1.1  christos 	{
   9227   1.1  christos 	  int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR;
   9228   1.1  christos 	  if (regno == AR_FPSR)
   9229   1.1  christos 	    {
   9230   1.1  christos 	      specs[count++] = tmpl;
   9231   1.1  christos 	    }
   9232   1.1  christos 	}
   9233   1.1  christos       else
   9234   1.1  christos 	{
   9235   1.1  christos 	  specs[count++] = tmpl;
   9236   1.1  christos 	}
   9237   1.1  christos       break;
   9238   1.1  christos 
   9239   1.1  christos     case IA64_RS_ARX:
   9240   1.1  christos       /* Handle all AR[REG] resources */
   9241   1.1  christos       if (note == 0 || note == 1)
   9242   1.1  christos 	{
   9243   1.1  christos 	  int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR;
   9244   1.1  christos 	  if (idesc->operands[!rsrc_write] == IA64_OPND_AR3
   9245   1.1  christos 	      && regno == dep->regindex)
   9246   1.1  christos 	    {
   9247   1.1  christos 	      specs[count++] = tmpl;
   9248   1.1  christos 	    }
   9249   1.1  christos 	  /* other AR[REG] resources may be affected by AR accesses */
   9250   1.1  christos 	  else if (idesc->operands[0] == IA64_OPND_AR3)
   9251   1.1  christos 	    {
   9252   1.1  christos 	      /* AR[] writes */
   9253   1.1  christos 	      regno = CURR_SLOT.opnd[0].X_add_number - REG_AR;
   9254   1.1  christos 	      switch (dep->regindex)
   9255   1.1  christos 		{
   9256   1.1  christos 		default:
   9257   1.1  christos 		  break;
   9258   1.1  christos 		case AR_BSP:
   9259   1.1  christos 		case AR_RNAT:
   9260   1.1  christos 		  if (regno == AR_BSPSTORE)
   9261   1.1  christos 		    {
   9262   1.1  christos 		      specs[count++] = tmpl;
   9263   1.1  christos 		    }
   9264   1.6  christos 		  /* Fall through.  */
   9265   1.1  christos 		case AR_RSC:
   9266   1.1  christos 		  if (!rsrc_write &&
   9267   1.1  christos 		      (regno == AR_BSPSTORE
   9268   1.1  christos 		       || regno == AR_RNAT))
   9269   1.1  christos 		    {
   9270   1.1  christos 		      specs[count++] = tmpl;
   9271   1.1  christos 		    }
   9272   1.1  christos 		  break;
   9273   1.1  christos 		}
   9274   1.1  christos 	    }
   9275   1.1  christos 	  else if (idesc->operands[1] == IA64_OPND_AR3)
   9276   1.1  christos 	    {
   9277   1.1  christos 	      /* AR[] reads */
   9278   1.1  christos 	      regno = CURR_SLOT.opnd[1].X_add_number - REG_AR;
   9279   1.1  christos 	      switch (dep->regindex)
   9280   1.1  christos 		{
   9281   1.1  christos 		default:
   9282   1.1  christos 		  break;
   9283   1.1  christos 		case AR_RSC:
   9284   1.1  christos 		  if (regno == AR_BSPSTORE || regno == AR_RNAT)
   9285   1.1  christos 		    {
   9286   1.1  christos 		      specs[count++] = tmpl;
   9287   1.1  christos 		    }
   9288   1.1  christos 		  break;
   9289   1.1  christos 		}
   9290   1.1  christos 	    }
   9291   1.1  christos 	  else
   9292   1.1  christos 	    {
   9293   1.1  christos 	      specs[count++] = tmpl;
   9294   1.1  christos 	    }
   9295   1.1  christos 	}
   9296   1.1  christos       else
   9297   1.1  christos 	{
   9298   1.1  christos 	  UNHANDLED;
   9299   1.1  christos 	}
   9300   1.1  christos       break;
   9301   1.1  christos 
   9302   1.1  christos     case IA64_RS_CRX:
   9303   1.1  christos       /* Handle all CR[REG] resources.
   9304   1.1  christos 	 ??? FIXME: The rule 17 isn't really handled correctly.   */
   9305   1.1  christos       if (note == 0 || note == 1 || note == 17)
   9306   1.1  christos 	{
   9307   1.1  christos 	  if (idesc->operands[!rsrc_write] == IA64_OPND_CR3)
   9308   1.1  christos 	    {
   9309   1.1  christos 	      int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_CR;
   9310   1.1  christos 	      if (regno == dep->regindex)
   9311   1.1  christos 		{
   9312   1.1  christos 		  specs[count++] = tmpl;
   9313   1.1  christos 		}
   9314   1.1  christos 	      else if (!rsrc_write)
   9315   1.1  christos 		{
   9316   1.1  christos 		  /* Reads from CR[IVR] affect other resources.  */
   9317   1.1  christos 		  if (regno == CR_IVR)
   9318   1.1  christos 		    {
   9319   1.1  christos 		      if ((dep->regindex >= CR_IRR0
   9320   1.1  christos 			   && dep->regindex <= CR_IRR3)
   9321   1.1  christos 			  || dep->regindex == CR_TPR)
   9322   1.1  christos 			{
   9323   1.1  christos 			  specs[count++] = tmpl;
   9324   1.1  christos 			}
   9325   1.1  christos 		    }
   9326   1.1  christos 		}
   9327   1.1  christos 	    }
   9328   1.1  christos 	  else
   9329   1.1  christos 	    {
   9330   1.1  christos 	      specs[count++] = tmpl;
   9331   1.1  christos 	    }
   9332   1.1  christos 	}
   9333   1.1  christos       else
   9334   1.1  christos 	{
   9335   1.1  christos 	  UNHANDLED;
   9336   1.1  christos 	}
   9337   1.1  christos       break;
   9338   1.1  christos 
   9339   1.1  christos     case IA64_RS_INSERVICE:
   9340   1.1  christos       /* look for write of EOI (67) or read of IVR (65) */
   9341   1.1  christos       if ((idesc->operands[0] == IA64_OPND_CR3
   9342   1.1  christos 	   && CURR_SLOT.opnd[0].X_add_number - REG_CR == CR_EOI)
   9343   1.1  christos 	  || (idesc->operands[1] == IA64_OPND_CR3
   9344   1.1  christos 	      && CURR_SLOT.opnd[1].X_add_number - REG_CR == CR_IVR))
   9345   1.1  christos 	{
   9346   1.1  christos 	  specs[count++] = tmpl;
   9347   1.1  christos 	}
   9348   1.1  christos       break;
   9349   1.1  christos 
   9350   1.1  christos     case IA64_RS_GR0:
   9351   1.1  christos       if (note == 1)
   9352   1.1  christos 	{
   9353   1.1  christos 	  specs[count++] = tmpl;
   9354   1.1  christos 	}
   9355   1.1  christos       else
   9356   1.1  christos 	{
   9357   1.1  christos 	  UNHANDLED;
   9358   1.1  christos 	}
   9359   1.1  christos       break;
   9360   1.1  christos 
   9361   1.1  christos     case IA64_RS_CFM:
   9362   1.1  christos       if (note != 2)
   9363   1.1  christos 	{
   9364   1.1  christos 	  specs[count++] = tmpl;
   9365   1.1  christos 	}
   9366   1.1  christos       else
   9367   1.1  christos 	{
   9368   1.1  christos 	  /* Check if any of the registers accessed are in the rotating region.
   9369   1.1  christos 	     mov to/from pr accesses CFM only when qp_regno is in the rotating
   9370   1.1  christos 	     region */
   9371   1.1  christos 	  for (i = 0; i < NELEMS (idesc->operands); i++)
   9372   1.1  christos 	    {
   9373   1.1  christos 	      if (idesc->operands[i] == IA64_OPND_R1
   9374   1.1  christos 		  || idesc->operands[i] == IA64_OPND_R2
   9375   1.1  christos 		  || idesc->operands[i] == IA64_OPND_R3)
   9376   1.1  christos 		{
   9377   1.1  christos 		  int num = CURR_SLOT.opnd[i].X_add_number - REG_GR;
   9378   1.1  christos 		  /* Assumes that md.rot.num_regs is always valid */
   9379   1.1  christos 		  if (md.rot.num_regs > 0
   9380   1.1  christos 		      && num > 31
   9381   1.1  christos 		      && num < 31 + md.rot.num_regs)
   9382   1.1  christos 		    {
   9383   1.1  christos 		      specs[count] = tmpl;
   9384   1.1  christos 		      specs[count++].specific = 0;
   9385   1.1  christos 		    }
   9386   1.1  christos 		}
   9387   1.1  christos 	      else if (idesc->operands[i] == IA64_OPND_F1
   9388   1.1  christos 		       || idesc->operands[i] == IA64_OPND_F2
   9389   1.1  christos 		       || idesc->operands[i] == IA64_OPND_F3
   9390   1.1  christos 		       || idesc->operands[i] == IA64_OPND_F4)
   9391   1.1  christos 		{
   9392   1.1  christos 		  int num = CURR_SLOT.opnd[i].X_add_number - REG_FR;
   9393   1.1  christos 		  if (num > 31)
   9394   1.1  christos 		    {
   9395   1.1  christos 		      specs[count] = tmpl;
   9396   1.1  christos 		      specs[count++].specific = 0;
   9397   1.1  christos 		    }
   9398   1.1  christos 		}
   9399   1.1  christos 	      else if (idesc->operands[i] == IA64_OPND_P1
   9400   1.1  christos 		       || idesc->operands[i] == IA64_OPND_P2)
   9401   1.1  christos 		{
   9402   1.1  christos 		  int num = CURR_SLOT.opnd[i].X_add_number - REG_P;
   9403   1.1  christos 		  if (num > 15)
   9404   1.1  christos 		    {
   9405   1.1  christos 		      specs[count] = tmpl;
   9406   1.1  christos 		      specs[count++].specific = 0;
   9407   1.1  christos 		    }
   9408   1.1  christos 		}
   9409   1.1  christos 	    }
   9410   1.1  christos 	  if (CURR_SLOT.qp_regno > 15)
   9411   1.1  christos 	    {
   9412   1.1  christos 	      specs[count] = tmpl;
   9413   1.1  christos 	      specs[count++].specific = 0;
   9414   1.1  christos 	    }
   9415   1.1  christos 	}
   9416   1.1  christos       break;
   9417   1.1  christos 
   9418   1.1  christos       /* This is the same as IA64_RS_PRr, except simplified to account for
   9419   1.1  christos 	 the fact that there is only one register.  */
   9420   1.1  christos     case IA64_RS_PR63:
   9421   1.1  christos       if (note == 0)
   9422   1.1  christos 	{
   9423   1.1  christos 	  specs[count++] = tmpl;
   9424   1.1  christos 	}
   9425   1.1  christos       else if (note == 7)
   9426   1.1  christos 	{
   9427   1.1  christos 	  valueT mask = 0;
   9428   1.1  christos 	  if (idesc->operands[2] == IA64_OPND_IMM17)
   9429   1.1  christos 	    mask = CURR_SLOT.opnd[2].X_add_number;
   9430   1.1  christos 	  if (mask & ((valueT) 1 << 63))
   9431   1.1  christos 	    specs[count++] = tmpl;
   9432   1.1  christos 	}
   9433   1.1  christos       else if (note == 11)
   9434   1.1  christos 	{
   9435   1.1  christos 	  if ((idesc->operands[0] == IA64_OPND_P1
   9436   1.1  christos 	       && CURR_SLOT.opnd[0].X_add_number - REG_P == 63)
   9437   1.1  christos 	      || (idesc->operands[1] == IA64_OPND_P2
   9438   1.1  christos 		  && CURR_SLOT.opnd[1].X_add_number - REG_P == 63))
   9439   1.1  christos 	    {
   9440   1.1  christos 	      specs[count++] = tmpl;
   9441   1.1  christos 	    }
   9442   1.1  christos 	}
   9443   1.1  christos       else if (note == 12)
   9444   1.1  christos 	{
   9445   1.1  christos 	  if (CURR_SLOT.qp_regno == 63)
   9446   1.1  christos 	    {
   9447   1.1  christos 	      specs[count++] = tmpl;
   9448   1.1  christos 	    }
   9449   1.1  christos 	}
   9450   1.1  christos       else if (note == 1)
   9451   1.1  christos 	{
   9452   1.1  christos 	  if (rsrc_write)
   9453   1.1  christos 	    {
   9454   1.1  christos 	      int p1 = CURR_SLOT.opnd[0].X_add_number - REG_P;
   9455   1.1  christos 	      int p2 = CURR_SLOT.opnd[1].X_add_number - REG_P;
   9456   1.1  christos 	      int or_andcm = strstr (idesc->name, "or.andcm") != NULL;
   9457   1.1  christos 	      int and_orcm = strstr (idesc->name, "and.orcm") != NULL;
   9458   1.1  christos 
   9459   1.1  christos 	      if (p1 == 63
   9460   1.1  christos 		  && (idesc->operands[0] == IA64_OPND_P1
   9461   1.1  christos 		      || idesc->operands[0] == IA64_OPND_P2))
   9462   1.1  christos 		{
   9463   1.1  christos 		  specs[count] = tmpl;
   9464   1.1  christos 		  specs[count++].cmp_type =
   9465   1.1  christos 		    (or_andcm ? CMP_OR : (and_orcm ? CMP_AND : CMP_NONE));
   9466   1.1  christos 		}
   9467   1.1  christos 	      if (p2 == 63
   9468   1.1  christos 		  && (idesc->operands[1] == IA64_OPND_P1
   9469   1.1  christos 		      || idesc->operands[1] == IA64_OPND_P2))
   9470   1.1  christos 		{
   9471   1.1  christos 		  specs[count] = tmpl;
   9472   1.1  christos 		  specs[count++].cmp_type =
   9473   1.1  christos 		    (or_andcm ? CMP_AND : (and_orcm ? CMP_OR : CMP_NONE));
   9474   1.1  christos 		}
   9475   1.1  christos 	    }
   9476   1.1  christos 	  else
   9477   1.1  christos 	    {
   9478   1.1  christos 	      if (CURR_SLOT.qp_regno == 63)
   9479   1.1  christos 		{
   9480   1.1  christos 		  specs[count++] = tmpl;
   9481   1.1  christos 		}
   9482   1.1  christos 	    }
   9483   1.1  christos 	}
   9484   1.1  christos       else
   9485   1.1  christos 	{
   9486   1.1  christos 	  UNHANDLED;
   9487   1.1  christos 	}
   9488   1.1  christos       break;
   9489   1.1  christos 
   9490   1.1  christos     case IA64_RS_RSE:
   9491   1.1  christos       /* FIXME we can identify some individual RSE written resources, but RSE
   9492   1.1  christos 	 read resources have not yet been completely identified, so for now
   9493   1.1  christos 	 treat RSE as a single resource */
   9494   1.8  christos       if (startswith (idesc->name, "mov"))
   9495   1.1  christos 	{
   9496   1.1  christos 	  if (rsrc_write)
   9497   1.1  christos 	    {
   9498   1.1  christos 	      if (idesc->operands[0] == IA64_OPND_AR3
   9499   1.1  christos 		  && CURR_SLOT.opnd[0].X_add_number - REG_AR == AR_BSPSTORE)
   9500   1.1  christos 		{
   9501   1.1  christos 		  specs[count++] = tmpl;
   9502   1.1  christos 		}
   9503   1.1  christos 	    }
   9504   1.1  christos 	  else
   9505   1.1  christos 	    {
   9506   1.1  christos 	      if (idesc->operands[0] == IA64_OPND_AR3)
   9507   1.1  christos 		{
   9508   1.1  christos 		  if (CURR_SLOT.opnd[0].X_add_number - REG_AR == AR_BSPSTORE
   9509   1.1  christos 		      || CURR_SLOT.opnd[0].X_add_number - REG_AR == AR_RNAT)
   9510   1.1  christos 		    {
   9511   1.1  christos 		      specs[count++] = tmpl;
   9512   1.1  christos 		    }
   9513   1.1  christos 		}
   9514   1.1  christos 	      else if (idesc->operands[1] == IA64_OPND_AR3)
   9515   1.1  christos 		{
   9516   1.1  christos 		  if (CURR_SLOT.opnd[1].X_add_number - REG_AR == AR_BSP
   9517   1.1  christos 		      || CURR_SLOT.opnd[1].X_add_number - REG_AR == AR_BSPSTORE
   9518   1.1  christos 		      || CURR_SLOT.opnd[1].X_add_number - REG_AR == AR_RNAT)
   9519   1.1  christos 		    {
   9520   1.1  christos 		      specs[count++] = tmpl;
   9521   1.1  christos 		    }
   9522   1.1  christos 		}
   9523   1.1  christos 	    }
   9524   1.1  christos 	}
   9525   1.1  christos       else
   9526   1.1  christos 	{
   9527   1.1  christos 	  specs[count++] = tmpl;
   9528   1.1  christos 	}
   9529   1.1  christos       break;
   9530   1.1  christos 
   9531   1.1  christos     case IA64_RS_ANY:
   9532   1.1  christos       /* FIXME -- do any of these need to be non-specific? */
   9533   1.1  christos       specs[count++] = tmpl;
   9534   1.1  christos       break;
   9535   1.1  christos 
   9536   1.1  christos     default:
   9537   1.1  christos       as_bad (_("Unrecognized dependency specifier %d\n"), dep->specifier);
   9538   1.1  christos       break;
   9539   1.1  christos     }
   9540   1.1  christos 
   9541   1.1  christos   return count;
   9542   1.1  christos }
   9543   1.1  christos 
   9544   1.1  christos /* Clear branch flags on marked resources.  This breaks the link between the
   9545   1.1  christos    QP of the marking instruction and a subsequent branch on the same QP.  */
   9546   1.1  christos 
   9547   1.1  christos static void
   9548   1.1  christos clear_qp_branch_flag (valueT mask)
   9549   1.1  christos {
   9550   1.1  christos   int i;
   9551   1.1  christos   for (i = 0; i < regdepslen; i++)
   9552   1.1  christos     {
   9553   1.1  christos       valueT bit = ((valueT) 1 << regdeps[i].qp_regno);
   9554   1.1  christos       if ((bit & mask) != 0)
   9555   1.1  christos 	{
   9556   1.1  christos 	  regdeps[i].link_to_qp_branch = 0;
   9557   1.1  christos 	}
   9558   1.1  christos     }
   9559   1.1  christos }
   9560   1.1  christos 
   9561   1.1  christos /* MASK contains 2 and only 2 PRs which are mutually exclusive.  Remove
   9562   1.1  christos    any mutexes which contain one of the PRs and create new ones when
   9563   1.1  christos    needed.  */
   9564   1.1  christos 
   9565   1.1  christos static int
   9566   1.1  christos update_qp_mutex (valueT mask)
   9567   1.1  christos {
   9568   1.1  christos   int i;
   9569   1.1  christos   int add = 0;
   9570   1.1  christos 
   9571   1.1  christos   i = 0;
   9572   1.1  christos   while (i < qp_mutexeslen)
   9573   1.1  christos     {
   9574   1.1  christos       if ((qp_mutexes[i].prmask & mask) != 0)
   9575   1.1  christos 	{
   9576   1.1  christos 	  /* If it destroys and creates the same mutex, do nothing.  */
   9577   1.1  christos 	  if (qp_mutexes[i].prmask == mask
   9578   1.1  christos 	      && qp_mutexes[i].path == md.path)
   9579   1.1  christos 	    {
   9580   1.1  christos 	      i++;
   9581   1.1  christos 	      add = -1;
   9582   1.1  christos 	    }
   9583   1.1  christos 	  else
   9584   1.1  christos 	    {
   9585   1.1  christos 	      int keep = 0;
   9586   1.1  christos 
   9587   1.1  christos 	      if (md.debug_dv)
   9588   1.1  christos 		{
   9589   1.1  christos 		  fprintf (stderr, "  Clearing mutex relation");
   9590   1.1  christos 		  print_prmask (qp_mutexes[i].prmask);
   9591   1.1  christos 		  fprintf (stderr, "\n");
   9592   1.1  christos 		}
   9593   1.3  christos 
   9594   1.1  christos 	      /* Deal with the old mutex with more than 3+ PRs only if
   9595   1.1  christos 		 the new mutex on the same execution path with it.
   9596   1.1  christos 
   9597   1.1  christos 		 FIXME: The 3+ mutex support is incomplete.
   9598   1.1  christos 		 dot_pred_rel () may be a better place to fix it.  */
   9599   1.1  christos 	      if (qp_mutexes[i].path == md.path)
   9600   1.1  christos 		{
   9601   1.1  christos 		  /* If it is a proper subset of the mutex, create a
   9602   1.1  christos 		     new mutex.  */
   9603   1.1  christos 		  if (add == 0
   9604   1.1  christos 		      && (qp_mutexes[i].prmask & mask) == mask)
   9605   1.1  christos 		    add = 1;
   9606   1.3  christos 
   9607   1.1  christos 		  qp_mutexes[i].prmask &= ~mask;
   9608   1.1  christos 		  if (qp_mutexes[i].prmask & (qp_mutexes[i].prmask - 1))
   9609   1.1  christos 		    {
   9610   1.1  christos 		      /* Modify the mutex if there are more than one
   9611   1.1  christos 			 PR left.  */
   9612   1.1  christos 		      keep = 1;
   9613   1.1  christos 		      i++;
   9614   1.1  christos 		    }
   9615   1.1  christos 		}
   9616   1.3  christos 
   9617   1.1  christos 	      if (keep == 0)
   9618   1.1  christos 		/* Remove the mutex.  */
   9619   1.1  christos 		qp_mutexes[i] = qp_mutexes[--qp_mutexeslen];
   9620   1.1  christos 	    }
   9621   1.1  christos 	}
   9622   1.1  christos       else
   9623   1.1  christos 	++i;
   9624   1.1  christos     }
   9625   1.1  christos 
   9626   1.1  christos   if (add == 1)
   9627   1.1  christos     add_qp_mutex (mask);
   9628   1.1  christos 
   9629   1.1  christos   return add;
   9630   1.1  christos }
   9631   1.1  christos 
   9632   1.1  christos /* Remove any mutexes which contain any of the PRs indicated in the mask.
   9633   1.1  christos 
   9634   1.1  christos    Any changes to a PR clears the mutex relations which include that PR.  */
   9635   1.1  christos 
   9636   1.1  christos static void
   9637   1.1  christos clear_qp_mutex (valueT mask)
   9638   1.1  christos {
   9639   1.1  christos   int i;
   9640   1.1  christos 
   9641   1.1  christos   i = 0;
   9642   1.1  christos   while (i < qp_mutexeslen)
   9643   1.1  christos     {
   9644   1.1  christos       if ((qp_mutexes[i].prmask & mask) != 0)
   9645   1.1  christos 	{
   9646   1.1  christos 	  if (md.debug_dv)
   9647   1.1  christos 	    {
   9648   1.1  christos 	      fprintf (stderr, "  Clearing mutex relation");
   9649   1.1  christos 	      print_prmask (qp_mutexes[i].prmask);
   9650   1.1  christos 	      fprintf (stderr, "\n");
   9651   1.1  christos 	    }
   9652   1.1  christos 	  qp_mutexes[i] = qp_mutexes[--qp_mutexeslen];
   9653   1.1  christos 	}
   9654   1.1  christos       else
   9655   1.1  christos 	++i;
   9656   1.1  christos     }
   9657   1.1  christos }
   9658   1.1  christos 
   9659   1.1  christos /* Clear implies relations which contain PRs in the given masks.
   9660   1.1  christos    P1_MASK indicates the source of the implies relation, while P2_MASK
   9661   1.1  christos    indicates the implied PR.  */
   9662   1.1  christos 
   9663   1.1  christos static void
   9664   1.1  christos clear_qp_implies (valueT p1_mask, valueT p2_mask)
   9665   1.1  christos {
   9666   1.1  christos   int i;
   9667   1.1  christos 
   9668   1.1  christos   i = 0;
   9669   1.1  christos   while (i < qp_implieslen)
   9670   1.1  christos     {
   9671   1.1  christos       if ((((valueT) 1 << qp_implies[i].p1) & p1_mask) != 0
   9672   1.1  christos 	  || (((valueT) 1 << qp_implies[i].p2) & p2_mask) != 0)
   9673   1.1  christos 	{
   9674   1.1  christos 	  if (md.debug_dv)
   9675   1.1  christos 	    fprintf (stderr, "Clearing implied relation PR%d->PR%d\n",
   9676   1.1  christos 		     qp_implies[i].p1, qp_implies[i].p2);
   9677   1.1  christos 	  qp_implies[i] = qp_implies[--qp_implieslen];
   9678   1.1  christos 	}
   9679   1.1  christos       else
   9680   1.1  christos 	++i;
   9681   1.1  christos     }
   9682   1.1  christos }
   9683   1.1  christos 
   9684   1.1  christos /* Add the PRs specified to the list of implied relations.  */
   9685   1.1  christos 
   9686   1.1  christos static void
   9687   1.1  christos add_qp_imply (int p1, int p2)
   9688   1.1  christos {
   9689   1.1  christos   valueT mask;
   9690   1.1  christos   valueT bit;
   9691   1.1  christos   int i;
   9692   1.1  christos 
   9693   1.1  christos   /* p0 is not meaningful here.  */
   9694   1.1  christos   if (p1 == 0 || p2 == 0)
   9695   1.1  christos     abort ();
   9696   1.1  christos 
   9697   1.1  christos   if (p1 == p2)
   9698   1.1  christos     return;
   9699   1.1  christos 
   9700   1.1  christos   /* If it exists already, ignore it.  */
   9701   1.1  christos   for (i = 0; i < qp_implieslen; i++)
   9702   1.1  christos     {
   9703   1.1  christos       if (qp_implies[i].p1 == p1
   9704   1.1  christos 	  && qp_implies[i].p2 == p2
   9705   1.1  christos 	  && qp_implies[i].path == md.path
   9706   1.1  christos 	  && !qp_implies[i].p2_branched)
   9707   1.1  christos 	return;
   9708   1.1  christos     }
   9709   1.1  christos 
   9710   1.1  christos   if (qp_implieslen == qp_impliestotlen)
   9711   1.1  christos     {
   9712   1.1  christos       qp_impliestotlen += 20;
   9713   1.5  christos       qp_implies = XRESIZEVEC (struct qp_imply, qp_implies, qp_impliestotlen);
   9714   1.1  christos     }
   9715   1.1  christos   if (md.debug_dv)
   9716   1.1  christos     fprintf (stderr, "  Registering PR%d implies PR%d\n", p1, p2);
   9717   1.1  christos   qp_implies[qp_implieslen].p1 = p1;
   9718   1.1  christos   qp_implies[qp_implieslen].p2 = p2;
   9719   1.1  christos   qp_implies[qp_implieslen].path = md.path;
   9720   1.1  christos   qp_implies[qp_implieslen++].p2_branched = 0;
   9721   1.1  christos 
   9722   1.1  christos   /* Add in the implied transitive relations; for everything that p2 implies,
   9723   1.1  christos      make p1 imply that, too; for everything that implies p1, make it imply p2
   9724   1.1  christos      as well.  */
   9725   1.1  christos   for (i = 0; i < qp_implieslen; i++)
   9726   1.1  christos     {
   9727   1.1  christos       if (qp_implies[i].p1 == p2)
   9728   1.1  christos 	add_qp_imply (p1, qp_implies[i].p2);
   9729   1.1  christos       if (qp_implies[i].p2 == p1)
   9730   1.1  christos 	add_qp_imply (qp_implies[i].p1, p2);
   9731   1.1  christos     }
   9732   1.1  christos   /* Add in mutex relations implied by this implies relation; for each mutex
   9733   1.1  christos      relation containing p2, duplicate it and replace p2 with p1.  */
   9734   1.1  christos   bit = (valueT) 1 << p1;
   9735   1.1  christos   mask = (valueT) 1 << p2;
   9736   1.1  christos   for (i = 0; i < qp_mutexeslen; i++)
   9737   1.1  christos     {
   9738   1.1  christos       if (qp_mutexes[i].prmask & mask)
   9739   1.1  christos 	add_qp_mutex ((qp_mutexes[i].prmask & ~mask) | bit);
   9740   1.1  christos     }
   9741   1.1  christos }
   9742   1.1  christos 
   9743   1.1  christos /* Add the PRs specified in the mask to the mutex list; this means that only
   9744   1.1  christos    one of the PRs can be true at any time.  PR0 should never be included in
   9745   1.1  christos    the mask.  */
   9746   1.1  christos 
   9747   1.1  christos static void
   9748   1.1  christos add_qp_mutex (valueT mask)
   9749   1.1  christos {
   9750   1.1  christos   if (mask & 0x1)
   9751   1.1  christos     abort ();
   9752   1.1  christos 
   9753   1.1  christos   if (qp_mutexeslen == qp_mutexestotlen)
   9754   1.1  christos     {
   9755   1.1  christos       qp_mutexestotlen += 20;
   9756   1.5  christos       qp_mutexes = XRESIZEVEC (struct qpmutex, qp_mutexes, qp_mutexestotlen);
   9757   1.1  christos     }
   9758   1.1  christos   if (md.debug_dv)
   9759   1.1  christos     {
   9760   1.1  christos       fprintf (stderr, "  Registering mutex on");
   9761   1.1  christos       print_prmask (mask);
   9762   1.1  christos       fprintf (stderr, "\n");
   9763   1.1  christos     }
   9764   1.1  christos   qp_mutexes[qp_mutexeslen].path = md.path;
   9765   1.1  christos   qp_mutexes[qp_mutexeslen++].prmask = mask;
   9766   1.1  christos }
   9767   1.1  christos 
   9768   1.1  christos static int
   9769   1.1  christos has_suffix_p (const char *name, const char *suffix)
   9770   1.1  christos {
   9771   1.1  christos   size_t namelen = strlen (name);
   9772   1.1  christos   size_t sufflen = strlen (suffix);
   9773   1.1  christos 
   9774   1.1  christos   if (namelen <= sufflen)
   9775   1.1  christos     return 0;
   9776   1.1  christos   return strcmp (name + namelen - sufflen, suffix) == 0;
   9777   1.1  christos }
   9778   1.1  christos 
   9779   1.1  christos static void
   9780   1.1  christos clear_register_values (void)
   9781   1.1  christos {
   9782   1.1  christos   int i;
   9783   1.1  christos   if (md.debug_dv)
   9784   1.1  christos     fprintf (stderr, "  Clearing register values\n");
   9785   1.1  christos   for (i = 1; i < NELEMS (gr_values); i++)
   9786   1.1  christos     gr_values[i].known = 0;
   9787   1.1  christos }
   9788   1.1  christos 
   9789   1.1  christos /* Keep track of register values/changes which affect DV tracking.
   9790   1.1  christos 
   9791   1.1  christos    optimization note: should add a flag to classes of insns where otherwise we
   9792   1.1  christos    have to examine a group of strings to identify them.  */
   9793   1.1  christos 
   9794   1.1  christos static void
   9795   1.1  christos note_register_values (struct ia64_opcode *idesc)
   9796   1.1  christos {
   9797   1.1  christos   valueT qp_changemask = 0;
   9798   1.1  christos   int i;
   9799   1.1  christos 
   9800   1.1  christos   /* Invalidate values for registers being written to.  */
   9801   1.1  christos   for (i = 0; i < idesc->num_outputs; i++)
   9802   1.1  christos     {
   9803   1.1  christos       if (idesc->operands[i] == IA64_OPND_R1
   9804   1.1  christos 	  || idesc->operands[i] == IA64_OPND_R2
   9805   1.1  christos 	  || idesc->operands[i] == IA64_OPND_R3)
   9806   1.1  christos 	{
   9807   1.1  christos 	  int regno = CURR_SLOT.opnd[i].X_add_number - REG_GR;
   9808   1.1  christos 	  if (regno > 0 && regno < NELEMS (gr_values))
   9809   1.1  christos 	    gr_values[regno].known = 0;
   9810   1.1  christos 	}
   9811   1.1  christos       else if (idesc->operands[i] == IA64_OPND_R3_2)
   9812   1.1  christos 	{
   9813   1.1  christos 	  int regno = CURR_SLOT.opnd[i].X_add_number - REG_GR;
   9814   1.1  christos 	  if (regno > 0 && regno < 4)
   9815   1.1  christos 	    gr_values[regno].known = 0;
   9816   1.1  christos 	}
   9817   1.1  christos       else if (idesc->operands[i] == IA64_OPND_P1
   9818   1.1  christos 	       || idesc->operands[i] == IA64_OPND_P2)
   9819   1.1  christos 	{
   9820   1.1  christos 	  int regno = CURR_SLOT.opnd[i].X_add_number - REG_P;
   9821   1.1  christos 	  qp_changemask |= (valueT) 1 << regno;
   9822   1.1  christos 	}
   9823   1.1  christos       else if (idesc->operands[i] == IA64_OPND_PR)
   9824   1.1  christos 	{
   9825   1.1  christos 	  if (idesc->operands[2] & (valueT) 0x10000)
   9826   1.1  christos 	    qp_changemask = ~(valueT) 0x1FFFF | idesc->operands[2];
   9827   1.1  christos 	  else
   9828   1.1  christos 	    qp_changemask = idesc->operands[2];
   9829   1.1  christos 	  break;
   9830   1.1  christos 	}
   9831   1.1  christos       else if (idesc->operands[i] == IA64_OPND_PR_ROT)
   9832   1.1  christos 	{
   9833   1.1  christos 	  if (idesc->operands[1] & ((valueT) 1 << 43))
   9834   1.1  christos 	    qp_changemask = -((valueT) 1 << 44) | idesc->operands[1];
   9835   1.1  christos 	  else
   9836   1.1  christos 	    qp_changemask = idesc->operands[1];
   9837   1.1  christos 	  qp_changemask &= ~(valueT) 0xFFFF;
   9838   1.1  christos 	  break;
   9839   1.1  christos 	}
   9840   1.1  christos     }
   9841   1.1  christos 
   9842   1.1  christos   /* Always clear qp branch flags on any PR change.  */
   9843   1.1  christos   /* FIXME there may be exceptions for certain compares.  */
   9844   1.1  christos   clear_qp_branch_flag (qp_changemask);
   9845   1.1  christos 
   9846   1.1  christos   /* Invalidate rotating registers on insns which affect RRBs in CFM.  */
   9847   1.1  christos   if (idesc->flags & IA64_OPCODE_MOD_RRBS)
   9848   1.1  christos     {
   9849   1.1  christos       qp_changemask |= ~(valueT) 0xFFFF;
   9850   1.1  christos       if (strcmp (idesc->name, "clrrrb.pr") != 0)
   9851   1.1  christos 	{
   9852   1.1  christos 	  for (i = 32; i < 32 + md.rot.num_regs; i++)
   9853   1.1  christos 	    gr_values[i].known = 0;
   9854   1.1  christos 	}
   9855   1.1  christos       clear_qp_mutex (qp_changemask);
   9856   1.1  christos       clear_qp_implies (qp_changemask, qp_changemask);
   9857   1.1  christos     }
   9858   1.1  christos   /* After a call, all register values are undefined, except those marked
   9859   1.1  christos      as "safe".  */
   9860   1.8  christos   else if (startswith (idesc->name, "br.call")
   9861   1.8  christos 	   || startswith (idesc->name, "brl.call"))
   9862   1.1  christos     {
   9863   1.1  christos       /* FIXME keep GR values which are marked as "safe_across_calls"  */
   9864   1.1  christos       clear_register_values ();
   9865   1.1  christos       clear_qp_mutex (~qp_safe_across_calls);
   9866   1.1  christos       clear_qp_implies (~qp_safe_across_calls, ~qp_safe_across_calls);
   9867   1.1  christos       clear_qp_branch_flag (~qp_safe_across_calls);
   9868   1.1  christos     }
   9869   1.1  christos   else if (is_interruption_or_rfi (idesc)
   9870   1.1  christos 	   || is_taken_branch (idesc))
   9871   1.1  christos     {
   9872   1.1  christos       clear_register_values ();
   9873   1.1  christos       clear_qp_mutex (~(valueT) 0);
   9874   1.1  christos       clear_qp_implies (~(valueT) 0, ~(valueT) 0);
   9875   1.1  christos     }
   9876   1.1  christos   /* Look for mutex and implies relations.  */
   9877   1.1  christos   else if ((idesc->operands[0] == IA64_OPND_P1
   9878   1.1  christos 	    || idesc->operands[0] == IA64_OPND_P2)
   9879   1.1  christos 	   && (idesc->operands[1] == IA64_OPND_P1
   9880   1.1  christos 	       || idesc->operands[1] == IA64_OPND_P2))
   9881   1.1  christos     {
   9882   1.1  christos       int p1 = CURR_SLOT.opnd[0].X_add_number - REG_P;
   9883   1.1  christos       int p2 = CURR_SLOT.opnd[1].X_add_number - REG_P;
   9884   1.1  christos       valueT p1mask = (p1 != 0) ? (valueT) 1 << p1 : 0;
   9885   1.1  christos       valueT p2mask = (p2 != 0) ? (valueT) 1 << p2 : 0;
   9886   1.1  christos 
   9887   1.1  christos       /* If both PRs are PR0, we can't really do anything.  */
   9888   1.1  christos       if (p1 == 0 && p2 == 0)
   9889   1.1  christos 	{
   9890   1.1  christos 	  if (md.debug_dv)
   9891   1.1  christos 	    fprintf (stderr, "  Ignoring PRs due to inclusion of p0\n");
   9892   1.1  christos 	}
   9893   1.1  christos       /* In general, clear mutexes and implies which include P1 or P2,
   9894   1.1  christos 	 with the following exceptions.  */
   9895   1.1  christos       else if (has_suffix_p (idesc->name, ".or.andcm")
   9896   1.1  christos 	       || has_suffix_p (idesc->name, ".and.orcm"))
   9897   1.1  christos 	{
   9898   1.1  christos 	  clear_qp_implies (p2mask, p1mask);
   9899   1.1  christos 	}
   9900   1.1  christos       else if (has_suffix_p (idesc->name, ".andcm")
   9901   1.1  christos 	       || has_suffix_p (idesc->name, ".and"))
   9902   1.1  christos 	{
   9903   1.1  christos 	  clear_qp_implies (0, p1mask | p2mask);
   9904   1.1  christos 	}
   9905   1.1  christos       else if (has_suffix_p (idesc->name, ".orcm")
   9906   1.1  christos 	       || has_suffix_p (idesc->name, ".or"))
   9907   1.1  christos 	{
   9908   1.1  christos 	  clear_qp_mutex (p1mask | p2mask);
   9909   1.1  christos 	  clear_qp_implies (p1mask | p2mask, 0);
   9910   1.1  christos 	}
   9911   1.1  christos       else
   9912   1.1  christos 	{
   9913   1.1  christos 	  int added = 0;
   9914   1.1  christos 
   9915   1.1  christos 	  clear_qp_implies (p1mask | p2mask, p1mask | p2mask);
   9916   1.1  christos 
   9917   1.1  christos 	  /* If one of the PRs is PR0, we call clear_qp_mutex.  */
   9918   1.1  christos 	  if (p1 == 0 || p2 == 0)
   9919   1.1  christos 	    clear_qp_mutex (p1mask | p2mask);
   9920   1.1  christos 	  else
   9921   1.1  christos 	    added = update_qp_mutex (p1mask | p2mask);
   9922   1.1  christos 
   9923   1.1  christos 	  if (CURR_SLOT.qp_regno == 0
   9924   1.1  christos 	      || has_suffix_p (idesc->name, ".unc"))
   9925   1.1  christos 	    {
   9926   1.1  christos 	      if (added == 0 && p1 && p2)
   9927   1.1  christos 		add_qp_mutex (p1mask | p2mask);
   9928   1.1  christos 	      if (CURR_SLOT.qp_regno != 0)
   9929   1.1  christos 		{
   9930   1.1  christos 		  if (p1)
   9931   1.1  christos 		    add_qp_imply (p1, CURR_SLOT.qp_regno);
   9932   1.1  christos 		  if (p2)
   9933   1.1  christos 		    add_qp_imply (p2, CURR_SLOT.qp_regno);
   9934   1.1  christos 		}
   9935   1.1  christos 	    }
   9936   1.1  christos 	}
   9937   1.1  christos     }
   9938   1.1  christos   /* Look for mov imm insns into GRs.  */
   9939   1.1  christos   else if (idesc->operands[0] == IA64_OPND_R1
   9940   1.1  christos 	   && (idesc->operands[1] == IA64_OPND_IMM22
   9941   1.1  christos 	       || idesc->operands[1] == IA64_OPND_IMMU64)
   9942   1.1  christos 	   && CURR_SLOT.opnd[1].X_op == O_constant
   9943   1.1  christos 	   && (strcmp (idesc->name, "mov") == 0
   9944   1.1  christos 	       || strcmp (idesc->name, "movl") == 0))
   9945   1.1  christos     {
   9946   1.1  christos       int regno = CURR_SLOT.opnd[0].X_add_number - REG_GR;
   9947   1.1  christos       if (regno > 0 && regno < NELEMS (gr_values))
   9948   1.1  christos 	{
   9949   1.1  christos 	  gr_values[regno].known = 1;
   9950   1.1  christos 	  gr_values[regno].value = CURR_SLOT.opnd[1].X_add_number;
   9951   1.1  christos 	  gr_values[regno].path = md.path;
   9952   1.1  christos 	  if (md.debug_dv)
   9953   1.9  christos 	    fprintf (stderr, "  Know gr%d = %" PRIx64 "\n",
   9954   1.9  christos 		     regno, gr_values[regno].value);
   9955   1.1  christos 	}
   9956   1.1  christos     }
   9957   1.1  christos   /* Look for dep.z imm insns.  */
   9958   1.1  christos   else if (idesc->operands[0] == IA64_OPND_R1
   9959   1.1  christos 	   && idesc->operands[1] == IA64_OPND_IMM8
   9960   1.1  christos 	   && strcmp (idesc->name, "dep.z") == 0)
   9961   1.1  christos     {
   9962   1.1  christos       int regno = CURR_SLOT.opnd[0].X_add_number - REG_GR;
   9963   1.1  christos       if (regno > 0 && regno < NELEMS (gr_values))
   9964   1.1  christos 	{
   9965   1.1  christos 	  valueT value = CURR_SLOT.opnd[1].X_add_number;
   9966   1.1  christos 
   9967   1.1  christos 	  if (CURR_SLOT.opnd[3].X_add_number < 64)
   9968   1.1  christos 	    value &= ((valueT)1 << CURR_SLOT.opnd[3].X_add_number) - 1;
   9969   1.1  christos 	  value <<= CURR_SLOT.opnd[2].X_add_number;
   9970   1.1  christos 	  gr_values[regno].known = 1;
   9971   1.1  christos 	  gr_values[regno].value = value;
   9972   1.1  christos 	  gr_values[regno].path = md.path;
   9973   1.1  christos 	  if (md.debug_dv)
   9974   1.9  christos 	    fprintf (stderr, "  Know gr%d = %" PRIx64 "\n",
   9975   1.9  christos 		     regno, gr_values[regno].value);
   9976   1.1  christos 	}
   9977   1.1  christos     }
   9978   1.1  christos   else
   9979   1.1  christos     {
   9980   1.1  christos       clear_qp_mutex (qp_changemask);
   9981   1.1  christos       clear_qp_implies (qp_changemask, qp_changemask);
   9982   1.1  christos     }
   9983   1.1  christos }
   9984   1.1  christos 
   9985   1.1  christos /* Return whether the given predicate registers are currently mutex.  */
   9986   1.1  christos 
   9987   1.1  christos static int
   9988   1.1  christos qp_mutex (int p1, int p2, int path)
   9989   1.1  christos {
   9990   1.1  christos   int i;
   9991   1.1  christos   valueT mask;
   9992   1.1  christos 
   9993   1.1  christos   if (p1 != p2)
   9994   1.1  christos     {
   9995   1.1  christos       mask = ((valueT) 1 << p1) | (valueT) 1 << p2;
   9996   1.1  christos       for (i = 0; i < qp_mutexeslen; i++)
   9997   1.1  christos 	{
   9998   1.1  christos 	  if (qp_mutexes[i].path >= path
   9999   1.1  christos 	      && (qp_mutexes[i].prmask & mask) == mask)
   10000   1.1  christos 	    return 1;
   10001   1.1  christos 	}
   10002   1.1  christos     }
   10003   1.1  christos   return 0;
   10004   1.1  christos }
   10005   1.1  christos 
   10006   1.1  christos /* Return whether the given resource is in the given insn's list of chks
   10007   1.1  christos    Return 1 if the conflict is absolutely determined, 2 if it's a potential
   10008   1.1  christos    conflict.  */
   10009   1.1  christos 
   10010   1.1  christos static int
   10011   1.1  christos resources_match (struct rsrc *rs,
   10012   1.1  christos 		 struct ia64_opcode *idesc,
   10013   1.1  christos 		 int note,
   10014   1.1  christos 		 int qp_regno,
   10015   1.1  christos 		 int path)
   10016   1.1  christos {
   10017   1.1  christos   struct rsrc specs[MAX_SPECS];
   10018   1.1  christos   int count;
   10019   1.1  christos 
   10020   1.1  christos   /* If the marked resource's qp_regno and the given qp_regno are mutex,
   10021   1.1  christos      we don't need to check.  One exception is note 11, which indicates that
   10022   1.1  christos      target predicates are written regardless of PR[qp].  */
   10023   1.1  christos   if (qp_mutex (rs->qp_regno, qp_regno, path)
   10024   1.1  christos       && note != 11)
   10025   1.1  christos     return 0;
   10026   1.1  christos 
   10027   1.1  christos   count = specify_resource (rs->dependency, idesc, DV_CHK, specs, note, path);
   10028   1.1  christos   while (count-- > 0)
   10029   1.1  christos     {
   10030   1.1  christos       /* UNAT checking is a bit more specific than other resources */
   10031   1.1  christos       if (rs->dependency->specifier == IA64_RS_AR_UNAT
   10032   1.1  christos 	  && specs[count].mem_offset.hint
   10033   1.1  christos 	  && rs->mem_offset.hint)
   10034   1.1  christos 	{
   10035   1.1  christos 	  if (rs->mem_offset.base == specs[count].mem_offset.base)
   10036   1.1  christos 	    {
   10037   1.1  christos 	      if (((rs->mem_offset.offset >> 3) & 0x3F) ==
   10038   1.1  christos 		  ((specs[count].mem_offset.offset >> 3) & 0x3F))
   10039   1.1  christos 		return 1;
   10040   1.1  christos 	      else
   10041   1.1  christos 		continue;
   10042   1.1  christos 	    }
   10043   1.1  christos 	}
   10044   1.1  christos 
   10045   1.1  christos       /* Skip apparent PR write conflicts where both writes are an AND or both
   10046   1.1  christos 	 writes are an OR.  */
   10047   1.1  christos       if (rs->dependency->specifier == IA64_RS_PR
   10048   1.1  christos 	  || rs->dependency->specifier == IA64_RS_PRr
   10049   1.1  christos 	  || rs->dependency->specifier == IA64_RS_PR63)
   10050   1.1  christos 	{
   10051   1.1  christos 	  if (specs[count].cmp_type != CMP_NONE
   10052   1.1  christos 	      && specs[count].cmp_type == rs->cmp_type)
   10053   1.1  christos 	    {
   10054   1.1  christos 	      if (md.debug_dv)
   10055   1.1  christos 		fprintf (stderr, "  %s on parallel compare allowed (PR%d)\n",
   10056   1.1  christos 			 dv_mode[rs->dependency->mode],
   10057   1.1  christos 			 rs->dependency->specifier != IA64_RS_PR63 ?
   10058   1.1  christos 			 specs[count].index : 63);
   10059   1.1  christos 	      continue;
   10060   1.1  christos 	    }
   10061   1.1  christos 	  if (md.debug_dv)
   10062   1.1  christos 	    fprintf (stderr,
   10063   1.1  christos 		     "  %s on parallel compare conflict %s vs %s on PR%d\n",
   10064   1.1  christos 		     dv_mode[rs->dependency->mode],
   10065   1.1  christos 		     dv_cmp_type[rs->cmp_type],
   10066   1.1  christos 		     dv_cmp_type[specs[count].cmp_type],
   10067   1.1  christos 		     rs->dependency->specifier != IA64_RS_PR63 ?
   10068   1.1  christos 		     specs[count].index : 63);
   10069   1.1  christos 
   10070   1.1  christos 	}
   10071   1.1  christos 
   10072   1.1  christos       /* If either resource is not specific, conservatively assume a conflict
   10073   1.1  christos        */
   10074   1.1  christos       if (!specs[count].specific || !rs->specific)
   10075   1.1  christos 	return 2;
   10076   1.1  christos       else if (specs[count].index == rs->index)
   10077   1.1  christos 	return 1;
   10078   1.1  christos     }
   10079   1.1  christos 
   10080   1.1  christos   return 0;
   10081   1.1  christos }
   10082   1.1  christos 
   10083   1.1  christos /* Indicate an instruction group break; if INSERT_STOP is non-zero, then
   10084   1.1  christos    insert a stop to create the break.  Update all resource dependencies
   10085   1.1  christos    appropriately.  If QP_REGNO is non-zero, only apply the break to resources
   10086   1.1  christos    which use the same QP_REGNO and have the link_to_qp_branch flag set.
   10087   1.1  christos    If SAVE_CURRENT is non-zero, don't affect resources marked by the current
   10088   1.1  christos    instruction.  */
   10089   1.1  christos 
   10090   1.1  christos static void
   10091   1.1  christos insn_group_break (int insert_stop, int qp_regno, int save_current)
   10092   1.1  christos {
   10093   1.1  christos   int i;
   10094   1.1  christos 
   10095   1.1  christos   if (insert_stop && md.num_slots_in_use > 0)
   10096   1.1  christos     PREV_SLOT.end_of_insn_group = 1;
   10097   1.1  christos 
   10098   1.1  christos   if (md.debug_dv)
   10099   1.1  christos     {
   10100   1.1  christos       fprintf (stderr, "  Insn group break%s",
   10101   1.1  christos 	       (insert_stop ? " (w/stop)" : ""));
   10102   1.1  christos       if (qp_regno != 0)
   10103   1.1  christos 	fprintf (stderr, " effective for QP=%d", qp_regno);
   10104   1.1  christos       fprintf (stderr, "\n");
   10105   1.1  christos     }
   10106   1.1  christos 
   10107   1.1  christos   i = 0;
   10108   1.1  christos   while (i < regdepslen)
   10109   1.1  christos     {
   10110   1.1  christos       const struct ia64_dependency *dep = regdeps[i].dependency;
   10111   1.1  christos 
   10112   1.1  christos       if (qp_regno != 0
   10113   1.1  christos 	  && regdeps[i].qp_regno != qp_regno)
   10114   1.1  christos 	{
   10115   1.1  christos 	  ++i;
   10116   1.1  christos 	  continue;
   10117   1.1  christos 	}
   10118   1.1  christos 
   10119   1.1  christos       if (save_current
   10120   1.1  christos 	  && CURR_SLOT.src_file == regdeps[i].file
   10121   1.1  christos 	  && CURR_SLOT.src_line == regdeps[i].line)
   10122   1.1  christos 	{
   10123   1.1  christos 	  ++i;
   10124   1.1  christos 	  continue;
   10125   1.1  christos 	}
   10126   1.1  christos 
   10127   1.1  christos       /* clear dependencies which are automatically cleared by a stop, or
   10128   1.1  christos 	 those that have reached the appropriate state of insn serialization */
   10129   1.1  christos       if (dep->semantics == IA64_DVS_IMPLIED
   10130   1.1  christos 	  || dep->semantics == IA64_DVS_IMPLIEDF
   10131   1.1  christos 	  || regdeps[i].insn_srlz == STATE_SRLZ)
   10132   1.1  christos 	{
   10133   1.1  christos 	  print_dependency ("Removing", i);
   10134   1.1  christos 	  regdeps[i] = regdeps[--regdepslen];
   10135   1.1  christos 	}
   10136   1.1  christos       else
   10137   1.1  christos 	{
   10138   1.1  christos 	  if (dep->semantics == IA64_DVS_DATA
   10139   1.1  christos 	      || dep->semantics == IA64_DVS_INSTR
   10140   1.1  christos 	      || dep->semantics == IA64_DVS_SPECIFIC)
   10141   1.1  christos 	    {
   10142   1.1  christos 	      if (regdeps[i].insn_srlz == STATE_NONE)
   10143   1.1  christos 		regdeps[i].insn_srlz = STATE_STOP;
   10144   1.1  christos 	      if (regdeps[i].data_srlz == STATE_NONE)
   10145   1.1  christos 		regdeps[i].data_srlz = STATE_STOP;
   10146   1.1  christos 	    }
   10147   1.1  christos 	  ++i;
   10148   1.1  christos 	}
   10149   1.1  christos     }
   10150   1.1  christos }
   10151   1.1  christos 
   10152   1.1  christos /* Add the given resource usage spec to the list of active dependencies.  */
   10153   1.1  christos 
   10154   1.1  christos static void
   10155   1.1  christos mark_resource (struct ia64_opcode *idesc ATTRIBUTE_UNUSED,
   10156   1.1  christos 	       const struct ia64_dependency *dep ATTRIBUTE_UNUSED,
   10157   1.1  christos 	       struct rsrc *spec,
   10158   1.1  christos 	       int depind,
   10159   1.1  christos 	       int path)
   10160   1.1  christos {
   10161   1.1  christos   if (regdepslen == regdepstotlen)
   10162   1.1  christos     {
   10163   1.1  christos       regdepstotlen += 20;
   10164   1.5  christos       regdeps = XRESIZEVEC (struct rsrc, regdeps, regdepstotlen);
   10165   1.1  christos     }
   10166   1.1  christos 
   10167   1.1  christos   regdeps[regdepslen] = *spec;
   10168   1.1  christos   regdeps[regdepslen].depind = depind;
   10169   1.1  christos   regdeps[regdepslen].path = path;
   10170   1.1  christos   regdeps[regdepslen].file = CURR_SLOT.src_file;
   10171   1.1  christos   regdeps[regdepslen].line = CURR_SLOT.src_line;
   10172   1.1  christos 
   10173   1.1  christos   print_dependency ("Adding", regdepslen);
   10174   1.1  christos 
   10175   1.1  christos   ++regdepslen;
   10176   1.1  christos }
   10177   1.1  christos 
   10178   1.1  christos static void
   10179   1.1  christos print_dependency (const char *action, int depind)
   10180   1.1  christos {
   10181   1.1  christos   if (md.debug_dv)
   10182   1.1  christos     {
   10183   1.1  christos       fprintf (stderr, "  %s %s '%s'",
   10184   1.1  christos 	       action, dv_mode[(regdeps[depind].dependency)->mode],
   10185   1.1  christos 	       (regdeps[depind].dependency)->name);
   10186   1.1  christos       if (regdeps[depind].specific && regdeps[depind].index >= 0)
   10187   1.1  christos 	fprintf (stderr, " (%d)", regdeps[depind].index);
   10188   1.1  christos       if (regdeps[depind].mem_offset.hint)
   10189   1.9  christos 	fprintf (stderr, " %" PRIx64 "+%" PRIx64,
   10190   1.9  christos 		 regdeps[depind].mem_offset.base,
   10191   1.9  christos 		 regdeps[depind].mem_offset.offset);
   10192   1.1  christos       fprintf (stderr, "\n");
   10193   1.1  christos     }
   10194   1.1  christos }
   10195   1.1  christos 
   10196   1.1  christos static void
   10197   1.1  christos instruction_serialization (void)
   10198   1.1  christos {
   10199   1.1  christos   int i;
   10200   1.1  christos   if (md.debug_dv)
   10201   1.1  christos     fprintf (stderr, "  Instruction serialization\n");
   10202   1.1  christos   for (i = 0; i < regdepslen; i++)
   10203   1.1  christos     if (regdeps[i].insn_srlz == STATE_STOP)
   10204   1.1  christos       regdeps[i].insn_srlz = STATE_SRLZ;
   10205   1.1  christos }
   10206   1.1  christos 
   10207   1.1  christos static void
   10208   1.1  christos data_serialization (void)
   10209   1.1  christos {
   10210   1.1  christos   int i = 0;
   10211   1.1  christos   if (md.debug_dv)
   10212   1.1  christos     fprintf (stderr, "  Data serialization\n");
   10213   1.1  christos   while (i < regdepslen)
   10214   1.1  christos     {
   10215   1.1  christos       if (regdeps[i].data_srlz == STATE_STOP
   10216   1.1  christos 	  /* Note: as of 991210, all "other" dependencies are cleared by a
   10217   1.1  christos 	     data serialization.  This might change with new tables */
   10218   1.1  christos 	  || (regdeps[i].dependency)->semantics == IA64_DVS_OTHER)
   10219   1.1  christos 	{
   10220   1.1  christos 	  print_dependency ("Removing", i);
   10221   1.1  christos 	  regdeps[i] = regdeps[--regdepslen];
   10222   1.1  christos 	}
   10223   1.1  christos       else
   10224   1.1  christos 	++i;
   10225   1.1  christos     }
   10226   1.1  christos }
   10227   1.1  christos 
   10228   1.1  christos /* Insert stops and serializations as needed to avoid DVs.  */
   10229   1.1  christos 
   10230   1.1  christos static void
   10231   1.1  christos remove_marked_resource (struct rsrc *rs)
   10232   1.1  christos {
   10233   1.1  christos   switch (rs->dependency->semantics)
   10234   1.1  christos     {
   10235   1.1  christos     case IA64_DVS_SPECIFIC:
   10236   1.1  christos       if (md.debug_dv)
   10237   1.1  christos 	fprintf (stderr, "Implementation-specific, assume worst case...\n");
   10238   1.6  christos       /* Fall through.  */
   10239   1.1  christos     case IA64_DVS_INSTR:
   10240   1.1  christos       if (md.debug_dv)
   10241   1.1  christos 	fprintf (stderr, "Inserting instr serialization\n");
   10242   1.1  christos       if (rs->insn_srlz < STATE_STOP)
   10243   1.1  christos 	insn_group_break (1, 0, 0);
   10244   1.1  christos       if (rs->insn_srlz < STATE_SRLZ)
   10245   1.1  christos 	{
   10246   1.1  christos 	  struct slot oldslot = CURR_SLOT;
   10247   1.1  christos 	  /* Manually jam a srlz.i insn into the stream */
   10248   1.1  christos 	  memset (&CURR_SLOT, 0, sizeof (CURR_SLOT));
   10249   1.1  christos 	  CURR_SLOT.user_template = -1;
   10250   1.1  christos 	  CURR_SLOT.idesc = ia64_find_opcode ("srlz.i");
   10251   1.1  christos 	  instruction_serialization ();
   10252   1.1  christos 	  md.curr_slot = (md.curr_slot + 1) % NUM_SLOTS;
   10253   1.1  christos 	  if (++md.num_slots_in_use >= NUM_SLOTS)
   10254   1.1  christos 	    emit_one_bundle ();
   10255   1.1  christos 	  CURR_SLOT = oldslot;
   10256   1.1  christos 	}
   10257   1.1  christos       insn_group_break (1, 0, 0);
   10258   1.1  christos       break;
   10259   1.1  christos     case IA64_DVS_OTHER: /* as of rev2 (991220) of the DV tables, all
   10260   1.1  christos 			    "other" types of DV are eliminated
   10261   1.1  christos 			    by a data serialization */
   10262   1.1  christos     case IA64_DVS_DATA:
   10263   1.1  christos       if (md.debug_dv)
   10264   1.1  christos 	fprintf (stderr, "Inserting data serialization\n");
   10265   1.1  christos       if (rs->data_srlz < STATE_STOP)
   10266   1.1  christos 	insn_group_break (1, 0, 0);
   10267   1.1  christos       {
   10268   1.1  christos 	struct slot oldslot = CURR_SLOT;
   10269   1.1  christos 	/* Manually jam a srlz.d insn into the stream */
   10270   1.1  christos 	memset (&CURR_SLOT, 0, sizeof (CURR_SLOT));
   10271   1.1  christos 	CURR_SLOT.user_template = -1;
   10272   1.1  christos 	CURR_SLOT.idesc = ia64_find_opcode ("srlz.d");
   10273   1.1  christos 	data_serialization ();
   10274   1.1  christos 	md.curr_slot = (md.curr_slot + 1) % NUM_SLOTS;
   10275   1.1  christos 	if (++md.num_slots_in_use >= NUM_SLOTS)
   10276   1.1  christos 	  emit_one_bundle ();
   10277   1.1  christos 	CURR_SLOT = oldslot;
   10278   1.1  christos       }
   10279   1.1  christos       break;
   10280   1.1  christos     case IA64_DVS_IMPLIED:
   10281   1.1  christos     case IA64_DVS_IMPLIEDF:
   10282   1.1  christos       if (md.debug_dv)
   10283   1.1  christos 	fprintf (stderr, "Inserting stop\n");
   10284   1.1  christos       insn_group_break (1, 0, 0);
   10285   1.1  christos       break;
   10286   1.1  christos     default:
   10287   1.1  christos       break;
   10288   1.1  christos     }
   10289   1.1  christos }
   10290   1.1  christos 
   10291   1.1  christos /* Check the resources used by the given opcode against the current dependency
   10292   1.1  christos    list.
   10293   1.1  christos 
   10294   1.1  christos    The check is run once for each execution path encountered.  In this case,
   10295   1.1  christos    a unique execution path is the sequence of instructions following a code
   10296   1.1  christos    entry point, e.g. the following has three execution paths, one starting
   10297   1.1  christos    at L0, one at L1, and one at L2.
   10298   1.1  christos 
   10299   1.1  christos    L0:     nop
   10300   1.1  christos    L1:     add
   10301   1.1  christos    L2:     add
   10302   1.1  christos    br.ret
   10303   1.1  christos */
   10304   1.1  christos 
   10305   1.1  christos static void
   10306   1.1  christos check_dependencies (struct ia64_opcode *idesc)
   10307   1.1  christos {
   10308   1.1  christos   const struct ia64_opcode_dependency *opdeps = idesc->dependencies;
   10309   1.1  christos   int path;
   10310   1.1  christos   int i;
   10311   1.1  christos 
   10312   1.1  christos   /* Note that the number of marked resources may change within the
   10313   1.1  christos      loop if in auto mode.  */
   10314   1.1  christos   i = 0;
   10315   1.1  christos   while (i < regdepslen)
   10316   1.1  christos     {
   10317   1.1  christos       struct rsrc *rs = &regdeps[i];
   10318   1.1  christos       const struct ia64_dependency *dep = rs->dependency;
   10319   1.1  christos       int chkind;
   10320   1.1  christos       int note;
   10321   1.1  christos       int start_over = 0;
   10322   1.1  christos 
   10323   1.1  christos       if (dep->semantics == IA64_DVS_NONE
   10324   1.1  christos 	  || (chkind = depends_on (rs->depind, idesc)) == -1)
   10325   1.1  christos 	{
   10326   1.1  christos 	  ++i;
   10327   1.1  christos 	  continue;
   10328   1.1  christos 	}
   10329   1.1  christos 
   10330   1.1  christos       note = NOTE (opdeps->chks[chkind]);
   10331   1.1  christos 
   10332   1.1  christos       /* Check this resource against each execution path seen thus far.  */
   10333   1.1  christos       for (path = 0; path <= md.path; path++)
   10334   1.1  christos 	{
   10335   1.1  christos 	  int matchtype;
   10336   1.1  christos 
   10337   1.1  christos 	  /* If the dependency wasn't on the path being checked, ignore it.  */
   10338   1.1  christos 	  if (rs->path < path)
   10339   1.1  christos 	    continue;
   10340   1.1  christos 
   10341   1.1  christos 	  /* If the QP for this insn implies a QP which has branched, don't
   10342   1.1  christos 	     bother checking.  Ed. NOTE: I don't think this check is terribly
   10343   1.1  christos 	     useful; what's the point of generating code which will only be
   10344   1.1  christos 	     reached if its QP is zero?
   10345   1.1  christos 	     This code was specifically inserted to handle the following code,
   10346   1.1  christos 	     based on notes from Intel's DV checking code, where p1 implies p2.
   10347   1.1  christos 
   10348   1.1  christos 		  mov r4 = 2
   10349   1.1  christos 	     (p2) br.cond L
   10350   1.1  christos 	     (p1) mov r4 = 7
   10351   1.1  christos 	  */
   10352   1.1  christos 	  if (CURR_SLOT.qp_regno != 0)
   10353   1.1  christos 	    {
   10354   1.1  christos 	      int skip = 0;
   10355   1.1  christos 	      int implies;
   10356   1.1  christos 	      for (implies = 0; implies < qp_implieslen; implies++)
   10357   1.1  christos 		{
   10358   1.1  christos 		  if (qp_implies[implies].path >= path
   10359   1.1  christos 		      && qp_implies[implies].p1 == CURR_SLOT.qp_regno
   10360   1.1  christos 		      && qp_implies[implies].p2_branched)
   10361   1.1  christos 		    {
   10362   1.1  christos 		      skip = 1;
   10363   1.1  christos 		      break;
   10364   1.1  christos 		    }
   10365   1.1  christos 		}
   10366   1.1  christos 	      if (skip)
   10367   1.1  christos 		continue;
   10368   1.1  christos 	    }
   10369   1.1  christos 
   10370   1.1  christos 	  if ((matchtype = resources_match (rs, idesc, note,
   10371   1.1  christos 					    CURR_SLOT.qp_regno, path)) != 0)
   10372   1.1  christos 	    {
   10373   1.1  christos 	      char msg[1024];
   10374   1.1  christos 	      char pathmsg[256] = "";
   10375   1.1  christos 	      char indexmsg[256] = "";
   10376   1.1  christos 	      int certain = (matchtype == 1 && CURR_SLOT.qp_regno == 0);
   10377   1.1  christos 
   10378   1.1  christos 	      if (path != 0)
   10379   1.1  christos 		snprintf (pathmsg, sizeof (pathmsg),
   10380   1.1  christos 			  " when entry is at label '%s'",
   10381   1.1  christos 			 md.entry_labels[path - 1]);
   10382   1.1  christos 	      if (matchtype == 1 && rs->index >= 0)
   10383   1.1  christos 		snprintf (indexmsg, sizeof (indexmsg),
   10384   1.1  christos 			  ", specific resource number is %d",
   10385   1.1  christos 			 rs->index);
   10386   1.1  christos 	      snprintf (msg, sizeof (msg),
   10387   1.1  christos 			"Use of '%s' %s %s dependency '%s' (%s)%s%s",
   10388   1.1  christos 		       idesc->name,
   10389   1.1  christos 		       (certain ? "violates" : "may violate"),
   10390   1.1  christos 		       dv_mode[dep->mode], dep->name,
   10391   1.1  christos 		       dv_sem[dep->semantics],
   10392   1.1  christos 		       pathmsg, indexmsg);
   10393   1.1  christos 
   10394   1.1  christos 	      if (md.explicit_mode)
   10395   1.1  christos 		{
   10396   1.1  christos 		  as_warn ("%s", msg);
   10397   1.1  christos 		  if (path < md.path)
   10398   1.1  christos 		    as_warn (_("Only the first path encountering the conflict is reported"));
   10399   1.1  christos 		  as_warn_where (rs->file, rs->line,
   10400   1.1  christos 				 _("This is the location of the conflicting usage"));
   10401   1.1  christos 		  /* Don't bother checking other paths, to avoid duplicating
   10402   1.1  christos 		     the same warning */
   10403   1.1  christos 		  break;
   10404   1.1  christos 		}
   10405   1.1  christos 	      else
   10406   1.1  christos 		{
   10407   1.1  christos 		  if (md.debug_dv)
   10408   1.1  christos 		    fprintf (stderr, "%s @ %s:%d\n", msg, rs->file, rs->line);
   10409   1.1  christos 
   10410   1.1  christos 		  remove_marked_resource (rs);
   10411   1.1  christos 
   10412   1.1  christos 		  /* since the set of dependencies has changed, start over */
   10413   1.1  christos 		  /* FIXME -- since we're removing dvs as we go, we
   10414   1.1  christos 		     probably don't really need to start over...  */
   10415   1.1  christos 		  start_over = 1;
   10416   1.1  christos 		  break;
   10417   1.1  christos 		}
   10418   1.1  christos 	    }
   10419   1.1  christos 	}
   10420   1.1  christos       if (start_over)
   10421   1.1  christos 	i = 0;
   10422   1.1  christos       else
   10423   1.1  christos 	++i;
   10424   1.1  christos     }
   10425   1.1  christos }
   10426   1.1  christos 
   10427   1.1  christos /* Register new dependencies based on the given opcode.  */
   10428   1.1  christos 
   10429   1.1  christos static void
   10430   1.1  christos mark_resources (struct ia64_opcode *idesc)
   10431   1.1  christos {
   10432   1.1  christos   int i;
   10433   1.1  christos   const struct ia64_opcode_dependency *opdeps = idesc->dependencies;
   10434   1.1  christos   int add_only_qp_reads = 0;
   10435   1.1  christos 
   10436   1.1  christos   /* A conditional branch only uses its resources if it is taken; if it is
   10437   1.1  christos      taken, we stop following that path.  The other branch types effectively
   10438   1.1  christos      *always* write their resources.  If it's not taken, register only QP
   10439   1.1  christos      reads.  */
   10440   1.1  christos   if (is_conditional_branch (idesc) || is_interruption_or_rfi (idesc))
   10441   1.1  christos     {
   10442   1.1  christos       add_only_qp_reads = 1;
   10443   1.1  christos     }
   10444   1.1  christos 
   10445   1.1  christos   if (md.debug_dv)
   10446   1.1  christos     fprintf (stderr, "Registering '%s' resource usage\n", idesc->name);
   10447   1.1  christos 
   10448   1.1  christos   for (i = 0; i < opdeps->nregs; i++)
   10449   1.1  christos     {
   10450   1.1  christos       const struct ia64_dependency *dep;
   10451   1.1  christos       struct rsrc specs[MAX_SPECS];
   10452   1.1  christos       int note;
   10453   1.1  christos       int path;
   10454   1.1  christos       int count;
   10455   1.1  christos 
   10456   1.1  christos       dep = ia64_find_dependency (opdeps->regs[i]);
   10457   1.1  christos       note = NOTE (opdeps->regs[i]);
   10458   1.1  christos 
   10459   1.1  christos       if (add_only_qp_reads
   10460   1.1  christos 	  && !(dep->mode == IA64_DV_WAR
   10461   1.1  christos 	       && (dep->specifier == IA64_RS_PR
   10462   1.1  christos 		   || dep->specifier == IA64_RS_PRr
   10463   1.1  christos 		   || dep->specifier == IA64_RS_PR63)))
   10464   1.1  christos 	continue;
   10465   1.1  christos 
   10466   1.1  christos       count = specify_resource (dep, idesc, DV_REG, specs, note, md.path);
   10467   1.1  christos 
   10468   1.1  christos       while (count-- > 0)
   10469   1.1  christos 	{
   10470   1.1  christos 	  mark_resource (idesc, dep, &specs[count],
   10471   1.1  christos 			 DEP (opdeps->regs[i]), md.path);
   10472   1.1  christos 	}
   10473   1.1  christos 
   10474   1.1  christos       /* The execution path may affect register values, which may in turn
   10475   1.1  christos 	 affect which indirect-access resources are accessed.  */
   10476   1.1  christos       switch (dep->specifier)
   10477   1.1  christos 	{
   10478   1.1  christos 	default:
   10479   1.1  christos 	  break;
   10480   1.1  christos 	case IA64_RS_CPUID:
   10481   1.1  christos 	case IA64_RS_DBR:
   10482   1.1  christos 	case IA64_RS_IBR:
   10483   1.1  christos 	case IA64_RS_MSR:
   10484   1.1  christos 	case IA64_RS_PKR:
   10485   1.1  christos 	case IA64_RS_PMC:
   10486   1.1  christos 	case IA64_RS_PMD:
   10487   1.1  christos 	case IA64_RS_RR:
   10488   1.1  christos 	  for (path = 0; path < md.path; path++)
   10489   1.1  christos 	    {
   10490   1.1  christos 	      count = specify_resource (dep, idesc, DV_REG, specs, note, path);
   10491   1.1  christos 	      while (count-- > 0)
   10492   1.1  christos 		mark_resource (idesc, dep, &specs[count],
   10493   1.1  christos 			       DEP (opdeps->regs[i]), path);
   10494   1.1  christos 	    }
   10495   1.1  christos 	  break;
   10496   1.1  christos 	}
   10497   1.1  christos     }
   10498   1.1  christos }
   10499   1.1  christos 
   10500   1.1  christos /* Remove dependencies when they no longer apply.  */
   10501   1.1  christos 
   10502   1.1  christos static void
   10503   1.1  christos update_dependencies (struct ia64_opcode *idesc)
   10504   1.1  christos {
   10505   1.1  christos   int i;
   10506   1.1  christos 
   10507   1.1  christos   if (strcmp (idesc->name, "srlz.i") == 0)
   10508   1.1  christos     {
   10509   1.1  christos       instruction_serialization ();
   10510   1.1  christos     }
   10511   1.1  christos   else if (strcmp (idesc->name, "srlz.d") == 0)
   10512   1.1  christos     {
   10513   1.1  christos       data_serialization ();
   10514   1.1  christos     }
   10515   1.1  christos   else if (is_interruption_or_rfi (idesc)
   10516   1.1  christos 	   || is_taken_branch (idesc))
   10517   1.1  christos     {
   10518   1.1  christos       /* Although technically the taken branch doesn't clear dependencies
   10519   1.1  christos 	 which require a srlz.[id], we don't follow the branch; the next
   10520   1.1  christos 	 instruction is assumed to start with a clean slate.  */
   10521   1.1  christos       regdepslen = 0;
   10522   1.1  christos       md.path = 0;
   10523   1.1  christos     }
   10524   1.1  christos   else if (is_conditional_branch (idesc)
   10525   1.1  christos 	   && CURR_SLOT.qp_regno != 0)
   10526   1.1  christos     {
   10527   1.1  christos       int is_call = strstr (idesc->name, ".call") != NULL;
   10528   1.1  christos 
   10529   1.1  christos       for (i = 0; i < qp_implieslen; i++)
   10530   1.1  christos 	{
   10531   1.1  christos 	  /* If the conditional branch's predicate is implied by the predicate
   10532   1.1  christos 	     in an existing dependency, remove that dependency.  */
   10533   1.1  christos 	  if (qp_implies[i].p2 == CURR_SLOT.qp_regno)
   10534   1.1  christos 	    {
   10535   1.1  christos 	      int depind = 0;
   10536   1.1  christos 	      /* Note that this implied predicate takes a branch so that if
   10537   1.1  christos 		 a later insn generates a DV but its predicate implies this
   10538   1.1  christos 		 one, we can avoid the false DV warning.  */
   10539   1.1  christos 	      qp_implies[i].p2_branched = 1;
   10540   1.1  christos 	      while (depind < regdepslen)
   10541   1.1  christos 		{
   10542   1.1  christos 		  if (regdeps[depind].qp_regno == qp_implies[i].p1)
   10543   1.1  christos 		    {
   10544   1.1  christos 		      print_dependency ("Removing", depind);
   10545   1.1  christos 		      regdeps[depind] = regdeps[--regdepslen];
   10546   1.1  christos 		    }
   10547   1.1  christos 		  else
   10548   1.1  christos 		    ++depind;
   10549   1.1  christos 		}
   10550   1.1  christos 	    }
   10551   1.1  christos 	}
   10552   1.1  christos       /* Any marked resources which have this same predicate should be
   10553   1.1  christos 	 cleared, provided that the QP hasn't been modified between the
   10554   1.1  christos 	 marking instruction and the branch.  */
   10555   1.1  christos       if (is_call)
   10556   1.1  christos 	{
   10557   1.1  christos 	  insn_group_break (0, CURR_SLOT.qp_regno, 1);
   10558   1.1  christos 	}
   10559   1.1  christos       else
   10560   1.1  christos 	{
   10561   1.1  christos 	  i = 0;
   10562   1.1  christos 	  while (i < regdepslen)
   10563   1.1  christos 	    {
   10564   1.1  christos 	      if (regdeps[i].qp_regno == CURR_SLOT.qp_regno
   10565   1.1  christos 		  && regdeps[i].link_to_qp_branch
   10566   1.1  christos 		  && (regdeps[i].file != CURR_SLOT.src_file
   10567   1.1  christos 		      || regdeps[i].line != CURR_SLOT.src_line))
   10568   1.1  christos 		{
   10569   1.1  christos 		  /* Treat like a taken branch */
   10570   1.1  christos 		  print_dependency ("Removing", i);
   10571   1.1  christos 		  regdeps[i] = regdeps[--regdepslen];
   10572   1.1  christos 		}
   10573   1.1  christos 	      else
   10574   1.1  christos 		++i;
   10575   1.1  christos 	    }
   10576   1.1  christos 	}
   10577   1.1  christos     }
   10578   1.1  christos }
   10579   1.1  christos 
   10580   1.1  christos /* Examine the current instruction for dependency violations.  */
   10581   1.1  christos 
   10582   1.1  christos static int
   10583   1.1  christos check_dv (struct ia64_opcode *idesc)
   10584   1.1  christos {
   10585   1.1  christos   if (md.debug_dv)
   10586   1.1  christos     {
   10587   1.1  christos       fprintf (stderr, "Checking %s for violations (line %d, %d/%d)\n",
   10588   1.1  christos 	       idesc->name, CURR_SLOT.src_line,
   10589   1.1  christos 	       idesc->dependencies->nchks,
   10590   1.1  christos 	       idesc->dependencies->nregs);
   10591   1.1  christos     }
   10592   1.1  christos 
   10593   1.1  christos   /* Look through the list of currently marked resources; if the current
   10594   1.1  christos      instruction has the dependency in its chks list which uses that resource,
   10595   1.1  christos      check against the specific resources used.  */
   10596   1.1  christos   check_dependencies (idesc);
   10597   1.1  christos 
   10598   1.1  christos   /* Look up the instruction's regdeps (RAW writes, WAW writes, and WAR reads),
   10599   1.1  christos      then add them to the list of marked resources.  */
   10600   1.1  christos   mark_resources (idesc);
   10601   1.1  christos 
   10602   1.1  christos   /* There are several types of dependency semantics, and each has its own
   10603   1.1  christos      requirements for being cleared
   10604   1.1  christos 
   10605   1.1  christos      Instruction serialization (insns separated by interruption, rfi, or
   10606   1.1  christos      writer + srlz.i + reader, all in separate groups) clears DVS_INSTR.
   10607   1.1  christos 
   10608   1.1  christos      Data serialization (instruction serialization, or writer + srlz.d +
   10609   1.1  christos      reader, where writer and srlz.d are in separate groups) clears
   10610   1.1  christos      DVS_DATA. (This also clears DVS_OTHER, but that is not guaranteed to
   10611   1.1  christos      always be the case).
   10612   1.1  christos 
   10613   1.1  christos      Instruction group break (groups separated by stop, taken branch,
   10614   1.1  christos      interruption or rfi) clears DVS_IMPLIED and DVS_IMPLIEDF.
   10615   1.1  christos    */
   10616   1.1  christos   update_dependencies (idesc);
   10617   1.1  christos 
   10618   1.1  christos   /* Sometimes, knowing a register value allows us to avoid giving a false DV
   10619   1.1  christos      warning.  Keep track of as many as possible that are useful.  */
   10620   1.1  christos   note_register_values (idesc);
   10621   1.1  christos 
   10622   1.1  christos   /* We don't need or want this anymore.  */
   10623   1.1  christos   md.mem_offset.hint = 0;
   10624   1.1  christos 
   10625   1.1  christos   return 0;
   10626   1.1  christos }
   10627   1.1  christos 
   10628   1.1  christos /* Translate one line of assembly.  Pseudo ops and labels do not show
   10629   1.1  christos    here.  */
   10630   1.1  christos void
   10631   1.1  christos md_assemble (char *str)
   10632   1.1  christos {
   10633   1.5  christos   char *saved_input_line_pointer, *temp;
   10634   1.5  christos   const char *mnemonic;
   10635   1.1  christos   const struct pseudo_opcode *pdesc;
   10636   1.1  christos   struct ia64_opcode *idesc;
   10637   1.1  christos   unsigned char qp_regno;
   10638   1.1  christos   unsigned int flags;
   10639   1.1  christos   int ch;
   10640   1.1  christos 
   10641   1.1  christos   saved_input_line_pointer = input_line_pointer;
   10642   1.1  christos   input_line_pointer = str;
   10643   1.1  christos 
   10644   1.1  christos   /* extract the opcode (mnemonic):  */
   10645   1.1  christos 
   10646   1.5  christos   ch = get_symbol_name (&temp);
   10647   1.5  christos   mnemonic = temp;
   10648  1.10  christos   pdesc = str_hash_find (md.pseudo_hash, mnemonic);
   10649   1.1  christos   if (pdesc)
   10650   1.1  christos     {
   10651   1.3  christos       (void) restore_line_pointer (ch);
   10652   1.1  christos       (*pdesc->handler) (pdesc->arg);
   10653   1.1  christos       goto done;
   10654   1.1  christos     }
   10655   1.1  christos 
   10656   1.1  christos   /* Find the instruction descriptor matching the arguments.  */
   10657   1.1  christos 
   10658   1.1  christos   idesc = ia64_find_opcode (mnemonic);
   10659   1.3  christos   (void) restore_line_pointer (ch);
   10660   1.1  christos   if (!idesc)
   10661   1.1  christos     {
   10662   1.1  christos       as_bad (_("Unknown opcode `%s'"), mnemonic);
   10663   1.1  christos       goto done;
   10664   1.1  christos     }
   10665   1.1  christos 
   10666   1.1  christos   idesc = parse_operands (idesc);
   10667   1.1  christos   if (!idesc)
   10668   1.1  christos     goto done;
   10669   1.1  christos 
   10670   1.1  christos   /* Handle the dynamic ops we can handle now:  */
   10671   1.1  christos   if (idesc->type == IA64_TYPE_DYN)
   10672   1.1  christos     {
   10673   1.1  christos       if (strcmp (idesc->name, "add") == 0)
   10674   1.1  christos 	{
   10675   1.1  christos 	  if (CURR_SLOT.opnd[2].X_op == O_register
   10676   1.1  christos 	      && CURR_SLOT.opnd[2].X_add_number < 4)
   10677   1.1  christos 	    mnemonic = "addl";
   10678   1.1  christos 	  else
   10679   1.1  christos 	    mnemonic = "adds";
   10680   1.1  christos 	  ia64_free_opcode (idesc);
   10681   1.1  christos 	  idesc = ia64_find_opcode (mnemonic);
   10682   1.1  christos 	}
   10683   1.1  christos       else if (strcmp (idesc->name, "mov") == 0)
   10684   1.1  christos 	{
   10685   1.1  christos 	  enum ia64_opnd opnd1, opnd2;
   10686   1.1  christos 	  int rop;
   10687   1.1  christos 
   10688   1.1  christos 	  opnd1 = idesc->operands[0];
   10689   1.1  christos 	  opnd2 = idesc->operands[1];
   10690   1.1  christos 	  if (opnd1 == IA64_OPND_AR3)
   10691   1.1  christos 	    rop = 0;
   10692   1.1  christos 	  else if (opnd2 == IA64_OPND_AR3)
   10693   1.1  christos 	    rop = 1;
   10694   1.1  christos 	  else
   10695   1.1  christos 	    abort ();
   10696   1.1  christos 	  if (CURR_SLOT.opnd[rop].X_op == O_register)
   10697   1.1  christos 	    {
   10698   1.1  christos 	      if (ar_is_only_in_integer_unit (CURR_SLOT.opnd[rop].X_add_number))
   10699   1.1  christos 		mnemonic = "mov.i";
   10700   1.1  christos 	      else if (ar_is_only_in_memory_unit (CURR_SLOT.opnd[rop].X_add_number))
   10701   1.1  christos 		mnemonic = "mov.m";
   10702   1.1  christos 	      else
   10703   1.1  christos 		rop = -1;
   10704   1.1  christos 	    }
   10705   1.1  christos 	  else
   10706   1.1  christos 	    abort ();
   10707   1.1  christos 	  if (rop >= 0)
   10708   1.1  christos 	    {
   10709   1.1  christos 	      ia64_free_opcode (idesc);
   10710   1.1  christos 	      idesc = ia64_find_opcode (mnemonic);
   10711   1.1  christos 	      while (idesc != NULL
   10712   1.1  christos 		     && (idesc->operands[0] != opnd1
   10713   1.1  christos 			 || idesc->operands[1] != opnd2))
   10714   1.1  christos 		idesc = get_next_opcode (idesc);
   10715   1.1  christos 	    }
   10716   1.1  christos 	}
   10717   1.1  christos     }
   10718   1.1  christos   else if (strcmp (idesc->name, "mov.i") == 0
   10719   1.1  christos 	   || strcmp (idesc->name, "mov.m") == 0)
   10720   1.1  christos     {
   10721   1.1  christos       enum ia64_opnd opnd1, opnd2;
   10722   1.1  christos       int rop;
   10723   1.3  christos 
   10724   1.1  christos       opnd1 = idesc->operands[0];
   10725   1.1  christos       opnd2 = idesc->operands[1];
   10726   1.1  christos       if (opnd1 == IA64_OPND_AR3)
   10727   1.1  christos 	rop = 0;
   10728   1.1  christos       else if (opnd2 == IA64_OPND_AR3)
   10729   1.1  christos 	rop = 1;
   10730   1.1  christos       else
   10731   1.1  christos 	abort ();
   10732   1.1  christos       if (CURR_SLOT.opnd[rop].X_op == O_register)
   10733   1.1  christos 	{
   10734   1.1  christos 	  char unit = 'a';
   10735   1.1  christos 	  if (ar_is_only_in_integer_unit (CURR_SLOT.opnd[rop].X_add_number))
   10736   1.1  christos 	    unit = 'i';
   10737   1.1  christos 	  else if (ar_is_only_in_memory_unit (CURR_SLOT.opnd[rop].X_add_number))
   10738   1.1  christos 	    unit = 'm';
   10739   1.1  christos 	  if (unit != 'a' && unit != idesc->name [4])
   10740   1.1  christos 	    as_bad (_("AR %d can only be accessed by %c-unit"),
   10741   1.1  christos 		    (int) (CURR_SLOT.opnd[rop].X_add_number - REG_AR),
   10742   1.1  christos 		    TOUPPER (unit));
   10743   1.1  christos 	}
   10744   1.1  christos     }
   10745   1.1  christos   else if (strcmp (idesc->name, "hint.b") == 0)
   10746   1.1  christos     {
   10747   1.1  christos       switch (md.hint_b)
   10748   1.1  christos 	{
   10749   1.1  christos 	case hint_b_ok:
   10750   1.1  christos 	  break;
   10751   1.1  christos 	case hint_b_warning:
   10752   1.1  christos 	  as_warn (_("hint.b may be treated as nop"));
   10753   1.1  christos 	  break;
   10754   1.1  christos 	case hint_b_error:
   10755   1.1  christos 	  as_bad (_("hint.b shouldn't be used"));
   10756   1.1  christos 	  break;
   10757   1.1  christos 	}
   10758   1.1  christos     }
   10759   1.1  christos 
   10760   1.1  christos   qp_regno = 0;
   10761   1.1  christos   if (md.qp.X_op == O_register)
   10762   1.1  christos     {
   10763   1.1  christos       qp_regno = md.qp.X_add_number - REG_P;
   10764   1.1  christos       md.qp.X_op = O_absent;
   10765   1.1  christos     }
   10766   1.1  christos 
   10767   1.1  christos   flags = idesc->flags;
   10768   1.1  christos 
   10769   1.1  christos   if ((flags & IA64_OPCODE_FIRST) != 0)
   10770   1.1  christos     {
   10771   1.1  christos       /* The alignment frag has to end with a stop bit only if the
   10772   1.1  christos 	 next instruction after the alignment directive has to be
   10773   1.1  christos 	 the first instruction in an instruction group.  */
   10774   1.1  christos       if (align_frag)
   10775   1.1  christos 	{
   10776   1.1  christos 	  while (align_frag->fr_type != rs_align_code)
   10777   1.1  christos 	    {
   10778   1.1  christos 	      align_frag = align_frag->fr_next;
   10779   1.1  christos 	      if (!align_frag)
   10780   1.1  christos 		break;
   10781   1.1  christos 	    }
   10782   1.1  christos 	  /* align_frag can be NULL if there are directives in
   10783   1.1  christos 	     between.  */
   10784   1.1  christos 	  if (align_frag && align_frag->fr_next == frag_now)
   10785   1.1  christos 	    align_frag->tc_frag_data = 1;
   10786   1.1  christos 	}
   10787   1.1  christos 
   10788   1.1  christos       insn_group_break (1, 0, 0);
   10789   1.1  christos     }
   10790   1.1  christos   align_frag = NULL;
   10791   1.1  christos 
   10792   1.1  christos   if ((flags & IA64_OPCODE_NO_PRED) != 0 && qp_regno != 0)
   10793   1.1  christos     {
   10794   1.1  christos       as_bad (_("`%s' cannot be predicated"), idesc->name);
   10795   1.1  christos       goto done;
   10796   1.1  christos     }
   10797   1.1  christos 
   10798   1.1  christos   /* Build the instruction.  */
   10799   1.1  christos   CURR_SLOT.qp_regno = qp_regno;
   10800   1.1  christos   CURR_SLOT.idesc = idesc;
   10801   1.5  christos   CURR_SLOT.src_file = as_where (&CURR_SLOT.src_line);
   10802   1.1  christos   dwarf2_where (&CURR_SLOT.debug_line);
   10803   1.1  christos   dwarf2_consume_line_info ();
   10804   1.1  christos 
   10805   1.1  christos   /* Add unwind entries, if there are any.  */
   10806   1.1  christos   if (unwind.current_entry)
   10807   1.1  christos     {
   10808   1.1  christos       CURR_SLOT.unwind_record = unwind.current_entry;
   10809   1.1  christos       unwind.current_entry = NULL;
   10810   1.1  christos     }
   10811   1.1  christos   if (unwind.pending_saves)
   10812   1.1  christos     {
   10813   1.1  christos       if (unwind.pending_saves->next)
   10814   1.1  christos 	{
   10815   1.1  christos 	  /* Attach the next pending save to the next slot so that its
   10816   1.1  christos 	     slot number will get set correctly.  */
   10817   1.1  christos 	  add_unwind_entry (unwind.pending_saves->next, NOT_A_CHAR);
   10818   1.1  christos 	  unwind.pending_saves = &unwind.pending_saves->next->r.record.p;
   10819   1.1  christos 	}
   10820   1.1  christos       else
   10821   1.1  christos 	unwind.pending_saves = NULL;
   10822   1.1  christos     }
   10823   1.1  christos   if (unwind.proc_pending.sym && S_IS_DEFINED (unwind.proc_pending.sym))
   10824   1.1  christos     unwind.insn = 1;
   10825   1.1  christos 
   10826   1.1  christos   /* Check for dependency violations.  */
   10827   1.1  christos   if (md.detect_dv)
   10828   1.1  christos     check_dv (idesc);
   10829   1.1  christos 
   10830   1.1  christos   md.curr_slot = (md.curr_slot + 1) % NUM_SLOTS;
   10831   1.1  christos   if (++md.num_slots_in_use >= NUM_SLOTS)
   10832   1.1  christos     emit_one_bundle ();
   10833   1.1  christos 
   10834   1.1  christos   if ((flags & IA64_OPCODE_LAST) != 0)
   10835   1.1  christos     insn_group_break (1, 0, 0);
   10836   1.1  christos 
   10837   1.1  christos   md.last_text_seg = now_seg;
   10838   1.8  christos   md.last_text_subseg = now_subseg;
   10839   1.1  christos 
   10840   1.1  christos  done:
   10841   1.1  christos   input_line_pointer = saved_input_line_pointer;
   10842   1.1  christos }
   10843   1.1  christos 
   10844   1.1  christos /* Called when symbol NAME cannot be found in the symbol table.
   10845   1.1  christos    Should be used for dynamic valued symbols only.  */
   10846   1.1  christos 
   10847   1.1  christos symbolS *
   10848   1.1  christos md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
   10849   1.1  christos {
   10850   1.1  christos   return 0;
   10851   1.1  christos }
   10852   1.1  christos 
   10853   1.1  christos /* Called for any expression that can not be recognized.  When the
   10854   1.1  christos    function is called, `input_line_pointer' will point to the start of
   10855   1.1  christos    the expression.  */
   10856   1.1  christos 
   10857   1.1  christos void
   10858   1.1  christos md_operand (expressionS *e)
   10859   1.1  christos {
   10860   1.1  christos   switch (*input_line_pointer)
   10861   1.1  christos     {
   10862   1.1  christos     case '[':
   10863   1.1  christos       ++input_line_pointer;
   10864   1.1  christos       expression_and_evaluate (e);
   10865   1.1  christos       if (*input_line_pointer != ']')
   10866   1.1  christos 	{
   10867   1.1  christos 	  as_bad (_("Closing bracket missing"));
   10868   1.1  christos 	  goto err;
   10869   1.1  christos 	}
   10870   1.1  christos       else
   10871   1.1  christos 	{
   10872   1.1  christos 	  if (e->X_op != O_register
   10873   1.1  christos 	      || e->X_add_number < REG_GR
   10874   1.1  christos 	      || e->X_add_number > REG_GR + 127)
   10875   1.1  christos 	    {
   10876   1.1  christos 	      as_bad (_("Index must be a general register"));
   10877   1.1  christos 	      e->X_add_number = REG_GR;
   10878   1.1  christos 	    }
   10879   1.1  christos 
   10880   1.1  christos 	  ++input_line_pointer;
   10881   1.1  christos 	  e->X_op = O_index;
   10882   1.1  christos 	}
   10883   1.1  christos       break;
   10884   1.1  christos 
   10885   1.1  christos     default:
   10886   1.1  christos       break;
   10887   1.1  christos     }
   10888   1.1  christos   return;
   10889   1.1  christos 
   10890   1.1  christos  err:
   10891   1.1  christos   ignore_rest_of_line ();
   10892   1.1  christos }
   10893   1.1  christos 
   10894   1.1  christos /* Return 1 if it's OK to adjust a reloc by replacing the symbol with
   10895   1.1  christos    a section symbol plus some offset.  For relocs involving @fptr(),
   10896   1.1  christos    directives we don't want such adjustments since we need to have the
   10897   1.1  christos    original symbol's name in the reloc.  */
   10898   1.1  christos int
   10899   1.1  christos ia64_fix_adjustable (fixS *fix)
   10900   1.1  christos {
   10901   1.1  christos   /* Prevent all adjustments to global symbols */
   10902   1.1  christos   if (S_IS_EXTERNAL (fix->fx_addsy) || S_IS_WEAK (fix->fx_addsy))
   10903   1.1  christos     return 0;
   10904   1.1  christos 
   10905   1.1  christos   switch (fix->fx_r_type)
   10906   1.1  christos     {
   10907   1.1  christos     case BFD_RELOC_IA64_FPTR64I:
   10908   1.1  christos     case BFD_RELOC_IA64_FPTR32MSB:
   10909   1.1  christos     case BFD_RELOC_IA64_FPTR32LSB:
   10910   1.1  christos     case BFD_RELOC_IA64_FPTR64MSB:
   10911   1.1  christos     case BFD_RELOC_IA64_FPTR64LSB:
   10912   1.1  christos     case BFD_RELOC_IA64_LTOFF_FPTR22:
   10913   1.1  christos     case BFD_RELOC_IA64_LTOFF_FPTR64I:
   10914   1.1  christos       return 0;
   10915   1.1  christos     default:
   10916   1.1  christos       break;
   10917   1.1  christos     }
   10918   1.1  christos 
   10919   1.1  christos   return 1;
   10920   1.1  christos }
   10921   1.1  christos 
   10922   1.1  christos int
   10923   1.1  christos ia64_force_relocation (fixS *fix)
   10924   1.1  christos {
   10925   1.1  christos   switch (fix->fx_r_type)
   10926   1.1  christos     {
   10927   1.1  christos     case BFD_RELOC_IA64_FPTR64I:
   10928   1.1  christos     case BFD_RELOC_IA64_FPTR32MSB:
   10929   1.1  christos     case BFD_RELOC_IA64_FPTR32LSB:
   10930   1.1  christos     case BFD_RELOC_IA64_FPTR64MSB:
   10931   1.1  christos     case BFD_RELOC_IA64_FPTR64LSB:
   10932   1.1  christos 
   10933   1.1  christos     case BFD_RELOC_IA64_LTOFF22:
   10934   1.1  christos     case BFD_RELOC_IA64_LTOFF64I:
   10935   1.1  christos     case BFD_RELOC_IA64_LTOFF_FPTR22:
   10936   1.1  christos     case BFD_RELOC_IA64_LTOFF_FPTR64I:
   10937   1.1  christos     case BFD_RELOC_IA64_PLTOFF22:
   10938   1.1  christos     case BFD_RELOC_IA64_PLTOFF64I:
   10939   1.1  christos     case BFD_RELOC_IA64_PLTOFF64MSB:
   10940   1.1  christos     case BFD_RELOC_IA64_PLTOFF64LSB:
   10941   1.1  christos 
   10942   1.1  christos     case BFD_RELOC_IA64_LTOFF22X:
   10943   1.1  christos     case BFD_RELOC_IA64_LDXMOV:
   10944   1.1  christos       return 1;
   10945   1.1  christos 
   10946   1.1  christos     default:
   10947   1.1  christos       break;
   10948   1.1  christos     }
   10949   1.1  christos 
   10950   1.1  christos   return generic_force_reloc (fix);
   10951   1.1  christos }
   10952   1.1  christos 
   10953   1.1  christos /* Decide from what point a pc-relative relocation is relative to,
   10954   1.1  christos    relative to the pc-relative fixup.  Er, relatively speaking.  */
   10955   1.1  christos long
   10956   1.1  christos ia64_pcrel_from_section (fixS *fix, segT sec)
   10957   1.1  christos {
   10958   1.1  christos   unsigned long off = fix->fx_frag->fr_address + fix->fx_where;
   10959   1.1  christos 
   10960   1.7  christos   if (bfd_section_flags (sec) & SEC_CODE)
   10961   1.1  christos     off &= ~0xfUL;
   10962   1.1  christos 
   10963   1.1  christos   return off;
   10964   1.1  christos }
   10965   1.1  christos 
   10966   1.1  christos 
   10967   1.1  christos /* Used to emit section-relative relocs for the dwarf2 debug data.  */
   10968   1.1  christos void
   10969   1.1  christos ia64_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
   10970   1.1  christos {
   10971   1.1  christos   expressionS exp;
   10972   1.1  christos 
   10973   1.1  christos   exp.X_op = O_pseudo_fixup;
   10974   1.1  christos   exp.X_op_symbol = pseudo_func[FUNC_SEC_RELATIVE].u.sym;
   10975   1.1  christos   exp.X_add_number = 0;
   10976   1.1  christos   exp.X_add_symbol = symbol;
   10977   1.1  christos   emit_expr (&exp, size);
   10978   1.1  christos }
   10979   1.1  christos 
   10980   1.1  christos /* This is called whenever some data item (not an instruction) needs a
   10981   1.1  christos    fixup.  We pick the right reloc code depending on the byteorder
   10982   1.1  christos    currently in effect.  */
   10983   1.1  christos void
   10984   1.3  christos ia64_cons_fix_new (fragS *f, int where, int nbytes, expressionS *exp,
   10985   1.3  christos 		   bfd_reloc_code_real_type code)
   10986   1.1  christos {
   10987   1.1  christos   fixS *fix;
   10988   1.1  christos 
   10989   1.1  christos   switch (nbytes)
   10990   1.1  christos     {
   10991   1.1  christos       /* There are no reloc for 8 and 16 bit quantities, but we allow
   10992   1.1  christos 	 them here since they will work fine as long as the expression
   10993   1.1  christos 	 is fully defined at the end of the pass over the source file.  */
   10994   1.1  christos     case 1: code = BFD_RELOC_8; break;
   10995   1.1  christos     case 2: code = BFD_RELOC_16; break;
   10996   1.1  christos     case 4:
   10997   1.1  christos       if (target_big_endian)
   10998   1.1  christos 	code = BFD_RELOC_IA64_DIR32MSB;
   10999   1.1  christos       else
   11000   1.1  christos 	code = BFD_RELOC_IA64_DIR32LSB;
   11001   1.1  christos       break;
   11002   1.1  christos 
   11003   1.1  christos     case 8:
   11004   1.1  christos       /* In 32-bit mode, data8 could mean function descriptors too.  */
   11005   1.1  christos       if (exp->X_op == O_pseudo_fixup
   11006   1.1  christos 	  && exp->X_op_symbol
   11007   1.1  christos 	  && S_GET_VALUE (exp->X_op_symbol) == FUNC_IPLT_RELOC
   11008   1.1  christos 	  && !(md.flags & EF_IA_64_ABI64))
   11009   1.1  christos 	{
   11010   1.1  christos 	  if (target_big_endian)
   11011   1.1  christos 	    code = BFD_RELOC_IA64_IPLTMSB;
   11012   1.1  christos 	  else
   11013   1.1  christos 	    code = BFD_RELOC_IA64_IPLTLSB;
   11014   1.1  christos 	  exp->X_op = O_symbol;
   11015   1.1  christos 	  break;
   11016   1.1  christos 	}
   11017   1.1  christos       else
   11018   1.1  christos 	{
   11019   1.1  christos 	  if (target_big_endian)
   11020   1.1  christos 	    code = BFD_RELOC_IA64_DIR64MSB;
   11021   1.1  christos 	  else
   11022   1.1  christos 	    code = BFD_RELOC_IA64_DIR64LSB;
   11023   1.1  christos 	  break;
   11024   1.1  christos 	}
   11025   1.1  christos 
   11026   1.1  christos     case 16:
   11027   1.1  christos       if (exp->X_op == O_pseudo_fixup
   11028   1.1  christos 	  && exp->X_op_symbol
   11029   1.1  christos 	  && S_GET_VALUE (exp->X_op_symbol) == FUNC_IPLT_RELOC)
   11030   1.1  christos 	{
   11031   1.1  christos 	  if (target_big_endian)
   11032   1.1  christos 	    code = BFD_RELOC_IA64_IPLTMSB;
   11033   1.1  christos 	  else
   11034   1.1  christos 	    code = BFD_RELOC_IA64_IPLTLSB;
   11035   1.1  christos 	  exp->X_op = O_symbol;
   11036   1.1  christos 	  break;
   11037   1.1  christos 	}
   11038   1.1  christos       /* FALLTHRU */
   11039   1.1  christos 
   11040   1.1  christos     default:
   11041   1.1  christos       as_bad (_("Unsupported fixup size %d"), nbytes);
   11042   1.1  christos       ignore_rest_of_line ();
   11043   1.1  christos       return;
   11044   1.1  christos     }
   11045   1.1  christos 
   11046   1.1  christos   if (exp->X_op == O_pseudo_fixup)
   11047   1.1  christos     {
   11048   1.1  christos       exp->X_op = O_symbol;
   11049   1.1  christos       code = ia64_gen_real_reloc_type (exp->X_op_symbol, code);
   11050   1.1  christos       /* ??? If code unchanged, unsupported.  */
   11051   1.1  christos     }
   11052   1.1  christos 
   11053   1.1  christos   fix = fix_new_exp (f, where, nbytes, exp, 0, code);
   11054   1.1  christos   /* We need to store the byte order in effect in case we're going
   11055   1.1  christos      to fix an 8 or 16 bit relocation (for which there no real
   11056   1.1  christos      relocs available).  See md_apply_fix().  */
   11057   1.1  christos   fix->tc_fix_data.bigendian = target_big_endian;
   11058   1.1  christos }
   11059   1.1  christos 
   11060   1.1  christos /* Return the actual relocation we wish to associate with the pseudo
   11061   1.1  christos    reloc described by SYM and R_TYPE.  SYM should be one of the
   11062   1.1  christos    symbols in the pseudo_func array, or NULL.  */
   11063   1.1  christos 
   11064   1.1  christos static bfd_reloc_code_real_type
   11065   1.1  christos ia64_gen_real_reloc_type (struct symbol *sym, bfd_reloc_code_real_type r_type)
   11066   1.1  christos {
   11067   1.1  christos   bfd_reloc_code_real_type newr = 0;
   11068   1.1  christos   const char *type = NULL, *suffix = "";
   11069   1.1  christos 
   11070   1.1  christos   if (sym == NULL)
   11071   1.1  christos     {
   11072   1.1  christos       return r_type;
   11073   1.1  christos     }
   11074   1.1  christos 
   11075   1.1  christos   switch (S_GET_VALUE (sym))
   11076   1.1  christos     {
   11077   1.1  christos     case FUNC_FPTR_RELATIVE:
   11078   1.1  christos       switch (r_type)
   11079   1.1  christos 	{
   11080   1.1  christos 	case BFD_RELOC_IA64_IMM64:	newr = BFD_RELOC_IA64_FPTR64I; break;
   11081   1.1  christos 	case BFD_RELOC_IA64_DIR32MSB:	newr = BFD_RELOC_IA64_FPTR32MSB; break;
   11082   1.1  christos 	case BFD_RELOC_IA64_DIR32LSB:	newr = BFD_RELOC_IA64_FPTR32LSB; break;
   11083   1.1  christos 	case BFD_RELOC_IA64_DIR64MSB:	newr = BFD_RELOC_IA64_FPTR64MSB; break;
   11084   1.1  christos 	case BFD_RELOC_IA64_DIR64LSB:	newr = BFD_RELOC_IA64_FPTR64LSB; break;
   11085   1.1  christos 	default:			type = "FPTR"; break;
   11086   1.1  christos 	}
   11087   1.1  christos       break;
   11088   1.1  christos 
   11089   1.1  christos     case FUNC_GP_RELATIVE:
   11090   1.1  christos       switch (r_type)
   11091   1.1  christos 	{
   11092   1.1  christos 	case BFD_RELOC_IA64_IMM22:	newr = BFD_RELOC_IA64_GPREL22; break;
   11093   1.1  christos 	case BFD_RELOC_IA64_IMM64:	newr = BFD_RELOC_IA64_GPREL64I; break;
   11094   1.1  christos 	case BFD_RELOC_IA64_DIR32MSB:	newr = BFD_RELOC_IA64_GPREL32MSB; break;
   11095   1.1  christos 	case BFD_RELOC_IA64_DIR32LSB:	newr = BFD_RELOC_IA64_GPREL32LSB; break;
   11096   1.1  christos 	case BFD_RELOC_IA64_DIR64MSB:	newr = BFD_RELOC_IA64_GPREL64MSB; break;
   11097   1.1  christos 	case BFD_RELOC_IA64_DIR64LSB:	newr = BFD_RELOC_IA64_GPREL64LSB; break;
   11098   1.1  christos 	default:			type = "GPREL"; break;
   11099   1.1  christos 	}
   11100   1.1  christos       break;
   11101   1.1  christos 
   11102   1.1  christos     case FUNC_LT_RELATIVE:
   11103   1.1  christos       switch (r_type)
   11104   1.1  christos 	{
   11105   1.1  christos 	case BFD_RELOC_IA64_IMM22:	newr = BFD_RELOC_IA64_LTOFF22; break;
   11106   1.1  christos 	case BFD_RELOC_IA64_IMM64:	newr = BFD_RELOC_IA64_LTOFF64I; break;
   11107   1.1  christos 	default:			type = "LTOFF"; break;
   11108   1.1  christos 	}
   11109   1.1  christos       break;
   11110   1.1  christos 
   11111   1.1  christos     case FUNC_LT_RELATIVE_X:
   11112   1.1  christos       switch (r_type)
   11113   1.1  christos 	{
   11114   1.1  christos 	case BFD_RELOC_IA64_IMM22:	newr = BFD_RELOC_IA64_LTOFF22X; break;
   11115   1.1  christos 	default:			type = "LTOFF"; suffix = "X"; break;
   11116   1.1  christos 	}
   11117   1.1  christos       break;
   11118   1.1  christos 
   11119   1.1  christos     case FUNC_PC_RELATIVE:
   11120   1.1  christos       switch (r_type)
   11121   1.1  christos 	{
   11122   1.1  christos 	case BFD_RELOC_IA64_IMM22:	newr = BFD_RELOC_IA64_PCREL22; break;
   11123   1.1  christos 	case BFD_RELOC_IA64_IMM64:	newr = BFD_RELOC_IA64_PCREL64I; break;
   11124   1.1  christos 	case BFD_RELOC_IA64_DIR32MSB:	newr = BFD_RELOC_IA64_PCREL32MSB; break;
   11125   1.1  christos 	case BFD_RELOC_IA64_DIR32LSB:	newr = BFD_RELOC_IA64_PCREL32LSB; break;
   11126   1.1  christos 	case BFD_RELOC_IA64_DIR64MSB:	newr = BFD_RELOC_IA64_PCREL64MSB; break;
   11127   1.1  christos 	case BFD_RELOC_IA64_DIR64LSB:	newr = BFD_RELOC_IA64_PCREL64LSB; break;
   11128   1.1  christos 	default:			type = "PCREL"; break;
   11129   1.1  christos 	}
   11130   1.1  christos       break;
   11131   1.1  christos 
   11132   1.1  christos     case FUNC_PLT_RELATIVE:
   11133   1.1  christos       switch (r_type)
   11134   1.1  christos 	{
   11135   1.1  christos 	case BFD_RELOC_IA64_IMM22:	newr = BFD_RELOC_IA64_PLTOFF22; break;
   11136   1.1  christos 	case BFD_RELOC_IA64_IMM64:	newr = BFD_RELOC_IA64_PLTOFF64I; break;
   11137   1.1  christos 	case BFD_RELOC_IA64_DIR64MSB:	newr = BFD_RELOC_IA64_PLTOFF64MSB;break;
   11138   1.1  christos 	case BFD_RELOC_IA64_DIR64LSB:	newr = BFD_RELOC_IA64_PLTOFF64LSB;break;
   11139   1.1  christos 	default:			type = "PLTOFF"; break;
   11140   1.1  christos 	}
   11141   1.1  christos       break;
   11142   1.1  christos 
   11143   1.1  christos     case FUNC_SEC_RELATIVE:
   11144   1.1  christos       switch (r_type)
   11145   1.1  christos 	{
   11146   1.1  christos 	case BFD_RELOC_IA64_DIR32MSB:	newr = BFD_RELOC_IA64_SECREL32MSB;break;
   11147   1.1  christos 	case BFD_RELOC_IA64_DIR32LSB:	newr = BFD_RELOC_IA64_SECREL32LSB;break;
   11148   1.1  christos 	case BFD_RELOC_IA64_DIR64MSB:	newr = BFD_RELOC_IA64_SECREL64MSB;break;
   11149   1.1  christos 	case BFD_RELOC_IA64_DIR64LSB:	newr = BFD_RELOC_IA64_SECREL64LSB;break;
   11150   1.1  christos 	default:			type = "SECREL"; break;
   11151   1.1  christos 	}
   11152   1.1  christos       break;
   11153   1.1  christos 
   11154   1.1  christos     case FUNC_SEG_RELATIVE:
   11155   1.1  christos       switch (r_type)
   11156   1.1  christos 	{
   11157   1.1  christos 	case BFD_RELOC_IA64_DIR32MSB:	newr = BFD_RELOC_IA64_SEGREL32MSB;break;
   11158   1.1  christos 	case BFD_RELOC_IA64_DIR32LSB:	newr = BFD_RELOC_IA64_SEGREL32LSB;break;
   11159   1.1  christos 	case BFD_RELOC_IA64_DIR64MSB:	newr = BFD_RELOC_IA64_SEGREL64MSB;break;
   11160   1.1  christos 	case BFD_RELOC_IA64_DIR64LSB:	newr = BFD_RELOC_IA64_SEGREL64LSB;break;
   11161   1.1  christos 	default:			type = "SEGREL"; break;
   11162   1.1  christos 	}
   11163   1.1  christos       break;
   11164   1.1  christos 
   11165   1.1  christos     case FUNC_LTV_RELATIVE:
   11166   1.1  christos       switch (r_type)
   11167   1.1  christos 	{
   11168   1.1  christos 	case BFD_RELOC_IA64_DIR32MSB:	newr = BFD_RELOC_IA64_LTV32MSB; break;
   11169   1.1  christos 	case BFD_RELOC_IA64_DIR32LSB:	newr = BFD_RELOC_IA64_LTV32LSB; break;
   11170   1.1  christos 	case BFD_RELOC_IA64_DIR64MSB:	newr = BFD_RELOC_IA64_LTV64MSB; break;
   11171   1.1  christos 	case BFD_RELOC_IA64_DIR64LSB:	newr = BFD_RELOC_IA64_LTV64LSB; break;
   11172   1.1  christos 	default:			type = "LTV"; break;
   11173   1.1  christos 	}
   11174   1.1  christos       break;
   11175   1.1  christos 
   11176   1.1  christos     case FUNC_LT_FPTR_RELATIVE:
   11177   1.1  christos       switch (r_type)
   11178   1.1  christos 	{
   11179   1.1  christos 	case BFD_RELOC_IA64_IMM22:
   11180   1.1  christos 	  newr = BFD_RELOC_IA64_LTOFF_FPTR22; break;
   11181   1.1  christos 	case BFD_RELOC_IA64_IMM64:
   11182   1.1  christos 	  newr = BFD_RELOC_IA64_LTOFF_FPTR64I; break;
   11183   1.1  christos 	case BFD_RELOC_IA64_DIR32MSB:
   11184   1.1  christos 	  newr = BFD_RELOC_IA64_LTOFF_FPTR32MSB; break;
   11185   1.1  christos 	case BFD_RELOC_IA64_DIR32LSB:
   11186   1.1  christos 	  newr = BFD_RELOC_IA64_LTOFF_FPTR32LSB; break;
   11187   1.1  christos 	case BFD_RELOC_IA64_DIR64MSB:
   11188   1.1  christos 	  newr = BFD_RELOC_IA64_LTOFF_FPTR64MSB; break;
   11189   1.1  christos 	case BFD_RELOC_IA64_DIR64LSB:
   11190   1.1  christos 	  newr = BFD_RELOC_IA64_LTOFF_FPTR64LSB; break;
   11191   1.1  christos 	default:
   11192   1.1  christos 	  type = "LTOFF_FPTR"; break;
   11193   1.1  christos 	}
   11194   1.1  christos       break;
   11195   1.1  christos 
   11196   1.1  christos     case FUNC_TP_RELATIVE:
   11197   1.1  christos       switch (r_type)
   11198   1.1  christos 	{
   11199   1.1  christos 	case BFD_RELOC_IA64_IMM14:      newr = BFD_RELOC_IA64_TPREL14; break;
   11200   1.1  christos 	case BFD_RELOC_IA64_IMM22:      newr = BFD_RELOC_IA64_TPREL22; break;
   11201   1.1  christos 	case BFD_RELOC_IA64_IMM64:      newr = BFD_RELOC_IA64_TPREL64I; break;
   11202   1.1  christos 	case BFD_RELOC_IA64_DIR64MSB:   newr = BFD_RELOC_IA64_TPREL64MSB; break;
   11203   1.1  christos 	case BFD_RELOC_IA64_DIR64LSB:   newr = BFD_RELOC_IA64_TPREL64LSB; break;
   11204   1.1  christos 	default:                        type = "TPREL"; break;
   11205   1.1  christos 	}
   11206   1.1  christos       break;
   11207   1.1  christos 
   11208   1.1  christos     case FUNC_LT_TP_RELATIVE:
   11209   1.1  christos       switch (r_type)
   11210   1.1  christos 	{
   11211   1.1  christos 	case BFD_RELOC_IA64_IMM22:
   11212   1.1  christos 	  newr = BFD_RELOC_IA64_LTOFF_TPREL22; break;
   11213   1.1  christos 	default:
   11214   1.1  christos 	  type = "LTOFF_TPREL"; break;
   11215   1.1  christos 	}
   11216   1.1  christos       break;
   11217   1.1  christos 
   11218   1.1  christos     case FUNC_DTP_MODULE:
   11219   1.1  christos       switch (r_type)
   11220   1.1  christos 	{
   11221   1.1  christos 	case BFD_RELOC_IA64_DIR64MSB:
   11222   1.1  christos 	  newr = BFD_RELOC_IA64_DTPMOD64MSB; break;
   11223   1.1  christos 	case BFD_RELOC_IA64_DIR64LSB:
   11224   1.1  christos 	  newr = BFD_RELOC_IA64_DTPMOD64LSB; break;
   11225   1.1  christos 	default:
   11226   1.1  christos 	  type = "DTPMOD"; break;
   11227   1.1  christos 	}
   11228   1.1  christos       break;
   11229   1.1  christos 
   11230   1.1  christos     case FUNC_LT_DTP_MODULE:
   11231   1.1  christos       switch (r_type)
   11232   1.1  christos 	{
   11233   1.1  christos 	case BFD_RELOC_IA64_IMM22:
   11234   1.1  christos 	  newr = BFD_RELOC_IA64_LTOFF_DTPMOD22; break;
   11235   1.1  christos 	default:
   11236   1.1  christos 	  type = "LTOFF_DTPMOD"; break;
   11237   1.1  christos 	}
   11238   1.1  christos       break;
   11239   1.1  christos 
   11240   1.1  christos     case FUNC_DTP_RELATIVE:
   11241   1.1  christos       switch (r_type)
   11242   1.1  christos 	{
   11243   1.1  christos 	case BFD_RELOC_IA64_DIR32MSB:
   11244   1.1  christos 	  newr = BFD_RELOC_IA64_DTPREL32MSB; break;
   11245   1.1  christos 	case BFD_RELOC_IA64_DIR32LSB:
   11246   1.1  christos 	  newr = BFD_RELOC_IA64_DTPREL32LSB; break;
   11247   1.1  christos 	case BFD_RELOC_IA64_DIR64MSB:
   11248   1.1  christos 	  newr = BFD_RELOC_IA64_DTPREL64MSB; break;
   11249   1.1  christos 	case BFD_RELOC_IA64_DIR64LSB:
   11250   1.1  christos 	  newr = BFD_RELOC_IA64_DTPREL64LSB; break;
   11251   1.1  christos 	case BFD_RELOC_IA64_IMM14:
   11252   1.1  christos 	  newr = BFD_RELOC_IA64_DTPREL14; break;
   11253   1.1  christos 	case BFD_RELOC_IA64_IMM22:
   11254   1.1  christos 	  newr = BFD_RELOC_IA64_DTPREL22; break;
   11255   1.1  christos 	case BFD_RELOC_IA64_IMM64:
   11256   1.1  christos 	  newr = BFD_RELOC_IA64_DTPREL64I; break;
   11257   1.1  christos 	default:
   11258   1.1  christos 	  type = "DTPREL"; break;
   11259   1.1  christos 	}
   11260   1.1  christos       break;
   11261   1.1  christos 
   11262   1.1  christos     case FUNC_LT_DTP_RELATIVE:
   11263   1.1  christos       switch (r_type)
   11264   1.1  christos 	{
   11265   1.1  christos 	case BFD_RELOC_IA64_IMM22:
   11266   1.1  christos 	  newr = BFD_RELOC_IA64_LTOFF_DTPREL22; break;
   11267   1.1  christos 	default:
   11268   1.1  christos 	  type = "LTOFF_DTPREL"; break;
   11269   1.1  christos 	}
   11270   1.1  christos       break;
   11271   1.1  christos 
   11272   1.1  christos     case FUNC_IPLT_RELOC:
   11273   1.1  christos       switch (r_type)
   11274   1.1  christos 	{
   11275   1.1  christos 	case BFD_RELOC_IA64_IPLTMSB:    return r_type;
   11276   1.1  christos 	case BFD_RELOC_IA64_IPLTLSB:    return r_type;
   11277   1.1  christos 	default:                        type = "IPLT"; break;
   11278   1.1  christos 	}
   11279   1.1  christos       break;
   11280   1.1  christos 
   11281   1.1  christos #ifdef TE_VMS
   11282   1.1  christos     case FUNC_SLOTCOUNT_RELOC:
   11283   1.1  christos       return DUMMY_RELOC_IA64_SLOTCOUNT;
   11284   1.1  christos #endif
   11285   1.1  christos 
   11286   1.1  christos     default:
   11287   1.1  christos       abort ();
   11288   1.1  christos     }
   11289   1.1  christos 
   11290   1.1  christos   if (newr)
   11291   1.1  christos     return newr;
   11292   1.1  christos   else
   11293   1.1  christos     {
   11294   1.1  christos       int width;
   11295   1.1  christos 
   11296   1.1  christos       if (!type)
   11297   1.1  christos 	abort ();
   11298   1.1  christos       switch (r_type)
   11299   1.1  christos 	{
   11300   1.1  christos 	case BFD_RELOC_IA64_DIR32MSB: width = 32; suffix = "MSB"; break;
   11301   1.1  christos 	case BFD_RELOC_IA64_DIR32LSB: width = 32; suffix = "LSB"; break;
   11302   1.1  christos 	case BFD_RELOC_IA64_DIR64MSB: width = 64; suffix = "MSB"; break;
   11303   1.1  christos 	case BFD_RELOC_IA64_DIR64LSB: width = 64; suffix = "LSB"; break;
   11304   1.1  christos 	case BFD_RELOC_UNUSED:        width = 13; break;
   11305   1.1  christos 	case BFD_RELOC_IA64_IMM14:    width = 14; break;
   11306   1.1  christos 	case BFD_RELOC_IA64_IMM22:    width = 22; break;
   11307   1.1  christos 	case BFD_RELOC_IA64_IMM64:    width = 64; suffix = "I"; break;
   11308   1.1  christos 	default:                      abort ();
   11309   1.1  christos 	}
   11310   1.1  christos 
   11311   1.1  christos       /* This should be an error, but since previously there wasn't any
   11312   1.1  christos 	 diagnostic here, don't make it fail because of this for now.  */
   11313   1.1  christos       as_warn (_("Cannot express %s%d%s relocation"), type, width, suffix);
   11314   1.1  christos       return r_type;
   11315   1.1  christos     }
   11316   1.1  christos }
   11317   1.1  christos 
   11318   1.1  christos /* Here is where generate the appropriate reloc for pseudo relocation
   11319   1.1  christos    functions.  */
   11320   1.1  christos void
   11321   1.1  christos ia64_validate_fix (fixS *fix)
   11322   1.1  christos {
   11323   1.1  christos   switch (fix->fx_r_type)
   11324   1.1  christos     {
   11325   1.1  christos     case BFD_RELOC_IA64_FPTR64I:
   11326   1.1  christos     case BFD_RELOC_IA64_FPTR32MSB:
   11327   1.1  christos     case BFD_RELOC_IA64_FPTR64LSB:
   11328   1.1  christos     case BFD_RELOC_IA64_LTOFF_FPTR22:
   11329   1.1  christos     case BFD_RELOC_IA64_LTOFF_FPTR64I:
   11330   1.1  christos       if (fix->fx_offset != 0)
   11331   1.1  christos 	as_bad_where (fix->fx_file, fix->fx_line,
   11332   1.1  christos 		      _("No addend allowed in @fptr() relocation"));
   11333   1.1  christos       break;
   11334   1.1  christos     default:
   11335   1.1  christos       break;
   11336   1.1  christos     }
   11337   1.1  christos }
   11338   1.1  christos 
   11339   1.1  christos static void
   11340   1.1  christos fix_insn (fixS *fix, const struct ia64_operand *odesc, valueT value)
   11341   1.1  christos {
   11342   1.1  christos   bfd_vma insn[3], t0, t1, control_bits;
   11343   1.1  christos   const char *err;
   11344   1.1  christos   char *fixpos;
   11345   1.1  christos   long slot;
   11346   1.1  christos 
   11347   1.1  christos   slot = fix->fx_where & 0x3;
   11348   1.1  christos   fixpos = fix->fx_frag->fr_literal + (fix->fx_where - slot);
   11349   1.1  christos 
   11350   1.1  christos   /* Bundles are always in little-endian byte order */
   11351   1.1  christos   t0 = bfd_getl64 (fixpos);
   11352   1.1  christos   t1 = bfd_getl64 (fixpos + 8);
   11353   1.1  christos   control_bits = t0 & 0x1f;
   11354   1.1  christos   insn[0] = (t0 >>  5) & 0x1ffffffffffLL;
   11355   1.1  christos   insn[1] = ((t0 >> 46) & 0x3ffff) | ((t1 & 0x7fffff) << 18);
   11356   1.1  christos   insn[2] = (t1 >> 23) & 0x1ffffffffffLL;
   11357   1.1  christos 
   11358   1.1  christos   err = NULL;
   11359   1.1  christos   if (odesc - elf64_ia64_operands == IA64_OPND_IMMU64)
   11360   1.1  christos     {
   11361   1.1  christos       insn[1] = (value >> 22) & 0x1ffffffffffLL;
   11362   1.1  christos       insn[2] |= (((value & 0x7f) << 13)
   11363   1.1  christos 		  | (((value >> 7) & 0x1ff) << 27)
   11364   1.1  christos 		  | (((value >> 16) & 0x1f) << 22)
   11365   1.1  christos 		  | (((value >> 21) & 0x1) << 21)
   11366   1.1  christos 		  | (((value >> 63) & 0x1) << 36));
   11367   1.1  christos     }
   11368   1.1  christos   else if (odesc - elf64_ia64_operands == IA64_OPND_IMMU62)
   11369   1.1  christos     {
   11370   1.1  christos       if (value & ~0x3fffffffffffffffULL)
   11371   1.1  christos 	err = _("integer operand out of range");
   11372   1.1  christos       insn[1] = (value >> 21) & 0x1ffffffffffLL;
   11373   1.1  christos       insn[2] |= (((value & 0xfffff) << 6) | (((value >> 20) & 0x1) << 36));
   11374   1.1  christos     }
   11375   1.1  christos   else if (odesc - elf64_ia64_operands == IA64_OPND_TGT64)
   11376   1.1  christos     {
   11377   1.1  christos       value >>= 4;
   11378   1.1  christos       insn[1] = ((value >> 20) & 0x7fffffffffLL) << 2;
   11379   1.1  christos       insn[2] |= ((((value >> 59) & 0x1) << 36)
   11380   1.1  christos 		  | (((value >> 0) & 0xfffff) << 13));
   11381   1.1  christos     }
   11382   1.1  christos   else
   11383   1.1  christos     err = (*odesc->insert) (odesc, value, insn + slot);
   11384   1.1  christos 
   11385   1.1  christos   if (err)
   11386   1.1  christos     as_bad_where (fix->fx_file, fix->fx_line, "%s", err);
   11387   1.1  christos 
   11388   1.1  christos   t0 = control_bits | (insn[0] << 5) | (insn[1] << 46);
   11389   1.1  christos   t1 = ((insn[1] >> 18) & 0x7fffff) | (insn[2] << 23);
   11390   1.1  christos   number_to_chars_littleendian (fixpos + 0, t0, 8);
   11391   1.1  christos   number_to_chars_littleendian (fixpos + 8, t1, 8);
   11392   1.1  christos }
   11393   1.1  christos 
   11394   1.1  christos /* Attempt to simplify or even eliminate a fixup.  The return value is
   11395   1.1  christos    ignored; perhaps it was once meaningful, but now it is historical.
   11396   1.1  christos    To indicate that a fixup has been eliminated, set FIXP->FX_DONE.
   11397   1.1  christos 
   11398   1.1  christos    If fixp->fx_addsy is non-NULL, we'll have to generate a reloc entry
   11399   1.1  christos    (if possible).  */
   11400   1.1  christos 
   11401   1.1  christos void
   11402   1.1  christos md_apply_fix (fixS *fix, valueT *valP, segT seg ATTRIBUTE_UNUSED)
   11403   1.1  christos {
   11404   1.1  christos   char *fixpos;
   11405   1.1  christos   valueT value = *valP;
   11406   1.1  christos 
   11407   1.1  christos   fixpos = fix->fx_frag->fr_literal + fix->fx_where;
   11408   1.1  christos 
   11409   1.1  christos   if (fix->fx_pcrel)
   11410   1.1  christos     {
   11411   1.1  christos     switch (fix->fx_r_type)
   11412   1.1  christos       {
   11413   1.1  christos       case BFD_RELOC_IA64_PCREL21B: break;
   11414   1.1  christos       case BFD_RELOC_IA64_PCREL21BI: break;
   11415   1.1  christos       case BFD_RELOC_IA64_PCREL21F: break;
   11416   1.1  christos       case BFD_RELOC_IA64_PCREL21M: break;
   11417   1.1  christos       case BFD_RELOC_IA64_PCREL60B: break;
   11418   1.1  christos       case BFD_RELOC_IA64_PCREL22: break;
   11419   1.1  christos       case BFD_RELOC_IA64_PCREL64I: break;
   11420   1.1  christos       case BFD_RELOC_IA64_PCREL32MSB: break;
   11421   1.1  christos       case BFD_RELOC_IA64_PCREL32LSB: break;
   11422   1.1  christos       case BFD_RELOC_IA64_PCREL64MSB: break;
   11423   1.1  christos       case BFD_RELOC_IA64_PCREL64LSB: break;
   11424   1.1  christos       default:
   11425   1.1  christos 	fix->fx_r_type = ia64_gen_real_reloc_type (pseudo_func[FUNC_PC_RELATIVE].u.sym,
   11426   1.1  christos 					       fix->fx_r_type);
   11427   1.1  christos 	break;
   11428   1.1  christos       }
   11429   1.1  christos     }
   11430   1.1  christos   if (fix->fx_addsy)
   11431   1.1  christos     {
   11432   1.1  christos       switch ((unsigned) fix->fx_r_type)
   11433   1.1  christos 	{
   11434   1.1  christos 	case BFD_RELOC_UNUSED:
   11435   1.1  christos 	  /* This must be a TAG13 or TAG13b operand.  There are no external
   11436   1.1  christos 	     relocs defined for them, so we must give an error.  */
   11437   1.1  christos 	  as_bad_where (fix->fx_file, fix->fx_line,
   11438   1.1  christos 			_("%s must have a constant value"),
   11439   1.1  christos 			elf64_ia64_operands[fix->tc_fix_data.opnd].desc);
   11440   1.1  christos 	  fix->fx_done = 1;
   11441   1.1  christos 	  return;
   11442   1.1  christos 
   11443   1.1  christos 	case BFD_RELOC_IA64_TPREL14:
   11444   1.1  christos 	case BFD_RELOC_IA64_TPREL22:
   11445   1.1  christos 	case BFD_RELOC_IA64_TPREL64I:
   11446   1.1  christos 	case BFD_RELOC_IA64_LTOFF_TPREL22:
   11447   1.1  christos 	case BFD_RELOC_IA64_LTOFF_DTPMOD22:
   11448   1.1  christos 	case BFD_RELOC_IA64_DTPREL14:
   11449   1.1  christos 	case BFD_RELOC_IA64_DTPREL22:
   11450   1.1  christos 	case BFD_RELOC_IA64_DTPREL64I:
   11451   1.1  christos 	case BFD_RELOC_IA64_LTOFF_DTPREL22:
   11452   1.1  christos 	  S_SET_THREAD_LOCAL (fix->fx_addsy);
   11453   1.1  christos 	  break;
   11454   1.1  christos 
   11455   1.1  christos #ifdef TE_VMS
   11456   1.1  christos         case DUMMY_RELOC_IA64_SLOTCOUNT:
   11457   1.1  christos 	  as_bad_where (fix->fx_file, fix->fx_line,
   11458   1.1  christos 			_("cannot resolve @slotcount parameter"));
   11459   1.1  christos 	  fix->fx_done = 1;
   11460   1.1  christos 	  return;
   11461   1.1  christos #endif
   11462   1.1  christos 
   11463   1.1  christos 	default:
   11464   1.1  christos 	  break;
   11465   1.1  christos 	}
   11466   1.1  christos     }
   11467   1.1  christos   else if (fix->tc_fix_data.opnd == IA64_OPND_NIL)
   11468   1.1  christos     {
   11469   1.1  christos #ifdef TE_VMS
   11470   1.1  christos       if (fix->fx_r_type == DUMMY_RELOC_IA64_SLOTCOUNT)
   11471   1.1  christos         {
   11472   1.1  christos           /* For @slotcount, convert an addresses difference to a slots
   11473   1.1  christos              difference.  */
   11474   1.1  christos           valueT v;
   11475   1.1  christos 
   11476   1.1  christos           v = (value >> 4) * 3;
   11477   1.1  christos           switch (value & 0x0f)
   11478   1.1  christos             {
   11479   1.1  christos             case 0:
   11480   1.1  christos             case 1:
   11481   1.1  christos             case 2:
   11482   1.1  christos               v += value & 0x0f;
   11483   1.1  christos               break;
   11484   1.1  christos             case 0x0f:
   11485   1.1  christos               v += 2;
   11486   1.1  christos               break;
   11487   1.1  christos             case 0x0e:
   11488   1.1  christos               v += 1;
   11489   1.1  christos               break;
   11490   1.1  christos             default:
   11491   1.1  christos               as_bad (_("invalid @slotcount value"));
   11492   1.1  christos             }
   11493   1.1  christos           value = v;
   11494   1.1  christos         }
   11495   1.1  christos #endif
   11496   1.1  christos 
   11497   1.1  christos       if (fix->tc_fix_data.bigendian)
   11498   1.1  christos 	number_to_chars_bigendian (fixpos, value, fix->fx_size);
   11499   1.1  christos       else
   11500   1.1  christos 	number_to_chars_littleendian (fixpos, value, fix->fx_size);
   11501   1.1  christos       fix->fx_done = 1;
   11502   1.1  christos     }
   11503   1.1  christos   else
   11504   1.1  christos     {
   11505   1.1  christos       fix_insn (fix, elf64_ia64_operands + fix->tc_fix_data.opnd, value);
   11506   1.1  christos       fix->fx_done = 1;
   11507   1.1  christos     }
   11508   1.1  christos }
   11509   1.1  christos 
   11510   1.1  christos /* Generate the BFD reloc to be stuck in the object file from the
   11511   1.1  christos    fixup used internally in the assembler.  */
   11512   1.1  christos 
   11513   1.1  christos arelent *
   11514   1.1  christos tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED, fixS *fixp)
   11515   1.1  christos {
   11516   1.1  christos   arelent *reloc;
   11517   1.1  christos 
   11518  1.10  christos   reloc = notes_alloc (sizeof (arelent));
   11519  1.10  christos   reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *));
   11520   1.1  christos   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   11521   1.1  christos   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
   11522   1.1  christos   reloc->addend = fixp->fx_offset;
   11523   1.1  christos   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
   11524   1.1  christos 
   11525   1.1  christos   if (!reloc->howto)
   11526   1.1  christos     {
   11527   1.1  christos       as_bad_where (fixp->fx_file, fixp->fx_line,
   11528   1.1  christos 		    _("Cannot represent %s relocation in object file"),
   11529   1.1  christos 		    bfd_get_reloc_code_name (fixp->fx_r_type));
   11530   1.1  christos       return NULL;
   11531   1.1  christos     }
   11532   1.1  christos   return reloc;
   11533   1.1  christos }
   11534   1.1  christos 
   11535   1.1  christos /* Turn a string in input_line_pointer into a floating point constant
   11536   1.1  christos    of type TYPE, and store the appropriate bytes in *LIT.  The number
   11537   1.1  christos    of LITTLENUMS emitted is stored in *SIZE.  An error message is
   11538   1.1  christos    returned, or NULL on OK.  */
   11539   1.1  christos 
   11540   1.5  christos const char *
   11541   1.1  christos md_atof (int type, char *lit, int *size)
   11542   1.1  christos {
   11543   1.1  christos   LITTLENUM_TYPE words[MAX_LITTLENUMS];
   11544   1.1  christos   char *t;
   11545   1.1  christos   int prec;
   11546   1.1  christos 
   11547   1.1  christos   switch (type)
   11548   1.1  christos     {
   11549   1.1  christos       /* IEEE floats */
   11550   1.1  christos     case 'f':
   11551   1.1  christos     case 'F':
   11552   1.1  christos     case 's':
   11553   1.1  christos     case 'S':
   11554   1.1  christos       prec = 2;
   11555   1.1  christos       break;
   11556   1.1  christos 
   11557   1.1  christos     case 'd':
   11558   1.1  christos     case 'D':
   11559   1.1  christos     case 'r':
   11560   1.1  christos     case 'R':
   11561   1.1  christos       prec = 4;
   11562   1.1  christos       break;
   11563   1.1  christos 
   11564   1.1  christos     case 'x':
   11565   1.1  christos     case 'X':
   11566   1.1  christos     case 'p':
   11567   1.1  christos     case 'P':
   11568   1.1  christos       prec = 5;
   11569   1.1  christos       break;
   11570   1.1  christos 
   11571   1.1  christos     default:
   11572   1.1  christos       *size = 0;
   11573   1.1  christos       return _("Unrecognized or unsupported floating point constant");
   11574   1.1  christos     }
   11575   1.1  christos   t = atof_ieee (input_line_pointer, type, words);
   11576   1.1  christos   if (t)
   11577   1.1  christos     input_line_pointer = t;
   11578   1.1  christos 
   11579   1.1  christos   (*ia64_float_to_chars) (lit, words, prec);
   11580   1.1  christos 
   11581   1.1  christos   if (type == 'X')
   11582   1.1  christos     {
   11583   1.1  christos       /* It is 10 byte floating point with 6 byte padding.  */
   11584   1.1  christos       memset (&lit [10], 0, 6);
   11585   1.1  christos       *size = 8 * sizeof (LITTLENUM_TYPE);
   11586   1.1  christos     }
   11587   1.1  christos   else
   11588   1.1  christos     *size = prec * sizeof (LITTLENUM_TYPE);
   11589   1.1  christos 
   11590   1.1  christos   return NULL;
   11591   1.1  christos }
   11592   1.1  christos 
   11593   1.1  christos /* Handle ia64 specific semantics of the align directive.  */
   11594   1.1  christos 
   11595   1.1  christos void
   11596   1.1  christos ia64_md_do_align (int n ATTRIBUTE_UNUSED,
   11597   1.1  christos 		  const char *fill ATTRIBUTE_UNUSED,
   11598   1.1  christos 		  int len ATTRIBUTE_UNUSED,
   11599   1.1  christos 		  int max ATTRIBUTE_UNUSED)
   11600   1.1  christos {
   11601   1.1  christos   if (subseg_text_p (now_seg))
   11602   1.1  christos     ia64_flush_insns ();
   11603   1.1  christos }
   11604   1.1  christos 
   11605   1.1  christos /* This is called from HANDLE_ALIGN in write.c.  Fill in the contents
   11606   1.1  christos    of an rs_align_code fragment.  */
   11607   1.1  christos 
   11608   1.1  christos void
   11609   1.1  christos ia64_handle_align (fragS *fragp)
   11610   1.1  christos {
   11611   1.1  christos   int bytes;
   11612   1.1  christos   char *p;
   11613   1.1  christos   const unsigned char *nop_type;
   11614   1.1  christos 
   11615   1.1  christos   if (fragp->fr_type != rs_align_code)
   11616   1.1  christos     return;
   11617   1.1  christos 
   11618   1.1  christos   /* Check if this frag has to end with a stop bit.  */
   11619   1.1  christos   nop_type = fragp->tc_frag_data ? le_nop_stop : le_nop;
   11620   1.1  christos 
   11621   1.1  christos   bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
   11622   1.1  christos   p = fragp->fr_literal + fragp->fr_fix;
   11623   1.1  christos 
   11624   1.3  christos   /* If no paddings are needed, we check if we need a stop bit.  */
   11625   1.1  christos   if (!bytes && fragp->tc_frag_data)
   11626   1.1  christos     {
   11627   1.1  christos       if (fragp->fr_fix < 16)
   11628   1.1  christos #if 1
   11629   1.1  christos 	/* FIXME: It won't work with
   11630   1.1  christos 	   .align 16
   11631   1.1  christos 	   alloc r32=ar.pfs,1,2,4,0
   11632   1.1  christos 	 */
   11633   1.1  christos 	;
   11634   1.1  christos #else
   11635   1.1  christos 	as_bad_where (fragp->fr_file, fragp->fr_line,
   11636   1.1  christos 		      _("Can't add stop bit to mark end of instruction group"));
   11637   1.1  christos #endif
   11638   1.1  christos       else
   11639   1.1  christos 	/* Bundles are always in little-endian byte order. Make sure
   11640   1.1  christos 	   the previous bundle has the stop bit.  */
   11641   1.1  christos 	*(p - 16) |= 1;
   11642   1.1  christos     }
   11643   1.1  christos 
   11644   1.1  christos   /* Make sure we are on a 16-byte boundary, in case someone has been
   11645   1.1  christos      putting data into a text section.  */
   11646   1.1  christos   if (bytes & 15)
   11647   1.1  christos     {
   11648   1.1  christos       int fix = bytes & 15;
   11649   1.1  christos       memset (p, 0, fix);
   11650   1.1  christos       p += fix;
   11651   1.1  christos       bytes -= fix;
   11652   1.1  christos       fragp->fr_fix += fix;
   11653   1.1  christos     }
   11654   1.1  christos 
   11655   1.1  christos   /* Instruction bundles are always little-endian.  */
   11656   1.1  christos   memcpy (p, nop_type, 16);
   11657   1.1  christos   fragp->fr_var = 16;
   11658   1.1  christos }
   11659   1.1  christos 
   11660   1.1  christos static void
   11661   1.1  christos ia64_float_to_chars_bigendian (char *lit, LITTLENUM_TYPE *words,
   11662   1.1  christos 			       int prec)
   11663   1.1  christos {
   11664   1.1  christos   while (prec--)
   11665   1.1  christos     {
   11666  1.10  christos       number_to_chars_bigendian (lit, *words++, sizeof (LITTLENUM_TYPE));
   11667   1.1  christos       lit += sizeof (LITTLENUM_TYPE);
   11668   1.1  christos     }
   11669   1.1  christos }
   11670   1.1  christos 
   11671   1.1  christos static void
   11672   1.1  christos ia64_float_to_chars_littleendian (char *lit, LITTLENUM_TYPE *words,
   11673   1.1  christos 				  int prec)
   11674   1.1  christos {
   11675   1.1  christos   while (prec--)
   11676   1.1  christos     {
   11677  1.10  christos       number_to_chars_littleendian (lit, words[prec],
   11678   1.1  christos 				    sizeof (LITTLENUM_TYPE));
   11679   1.1  christos       lit += sizeof (LITTLENUM_TYPE);
   11680   1.1  christos     }
   11681   1.1  christos }
   11682   1.1  christos 
   11683   1.1  christos void
   11684   1.1  christos ia64_elf_section_change_hook (void)
   11685   1.1  christos {
   11686   1.1  christos   if (elf_section_type (now_seg) == SHT_IA_64_UNWIND
   11687   1.1  christos       && elf_linked_to_section (now_seg) == NULL)
   11688   1.1  christos     elf_linked_to_section (now_seg) = text_section;
   11689   1.1  christos   dot_byteorder (-1);
   11690   1.1  christos }
   11691   1.1  christos 
   11692   1.1  christos /* Check if a label should be made global.  */
   11693   1.1  christos void
   11694   1.1  christos ia64_check_label (symbolS *label)
   11695   1.1  christos {
   11696   1.1  christos   if (*input_line_pointer == ':')
   11697   1.1  christos     {
   11698   1.1  christos       S_SET_EXTERNAL (label);
   11699   1.1  christos       input_line_pointer++;
   11700   1.1  christos     }
   11701   1.1  christos }
   11702   1.1  christos 
   11703   1.1  christos /* Used to remember where .alias and .secalias directives are seen. We
   11704   1.1  christos    will rename symbol and section names when we are about to output
   11705   1.1  christos    the relocatable file.  */
   11706   1.1  christos struct alias
   11707   1.1  christos {
   11708   1.5  christos   const char *file;		/* The file where the directive is seen.  */
   11709   1.1  christos   unsigned int line;	/* The line number the directive is at.  */
   11710   1.1  christos   const char *name;	/* The original name of the symbol.  */
   11711   1.1  christos };
   11712   1.1  christos 
   11713   1.1  christos /* Called for .alias and .secalias directives. If SECTION is 1, it is
   11714   1.1  christos    .secalias. Otherwise, it is .alias.  */
   11715   1.1  christos static void
   11716   1.1  christos dot_alias (int section)
   11717   1.1  christos {
   11718   1.1  christos   char *name, *alias;
   11719   1.1  christos   char delim;
   11720   1.1  christos   char *end_name;
   11721   1.1  christos   int len;
   11722   1.1  christos   struct alias *h;
   11723   1.1  christos   const char *a;
   11724   1.8  christos   htab_t ahash, nhash;
   11725   1.1  christos   const char *kind;
   11726   1.1  christos 
   11727   1.3  christos   delim = get_symbol_name (&name);
   11728   1.1  christos   end_name = input_line_pointer;
   11729  1.10  christos   restore_line_pointer (delim);
   11730   1.1  christos 
   11731   1.1  christos   if (name == end_name)
   11732   1.1  christos     {
   11733   1.1  christos       as_bad (_("expected symbol name"));
   11734   1.1  christos       ignore_rest_of_line ();
   11735   1.1  christos       return;
   11736   1.1  christos     }
   11737   1.1  christos 
   11738  1.10  christos   SKIP_WHITESPACE ();
   11739   1.1  christos 
   11740   1.1  christos   if (*input_line_pointer != ',')
   11741   1.1  christos     {
   11742   1.1  christos       *end_name = 0;
   11743   1.1  christos       as_bad (_("expected comma after \"%s\""), name);
   11744   1.1  christos       *end_name = delim;
   11745   1.1  christos       ignore_rest_of_line ();
   11746   1.1  christos       return;
   11747   1.1  christos     }
   11748   1.1  christos 
   11749   1.1  christos   input_line_pointer++;
   11750   1.1  christos   *end_name = 0;
   11751   1.1  christos   ia64_canonicalize_symbol_name (name);
   11752   1.1  christos 
   11753   1.1  christos   /* We call demand_copy_C_string to check if alias string is valid.
   11754   1.1  christos      There should be a closing `"' and no `\0' in the string.  */
   11755   1.1  christos   alias = demand_copy_C_string (&len);
   11756   1.1  christos   if (alias == NULL)
   11757   1.1  christos     {
   11758   1.1  christos       ignore_rest_of_line ();
   11759   1.1  christos       return;
   11760   1.1  christos     }
   11761   1.1  christos 
   11762   1.1  christos   /* Make a copy of name string.  */
   11763   1.9  christos   name = notes_strdup (name);
   11764   1.1  christos 
   11765   1.1  christos   if (section)
   11766   1.1  christos     {
   11767   1.1  christos       kind = "section";
   11768   1.1  christos       ahash = secalias_hash;
   11769   1.1  christos       nhash = secalias_name_hash;
   11770   1.1  christos     }
   11771   1.1  christos   else
   11772   1.1  christos     {
   11773   1.1  christos       kind = "symbol";
   11774   1.1  christos       ahash = alias_hash;
   11775   1.1  christos       nhash = alias_name_hash;
   11776   1.1  christos     }
   11777   1.1  christos 
   11778   1.1  christos   /* Check if alias has been used before.  */
   11779   1.8  christos 
   11780  1.10  christos   h = str_hash_find (ahash, alias);
   11781   1.1  christos   if (h)
   11782   1.1  christos     {
   11783   1.1  christos       if (strcmp (h->name, name))
   11784   1.1  christos 	as_bad (_("`%s' is already the alias of %s `%s'"),
   11785   1.1  christos 		alias, kind, h->name);
   11786   1.9  christos       notes_free (alias);
   11787   1.1  christos       goto out;
   11788   1.1  christos     }
   11789   1.1  christos 
   11790   1.1  christos   /* Check if name already has an alias.  */
   11791  1.10  christos   a = str_hash_find (nhash, name);
   11792   1.1  christos   if (a)
   11793   1.1  christos     {
   11794   1.1  christos       if (strcmp (a, alias))
   11795   1.1  christos 	as_bad (_("%s `%s' already has an alias `%s'"), kind, name, a);
   11796   1.9  christos       notes_free (alias);
   11797   1.1  christos       goto out;
   11798   1.1  christos     }
   11799   1.1  christos 
   11800   1.9  christos   h = notes_alloc (sizeof (*h));
   11801   1.5  christos   h->file = as_where (&h->line);
   11802   1.1  christos   h->name = name;
   11803   1.3  christos 
   11804   1.8  christos   str_hash_insert (ahash, alias, h, 0);
   11805   1.8  christos   str_hash_insert (nhash, name, alias, 0);
   11806   1.1  christos 
   11807   1.1  christos out:
   11808   1.1  christos   demand_empty_rest_of_line ();
   11809   1.1  christos }
   11810   1.1  christos 
   11811   1.1  christos /* It renames the original symbol name to its alias.  */
   11812   1.8  christos static int
   11813   1.8  christos do_alias (void **slot, void *arg ATTRIBUTE_UNUSED)
   11814   1.1  christos {
   11815   1.8  christos   string_tuple_t *tuple = *((string_tuple_t **) slot);
   11816   1.8  christos   struct alias *h = (struct alias *) tuple->value;
   11817   1.1  christos   symbolS *sym = symbol_find (h->name);
   11818   1.1  christos 
   11819   1.1  christos   if (sym == NULL)
   11820   1.1  christos     {
   11821   1.1  christos #ifdef TE_VMS
   11822   1.1  christos       /* Uses .alias extensively to alias CRTL functions to same with
   11823   1.1  christos 	 decc$ prefix. Sometimes function gets optimized away and a
   11824   1.1  christos 	 warning results, which should be suppressed.  */
   11825   1.8  christos       if (!startswith (tuple->key, "decc$"))
   11826   1.1  christos #endif
   11827   1.1  christos 	as_warn_where (h->file, h->line,
   11828   1.1  christos 		       _("symbol `%s' aliased to `%s' is not used"),
   11829   1.8  christos 		       h->name, tuple->key);
   11830   1.1  christos     }
   11831   1.1  christos     else
   11832   1.8  christos       S_SET_NAME (sym, (char *) tuple->key);
   11833   1.8  christos 
   11834   1.8  christos   return 1;
   11835   1.1  christos }
   11836   1.1  christos 
   11837   1.1  christos /* Called from write_object_file.  */
   11838   1.1  christos void
   11839   1.1  christos ia64_adjust_symtab (void)
   11840   1.1  christos {
   11841   1.9  christos   htab_traverse_noresize (alias_hash, do_alias, NULL);
   11842   1.1  christos }
   11843   1.1  christos 
   11844   1.1  christos /* It renames the original section name to its alias.  */
   11845   1.8  christos static int
   11846   1.8  christos do_secalias (void **slot, void *arg ATTRIBUTE_UNUSED)
   11847   1.1  christos {
   11848   1.8  christos   string_tuple_t *tuple = *((string_tuple_t **) slot);
   11849   1.8  christos   struct alias *h = (struct alias *) tuple->value;
   11850   1.1  christos   segT sec = bfd_get_section_by_name (stdoutput, h->name);
   11851   1.1  christos 
   11852   1.1  christos   if (sec == NULL)
   11853   1.1  christos     as_warn_where (h->file, h->line,
   11854   1.1  christos 		   _("section `%s' aliased to `%s' is not used"),
   11855   1.8  christos 		   h->name, tuple->key);
   11856   1.1  christos   else
   11857   1.8  christos     sec->name = tuple->key;
   11858   1.8  christos 
   11859   1.8  christos   return 1;
   11860   1.1  christos }
   11861   1.1  christos 
   11862   1.1  christos /* Called from write_object_file.  */
   11863   1.1  christos void
   11864   1.1  christos ia64_frob_file (void)
   11865   1.1  christos {
   11866   1.9  christos   htab_traverse_noresize (secalias_hash, do_secalias, NULL);
   11867   1.1  christos }
   11868   1.1  christos 
   11869   1.1  christos #ifdef TE_VMS
   11870   1.1  christos #define NT_VMS_MHD 1
   11871   1.1  christos #define NT_VMS_LNM 2
   11872   1.1  christos 
   11873   1.1  christos /* Integrity VMS 8.x identifies it's ELF modules with a standard ELF
   11874   1.1  christos    .note section.  */
   11875   1.1  christos 
   11876   1.1  christos /* Manufacture a VMS-like time string.  */
   11877   1.1  christos static void
   11878   1.1  christos get_vms_time (char *Now)
   11879   1.1  christos {
   11880   1.1  christos   char *pnt;
   11881   1.1  christos   time_t timeb;
   11882   1.1  christos 
   11883   1.1  christos   time (&timeb);
   11884   1.1  christos   pnt = ctime (&timeb);
   11885   1.1  christos   pnt[3] = 0;
   11886   1.1  christos   pnt[7] = 0;
   11887   1.1  christos   pnt[10] = 0;
   11888   1.1  christos   pnt[16] = 0;
   11889   1.1  christos   pnt[24] = 0;
   11890   1.1  christos   sprintf (Now, "%2s-%3s-%s %s", pnt + 8, pnt + 4, pnt + 20, pnt + 11);
   11891   1.1  christos }
   11892   1.1  christos 
   11893   1.1  christos void
   11894   1.1  christos ia64_vms_note (void)
   11895   1.1  christos {
   11896   1.1  christos   char *p;
   11897   1.1  christos   asection *seg = now_seg;
   11898   1.1  christos   subsegT subseg = now_subseg;
   11899   1.1  christos   asection *secp = NULL;
   11900   1.1  christos   char *bname;
   11901   1.1  christos   char buf [256];
   11902   1.1  christos   symbolS *sym;
   11903   1.1  christos 
   11904   1.1  christos   /* Create the .note section.  */
   11905   1.1  christos 
   11906   1.1  christos   secp = subseg_new (".note", 0);
   11907   1.7  christos   bfd_set_section_flags (secp, SEC_HAS_CONTENTS | SEC_READONLY);
   11908   1.1  christos 
   11909   1.1  christos   /* Module header note (MHD).  */
   11910   1.1  christos   bname = xstrdup (lbasename (out_file_name));
   11911   1.1  christos   if ((p = strrchr (bname, '.')))
   11912   1.1  christos     *p = '\0';
   11913   1.3  christos 
   11914   1.1  christos   /* VMS note header is 24 bytes long.  */
   11915   1.1  christos   p = frag_more (8 + 8 + 8);
   11916   1.1  christos   number_to_chars_littleendian (p + 0, 8, 8);
   11917   1.1  christos   number_to_chars_littleendian (p + 8, 40 + strlen (bname), 8);
   11918   1.1  christos   number_to_chars_littleendian (p + 16, NT_VMS_MHD, 8);
   11919   1.1  christos 
   11920   1.1  christos   p = frag_more (8);
   11921   1.1  christos   strcpy (p, "IPF/VMS");
   11922   1.1  christos 
   11923   1.1  christos   p = frag_more (17 + 17 + strlen (bname) + 1 + 5);
   11924   1.1  christos   get_vms_time (p);
   11925   1.1  christos   strcpy (p + 17, "24-FEB-2005 15:00");
   11926   1.1  christos   p += 17 + 17;
   11927   1.1  christos   strcpy (p, bname);
   11928   1.1  christos   p += strlen (bname) + 1;
   11929   1.1  christos   free (bname);
   11930   1.1  christos   strcpy (p, "V1.0");
   11931   1.1  christos 
   11932   1.1  christos   frag_align (3, 0, 0);
   11933   1.1  christos 
   11934   1.1  christos   /* Language processor name note.  */
   11935   1.1  christos   sprintf (buf, "GNU assembler version %s (%s) using BFD version %s",
   11936   1.1  christos 	   VERSION, TARGET_ALIAS, BFD_VERSION_STRING);
   11937   1.1  christos 
   11938   1.1  christos   p = frag_more (8 + 8 + 8);
   11939   1.1  christos   number_to_chars_littleendian (p + 0, 8, 8);
   11940   1.1  christos   number_to_chars_littleendian (p + 8, strlen (buf) + 1, 8);
   11941   1.1  christos   number_to_chars_littleendian (p + 16, NT_VMS_LNM, 8);
   11942   1.1  christos 
   11943   1.1  christos   p = frag_more (8);
   11944   1.1  christos   strcpy (p, "IPF/VMS");
   11945   1.1  christos 
   11946   1.1  christos   p = frag_more (strlen (buf) + 1);
   11947   1.1  christos   strcpy (p, buf);
   11948   1.1  christos 
   11949   1.1  christos   frag_align (3, 0, 0);
   11950   1.1  christos 
   11951   1.1  christos   secp = subseg_new (".vms_display_name_info", 0);
   11952   1.7  christos   bfd_set_section_flags (secp, SEC_HAS_CONTENTS | SEC_READONLY);
   11953   1.1  christos 
   11954   1.1  christos   /* This symbol should be passed on the command line and be variable
   11955   1.1  christos      according to language.  */
   11956   1.1  christos   sym = symbol_new ("__gnat_vms_display_name@gnat_demangler_rtl",
   11957   1.8  christos 		    absolute_section, &zero_address_frag, 0);
   11958   1.1  christos   symbol_table_insert (sym);
   11959   1.1  christos   symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING | BSF_DYNAMIC;
   11960   1.1  christos 
   11961   1.1  christos   p = frag_more (4);
   11962   1.1  christos   /* Format 3 of VMS demangler Spec.  */
   11963   1.1  christos   number_to_chars_littleendian (p, 3, 4);
   11964   1.1  christos 
   11965   1.1  christos   p = frag_more (4);
   11966   1.1  christos   /* Place holder for symbol table index of above symbol.  */
   11967   1.1  christos   number_to_chars_littleendian (p, -1, 4);
   11968   1.1  christos 
   11969   1.1  christos   frag_align (3, 0, 0);
   11970   1.1  christos 
   11971   1.1  christos   /* We probably can't restore the current segment, for there likely
   11972   1.1  christos      isn't one yet...  */
   11973   1.1  christos   if (seg && subseg)
   11974   1.1  christos     subseg_set (seg, subseg);
   11975   1.1  christos }
   11976   1.1  christos 
   11977   1.1  christos #endif /* TE_VMS */
   11978