Home | History | Annotate | Line # | Download | only in config
tc-pru.c revision 1.1
      1  1.1  christos /* TI PRU assembler.
      2  1.1  christos    Copyright (C) 2014-2018 Free Software Foundation, Inc.
      3  1.1  christos    Contributed by Dimitar Dimitrov <dimitar (at) dinux.eu>
      4  1.1  christos    Based on tc-nios2.c
      5  1.1  christos 
      6  1.1  christos    This file is part of GAS, the GNU Assembler.
      7  1.1  christos 
      8  1.1  christos    GAS is free software; you can redistribute it and/or modify
      9  1.1  christos    it under the terms of the GNU General Public License as published by
     10  1.1  christos    the Free Software Foundation; either version 3, or (at your option)
     11  1.1  christos    any later version.
     12  1.1  christos 
     13  1.1  christos    GAS is distributed in the hope that it will be useful,
     14  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  1.1  christos    GNU General Public License for more details.
     17  1.1  christos 
     18  1.1  christos    You should have received a copy of the GNU General Public License
     19  1.1  christos    along with GAS; see the file COPYING.  If not, write to the Free
     20  1.1  christos    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
     21  1.1  christos    02110-1301, USA.  */
     22  1.1  christos 
     23  1.1  christos #include "as.h"
     24  1.1  christos #include "bfd_stdint.h"
     25  1.1  christos #include "opcode/pru.h"
     26  1.1  christos #include "elf/pru.h"
     27  1.1  christos #include "tc-pru.h"
     28  1.1  christos #include "bfd.h"
     29  1.1  christos #include "dwarf2dbg.h"
     30  1.1  christos #include "subsegs.h"
     31  1.1  christos #include "safe-ctype.h"
     32  1.1  christos #include "dw2gencfi.h"
     33  1.1  christos 
     34  1.1  christos #ifndef OBJ_ELF
     35  1.1  christos /* We are not supporting any other target so we throw a compile time error.  */
     36  1.1  christos   #error "OBJ_ELF not defined"
     37  1.1  christos #endif
     38  1.1  christos 
     39  1.1  christos /* This array holds the chars that always start a comment.  If the
     40  1.1  christos    pre-processor is disabled, these aren't very useful.  */
     41  1.1  christos const char comment_chars[] = "#;";
     42  1.1  christos 
     43  1.1  christos /* This array holds the chars that only start a comment at the beginning of
     44  1.1  christos    a line.  If the line seems to have the form '# 123 filename'
     45  1.1  christos    .line and .file directives will appear in the pre-processed output.  */
     46  1.1  christos /* Note that input_file.c hand checks for '#' at the beginning of the
     47  1.1  christos    first line of the input file.  This is because the compiler outputs
     48  1.1  christos    #NO_APP at the beginning of its output.  */
     49  1.1  christos /* Also note that C style comments are always supported.  */
     50  1.1  christos const char line_comment_chars[] = "#;*";
     51  1.1  christos 
     52  1.1  christos /* This array holds machine specific line separator characters.  */
     53  1.1  christos const char line_separator_chars[] = "";
     54  1.1  christos 
     55  1.1  christos /* Chars that can be used to separate mant from exp in floating point nums.  */
     56  1.1  christos const char EXP_CHARS[] = "eE";
     57  1.1  christos 
     58  1.1  christos /* Chars that mean this number is a floating point constant.
     59  1.1  christos    As in 0f12.456
     60  1.1  christos    or	 0d1.2345e12  */
     61  1.1  christos const char FLT_CHARS[] = "rRsSfFdDxXpP";
     62  1.1  christos 
     63  1.1  christos /* Machine-dependent command-line options.  */
     64  1.1  christos 
     65  1.1  christos struct pru_opt_s
     66  1.1  christos {
     67  1.1  christos   /* -mno-link-relax / -mlink-relax: generate (or not)
     68  1.1  christos      relocations for linker relaxation.  */
     69  1.1  christos   bfd_boolean link_relax;
     70  1.1  christos 
     71  1.1  christos   /* -mno-warn-regname-label: do not output a warning that a label name
     72  1.1  christos      matches a register name.  */
     73  1.1  christos   bfd_boolean warn_regname_label;
     74  1.1  christos };
     75  1.1  christos 
     76  1.1  christos static struct pru_opt_s pru_opt = { TRUE, TRUE };
     77  1.1  christos 
     78  1.1  christos const char *md_shortopts = "r";
     79  1.1  christos 
     80  1.1  christos enum options
     81  1.1  christos {
     82  1.1  christos   OPTION_LINK_RELAX = OPTION_MD_BASE + 1,
     83  1.1  christos   OPTION_NO_LINK_RELAX,
     84  1.1  christos   OPTION_NO_WARN_REGNAME_LABEL,
     85  1.1  christos };
     86  1.1  christos 
     87  1.1  christos struct option md_longopts[] = {
     88  1.1  christos   { "mlink-relax",  no_argument, NULL, OPTION_LINK_RELAX  },
     89  1.1  christos   { "mno-link-relax",  no_argument, NULL, OPTION_NO_LINK_RELAX  },
     90  1.1  christos   { "mno-warn-regname-label",  no_argument, NULL,
     91  1.1  christos     OPTION_NO_WARN_REGNAME_LABEL  },
     92  1.1  christos   { NULL, no_argument, NULL, 0 }
     93  1.1  christos };
     94  1.1  christos 
     95  1.1  christos size_t md_longopts_size = sizeof (md_longopts);
     96  1.1  christos 
     97  1.1  christos typedef struct pru_insn_reloc
     98  1.1  christos {
     99  1.1  christos   /* Any expression in the instruction is parsed into this field,
    100  1.1  christos      which is passed to fix_new_exp () to generate a fixup.  */
    101  1.1  christos   expressionS reloc_expression;
    102  1.1  christos 
    103  1.1  christos   /* The type of the relocation to be applied.  */
    104  1.1  christos   bfd_reloc_code_real_type reloc_type;
    105  1.1  christos 
    106  1.1  christos   /* PC-relative.  */
    107  1.1  christos   unsigned int reloc_pcrel;
    108  1.1  christos 
    109  1.1  christos   /* The next relocation to be applied to the instruction.  */
    110  1.1  christos   struct pru_insn_reloc *reloc_next;
    111  1.1  christos } pru_insn_relocS;
    112  1.1  christos 
    113  1.1  christos /* This struct is used to hold state when assembling instructions.  */
    114  1.1  christos typedef struct pru_insn_info
    115  1.1  christos {
    116  1.1  christos   /* Assembled instruction.  */
    117  1.1  christos   unsigned long insn_code;
    118  1.1  christos   /* Used for assembling LDI32.  */
    119  1.1  christos   unsigned long ldi32_imm32;
    120  1.1  christos 
    121  1.1  christos   /* Pointer to the relevant bit of the opcode table.  */
    122  1.1  christos   const struct pru_opcode *insn_pru_opcode;
    123  1.1  christos   /* After parsing ptrs to the tokens in the instruction fill this array
    124  1.1  christos      it is terminated with a null pointer (hence the first +1).
    125  1.1  christos      The second +1 is because in some parts of the code the opcode
    126  1.1  christos      is not counted as a token, but still placed in this array.  */
    127  1.1  christos   const char *insn_tokens[PRU_MAX_INSN_TOKENS + 1 + 1];
    128  1.1  christos 
    129  1.1  christos   /* This holds information used to generate fixups
    130  1.1  christos      and eventually relocations if it is not null.  */
    131  1.1  christos   pru_insn_relocS *insn_reloc;
    132  1.1  christos } pru_insn_infoS;
    133  1.1  christos 
    134  1.1  christos /* Opcode hash table.  */
    135  1.1  christos static struct hash_control *pru_opcode_hash = NULL;
    136  1.1  christos #define pru_opcode_lookup(NAME) \
    137  1.1  christos   ((struct pru_opcode *) hash_find (pru_opcode_hash, (NAME)))
    138  1.1  christos 
    139  1.1  christos /* Register hash table.  */
    140  1.1  christos static struct hash_control *pru_reg_hash = NULL;
    141  1.1  christos #define pru_reg_lookup(NAME) \
    142  1.1  christos   ((struct pru_reg *) hash_find (pru_reg_hash, (NAME)))
    143  1.1  christos 
    144  1.1  christos /* The known current alignment of the current section.  */
    145  1.1  christos static int pru_current_align;
    146  1.1  christos static segT pru_current_align_seg;
    147  1.1  christos 
    148  1.1  christos static int pru_auto_align_on = 1;
    149  1.1  christos 
    150  1.1  christos /* The last seen label in the current section.  This is used to auto-align
    151  1.1  christos    labels preceding instructions.  */
    152  1.1  christos static symbolS *pru_last_label;
    153  1.1  christos 
    154  1.1  christos 
    155  1.1  christos /** Utility routines.  */
    157  1.1  christos /* Function md_chars_to_number takes the sequence of
    158  1.1  christos    bytes in buf and returns the corresponding value
    159  1.1  christos    in an int.  n must be 1, 2, 4 or 8.  */
    160  1.1  christos static uint64_t
    161  1.1  christos md_chars_to_number (char *buf, int n)
    162  1.1  christos {
    163  1.1  christos   int i;
    164  1.1  christos   uint64_t val;
    165  1.1  christos 
    166  1.1  christos   gas_assert (n == 1 || n == 2 || n == 4 || n == 8);
    167  1.1  christos 
    168  1.1  christos   val = 0;
    169  1.1  christos   for (i = 0; i < n; ++i)
    170  1.1  christos     val = val | ((buf[i] & 0xff) << 8 * i);
    171  1.1  christos   return val;
    172  1.1  christos }
    173  1.1  christos 
    174  1.1  christos 
    175  1.1  christos /* This function turns a C long int, short int or char
    176  1.1  christos    into the series of bytes that represent the number
    177  1.1  christos    on the target machine.  */
    178  1.1  christos void
    179  1.1  christos md_number_to_chars (char *buf, valueT val, int n)
    180  1.1  christos {
    181  1.1  christos   gas_assert (n == 1 || n == 2 || n == 4 || n == 8);
    182  1.1  christos   number_to_chars_littleendian (buf, val, n);
    183  1.1  christos }
    184  1.1  christos 
    185  1.1  christos /* Turn a string in input_line_pointer into a floating point constant
    186  1.1  christos    of type TYPE, and store the appropriate bytes in *LITP.  The number
    187  1.1  christos    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
    188  1.1  christos    returned, or NULL on OK.  */
    189  1.1  christos const char *
    190  1.1  christos md_atof (int type, char *litP, int *sizeP)
    191  1.1  christos {
    192  1.1  christos   return ieee_md_atof (type, litP, sizeP, FALSE);
    193  1.1  christos }
    194  1.1  christos 
    195  1.1  christos /* Return true if STR starts with PREFIX, which should be a string literal.  */
    196  1.1  christos #define strprefix(STR, PREFIX) \
    197  1.1  christos   (strncmp ((STR), PREFIX, strlen (PREFIX)) == 0)
    198  1.1  christos 
    199  1.1  christos /* nop fill pattern for text section.  */
    200  1.1  christos static char const nop[4] = { 0xe0, 0xe0, 0xe0, 0x12 };
    201  1.1  christos 
    202  1.1  christos /* Handles all machine-dependent alignment needs.  */
    203  1.1  christos static void
    204  1.1  christos pru_align (int log_size, const char *pfill, symbolS *label)
    205  1.1  christos {
    206  1.1  christos   int align;
    207  1.1  christos   long max_alignment = 15;
    208  1.1  christos 
    209  1.1  christos   /* The front end is prone to changing segments out from under us
    210  1.1  christos      temporarily when -g is in effect.  */
    211  1.1  christos   int switched_seg_p = (pru_current_align_seg != now_seg);
    212  1.1  christos 
    213  1.1  christos   align = log_size;
    214  1.1  christos   if (align > max_alignment)
    215  1.1  christos     {
    216  1.1  christos       align = max_alignment;
    217  1.1  christos       as_bad (_("Alignment too large: %d assumed"), align);
    218  1.1  christos     }
    219  1.1  christos   else if (align < 0)
    220  1.1  christos     {
    221  1.1  christos       as_warn (_("Alignment negative: 0 assumed"));
    222  1.1  christos       align = 0;
    223  1.1  christos     }
    224  1.1  christos 
    225  1.1  christos   if (align != 0)
    226  1.1  christos     {
    227  1.1  christos       if (subseg_text_p (now_seg) && align >= 2)
    228  1.1  christos 	{
    229  1.1  christos 	  /* First, make sure we're on a four-byte boundary, in case
    230  1.1  christos 	     someone has been putting .byte values the text section.  */
    231  1.1  christos 	  if (pru_current_align < 2 || switched_seg_p)
    232  1.1  christos 	    frag_align (2, 0, 0);
    233  1.1  christos 
    234  1.1  christos 	  /* Now fill in the alignment pattern.  */
    235  1.1  christos 	  if (pfill != NULL)
    236  1.1  christos 	    frag_align_pattern (align, pfill, sizeof nop, 0);
    237  1.1  christos 	  else
    238  1.1  christos 	    frag_align (align, 0, 0);
    239  1.1  christos 	}
    240  1.1  christos       else
    241  1.1  christos 	frag_align (align, 0, 0);
    242  1.1  christos 
    243  1.1  christos       if (!switched_seg_p)
    244  1.1  christos 	pru_current_align = align;
    245  1.1  christos 
    246  1.1  christos       /* If the last label was in a different section we can't align it.  */
    247  1.1  christos       if (label != NULL && !switched_seg_p)
    248  1.1  christos 	{
    249  1.1  christos 	  symbolS *sym;
    250  1.1  christos 	  int label_seen = FALSE;
    251  1.1  christos 	  struct frag *old_frag;
    252  1.1  christos 	  valueT old_value;
    253  1.1  christos 	  valueT new_value;
    254  1.1  christos 
    255  1.1  christos 	  gas_assert (S_GET_SEGMENT (label) == now_seg);
    256  1.1  christos 
    257  1.1  christos 	  old_frag = symbol_get_frag (label);
    258  1.1  christos 	  old_value = S_GET_VALUE (label);
    259  1.1  christos 	  new_value = (valueT) frag_now_fix ();
    260  1.1  christos 
    261  1.1  christos 	  /* It is possible to have more than one label at a particular
    262  1.1  christos 	     address, especially if debugging is enabled, so we must
    263  1.1  christos 	     take care to adjust all the labels at this address in this
    264  1.1  christos 	     fragment.  To save time we search from the end of the symbol
    265  1.1  christos 	     list, backwards, since the symbols we are interested in are
    266  1.1  christos 	     almost certainly the ones that were most recently added.
    267  1.1  christos 	     Also to save time we stop searching once we have seen at least
    268  1.1  christos 	     one matching label, and we encounter a label that is no longer
    269  1.1  christos 	     in the target fragment.  Note, this search is guaranteed to
    270  1.1  christos 	     find at least one match when sym == label, so no special case
    271  1.1  christos 	     code is necessary.  */
    272  1.1  christos 	  for (sym = symbol_lastP; sym != NULL; sym = symbol_previous (sym))
    273  1.1  christos 	    if (symbol_get_frag (sym) == old_frag
    274  1.1  christos 		&& S_GET_VALUE (sym) == old_value)
    275  1.1  christos 	      {
    276  1.1  christos 		label_seen = TRUE;
    277  1.1  christos 		symbol_set_frag (sym, frag_now);
    278  1.1  christos 		S_SET_VALUE (sym, new_value);
    279  1.1  christos 	      }
    280  1.1  christos 	    else if (label_seen && symbol_get_frag (sym) != old_frag)
    281  1.1  christos 	      break;
    282  1.1  christos 	}
    283  1.1  christos       record_alignment (now_seg, align);
    284  1.1  christos     }
    285  1.1  christos }
    286  1.1  christos 
    287  1.1  christos 
    288  1.1  christos /** Support for self-check mode.  */
    290  1.1  christos 
    291  1.1  christos /* Mode of the assembler.  */
    292  1.1  christos typedef enum
    293  1.1  christos {
    294  1.1  christos   PRU_MODE_ASSEMBLE,		/* Ordinary operation.  */
    295  1.1  christos   PRU_MODE_TEST		/* Hidden mode used for self testing.  */
    296  1.1  christos } PRU_MODE;
    297  1.1  christos 
    298  1.1  christos static PRU_MODE pru_mode = PRU_MODE_ASSEMBLE;
    299  1.1  christos 
    300  1.1  christos /* This function is used to in self-checking mode
    301  1.1  christos    to check the assembled instruction.
    302  1.1  christos    OPCODE should be the assembled opcode, and exp_opcode
    303  1.1  christos    the parsed string representing the expected opcode.  */
    304  1.1  christos 
    305  1.1  christos static void
    306  1.1  christos pru_check_assembly (unsigned int opcode, const char *exp_opcode)
    307  1.1  christos {
    308  1.1  christos   if (pru_mode == PRU_MODE_TEST)
    309  1.1  christos     {
    310  1.1  christos       if (exp_opcode == NULL)
    311  1.1  christos 	as_bad (_("expecting opcode string in self test mode"));
    312  1.1  christos       else if (opcode != strtoul (exp_opcode, NULL, 16))
    313  1.1  christos 	as_bad (_("assembly 0x%08x, expected %s"), opcode, exp_opcode);
    314  1.1  christos     }
    315  1.1  christos }
    316  1.1  christos 
    317  1.1  christos 
    318  1.1  christos /** Support for machine-dependent assembler directives.  */
    320  1.1  christos /* Handle the .align pseudo-op.  This aligns to a power of two.  It
    321  1.1  christos    also adjusts any current instruction label.  We treat this the same
    322  1.1  christos    way the MIPS port does: .align 0 turns off auto alignment.  */
    323  1.1  christos static void
    324  1.1  christos s_pru_align (int ignore ATTRIBUTE_UNUSED)
    325  1.1  christos {
    326  1.1  christos   int align;
    327  1.1  christos   char fill;
    328  1.1  christos   const char *pfill = NULL;
    329  1.1  christos   long max_alignment = 15;
    330  1.1  christos 
    331  1.1  christos   align = get_absolute_expression ();
    332  1.1  christos   if (align > max_alignment)
    333  1.1  christos     {
    334  1.1  christos       align = max_alignment;
    335  1.1  christos       as_bad (_("Alignment too large: %d assumed"), align);
    336  1.1  christos     }
    337  1.1  christos   else if (align < 0)
    338  1.1  christos     {
    339  1.1  christos       as_warn (_("Alignment negative: 0 assumed"));
    340  1.1  christos       align = 0;
    341  1.1  christos     }
    342  1.1  christos 
    343  1.1  christos   if (*input_line_pointer == ',')
    344  1.1  christos     {
    345  1.1  christos       input_line_pointer++;
    346  1.1  christos       fill = get_absolute_expression ();
    347  1.1  christos       pfill = (const char *) &fill;
    348  1.1  christos     }
    349  1.1  christos   else if (subseg_text_p (now_seg))
    350  1.1  christos     pfill = (const char *) &nop;
    351  1.1  christos   else
    352  1.1  christos     {
    353  1.1  christos       pfill = NULL;
    354  1.1  christos       pru_last_label = NULL;
    355  1.1  christos     }
    356  1.1  christos 
    357  1.1  christos   if (align != 0)
    358  1.1  christos     {
    359  1.1  christos       pru_auto_align_on = 1;
    360  1.1  christos       pru_align (align, pfill, pru_last_label);
    361  1.1  christos       pru_last_label = NULL;
    362  1.1  christos     }
    363  1.1  christos   else
    364  1.1  christos     pru_auto_align_on = 0;
    365  1.1  christos 
    366  1.1  christos   demand_empty_rest_of_line ();
    367  1.1  christos }
    368  1.1  christos 
    369  1.1  christos /* Handle the .text pseudo-op.  This is like the usual one, but it
    370  1.1  christos    clears the saved last label and resets known alignment.  */
    371  1.1  christos static void
    372  1.1  christos s_pru_text (int i)
    373  1.1  christos {
    374  1.1  christos   s_text (i);
    375  1.1  christos   pru_last_label = NULL;
    376  1.1  christos   pru_current_align = 0;
    377  1.1  christos   pru_current_align_seg = now_seg;
    378  1.1  christos }
    379  1.1  christos 
    380  1.1  christos /* Handle the .data pseudo-op.  This is like the usual one, but it
    381  1.1  christos    clears the saved last label and resets known alignment.  */
    382  1.1  christos static void
    383  1.1  christos s_pru_data (int i)
    384  1.1  christos {
    385  1.1  christos   s_data (i);
    386  1.1  christos   pru_last_label = NULL;
    387  1.1  christos   pru_current_align = 0;
    388  1.1  christos   pru_current_align_seg = now_seg;
    389  1.1  christos }
    390  1.1  christos 
    391  1.1  christos /* Handle the .section pseudo-op.  This is like the usual one, but it
    392  1.1  christos    clears the saved last label and resets known alignment.  */
    393  1.1  christos static void
    394  1.1  christos s_pru_section (int ignore)
    395  1.1  christos {
    396  1.1  christos   obj_elf_section (ignore);
    397  1.1  christos   pru_last_label = NULL;
    398  1.1  christos   pru_current_align = 0;
    399  1.1  christos   pru_current_align_seg = now_seg;
    400  1.1  christos }
    401  1.1  christos 
    402  1.1  christos /* Explicitly unaligned cons.  */
    403  1.1  christos static void
    404  1.1  christos s_pru_ucons (int nbytes)
    405  1.1  christos {
    406  1.1  christos   int hold;
    407  1.1  christos   hold = pru_auto_align_on;
    408  1.1  christos   pru_auto_align_on = 0;
    409  1.1  christos   cons (nbytes);
    410  1.1  christos   pru_auto_align_on = hold;
    411  1.1  christos }
    412  1.1  christos 
    413  1.1  christos /* .set sets assembler options.  */
    414  1.1  christos static void
    415  1.1  christos s_pru_set (int equiv)
    416  1.1  christos {
    417  1.1  christos   char *save = input_line_pointer;
    418  1.1  christos   char *directive;
    419  1.1  christos   char delim = get_symbol_name (&directive);
    420  1.1  christos   char *endline = input_line_pointer;
    421  1.1  christos 
    422  1.1  christos   (void) restore_line_pointer (delim);
    423  1.1  christos 
    424  1.1  christos   /* We only want to handle ".set XXX" if the
    425  1.1  christos      user has tried ".set XXX, YYY" they are not
    426  1.1  christos      trying a directive.  This prevents
    427  1.1  christos      us from polluting the name space.  */
    428  1.1  christos   SKIP_WHITESPACE ();
    429  1.1  christos   if (is_end_of_line[(unsigned char) *input_line_pointer])
    430  1.1  christos     {
    431  1.1  christos       bfd_boolean done = TRUE;
    432  1.1  christos       *endline = 0;
    433  1.1  christos 
    434  1.1  christos       if (!strcmp (directive, "no_warn_regname_label"))
    435  1.1  christos 	  pru_opt.warn_regname_label = FALSE;
    436  1.1  christos       else
    437  1.1  christos 	done = FALSE;
    438  1.1  christos 
    439  1.1  christos       if (done)
    440  1.1  christos 	{
    441  1.1  christos 	  *endline = delim;
    442  1.1  christos 	  demand_empty_rest_of_line ();
    443  1.1  christos 	  return;
    444  1.1  christos 	}
    445  1.1  christos     }
    446  1.1  christos 
    447  1.1  christos   /* If we fall through to here, either we have ".set XXX, YYY"
    448  1.1  christos      or we have ".set XXX" where XXX is unknown or we have
    449  1.1  christos      a syntax error.  */
    450  1.1  christos   input_line_pointer = save;
    451  1.1  christos   s_set (equiv);
    452  1.1  christos }
    453  1.1  christos 
    454  1.1  christos /* Machine-dependent assembler directives.
    455  1.1  christos    Format of each entry is:
    456  1.1  christos    { "directive", handler_func, param }	 */
    457  1.1  christos const pseudo_typeS md_pseudo_table[] = {
    458  1.1  christos   {"align", s_pru_align, 0},
    459  1.1  christos   {"text", s_pru_text, 0},
    460  1.1  christos   {"data", s_pru_data, 0},
    461  1.1  christos   {"section", s_pru_section, 0},
    462  1.1  christos   {"section.s", s_pru_section, 0},
    463  1.1  christos   {"sect", s_pru_section, 0},
    464  1.1  christos   {"sect.s", s_pru_section, 0},
    465  1.1  christos   /* .dword and .half are included for compatibility with MIPS.  */
    466  1.1  christos   {"dword", cons, 8},
    467  1.1  christos   {"half", cons, 2},
    468  1.1  christos   /* PRU native word size is 4 bytes, so we override
    469  1.1  christos      the GAS default of 2.  */
    470  1.1  christos   {"word", cons, 4},
    471  1.1  christos   /* Explicitly unaligned directives.  */
    472  1.1  christos   {"2byte", s_pru_ucons, 2},
    473  1.1  christos   {"4byte", s_pru_ucons, 4},
    474  1.1  christos   {"8byte", s_pru_ucons, 8},
    475  1.1  christos   {"16byte", s_pru_ucons, 16},
    476  1.1  christos   {"set", s_pru_set, 0},
    477  1.1  christos   {NULL, NULL, 0}
    478  1.1  christos };
    479  1.1  christos 
    480  1.1  christos 
    481  1.1  christos int
    483  1.1  christos md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
    484  1.1  christos 			       asection *seg ATTRIBUTE_UNUSED)
    485  1.1  christos {
    486  1.1  christos   abort ();
    487  1.1  christos   return 0;
    488  1.1  christos }
    489  1.1  christos 
    490  1.1  christos void
    491  1.1  christos md_convert_frag (bfd *headers ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED,
    492  1.1  christos 		 fragS *fragp ATTRIBUTE_UNUSED)
    493  1.1  christos {
    494  1.1  christos   abort ();
    495  1.1  christos }
    496  1.1  christos 
    497  1.1  christos 
    498  1.1  christos static bfd_boolean
    500  1.1  christos relaxable_section (asection *sec)
    501  1.1  christos {
    502  1.1  christos   return ((sec->flags & SEC_DEBUGGING) == 0
    503  1.1  christos 	  && (sec->flags & SEC_CODE) != 0
    504  1.1  christos 	  && (sec->flags & SEC_ALLOC) != 0);
    505  1.1  christos }
    506  1.1  christos 
    507  1.1  christos /* Does whatever the xtensa port does.  */
    508  1.1  christos int
    509  1.1  christos pru_validate_fix_sub (fixS *fix)
    510  1.1  christos {
    511  1.1  christos   segT add_symbol_segment, sub_symbol_segment;
    512  1.1  christos 
    513  1.1  christos   /* The difference of two symbols should be resolved by the assembler when
    514  1.1  christos      linkrelax is not set.  If the linker may relax the section containing
    515  1.1  christos      the symbols, then an Xtensa DIFF relocation must be generated so that
    516  1.1  christos      the linker knows to adjust the difference value.  */
    517  1.1  christos   if (!linkrelax || fix->fx_addsy == NULL)
    518  1.1  christos     return 0;
    519  1.1  christos 
    520  1.1  christos   /* Make sure both symbols are in the same segment, and that segment is
    521  1.1  christos      "normal" and relaxable.  If the segment is not "normal", then the
    522  1.1  christos      fix is not valid.  If the segment is not "relaxable", then the fix
    523  1.1  christos      should have been handled earlier.  */
    524  1.1  christos   add_symbol_segment = S_GET_SEGMENT (fix->fx_addsy);
    525  1.1  christos   if (! SEG_NORMAL (add_symbol_segment)
    526  1.1  christos       || ! relaxable_section (add_symbol_segment))
    527  1.1  christos     return 0;
    528  1.1  christos 
    529  1.1  christos   sub_symbol_segment = S_GET_SEGMENT (fix->fx_subsy);
    530  1.1  christos   return (sub_symbol_segment == add_symbol_segment);
    531  1.1  christos }
    532  1.1  christos 
    533  1.1  christos /* TC_FORCE_RELOCATION hook.  */
    534  1.1  christos 
    535  1.1  christos /* If linkrelax is turned on, and the symbol to relocate
    536  1.1  christos    against is in a relaxable segment, don't compute the value -
    537  1.1  christos    generate a relocation instead.  */
    538  1.1  christos int
    539  1.1  christos pru_force_relocation (fixS *fix)
    540  1.1  christos {
    541  1.1  christos   if (linkrelax && fix->fx_addsy
    542  1.1  christos       && relaxable_section (S_GET_SEGMENT (fix->fx_addsy)))
    543  1.1  christos     return 1;
    544  1.1  christos 
    545  1.1  christos   return generic_force_reloc (fix);
    546  1.1  christos }
    547  1.1  christos 
    548  1.1  christos 
    549  1.1  christos 
    550  1.1  christos /** Fixups and overflow checking.  */
    552  1.1  christos 
    553  1.1  christos /* Check a fixup for overflow.  */
    554  1.1  christos static bfd_reloc_status_type
    555  1.1  christos pru_check_overflow (valueT fixup, reloc_howto_type *howto)
    556  1.1  christos {
    557  1.1  christos   bfd_reloc_status_type ret;
    558  1.1  christos 
    559  1.1  christos   ret = bfd_check_overflow (howto->complain_on_overflow,
    560  1.1  christos 			    howto->bitsize,
    561  1.1  christos 			    howto->rightshift,
    562  1.1  christos 			    bfd_get_reloc_size (howto) * 8,
    563  1.1  christos 			    fixup);
    564  1.1  christos 
    565  1.1  christos   return ret;
    566  1.1  christos }
    567  1.1  christos 
    568  1.1  christos /* Emit diagnostic for fixup overflow.  */
    569  1.1  christos static void
    570  1.1  christos pru_diagnose_overflow (valueT fixup, reloc_howto_type *howto,
    571  1.1  christos 			 fixS *fixP, valueT value)
    572  1.1  christos {
    573  1.1  christos   if (fixP->fx_r_type == BFD_RELOC_8
    574  1.1  christos       || fixP->fx_r_type == BFD_RELOC_16
    575  1.1  christos       || fixP->fx_r_type == BFD_RELOC_32)
    576  1.1  christos     /* These relocs are against data, not instructions.  */
    577  1.1  christos     as_bad_where (fixP->fx_file, fixP->fx_line,
    578  1.1  christos 		  _("immediate value 0x%x truncated to 0x%x"),
    579  1.1  christos 		  (unsigned int) fixup,
    580  1.1  christos 		  (unsigned int) (~(~(valueT) 0 << howto->bitsize) & fixup));
    581  1.1  christos   else
    582  1.1  christos     {
    583  1.1  christos       /* What opcode is the instruction?  This will determine
    584  1.1  christos 	 whether we check for overflow in immediate values
    585  1.1  christos 	 and what error message we get.  */
    586  1.1  christos       const struct pru_opcode *opcode;
    587  1.1  christos       enum overflow_type overflow_msg_type;
    588  1.1  christos       unsigned int range_min;
    589  1.1  christos       unsigned int range_max;
    590  1.1  christos       unsigned int address;
    591  1.1  christos       gas_assert (fixP->fx_size == 4);
    592  1.1  christos       opcode = pru_find_opcode (value);
    593  1.1  christos       gas_assert (opcode);
    594  1.1  christos       overflow_msg_type = opcode->overflow_msg;
    595  1.1  christos       switch (overflow_msg_type)
    596  1.1  christos 	{
    597  1.1  christos 	case call_target_overflow:
    598  1.1  christos 	  range_min
    599  1.1  christos 	    = ((fixP->fx_frag->fr_address + fixP->fx_where) & 0xf0000000);
    600  1.1  christos 	  range_max = range_min + 0x0fffffff;
    601  1.1  christos 	  address = fixup | range_min;
    602  1.1  christos 
    603  1.1  christos 	  as_bad_where (fixP->fx_file, fixP->fx_line,
    604  1.1  christos 			_("call target address 0x%08x out of range 0x%08x to 0x%08x"),
    605  1.1  christos 			address, range_min, range_max);
    606  1.1  christos 	  break;
    607  1.1  christos 	case qbranch_target_overflow:
    608  1.1  christos 	  as_bad_where (fixP->fx_file, fixP->fx_line,
    609  1.1  christos 			_("quick branch offset %d out of range %d to %d"),
    610  1.1  christos 			(int)fixup, -((1<<9) * 4), (1 << 9) * 4);
    611  1.1  christos 	  break;
    612  1.1  christos 	case address_offset_overflow:
    613  1.1  christos 	  as_bad_where (fixP->fx_file, fixP->fx_line,
    614  1.1  christos 			_("%s offset %d out of range %d to %d"),
    615  1.1  christos 			opcode->name, (int)fixup, -32768, 32767);
    616  1.1  christos 	  break;
    617  1.1  christos 	case signed_immed16_overflow:
    618  1.1  christos 	  as_bad_where (fixP->fx_file, fixP->fx_line,
    619  1.1  christos 			_("immediate value %d out of range %d to %d"),
    620  1.1  christos 			(int)fixup, -32768, 32767);
    621  1.1  christos 	  break;
    622  1.1  christos 	case unsigned_immed32_overflow:
    623  1.1  christos 	  as_bad_where (fixP->fx_file, fixP->fx_line,
    624  1.1  christos 			_("immediate value %llu out of range %u to %lu"),
    625  1.1  christos 			(unsigned long long)fixup, 0, 0xfffffffflu);
    626  1.1  christos 	  break;
    627  1.1  christos 	case unsigned_immed16_overflow:
    628  1.1  christos 	  as_bad_where (fixP->fx_file, fixP->fx_line,
    629  1.1  christos 			_("immediate value %u out of range %u to %u"),
    630  1.1  christos 			(unsigned int)fixup, 0, 65535);
    631  1.1  christos 	  break;
    632  1.1  christos 	case unsigned_immed5_overflow:
    633  1.1  christos 	  as_bad_where (fixP->fx_file, fixP->fx_line,
    634  1.1  christos 			_("immediate value %u out of range %u to %u"),
    635  1.1  christos 			(unsigned int)fixup, 0, 31);
    636  1.1  christos 	  break;
    637  1.1  christos 	default:
    638  1.1  christos 	  as_bad_where (fixP->fx_file, fixP->fx_line,
    639  1.1  christos 			_("overflow in immediate argument"));
    640  1.1  christos 	  break;
    641  1.1  christos 	}
    642  1.1  christos     }
    643  1.1  christos }
    644  1.1  christos 
    645  1.1  christos /* Apply a fixup to the object file.  */
    646  1.1  christos void
    647  1.1  christos md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
    648  1.1  christos {
    649  1.1  christos   unsigned char *where;
    650  1.1  christos   valueT value = *valP;
    651  1.1  christos   long n;
    652  1.1  christos 
    653  1.1  christos   /* Assert that the fixup is one we can handle.  */
    654  1.1  christos   gas_assert (fixP != NULL && valP != NULL
    655  1.1  christos 	      && (fixP->fx_r_type == BFD_RELOC_8
    656  1.1  christos 		  || fixP->fx_r_type == BFD_RELOC_16
    657  1.1  christos 		  || fixP->fx_r_type == BFD_RELOC_32
    658  1.1  christos 		  || fixP->fx_r_type == BFD_RELOC_64
    659  1.1  christos 		  || fixP->fx_r_type == BFD_RELOC_PRU_LDI32
    660  1.1  christos 		  || fixP->fx_r_type == BFD_RELOC_PRU_U16
    661  1.1  christos 		  || fixP->fx_r_type == BFD_RELOC_PRU_U16_PMEMIMM
    662  1.1  christos 		  || fixP->fx_r_type == BFD_RELOC_PRU_S10_PCREL
    663  1.1  christos 		  || fixP->fx_r_type == BFD_RELOC_PRU_U8_PCREL
    664  1.1  christos 		  || fixP->fx_r_type == BFD_RELOC_PRU_32_PMEM
    665  1.1  christos 		  || fixP->fx_r_type == BFD_RELOC_PRU_16_PMEM
    666  1.1  christos 		  /* Add other relocs here as we generate them.  */
    667  1.1  christos 	      ));
    668  1.1  christos 
    669  1.1  christos   if (fixP->fx_r_type == BFD_RELOC_64)
    670  1.1  christos     {
    671  1.1  christos       /* We may reach here due to .8byte directives, but we never output
    672  1.1  christos 	 BFD_RELOC_64; it must be resolved.  */
    673  1.1  christos       if (fixP->fx_addsy != NULL)
    674  1.1  christos 	as_bad_where (fixP->fx_file, fixP->fx_line,
    675  1.1  christos 		      _("cannot create 64-bit relocation"));
    676  1.1  christos       else
    677  1.1  christos 	{
    678  1.1  christos 	  md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
    679  1.1  christos 			      *valP, 8);
    680  1.1  christos 	  fixP->fx_done = 1;
    681  1.1  christos 	}
    682  1.1  christos       return;
    683  1.1  christos     }
    684  1.1  christos 
    685  1.1  christos   /* gas_assert (had_errors () || !fixP->fx_subsy); */
    686  1.1  christos 
    687  1.1  christos   /* In general, fix instructions with immediate
    688  1.1  christos      constants.  But leave LDI32 for the linker,
    689  1.1  christos      which is prepared to shorten insns.  */
    690  1.1  christos   if (fixP->fx_addsy == (symbolS *) NULL
    691  1.1  christos       && fixP->fx_r_type != BFD_RELOC_PRU_LDI32)
    692  1.1  christos     fixP->fx_done = 1;
    693  1.1  christos 
    694  1.1  christos   else if (fixP->fx_pcrel)
    695  1.1  christos     {
    696  1.1  christos       segT s = S_GET_SEGMENT (fixP->fx_addsy);
    697  1.1  christos 
    698  1.1  christos       if (s == seg || s == absolute_section)
    699  1.1  christos 	{
    700  1.1  christos 	  /* Blindly copied from AVR, but I don't understand why
    701  1.1  christos 	     this is needed in the first place.  Fail hard to catch
    702  1.1  christos 	     when this curious code snippet is utilized.  */
    703  1.1  christos 	  as_bad_where (fixP->fx_file, fixP->fx_line,
    704  1.1  christos 			_("unexpected PC relative expression"));
    705  1.1  christos 	  value += S_GET_VALUE (fixP->fx_addsy);
    706  1.1  christos 	  fixP->fx_done = 1;
    707  1.1  christos 	}
    708  1.1  christos     }
    709  1.1  christos   else if (linkrelax && fixP->fx_subsy)
    710  1.1  christos     {
    711  1.1  christos       /* For a subtraction relocation expression, generate one
    712  1.1  christos 	 of the DIFF relocs, with the value being the difference.
    713  1.1  christos 	 Note that a sym1 - sym2 expression is adjusted into a
    714  1.1  christos 	 section_start_sym + sym4_offset_from_section_start - sym1
    715  1.1  christos 	 expression.  fixP->fx_addsy holds the section start symbol,
    716  1.1  christos 	 fixP->fx_offset holds sym2's offset, and fixP->fx_subsy
    717  1.1  christos 	 holds sym1.  Calculate the current difference and write value,
    718  1.1  christos 	 but leave fx_offset as is - during relaxation,
    719  1.1  christos 	 fx_offset - value gives sym1's value.  */
    720  1.1  christos 
    721  1.1  christos       offsetT diffval;	/* valueT is unsigned, so use offsetT.  */
    722  1.1  christos 
    723  1.1  christos       diffval = S_GET_VALUE (fixP->fx_addsy)
    724  1.1  christos 		+ fixP->fx_offset - S_GET_VALUE (fixP->fx_subsy);
    725  1.1  christos 
    726  1.1  christos       switch (fixP->fx_r_type)
    727  1.1  christos 	{
    728  1.1  christos 	case BFD_RELOC_8:
    729  1.1  christos 	  fixP->fx_r_type = BFD_RELOC_PRU_GNU_DIFF8;
    730  1.1  christos 	  break;
    731  1.1  christos 	case BFD_RELOC_16:
    732  1.1  christos 	  fixP->fx_r_type = BFD_RELOC_PRU_GNU_DIFF16;
    733  1.1  christos 	  break;
    734  1.1  christos 	case BFD_RELOC_32:
    735  1.1  christos 	  fixP->fx_r_type = BFD_RELOC_PRU_GNU_DIFF32;
    736  1.1  christos 	  break;
    737  1.1  christos 	case BFD_RELOC_PRU_16_PMEM:
    738  1.1  christos 	  fixP->fx_r_type = BFD_RELOC_PRU_GNU_DIFF16_PMEM;
    739  1.1  christos 	  if (diffval % 4)
    740  1.1  christos 	    as_bad_where (fixP->fx_file, fixP->fx_line,
    741  1.1  christos 			  _("residual low bits in pmem diff relocation"));
    742  1.1  christos 	  diffval /= 4;
    743  1.1  christos 	  break;
    744  1.1  christos 	case BFD_RELOC_PRU_32_PMEM:
    745  1.1  christos 	  fixP->fx_r_type = BFD_RELOC_PRU_GNU_DIFF32_PMEM;
    746  1.1  christos 	  if (diffval % 4)
    747  1.1  christos 	    as_bad_where (fixP->fx_file, fixP->fx_line,
    748  1.1  christos 			  _("residual low bits in pmem diff relocation"));
    749  1.1  christos 	  diffval /= 4;
    750  1.1  christos 	  break;
    751  1.1  christos 	default:
    752  1.1  christos 	  as_bad_where (fixP->fx_file, fixP->fx_line,
    753  1.1  christos 			_("expression too complex"));
    754  1.1  christos 	  break;
    755  1.1  christos 	}
    756  1.1  christos 
    757  1.1  christos       value = *valP = diffval;
    758  1.1  christos 
    759  1.1  christos       fixP->fx_subsy = NULL;
    760  1.1  christos   }
    761  1.1  christos   /* We don't actually support subtracting a symbol.  */
    762  1.1  christos   if (fixP->fx_subsy != (symbolS *) NULL)
    763  1.1  christos     as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
    764  1.1  christos 
    765  1.1  christos   /* For the DIFF relocs, write the value into the object file while still
    766  1.1  christos      keeping fx_done FALSE, as both the difference (recorded in the object file)
    767  1.1  christos      and the sym offset (part of fixP) are needed at link relax time.  */
    768  1.1  christos   where = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
    769  1.1  christos   switch (fixP->fx_r_type)
    770  1.1  christos     {
    771  1.1  christos     case BFD_RELOC_PRU_GNU_DIFF8:
    772  1.1  christos       *where = value;
    773  1.1  christos       break;
    774  1.1  christos     case BFD_RELOC_PRU_GNU_DIFF16:
    775  1.1  christos     case BFD_RELOC_PRU_GNU_DIFF16_PMEM:
    776  1.1  christos       bfd_putl16 ((bfd_vma) value, where);
    777  1.1  christos       break;
    778  1.1  christos     case BFD_RELOC_PRU_GNU_DIFF32:
    779  1.1  christos     case BFD_RELOC_PRU_GNU_DIFF32_PMEM:
    780  1.1  christos       bfd_putl32 ((bfd_vma) value, where);
    781  1.1  christos       break;
    782  1.1  christos     default:
    783  1.1  christos       break;
    784  1.1  christos     }
    785  1.1  christos 
    786  1.1  christos   if (fixP->fx_done)
    787  1.1  christos     /* Fully resolved fixup.  */
    788  1.1  christos     {
    789  1.1  christos       reloc_howto_type *howto
    790  1.1  christos 	= bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
    791  1.1  christos 
    792  1.1  christos       if (howto == NULL)
    793  1.1  christos 	as_bad_where (fixP->fx_file, fixP->fx_line,
    794  1.1  christos 		      _("relocation is not supported"));
    795  1.1  christos       else
    796  1.1  christos 	{
    797  1.1  christos 	  valueT fixup = value;
    798  1.1  christos 	  uint64_t insn;
    799  1.1  christos 	  char *buf;
    800  1.1  christos 
    801  1.1  christos 	  /* Get the instruction or data to be fixed up.  */
    802  1.1  christos 	  buf = fixP->fx_frag->fr_literal + fixP->fx_where;
    803  1.1  christos 	  insn = md_chars_to_number (buf, fixP->fx_size);
    804  1.1  christos 
    805  1.1  christos 	  /* Check for overflow, emitting a diagnostic if necessary.  */
    806  1.1  christos 	  if (pru_check_overflow (fixup, howto) != bfd_reloc_ok)
    807  1.1  christos 	    pru_diagnose_overflow (fixup, howto, fixP, insn);
    808  1.1  christos 
    809  1.1  christos 	  /* Apply the right shift.  */
    810  1.1  christos 	  fixup = ((offsetT)fixup) >> howto->rightshift;
    811  1.1  christos 
    812  1.1  christos 	  /* Truncate the fixup to right size.  */
    813  1.1  christos 	  n = sizeof (fixup) * 8 - howto->bitsize;
    814  1.1  christos 	  fixup = (fixup << n) >> n;
    815  1.1  christos 
    816  1.1  christos 	  /* Fix up the instruction.  Non-contiguous bitfields need
    817  1.1  christos 	     special handling.  */
    818  1.1  christos 	  if (fixP->fx_r_type == BFD_RELOC_PRU_LDI32)
    819  1.1  christos 	    {
    820  1.1  christos 	      /* As the only 64-bit "insn", LDI32 needs special handling. */
    821  1.1  christos 	      uint32_t insn1 = insn & 0xffffffff;
    822  1.1  christos 	      uint32_t insn2 = insn >> 32;
    823  1.1  christos 	      SET_INSN_FIELD (IMM16, insn1, fixup >> 16);
    824  1.1  christos 	      SET_INSN_FIELD (IMM16, insn2, fixup & 0xffff);
    825  1.1  christos 
    826  1.1  christos 	      SET_INSN_FIELD (RDSEL, insn1, RSEL_31_16);
    827  1.1  christos 	      SET_INSN_FIELD (RDSEL, insn2, RSEL_15_0);
    828  1.1  christos 
    829  1.1  christos 	      md_number_to_chars (buf, insn1, 4);
    830  1.1  christos 	      md_number_to_chars (buf + 4, insn2, 4);
    831  1.1  christos 	    }
    832  1.1  christos 	  else
    833  1.1  christos 	    {
    834  1.1  christos 	      if (fixP->fx_r_type == BFD_RELOC_PRU_S10_PCREL)
    835  1.1  christos 		SET_BROFF_URAW (insn, fixup);
    836  1.1  christos 	      else
    837  1.1  christos 		insn = (insn & ~howto->dst_mask) | (fixup << howto->bitpos);
    838  1.1  christos 	      md_number_to_chars (buf, insn, fixP->fx_size);
    839  1.1  christos 	    }
    840  1.1  christos 	}
    841  1.1  christos 
    842  1.1  christos       fixP->fx_done = 1;
    843  1.1  christos     }
    844  1.1  christos 
    845  1.1  christos   if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT)
    846  1.1  christos     {
    847  1.1  christos       fixP->fx_done = 0;
    848  1.1  christos       if (fixP->fx_addsy
    849  1.1  christos 	  && !S_IS_DEFINED (fixP->fx_addsy) && !S_IS_WEAK (fixP->fx_addsy))
    850  1.1  christos 	S_SET_WEAK (fixP->fx_addsy);
    851  1.1  christos     }
    852  1.1  christos   else if (fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
    853  1.1  christos     fixP->fx_done = 0;
    854  1.1  christos }
    855  1.1  christos 
    856  1.1  christos 
    857  1.1  christos 
    858  1.1  christos /** Instruction parsing support.  */
    860  1.1  christos 
    861  1.1  christos /* Creates a new pru_insn_relocS and returns a pointer to it.  */
    862  1.1  christos static pru_insn_relocS *
    863  1.1  christos pru_insn_reloc_new (bfd_reloc_code_real_type reloc_type, unsigned int pcrel)
    864  1.1  christos {
    865  1.1  christos   pru_insn_relocS *retval;
    866  1.1  christos   retval = XNEW (pru_insn_relocS);
    867  1.1  christos   if (retval == NULL)
    868  1.1  christos     {
    869  1.1  christos       as_bad (_("can't create relocation"));
    870  1.1  christos       abort ();
    871  1.1  christos     }
    872  1.1  christos 
    873  1.1  christos   /* Fill out the fields with default values.  */
    874  1.1  christos   retval->reloc_next = NULL;
    875  1.1  christos   retval->reloc_type = reloc_type;
    876  1.1  christos   retval->reloc_pcrel = pcrel;
    877  1.1  christos   return retval;
    878  1.1  christos }
    879  1.1  christos 
    880  1.1  christos /* Frees up memory previously allocated by pru_insn_reloc_new ().  */
    881  1.1  christos static void
    882  1.1  christos pru_insn_reloc_destroy (pru_insn_relocS *reloc)
    883  1.1  christos {
    884  1.1  christos   pru_insn_relocS *next;
    885  1.1  christos 
    886  1.1  christos   while (reloc)
    887  1.1  christos     {
    888  1.1  christos       next = reloc->reloc_next;
    889  1.1  christos       free (reloc);
    890  1.1  christos       reloc = next;
    891  1.1  christos     }
    892  1.1  christos }
    893  1.1  christos 
    894  1.1  christos /* The various pru_assemble_* functions call this
    895  1.1  christos    function to generate an expression from a string representing an expression.
    896  1.1  christos    It then tries to evaluate the expression, and if it can, returns its value.
    897  1.1  christos    If not, it creates a new pru_insn_relocS and stores the expression and
    898  1.1  christos    reloc_type for future use.  */
    899  1.1  christos static unsigned long
    900  1.1  christos pru_assemble_expression (const char *exprstr,
    901  1.1  christos 			   pru_insn_infoS *insn,
    902  1.1  christos 			   pru_insn_relocS *prev_reloc,
    903  1.1  christos 			   bfd_reloc_code_real_type reloc_type,
    904  1.1  christos 			   unsigned int pcrel)
    905  1.1  christos {
    906  1.1  christos   expressionS *ep;
    907  1.1  christos   pru_insn_relocS *reloc;
    908  1.1  christos   char *saved_line_ptr;
    909  1.1  christos   unsigned short value;
    910  1.1  christos 
    911  1.1  christos   gas_assert (exprstr != NULL);
    912  1.1  christos   gas_assert (insn != NULL);
    913  1.1  christos 
    914  1.1  christos   /* We use this blank keyword to distinguish register from
    915  1.1  christos      label operands.  */
    916  1.1  christos   if (strstr (exprstr, "%label") != NULL)
    917  1.1  christos     {
    918  1.1  christos       exprstr += strlen ("%label") + 1;
    919  1.1  christos     }
    920  1.1  christos 
    921  1.1  christos   /* Check for pmem relocation operator.
    922  1.1  christos      Change the relocation type and advance the ptr to the start of
    923  1.1  christos      the expression proper.  */
    924  1.1  christos   if (strstr (exprstr, "%pmem") != NULL)
    925  1.1  christos     {
    926  1.1  christos       reloc_type = BFD_RELOC_PRU_U16_PMEMIMM;
    927  1.1  christos       exprstr += strlen ("%pmem") + 1;
    928  1.1  christos     }
    929  1.1  christos 
    930  1.1  christos   /* We potentially have a relocation.  */
    931  1.1  christos   reloc = pru_insn_reloc_new (reloc_type, pcrel);
    932  1.1  christos   if (prev_reloc != NULL)
    933  1.1  christos     prev_reloc->reloc_next = reloc;
    934  1.1  christos   else
    935  1.1  christos     insn->insn_reloc = reloc;
    936  1.1  christos 
    937  1.1  christos   /* Parse the expression string.  */
    938  1.1  christos   ep = &reloc->reloc_expression;
    939  1.1  christos   saved_line_ptr = input_line_pointer;
    940  1.1  christos   input_line_pointer = (char *) exprstr;
    941  1.1  christos   SKIP_WHITESPACE ();
    942  1.1  christos   expression (ep);
    943  1.1  christos   SKIP_WHITESPACE ();
    944  1.1  christos   if (*input_line_pointer)
    945  1.1  christos     as_bad (_("trailing garbage after expression: %s"), input_line_pointer);
    946  1.1  christos   input_line_pointer = saved_line_ptr;
    947  1.1  christos 
    948  1.1  christos 
    949  1.1  christos   if (ep->X_op == O_illegal || ep->X_op == O_absent)
    950  1.1  christos     as_bad (_("expected expression, got %s"), exprstr);
    951  1.1  christos 
    952  1.1  christos   /* This is redundant as the fixup will put this into
    953  1.1  christos      the instruction, but it is included here so that
    954  1.1  christos      self-test mode (-r) works.  */
    955  1.1  christos   value = 0;
    956  1.1  christos   if (pru_mode == PRU_MODE_TEST && ep->X_op == O_constant)
    957  1.1  christos     value = ep->X_add_number;
    958  1.1  christos 
    959  1.1  christos   return (unsigned long) value;
    960  1.1  christos }
    961  1.1  christos 
    962  1.1  christos /* Try to parse a non-relocatable expression.  */
    963  1.1  christos static unsigned long
    964  1.1  christos pru_assemble_noreloc_expression (const char *exprstr)
    965  1.1  christos {
    966  1.1  christos   expressionS exp;
    967  1.1  christos   char *saved_line_ptr;
    968  1.1  christos   unsigned long val;
    969  1.1  christos 
    970  1.1  christos   gas_assert (exprstr != NULL);
    971  1.1  christos 
    972  1.1  christos   saved_line_ptr = input_line_pointer;
    973  1.1  christos   input_line_pointer = (char *) exprstr;
    974  1.1  christos   SKIP_WHITESPACE ();
    975  1.1  christos   expression (&exp);
    976  1.1  christos   SKIP_WHITESPACE ();
    977  1.1  christos   if (*input_line_pointer)
    978  1.1  christos     as_bad (_("trailing garbage after expression: %s"), input_line_pointer);
    979  1.1  christos   input_line_pointer = saved_line_ptr;
    980  1.1  christos 
    981  1.1  christos   val = 0;
    982  1.1  christos   if (exp.X_op != O_constant)
    983  1.1  christos     as_bad (_("expected constant expression, got %s"), exprstr);
    984  1.1  christos   else
    985  1.1  christos     val = exp.X_add_number;
    986  1.1  christos 
    987  1.1  christos   return val;
    988  1.1  christos }
    989  1.1  christos 
    990  1.1  christos /* Argument assemble functions.
    991  1.1  christos    All take an instruction argument string, and a pointer
    992  1.1  christos    to an instruction opcode.  Upon return the insn_opcode
    993  1.1  christos    has the relevant fields filled in to represent the arg
    994  1.1  christos    string.  The return value is NULL if successful, or
    995  1.1  christos    an error message if an error was detected.  */
    996  1.1  christos 
    997  1.1  christos static void
    998  1.1  christos pru_assemble_arg_d (pru_insn_infoS *insn_info, const char *argstr)
    999  1.1  christos {
   1000  1.1  christos   struct pru_reg *dst = pru_reg_lookup (argstr);
   1001  1.1  christos 
   1002  1.1  christos   if (dst == NULL)
   1003  1.1  christos     as_bad (_("unknown register %s"), argstr);
   1004  1.1  christos   else
   1005  1.1  christos     {
   1006  1.1  christos       SET_INSN_FIELD (RD, insn_info->insn_code, dst->index);
   1007  1.1  christos       SET_INSN_FIELD (RDSEL, insn_info->insn_code, dst->regsel);
   1008  1.1  christos     }
   1009  1.1  christos }
   1010  1.1  christos 
   1011  1.1  christos static void
   1012  1.1  christos pru_assemble_arg_D (pru_insn_infoS *insn_info, const char *argstr)
   1013  1.1  christos {
   1014  1.1  christos   struct pru_reg *dst;
   1015  1.1  christos 
   1016  1.1  christos   /* The leading & before an address register is optional.  */
   1017  1.1  christos   if (*argstr == '&')
   1018  1.1  christos     argstr++;
   1019  1.1  christos 
   1020  1.1  christos   dst = pru_reg_lookup (argstr);
   1021  1.1  christos 
   1022  1.1  christos   if (dst == NULL)
   1023  1.1  christos     as_bad (_("unknown register %s"), argstr);
   1024  1.1  christos   else
   1025  1.1  christos     {
   1026  1.1  christos       unsigned long rxb = 0;
   1027  1.1  christos 
   1028  1.1  christos       switch (dst->regsel)
   1029  1.1  christos 	{
   1030  1.1  christos 	case RSEL_31_0: rxb = 0; break;	/* whole register defaults to .b0  */
   1031  1.1  christos 	case RSEL_7_0: rxb = 0; break;
   1032  1.1  christos 	case RSEL_15_8: rxb = 1; break;
   1033  1.1  christos 	case RSEL_23_16: rxb = 2; break;
   1034  1.1  christos 	case RSEL_31_24: rxb = 3; break;
   1035  1.1  christos 	default:
   1036  1.1  christos 	  as_bad (_("data transfer register cannot be halfword"));
   1037  1.1  christos 	}
   1038  1.1  christos 
   1039  1.1  christos       SET_INSN_FIELD (RD, insn_info->insn_code, dst->index);
   1040  1.1  christos       SET_INSN_FIELD (RDB, insn_info->insn_code, rxb);
   1041  1.1  christos     }
   1042  1.1  christos }
   1043  1.1  christos 
   1044  1.1  christos static void
   1045  1.1  christos pru_assemble_arg_R (pru_insn_infoS *insn_info, const char *argstr)
   1046  1.1  christos {
   1047  1.1  christos   struct pru_reg *dst = pru_reg_lookup (argstr);
   1048  1.1  christos 
   1049  1.1  christos   if (dst == NULL)
   1050  1.1  christos     as_bad (_("unknown register %s"), argstr);
   1051  1.1  christos   else
   1052  1.1  christos     {
   1053  1.1  christos       if (dst->regsel != RSEL_31_0)
   1054  1.1  christos 	{
   1055  1.1  christos 	  as_bad (_("destination register must be full-word"));
   1056  1.1  christos 	}
   1057  1.1  christos 
   1058  1.1  christos       SET_INSN_FIELD (RD, insn_info->insn_code, dst->index);
   1059  1.1  christos       SET_INSN_FIELD (RDSEL, insn_info->insn_code, dst->regsel);
   1060  1.1  christos     }
   1061  1.1  christos }
   1062  1.1  christos 
   1063  1.1  christos static void
   1064  1.1  christos pru_assemble_arg_s (pru_insn_infoS *insn_info, const char *argstr)
   1065  1.1  christos {
   1066  1.1  christos   struct pru_reg *src1 = pru_reg_lookup (argstr);
   1067  1.1  christos 
   1068  1.1  christos   if (src1 == NULL)
   1069  1.1  christos     as_bad (_("unknown register %s"), argstr);
   1070  1.1  christos   else
   1071  1.1  christos     {
   1072  1.1  christos       SET_INSN_FIELD (RS1, insn_info->insn_code, src1->index);
   1073  1.1  christos       SET_INSN_FIELD (RS1SEL, insn_info->insn_code, src1->regsel);
   1074  1.1  christos     }
   1075  1.1  christos }
   1076  1.1  christos 
   1077  1.1  christos static void
   1078  1.1  christos pru_assemble_arg_S (pru_insn_infoS *insn_info, const char *argstr)
   1079  1.1  christos {
   1080  1.1  christos   struct pru_reg *src1 = pru_reg_lookup (argstr);
   1081  1.1  christos 
   1082  1.1  christos   if (src1 == NULL)
   1083  1.1  christos     as_bad (_("unknown register %s"), argstr);
   1084  1.1  christos   else
   1085  1.1  christos     {
   1086  1.1  christos       if (src1->regsel != RSEL_31_0)
   1087  1.1  christos 	as_bad (_("cannot use partial register %s for addressing"), argstr);
   1088  1.1  christos       SET_INSN_FIELD (RS1, insn_info->insn_code, src1->index);
   1089  1.1  christos     }
   1090  1.1  christos }
   1091  1.1  christos 
   1092  1.1  christos static void
   1093  1.1  christos pru_assemble_arg_b (pru_insn_infoS *insn_info, const char *argstr)
   1094  1.1  christos {
   1095  1.1  christos   struct pru_reg *src2 = pru_reg_lookup (argstr);
   1096  1.1  christos   if (src2 == NULL)
   1097  1.1  christos     {
   1098  1.1  christos       unsigned long imm8 = pru_assemble_noreloc_expression (argstr);
   1099  1.1  christos       if (imm8 >= 0x100)
   1100  1.1  christos 	as_bad (_("value %lu is too large for a byte operand"), imm8);
   1101  1.1  christos       SET_INSN_FIELD (IMM8, insn_info->insn_code, imm8);
   1102  1.1  christos       SET_INSN_FIELD (IO, insn_info->insn_code, 1);
   1103  1.1  christos     }
   1104  1.1  christos   else
   1105  1.1  christos     {
   1106  1.1  christos       SET_INSN_FIELD (IO, insn_info->insn_code, 0);
   1107  1.1  christos       SET_INSN_FIELD (RS2, insn_info->insn_code, src2->index);
   1108  1.1  christos       SET_INSN_FIELD (RS2SEL, insn_info->insn_code, src2->regsel);
   1109  1.1  christos     }
   1110  1.1  christos 
   1111  1.1  christos }
   1112  1.1  christos 
   1113  1.1  christos static void
   1114  1.1  christos pru_assemble_arg_B (pru_insn_infoS *insn_info, const char *argstr)
   1115  1.1  christos {
   1116  1.1  christos   struct pru_reg *src2 = pru_reg_lookup (argstr);
   1117  1.1  christos   if (src2 == NULL)
   1118  1.1  christos     {
   1119  1.1  christos       unsigned long imm8;
   1120  1.1  christos       imm8 = pru_assemble_noreloc_expression (argstr);
   1121  1.1  christos       if (!imm8 || imm8 > 0xff)
   1122  1.1  christos 	as_bad (_("loop count constant %ld is out of range [1..%d]"),
   1123  1.1  christos 		imm8, 0xff);
   1124  1.1  christos       /* Note: HW expects the immediate loop count field
   1125  1.1  christos 	 to be one less than the actual loop count.  */
   1126  1.1  christos       SET_INSN_FIELD (IMM8, insn_info->insn_code, imm8 - 1);
   1127  1.1  christos       SET_INSN_FIELD (IO, insn_info->insn_code, 1);
   1128  1.1  christos     }
   1129  1.1  christos   else
   1130  1.1  christos     {
   1131  1.1  christos       SET_INSN_FIELD (IO, insn_info->insn_code, 0);
   1132  1.1  christos       SET_INSN_FIELD (RS2, insn_info->insn_code, src2->index);
   1133  1.1  christos       SET_INSN_FIELD (RS2SEL, insn_info->insn_code, src2->regsel);
   1134  1.1  christos     }
   1135  1.1  christos }
   1136  1.1  christos 
   1137  1.1  christos static void
   1138  1.1  christos pru_assemble_arg_i (pru_insn_infoS *insn_info, const char *argstr)
   1139  1.1  christos {
   1140  1.1  christos   unsigned long imm32;
   1141  1.1  christos 
   1142  1.1  christos   /* We must not generate PRU_LDI32 relocation if relaxation is disabled in
   1143  1.1  christos      GAS. Consider the following scenario: GAS relaxation is disabled, so
   1144  1.1  christos      DIFF* expressions are fixed and not emitted as relocations. Then if LD
   1145  1.1  christos      has relaxation enabled, it may shorten LDI32 but will not update
   1146  1.1  christos      accordingly the DIFF expressions.  */
   1147  1.1  christos   if (pru_opt.link_relax)
   1148  1.1  christos     imm32 = pru_assemble_expression (argstr, insn_info,
   1149  1.1  christos 				     insn_info->insn_reloc,
   1150  1.1  christos 				     BFD_RELOC_PRU_LDI32, 0);
   1151  1.1  christos   else
   1152  1.1  christos     imm32 = pru_assemble_noreloc_expression (argstr);
   1153  1.1  christos 
   1154  1.1  christos   /* QUIRK: LDI must clear IO bit high, even though it has immediate arg. */
   1155  1.1  christos   SET_INSN_FIELD (IO, insn_info->insn_code, 0);
   1156  1.1  christos   SET_INSN_FIELD (RDSEL, insn_info->insn_code, RSEL_31_16);
   1157  1.1  christos   SET_INSN_FIELD (IMM16, insn_info->insn_code, imm32 >> 16);
   1158  1.1  christos   insn_info->ldi32_imm32 = imm32;
   1159  1.1  christos }
   1160  1.1  christos 
   1161  1.1  christos static void
   1162  1.1  christos pru_assemble_arg_j (pru_insn_infoS *insn_info, const char *argstr)
   1163  1.1  christos {
   1164  1.1  christos   struct pru_reg *src2 = pru_reg_lookup (argstr);
   1165  1.1  christos 
   1166  1.1  christos   if (src2 == NULL)
   1167  1.1  christos     {
   1168  1.1  christos       unsigned long imm16 = pru_assemble_expression (argstr, insn_info,
   1169  1.1  christos 						     insn_info->insn_reloc,
   1170  1.1  christos 						     BFD_RELOC_PRU_U16_PMEMIMM,
   1171  1.1  christos 						     0);
   1172  1.1  christos       SET_INSN_FIELD (IMM16, insn_info->insn_code, imm16);
   1173  1.1  christos       SET_INSN_FIELD (IO, insn_info->insn_code, 1);
   1174  1.1  christos     }
   1175  1.1  christos   else
   1176  1.1  christos     {
   1177  1.1  christos       SET_INSN_FIELD (IO, insn_info->insn_code, 0);
   1178  1.1  christos       SET_INSN_FIELD (RS2, insn_info->insn_code, src2->index);
   1179  1.1  christos       SET_INSN_FIELD (RS2SEL, insn_info->insn_code, src2->regsel);
   1180  1.1  christos     }
   1181  1.1  christos }
   1182  1.1  christos 
   1183  1.1  christos static void
   1184  1.1  christos pru_assemble_arg_W (pru_insn_infoS *insn_info, const char *argstr)
   1185  1.1  christos {
   1186  1.1  christos   unsigned long imm16 = pru_assemble_expression (argstr, insn_info,
   1187  1.1  christos 						 insn_info->insn_reloc,
   1188  1.1  christos 						 BFD_RELOC_PRU_U16, 0);
   1189  1.1  christos   /* QUIRK: LDI must clear IO bit high, even though it has immediate arg.  */
   1190  1.1  christos   SET_INSN_FIELD (IO, insn_info->insn_code, 0);
   1191  1.1  christos   SET_INSN_FIELD (IMM16, insn_info->insn_code, imm16);
   1192  1.1  christos }
   1193  1.1  christos 
   1194  1.1  christos static void
   1195  1.1  christos pru_assemble_arg_o (pru_insn_infoS *insn_info, const char *argstr)
   1196  1.1  christos {
   1197  1.1  christos   unsigned long imm10 = pru_assemble_expression (argstr, insn_info,
   1198  1.1  christos 						 insn_info->insn_reloc,
   1199  1.1  christos 						 BFD_RELOC_PRU_S10_PCREL, 1);
   1200  1.1  christos   SET_BROFF_URAW (insn_info->insn_code, imm10);
   1201  1.1  christos }
   1202  1.1  christos 
   1203  1.1  christos static void
   1204  1.1  christos pru_assemble_arg_O (pru_insn_infoS *insn_info, const char *argstr)
   1205  1.1  christos {
   1206  1.1  christos   unsigned long imm8 = pru_assemble_expression (argstr, insn_info,
   1207  1.1  christos 						insn_info->insn_reloc,
   1208  1.1  christos 						BFD_RELOC_PRU_U8_PCREL, 1);
   1209  1.1  christos   SET_INSN_FIELD (LOOP_JMPOFFS, insn_info->insn_code, imm8);
   1210  1.1  christos }
   1211  1.1  christos 
   1212  1.1  christos static void
   1213  1.1  christos pru_assemble_arg_l (pru_insn_infoS *insn_info, const char *argstr)
   1214  1.1  christos {
   1215  1.1  christos   unsigned long burstlen = 0;
   1216  1.1  christos   struct pru_reg *blreg = pru_reg_lookup (argstr);
   1217  1.1  christos 
   1218  1.1  christos   if (blreg == NULL)
   1219  1.1  christos     {
   1220  1.1  christos       burstlen = pru_assemble_noreloc_expression (argstr);
   1221  1.1  christos       if (!burstlen || burstlen > LSSBBO_BYTECOUNT_R0_BITS7_0)
   1222  1.1  christos 	as_bad (_("byte count constant %ld is out of range [1..%d]"),
   1223  1.1  christos 		burstlen, LSSBBO_BYTECOUNT_R0_BITS7_0);
   1224  1.1  christos       burstlen--;
   1225  1.1  christos     }
   1226  1.1  christos   else
   1227  1.1  christos     {
   1228  1.1  christos       if (blreg->index != 0)
   1229  1.1  christos 	as_bad (_("only r0 can be used as byte count register"));
   1230  1.1  christos       else if (blreg->regsel > RSEL_31_24)
   1231  1.1  christos 	as_bad (_("only r0.bX byte fields of r0 can be used as byte count"));
   1232  1.1  christos       else
   1233  1.1  christos 	burstlen = LSSBBO_BYTECOUNT_R0_BITS7_0 + blreg->regsel;
   1234  1.1  christos     }
   1235  1.1  christos     SET_BURSTLEN (insn_info->insn_code, burstlen);
   1236  1.1  christos }
   1237  1.1  christos 
   1238  1.1  christos static void
   1239  1.1  christos pru_assemble_arg_n (pru_insn_infoS *insn_info, const char *argstr)
   1240  1.1  christos {
   1241  1.1  christos   unsigned long burstlen = 0;
   1242  1.1  christos   struct pru_reg *blreg = pru_reg_lookup (argstr);
   1243  1.1  christos 
   1244  1.1  christos   if (blreg == NULL)
   1245  1.1  christos     {
   1246  1.1  christos       burstlen = pru_assemble_noreloc_expression (argstr);
   1247  1.1  christos       if (!burstlen || burstlen > LSSBBO_BYTECOUNT_R0_BITS7_0)
   1248  1.1  christos 	as_bad (_("byte count constant %ld is out of range [1..%d]"),
   1249  1.1  christos 		burstlen, LSSBBO_BYTECOUNT_R0_BITS7_0);
   1250  1.1  christos       burstlen--;
   1251  1.1  christos     }
   1252  1.1  christos   else
   1253  1.1  christos     {
   1254  1.1  christos       if (blreg->index != 0)
   1255  1.1  christos 	as_bad (_("only r0 can be used as byte count register"));
   1256  1.1  christos       else if (blreg->regsel > RSEL_31_24)
   1257  1.1  christos 	as_bad (_("only r0.bX byte fields of r0 can be used as byte count"));
   1258  1.1  christos       else
   1259  1.1  christos 	burstlen = LSSBBO_BYTECOUNT_R0_BITS7_0 + blreg->regsel;
   1260  1.1  christos     }
   1261  1.1  christos     SET_INSN_FIELD (XFR_LENGTH, insn_info->insn_code, burstlen);
   1262  1.1  christos }
   1263  1.1  christos 
   1264  1.1  christos static void
   1265  1.1  christos pru_assemble_arg_c (pru_insn_infoS *insn_info, const char *argstr)
   1266  1.1  christos {
   1267  1.1  christos   unsigned long cb = pru_assemble_noreloc_expression (argstr);
   1268  1.1  christos 
   1269  1.1  christos   if (cb > 31)
   1270  1.1  christos     as_bad (_("invalid constant table offset %ld"), cb);
   1271  1.1  christos   else
   1272  1.1  christos     SET_INSN_FIELD (CB, insn_info->insn_code, cb);
   1273  1.1  christos }
   1274  1.1  christos 
   1275  1.1  christos static void
   1276  1.1  christos pru_assemble_arg_w (pru_insn_infoS *insn_info, const char *argstr)
   1277  1.1  christos {
   1278  1.1  christos   unsigned long wk = pru_assemble_noreloc_expression (argstr);
   1279  1.1  christos 
   1280  1.1  christos   if (wk != 0 && wk != 1)
   1281  1.1  christos     as_bad (_("invalid WakeOnStatus %ld"), wk);
   1282  1.1  christos   else
   1283  1.1  christos     SET_INSN_FIELD (WAKEONSTATUS, insn_info->insn_code, wk);
   1284  1.1  christos }
   1285  1.1  christos 
   1286  1.1  christos static void
   1287  1.1  christos pru_assemble_arg_x (pru_insn_infoS *insn_info, const char *argstr)
   1288  1.1  christos {
   1289  1.1  christos   unsigned long wba = pru_assemble_noreloc_expression (argstr);
   1290  1.1  christos 
   1291  1.1  christos   if (wba > 255)
   1292  1.1  christos     as_bad (_("invalid XFR WideBus Address %ld"), wba);
   1293  1.1  christos   else
   1294  1.1  christos     SET_INSN_FIELD (XFR_WBA, insn_info->insn_code, wba);
   1295  1.1  christos }
   1296  1.1  christos 
   1297  1.1  christos /* The function consume_arg takes a pointer into a string
   1298  1.1  christos    of instruction tokens (args) and a pointer into a string
   1299  1.1  christos    representing the expected sequence of tokens and separators.
   1300  1.1  christos    It checks whether the first argument in argstr is of the
   1301  1.1  christos    expected type, throwing an error if it is not, and returns
   1302  1.1  christos    the pointer argstr.  */
   1303  1.1  christos static char *
   1304  1.1  christos pru_consume_arg (char *argstr, const char *parsestr)
   1305  1.1  christos {
   1306  1.1  christos   char *temp;
   1307  1.1  christos 
   1308  1.1  christos   switch (*parsestr)
   1309  1.1  christos     {
   1310  1.1  christos     case 'W':
   1311  1.1  christos       if (*argstr == '%')
   1312  1.1  christos 	{
   1313  1.1  christos 	  if (strprefix (argstr, "%pmem") || strprefix (argstr, "%label"))
   1314  1.1  christos 	    {
   1315  1.1  christos 	      /* We zap the parentheses because we don't want them confused
   1316  1.1  christos 		 with separators.  */
   1317  1.1  christos 	      temp = strchr (argstr, '(');
   1318  1.1  christos 	      if (temp != NULL)
   1319  1.1  christos 		*temp = ' ';
   1320  1.1  christos 	      temp = strchr (argstr, ')');
   1321  1.1  christos 	      if (temp != NULL)
   1322  1.1  christos 		*temp = ' ';
   1323  1.1  christos 	    }
   1324  1.1  christos 	  else
   1325  1.1  christos 	    as_bad (_("badly formed expression near %s"), argstr);
   1326  1.1  christos 	}
   1327  1.1  christos       break;
   1328  1.1  christos 
   1329  1.1  christos     case 'j':
   1330  1.1  christos     case 'o':
   1331  1.1  christos     case 'O':
   1332  1.1  christos       if (*argstr == '%')
   1333  1.1  christos 	{
   1334  1.1  christos 	  /* Only 'j' really requires %label for distinguishing registers
   1335  1.1  christos 	     from labels, but we include 'o' and 'O' here to avoid
   1336  1.1  christos 	     confusing assembler programmers. Thus for completeness all
   1337  1.1  christos 	     jump operands can be prefixed with %label.  */
   1338  1.1  christos 	  if (strprefix (argstr, "%label"))
   1339  1.1  christos 	    {
   1340  1.1  christos 	      /* We zap the parentheses because we don't want them confused
   1341  1.1  christos 		 with separators.  */
   1342  1.1  christos 	      temp = strchr (argstr, '(');
   1343  1.1  christos 	      if (temp != NULL)
   1344  1.1  christos 		*temp = ' ';
   1345  1.1  christos 	      temp = strchr (argstr, ')');
   1346  1.1  christos 	      if (temp != NULL)
   1347  1.1  christos 		*temp = ' ';
   1348  1.1  christos 	    }
   1349  1.1  christos 	  else
   1350  1.1  christos 	    as_bad (_("badly formed expression near %s"), argstr);
   1351  1.1  christos 	}
   1352  1.1  christos       break;
   1353  1.1  christos 
   1354  1.1  christos     case 'b':
   1355  1.1  christos     case 'B':
   1356  1.1  christos     case 'c':
   1357  1.1  christos     case 'd':
   1358  1.1  christos     case 'D':
   1359  1.1  christos     case 'E':
   1360  1.1  christos     case 'i':
   1361  1.1  christos     case 's':
   1362  1.1  christos     case 'S':
   1363  1.1  christos     case 'l':
   1364  1.1  christos     case 'n':
   1365  1.1  christos     case 'R':
   1366  1.1  christos     case 'w':
   1367  1.1  christos     case 'x':
   1368  1.1  christos       /* We can't have %pmem here.  */
   1369  1.1  christos       if (*argstr == '%')
   1370  1.1  christos 	as_bad (_("badly formed expression near %s"), argstr);
   1371  1.1  christos       break;
   1372  1.1  christos     default:
   1373  1.1  christos       BAD_CASE (*parsestr);
   1374  1.1  christos       break;
   1375  1.1  christos     }
   1376  1.1  christos 
   1377  1.1  christos   return argstr;
   1378  1.1  christos }
   1379  1.1  christos 
   1380  1.1  christos /* The function consume_separator takes a pointer into a string
   1381  1.1  christos    of instruction tokens (args) and a pointer into a string representing
   1382  1.1  christos    the expected sequence of tokens and separators.  It finds the first
   1383  1.1  christos    instance of the character pointed to by separator in argstr, and
   1384  1.1  christos    returns a pointer to the next element of argstr, which is the
   1385  1.1  christos    following token in the sequence.  */
   1386  1.1  christos static char *
   1387  1.1  christos pru_consume_separator (char *argstr, const char *separator)
   1388  1.1  christos {
   1389  1.1  christos   char *p;
   1390  1.1  christos 
   1391  1.1  christos   p = strchr (argstr, *separator);
   1392  1.1  christos 
   1393  1.1  christos   if (p != NULL)
   1394  1.1  christos     *p++ = 0;
   1395  1.1  christos   else
   1396  1.1  christos     as_bad (_("expecting %c near %s"), *separator, argstr);
   1397  1.1  christos   return p;
   1398  1.1  christos }
   1399  1.1  christos 
   1400  1.1  christos 
   1401  1.1  christos /* The principal argument parsing function which takes a string argstr
   1402  1.1  christos    representing the instruction arguments for insn, and extracts the argument
   1403  1.1  christos    tokens matching parsestr into parsed_args.  */
   1404  1.1  christos static void
   1405  1.1  christos pru_parse_args (pru_insn_infoS *insn ATTRIBUTE_UNUSED, char *argstr,
   1406  1.1  christos 		  const char *parsestr, char **parsed_args)
   1407  1.1  christos {
   1408  1.1  christos   char *p;
   1409  1.1  christos   char *end = NULL;
   1410  1.1  christos   int i;
   1411  1.1  christos   p = argstr;
   1412  1.1  christos   i = 0;
   1413  1.1  christos   bfd_boolean terminate = FALSE;
   1414  1.1  christos 
   1415  1.1  christos   /* This rest of this function is it too fragile and it mostly works,
   1416  1.1  christos      therefore special case this one.  */
   1417  1.1  christos   if (*parsestr == 0 && argstr != 0)
   1418  1.1  christos     {
   1419  1.1  christos       as_bad (_("too many arguments"));
   1420  1.1  christos       parsed_args[0] = NULL;
   1421  1.1  christos       return;
   1422  1.1  christos     }
   1423  1.1  christos 
   1424  1.1  christos   while (p != NULL && !terminate && i < PRU_MAX_INSN_TOKENS)
   1425  1.1  christos     {
   1426  1.1  christos       parsed_args[i] = pru_consume_arg (p, parsestr);
   1427  1.1  christos       ++parsestr;
   1428  1.1  christos       if (*parsestr != '\0')
   1429  1.1  christos 	{
   1430  1.1  christos 	  p = pru_consume_separator (p, parsestr);
   1431  1.1  christos 	  ++parsestr;
   1432  1.1  christos 	}
   1433  1.1  christos       else
   1434  1.1  christos 	{
   1435  1.1  christos 	  /* Check that the argument string has no trailing arguments.  */
   1436  1.1  christos 	  /* If we've got a %pmem relocation, we've zapped the parens with
   1437  1.1  christos 	     spaces.  */
   1438  1.1  christos 	  if (strprefix (p, "%pmem") || strprefix (p, "%label"))
   1439  1.1  christos 	    end = strpbrk (p, ",");
   1440  1.1  christos 	  else
   1441  1.1  christos 	    end = strpbrk (p, " ,");
   1442  1.1  christos 
   1443  1.1  christos 	  if (end != NULL)
   1444  1.1  christos 	    as_bad (_("too many arguments"));
   1445  1.1  christos 	}
   1446  1.1  christos 
   1447  1.1  christos       if (*parsestr == '\0' || (p != NULL && *p == '\0'))
   1448  1.1  christos 	terminate = TRUE;
   1449  1.1  christos       ++i;
   1450  1.1  christos     }
   1451  1.1  christos 
   1452  1.1  christos   parsed_args[i] = NULL;
   1453  1.1  christos 
   1454  1.1  christos   /* There are no instructions with optional arguments; complain.  */
   1455  1.1  christos   if (*parsestr != '\0')
   1456  1.1  christos     as_bad (_("missing argument"));
   1457  1.1  christos }
   1458  1.1  christos 
   1459  1.1  christos 
   1460  1.1  christos /** Assembler output support.  */
   1462  1.1  christos 
   1463  1.1  christos /* Output a normal instruction.  */
   1464  1.1  christos static void
   1465  1.1  christos output_insn (pru_insn_infoS *insn)
   1466  1.1  christos {
   1467  1.1  christos   char *f;
   1468  1.1  christos   pru_insn_relocS *reloc;
   1469  1.1  christos 
   1470  1.1  christos   f = frag_more (4);
   1471  1.1  christos   /* This allocates enough space for the instruction
   1472  1.1  christos      and puts it in the current frag.  */
   1473  1.1  christos   md_number_to_chars (f, insn->insn_code, 4);
   1474  1.1  christos   /* Emit debug info.  */
   1475  1.1  christos   dwarf2_emit_insn (4);
   1476  1.1  christos   /* Create any fixups to be acted on later.  */
   1477  1.1  christos   for (reloc = insn->insn_reloc; reloc != NULL; reloc = reloc->reloc_next)
   1478  1.1  christos     fix_new_exp (frag_now, f - frag_now->fr_literal, 4,
   1479  1.1  christos 		 &reloc->reloc_expression, reloc->reloc_pcrel,
   1480  1.1  christos 		 reloc->reloc_type);
   1481  1.1  christos }
   1482  1.1  christos 
   1483  1.1  christos /* Output two LDI instructions from LDI32 macro */
   1484  1.1  christos static void
   1485  1.1  christos output_insn_ldi32 (pru_insn_infoS *insn)
   1486  1.1  christos {
   1487  1.1  christos   char *f;
   1488  1.1  christos   pru_insn_relocS *reloc;
   1489  1.1  christos   unsigned long insn2;
   1490  1.1  christos 
   1491  1.1  christos   f = frag_more (8);
   1492  1.1  christos   SET_INSN_FIELD (IMM16, insn->insn_code, insn->ldi32_imm32 >> 16);
   1493  1.1  christos   SET_INSN_FIELD (RDSEL, insn->insn_code, RSEL_31_16);
   1494  1.1  christos   md_number_to_chars (f, insn->insn_code, 4);
   1495  1.1  christos 
   1496  1.1  christos   insn2 = insn->insn_code;
   1497  1.1  christos   SET_INSN_FIELD (IMM16, insn2, insn->ldi32_imm32 & 0xffff);
   1498  1.1  christos   SET_INSN_FIELD (RDSEL, insn2, RSEL_15_0);
   1499  1.1  christos   md_number_to_chars (f + 4, insn2, 4);
   1500  1.1  christos 
   1501  1.1  christos   /* Emit debug info.  */
   1502  1.1  christos   dwarf2_emit_insn (8);
   1503  1.1  christos 
   1504  1.1  christos   /* Create any fixups to be acted on later.  */
   1505  1.1  christos   for (reloc = insn->insn_reloc; reloc != NULL; reloc = reloc->reloc_next)
   1506  1.1  christos     fix_new_exp (frag_now, f - frag_now->fr_literal, 4,
   1507  1.1  christos 		 &reloc->reloc_expression, reloc->reloc_pcrel,
   1508  1.1  christos 		 reloc->reloc_type);
   1509  1.1  christos }
   1510  1.1  christos 
   1511  1.1  christos 
   1512  1.1  christos /** External interfaces.  */
   1514  1.1  christos 
   1515  1.1  christos /* The following functions are called by machine-independent parts of
   1516  1.1  christos    the assembler.  */
   1517  1.1  christos int
   1518  1.1  christos md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
   1519  1.1  christos {
   1520  1.1  christos   switch (c)
   1521  1.1  christos     {
   1522  1.1  christos     case 'r':
   1523  1.1  christos       /* Hidden option for self-test mode.  */
   1524  1.1  christos       pru_mode = PRU_MODE_TEST;
   1525  1.1  christos       break;
   1526  1.1  christos     case OPTION_LINK_RELAX:
   1527  1.1  christos       pru_opt.link_relax = TRUE;
   1528  1.1  christos       break;
   1529  1.1  christos     case OPTION_NO_LINK_RELAX:
   1530  1.1  christos       pru_opt.link_relax = FALSE;
   1531  1.1  christos       break;
   1532  1.1  christos     case OPTION_NO_WARN_REGNAME_LABEL:
   1533  1.1  christos       pru_opt.warn_regname_label = FALSE;
   1534  1.1  christos       break;
   1535  1.1  christos     default:
   1536  1.1  christos       return 0;
   1537  1.1  christos       break;
   1538  1.1  christos     }
   1539  1.1  christos 
   1540  1.1  christos   return 1;
   1541  1.1  christos }
   1542  1.1  christos 
   1543  1.1  christos const char *
   1544  1.1  christos pru_target_format (void)
   1545  1.1  christos {
   1546  1.1  christos   return "elf32-pru";
   1547  1.1  christos }
   1548  1.1  christos 
   1549  1.1  christos /* Machine-dependent usage message.  */
   1550  1.1  christos void
   1551  1.1  christos md_show_usage (FILE *stream)
   1552  1.1  christos {
   1553  1.1  christos   fprintf (stream,
   1554  1.1  christos     _("PRU options:\n"
   1555  1.1  christos       "  -mlink-relax     generate relocations for linker relaxation (default).\n"
   1556  1.1  christos       "  -mno-link-relax  don't generate relocations for linker relaxation.\n"
   1557  1.1  christos     ));
   1558  1.1  christos 
   1559  1.1  christos }
   1560  1.1  christos 
   1561  1.1  christos /* This function is called once, at assembler startup time.
   1562  1.1  christos    It should set up all the tables, etc.  that the MD part of the
   1563  1.1  christos    assembler will need.  */
   1564  1.1  christos void
   1565  1.1  christos md_begin (void)
   1566  1.1  christos {
   1567  1.1  christos   int i;
   1568  1.1  christos   const char *inserted;
   1569  1.1  christos 
   1570  1.1  christos   /* Create and fill a hashtable for the PRU opcodes, registers and
   1571  1.1  christos      arguments.  */
   1572  1.1  christos   pru_opcode_hash = hash_new ();
   1573  1.1  christos   pru_reg_hash = hash_new ();
   1574  1.1  christos 
   1575  1.1  christos   for (i = 0; i < NUMOPCODES; ++i)
   1576  1.1  christos     {
   1577  1.1  christos       inserted
   1578  1.1  christos 	= hash_insert (pru_opcode_hash, pru_opcodes[i].name,
   1579  1.1  christos 		       (PTR) & pru_opcodes[i]);
   1580  1.1  christos       if (inserted != NULL)
   1581  1.1  christos 	{
   1582  1.1  christos 	  fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
   1583  1.1  christos 		   pru_opcodes[i].name, inserted);
   1584  1.1  christos 	  /* Probably a memory allocation problem?  Give up now.  */
   1585  1.1  christos 	  as_fatal (_("Broken assembler.  No assembly attempted."));
   1586  1.1  christos 	}
   1587  1.1  christos     }
   1588  1.1  christos 
   1589  1.1  christos   for (i = 0; i < pru_num_regs; ++i)
   1590  1.1  christos     {
   1591  1.1  christos       inserted
   1592  1.1  christos 	= hash_insert (pru_reg_hash, pru_regs[i].name,
   1593  1.1  christos 		       (PTR) & pru_regs[i]);
   1594  1.1  christos       if (inserted != NULL)
   1595  1.1  christos 	{
   1596  1.1  christos 	  fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
   1597  1.1  christos 		   pru_regs[i].name, inserted);
   1598  1.1  christos 	  /* Probably a memory allocation problem?  Give up now.  */
   1599  1.1  christos 	  as_fatal (_("Broken assembler.  No assembly attempted."));
   1600  1.1  christos 	}
   1601  1.1  christos 
   1602  1.1  christos     }
   1603  1.1  christos 
   1604  1.1  christos   linkrelax = pru_opt.link_relax;
   1605  1.1  christos   /* Initialize the alignment data.  */
   1606  1.1  christos   pru_current_align_seg = now_seg;
   1607  1.1  christos   pru_last_label = NULL;
   1608  1.1  christos   pru_current_align = 0;
   1609  1.1  christos }
   1610  1.1  christos 
   1611  1.1  christos 
   1612  1.1  christos /* Assembles a single line of PRU assembly language.  */
   1613  1.1  christos void
   1614  1.1  christos md_assemble (char *op_str)
   1615  1.1  christos {
   1616  1.1  christos   char *argstr;
   1617  1.1  christos   char *op_strdup = NULL;
   1618  1.1  christos   pru_insn_infoS thisinsn;
   1619  1.1  christos   pru_insn_infoS *insn = &thisinsn;
   1620  1.1  christos 
   1621  1.1  christos   /* Make sure we are aligned on a 4-byte boundary.  */
   1622  1.1  christos   if (pru_current_align < 2)
   1623  1.1  christos     pru_align (2, NULL, pru_last_label);
   1624  1.1  christos   else if (pru_current_align > 2)
   1625  1.1  christos     pru_current_align = 2;
   1626  1.1  christos   pru_last_label = NULL;
   1627  1.1  christos 
   1628  1.1  christos   /* We don't want to clobber to op_str
   1629  1.1  christos      because we want to be able to use it in messages.  */
   1630  1.1  christos   op_strdup = strdup (op_str);
   1631  1.1  christos   insn->insn_tokens[0] = strtok (op_strdup, " ");
   1632  1.1  christos   argstr = strtok (NULL, "");
   1633  1.1  christos 
   1634  1.1  christos   /* Assemble the opcode.  */
   1635  1.1  christos   insn->insn_pru_opcode = pru_opcode_lookup (insn->insn_tokens[0]);
   1636  1.1  christos   insn->insn_reloc = NULL;
   1637  1.1  christos 
   1638  1.1  christos   if (insn->insn_pru_opcode != NULL)
   1639  1.1  christos     {
   1640  1.1  christos       const char *argsfmt = insn->insn_pru_opcode->args;
   1641  1.1  christos       const char **argtk = &insn->insn_tokens[1];
   1642  1.1  christos       const char *argp;
   1643  1.1  christos 
   1644  1.1  christos       /* Set the opcode for the instruction.  */
   1645  1.1  christos       insn->insn_code = insn->insn_pru_opcode->match;
   1646  1.1  christos 
   1647  1.1  christos       if (pru_mode == PRU_MODE_TEST)
   1648  1.1  christos 	{
   1649  1.1  christos 	  /* Add the "expected" instruction parameter used for validation.  */
   1650  1.1  christos 	  argsfmt = malloc (strlen (argsfmt) + 3);
   1651  1.1  christos 	  sprintf ((char *)argsfmt, "%s,E", insn->insn_pru_opcode->args);
   1652  1.1  christos 	}
   1653  1.1  christos       pru_parse_args (insn, argstr, argsfmt,
   1654  1.1  christos 		      (char **) &insn->insn_tokens[1]);
   1655  1.1  christos 
   1656  1.1  christos       for (argp = argsfmt; !had_errors () && *argp && *argtk; ++argp)
   1657  1.1  christos 	{
   1658  1.1  christos 	  gas_assert (argtk <= &insn->insn_tokens[PRU_MAX_INSN_TOKENS]);
   1659  1.1  christos 
   1660  1.1  christos 	  switch (*argp)
   1661  1.1  christos 	    {
   1662  1.1  christos 	    case ',':
   1663  1.1  christos 	      continue;
   1664  1.1  christos 
   1665  1.1  christos 	    case 'd':
   1666  1.1  christos 	      pru_assemble_arg_d (insn, *argtk++);
   1667  1.1  christos 	      continue;
   1668  1.1  christos 	    case 'D':
   1669  1.1  christos 	      pru_assemble_arg_D (insn, *argtk++);
   1670  1.1  christos 	      continue;
   1671  1.1  christos 	    case 'R':
   1672  1.1  christos 	      pru_assemble_arg_R (insn, *argtk++);
   1673  1.1  christos 	      continue;
   1674  1.1  christos 	    case 's':
   1675  1.1  christos 	      pru_assemble_arg_s (insn, *argtk++);
   1676  1.1  christos 	      continue;
   1677  1.1  christos 	    case 'S':
   1678  1.1  christos 	      pru_assemble_arg_S (insn, *argtk++);
   1679  1.1  christos 	      continue;
   1680  1.1  christos 	    case 'b':
   1681  1.1  christos 	      pru_assemble_arg_b (insn, *argtk++);
   1682  1.1  christos 	      continue;
   1683  1.1  christos 	    case 'B':
   1684  1.1  christos 	      pru_assemble_arg_B (insn, *argtk++);
   1685  1.1  christos 	      continue;
   1686  1.1  christos 	    case 'i':
   1687  1.1  christos 	      pru_assemble_arg_i (insn, *argtk++);
   1688  1.1  christos 	      continue;
   1689  1.1  christos 	    case 'j':
   1690  1.1  christos 	      pru_assemble_arg_j (insn, *argtk++);
   1691  1.1  christos 	      continue;
   1692  1.1  christos 	    case 'W':
   1693  1.1  christos 	      pru_assemble_arg_W (insn, *argtk++);
   1694  1.1  christos 	      continue;
   1695  1.1  christos 	    case 'o':
   1696  1.1  christos 	      pru_assemble_arg_o (insn, *argtk++);
   1697  1.1  christos 	      continue;
   1698  1.1  christos 	    case 'O':
   1699  1.1  christos 	      pru_assemble_arg_O (insn, *argtk++);
   1700  1.1  christos 	      continue;
   1701  1.1  christos 	    case 'l':
   1702  1.1  christos 	      pru_assemble_arg_l (insn, *argtk++);
   1703  1.1  christos 	      continue;
   1704  1.1  christos 	    case 'n':
   1705  1.1  christos 	      pru_assemble_arg_n (insn, *argtk++);
   1706  1.1  christos 	      continue;
   1707  1.1  christos 	    case 'c':
   1708  1.1  christos 	      pru_assemble_arg_c (insn, *argtk++);
   1709  1.1  christos 	      continue;
   1710  1.1  christos 	    case 'w':
   1711  1.1  christos 	      pru_assemble_arg_w (insn, *argtk++);
   1712  1.1  christos 	      continue;
   1713  1.1  christos 	    case 'x':
   1714  1.1  christos 	      pru_assemble_arg_x (insn, *argtk++);
   1715  1.1  christos 	      continue;
   1716  1.1  christos 
   1717  1.1  christos 	    case 'E':
   1718  1.1  christos 	      pru_check_assembly (insn->insn_code, *argtk++);
   1719  1.1  christos 	      continue;
   1720  1.1  christos 
   1721  1.1  christos 	    default:
   1722  1.1  christos 	      BAD_CASE (*argp);
   1723  1.1  christos 	    }
   1724  1.1  christos 	}
   1725  1.1  christos 
   1726  1.1  christos       if (*argp && !had_errors ())
   1727  1.1  christos 	as_bad (_("missing argument"));
   1728  1.1  christos 
   1729  1.1  christos       if (!had_errors ())
   1730  1.1  christos 	{
   1731  1.1  christos 	  if (insn->insn_pru_opcode->pinfo & PRU_INSN_LDI32)
   1732  1.1  christos 	    {
   1733  1.1  christos 	      output_insn_ldi32 (insn);
   1734  1.1  christos 	    }
   1735  1.1  christos 	  else
   1736  1.1  christos 	    {
   1737  1.1  christos 	      output_insn (insn);
   1738  1.1  christos 	    }
   1739  1.1  christos 	}
   1740  1.1  christos 
   1741  1.1  christos       if (pru_mode == PRU_MODE_TEST)
   1742  1.1  christos 	free ((char *)argsfmt);
   1743  1.1  christos     }
   1744  1.1  christos   else
   1745  1.1  christos     /* Unrecognised instruction - error.  */
   1746  1.1  christos     as_bad (_("unrecognised instruction %s"), insn->insn_tokens[0]);
   1747  1.1  christos 
   1748  1.1  christos   /* Don't leak memory.  */
   1749  1.1  christos   pru_insn_reloc_destroy (insn->insn_reloc);
   1750  1.1  christos   free (op_strdup);
   1751  1.1  christos }
   1752  1.1  christos 
   1753  1.1  christos /* Round up section size.  */
   1754  1.1  christos valueT
   1755  1.1  christos md_section_align (asection *seg, valueT addr)
   1756  1.1  christos {
   1757  1.1  christos   int align = bfd_get_section_alignment (stdoutput, seg);
   1758  1.1  christos   return ((addr + (1 << align) - 1) & (-((valueT) 1 << align)));
   1759  1.1  christos }
   1760  1.1  christos 
   1761  1.1  christos /* Implement tc_fix_adjustable.  */
   1762  1.1  christos int
   1763  1.1  christos pru_fix_adjustable (fixS *fixp)
   1764  1.1  christos {
   1765  1.1  christos   if (fixp->fx_addsy == NULL)
   1766  1.1  christos     return 1;
   1767  1.1  christos 
   1768  1.1  christos   /* Prevent all adjustments to global symbols.  */
   1769  1.1  christos   if (OUTPUT_FLAVOR == bfd_target_elf_flavour
   1770  1.1  christos       && (S_IS_EXTERNAL (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)))
   1771  1.1  christos     return 0;
   1772  1.1  christos 
   1773  1.1  christos   if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
   1774  1.1  christos       || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
   1775  1.1  christos     return 0;
   1776  1.1  christos 
   1777  1.1  christos   /* Preserve relocations against symbols with function type.  */
   1778  1.1  christos   if (symbol_get_bfdsym (fixp->fx_addsy)->flags & BSF_FUNCTION)
   1779  1.1  christos     return 0;
   1780  1.1  christos 
   1781  1.1  christos   return 1;
   1782  1.1  christos }
   1783  1.1  christos 
   1784  1.1  christos /* The function tc_gen_reloc creates a relocation structure for the
   1785  1.1  christos    fixup fixp, and returns a pointer to it.  This structure is passed
   1786  1.1  christos    to bfd_install_relocation so that it can be written to the object
   1787  1.1  christos    file for linking.  */
   1788  1.1  christos arelent *
   1789  1.1  christos tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
   1790  1.1  christos {
   1791  1.1  christos   arelent *reloc = XNEW (arelent);
   1792  1.1  christos   reloc->sym_ptr_ptr = XNEW (asymbol *);
   1793  1.1  christos   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   1794  1.1  christos 
   1795  1.1  christos   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
   1796  1.1  christos   reloc->addend = fixp->fx_offset;  /* fixp->fx_addnumber; */
   1797  1.1  christos 
   1798  1.1  christos   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
   1799  1.1  christos   if (reloc->howto == NULL)
   1800  1.1  christos     {
   1801  1.1  christos       as_bad_where (fixp->fx_file, fixp->fx_line,
   1802  1.1  christos 		    _("can't represent relocation type %s"),
   1803  1.1  christos 		    bfd_get_reloc_code_name (fixp->fx_r_type));
   1804  1.1  christos 
   1805  1.1  christos       /* Set howto to a garbage value so that we can keep going.  */
   1806  1.1  christos       reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
   1807  1.1  christos       gas_assert (reloc->howto != NULL);
   1808  1.1  christos     }
   1809  1.1  christos   return reloc;
   1810  1.1  christos }
   1811  1.1  christos 
   1812  1.1  christos long
   1813  1.1  christos md_pcrel_from (fixS *fixP ATTRIBUTE_UNUSED)
   1814  1.1  christos {
   1815  1.1  christos   return fixP->fx_where + fixP->fx_frag->fr_address;
   1816  1.1  christos }
   1817  1.1  christos 
   1818  1.1  christos /* Called just before the assembler exits.  */
   1819  1.1  christos void
   1820  1.1  christos md_end (void)
   1821  1.1  christos {
   1822  1.1  christos   hash_die (pru_opcode_hash);
   1823  1.1  christos   hash_die (pru_reg_hash);
   1824  1.1  christos }
   1825  1.1  christos 
   1826  1.1  christos symbolS *
   1827  1.1  christos md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
   1828  1.1  christos {
   1829  1.1  christos   return NULL;
   1830  1.1  christos }
   1831  1.1  christos 
   1832  1.1  christos /* Implement tc_frob_label.  */
   1833  1.1  christos void
   1834  1.1  christos pru_frob_label (symbolS *lab)
   1835  1.1  christos {
   1836  1.1  christos   /* Emit dwarf information.  */
   1837  1.1  christos   dwarf2_emit_label (lab);
   1838  1.1  christos 
   1839  1.1  christos   /* Update the label's address with the current output pointer.  */
   1840  1.1  christos   symbol_set_frag (lab, frag_now);
   1841  1.1  christos   S_SET_VALUE (lab, (valueT) frag_now_fix ());
   1842  1.1  christos 
   1843  1.1  christos   /* Record this label for future adjustment after we find out what
   1844  1.1  christos      kind of data it references, and the required alignment therewith.  */
   1845  1.1  christos   pru_last_label = lab;
   1846  1.1  christos 
   1847  1.1  christos   if (pru_opt.warn_regname_label && pru_reg_lookup (S_GET_NAME (lab)))
   1848  1.1  christos     as_warn (_("Label \"%s\" matches a CPU register name"), S_GET_NAME (lab));
   1849  1.1  christos }
   1850  1.1  christos 
   1851  1.1  christos static inline char *
   1852  1.1  christos skip_space (char *s)
   1853  1.1  christos {
   1854  1.1  christos   while (*s == ' ' || *s == '\t')
   1855  1.1  christos     ++s;
   1856  1.1  christos   return s;
   1857  1.1  christos }
   1858  1.1  christos 
   1859  1.1  christos /* Parse special CONS expression: pmem (expression).  Idea from AVR.
   1860  1.1  christos 
   1861  1.1  christos    Used to catch and mark code (program memory) in constant expression
   1862  1.1  christos    relocations.  Return non-zero for program memory.  */
   1863  1.1  christos 
   1864  1.1  christos int
   1865  1.1  christos pru_parse_cons_expression (expressionS *exp, int nbytes)
   1866  1.1  christos {
   1867  1.1  christos   int is_pmem = FALSE;
   1868  1.1  christos   char *tmp;
   1869  1.1  christos 
   1870  1.1  christos   tmp = input_line_pointer = skip_space (input_line_pointer);
   1871  1.1  christos 
   1872  1.1  christos   if (nbytes == 4 || nbytes == 2)
   1873  1.1  christos     {
   1874  1.1  christos       const char *pmem_str = "%pmem";
   1875  1.1  christos       int len = strlen (pmem_str);
   1876  1.1  christos 
   1877  1.1  christos       if (strncasecmp (input_line_pointer, pmem_str, len) == 0)
   1878  1.1  christos 	{
   1879  1.1  christos 	  input_line_pointer = skip_space (input_line_pointer + len);
   1880  1.1  christos 
   1881  1.1  christos 	  if (*input_line_pointer == '(')
   1882  1.1  christos 	    {
   1883  1.1  christos 	      input_line_pointer = skip_space (input_line_pointer + 1);
   1884  1.1  christos 	      is_pmem = TRUE;
   1885  1.1  christos 	      expression (exp);
   1886  1.1  christos 
   1887  1.1  christos 	      if (*input_line_pointer == ')')
   1888  1.1  christos 		++input_line_pointer;
   1889  1.1  christos 	      else
   1890  1.1  christos 		{
   1891  1.1  christos 		  as_bad (_("`)' required"));
   1892  1.1  christos 		  is_pmem = FALSE;
   1893  1.1  christos 		}
   1894  1.1  christos 
   1895  1.1  christos 	      return is_pmem;
   1896  1.1  christos 	    }
   1897  1.1  christos 
   1898  1.1  christos 	  input_line_pointer = tmp;
   1899  1.1  christos 	}
   1900  1.1  christos     }
   1901  1.1  christos 
   1902  1.1  christos   expression (exp);
   1903  1.1  christos 
   1904  1.1  christos   return is_pmem;
   1905  1.1  christos }
   1906  1.1  christos 
   1907  1.1  christos /* Implement TC_CONS_FIX_NEW.  */
   1908  1.1  christos void
   1909  1.1  christos pru_cons_fix_new (fragS *frag, int where, unsigned int nbytes,
   1910  1.1  christos 		    expressionS *exp, const int is_pmem)
   1911  1.1  christos {
   1912  1.1  christos   bfd_reloc_code_real_type r;
   1913  1.1  christos 
   1914  1.1  christos   switch (nbytes | (!!is_pmem << 8))
   1915  1.1  christos     {
   1916  1.1  christos     case 1 | (0 << 8): r = BFD_RELOC_8; break;
   1917  1.1  christos     case 2 | (0 << 8): r = BFD_RELOC_16; break;
   1918  1.1  christos     case 4 | (0 << 8): r = BFD_RELOC_32; break;
   1919  1.1  christos     case 8 | (0 << 8): r = BFD_RELOC_64; break;
   1920  1.1  christos     case 2 | (1 << 8): r = BFD_RELOC_PRU_16_PMEM; break;
   1921  1.1  christos     case 4 | (1 << 8): r = BFD_RELOC_PRU_32_PMEM; break;
   1922  1.1  christos     default:
   1923  1.1  christos       as_bad (_("illegal %s relocation size: %d"),
   1924  1.1  christos 	      is_pmem ? "text" : "data", nbytes);
   1925  1.1  christos       return;
   1926  1.1  christos     }
   1927  1.1  christos 
   1928  1.1  christos   fix_new_exp (frag, where, (int) nbytes, exp, 0, r);
   1929  1.1  christos }
   1930  1.1  christos 
   1931  1.1  christos /* Implement tc_regname_to_dw2regnum, to convert REGNAME to a DWARF-2
   1932  1.1  christos    register number.  */
   1933  1.1  christos int
   1934  1.1  christos pru_regname_to_dw2regnum (char *regname)
   1935  1.1  christos {
   1936  1.1  christos   struct pru_reg *r = pru_reg_lookup (regname);
   1937  1.1  christos   if (r == NULL)
   1938  1.1  christos     return -1;
   1939  1.1  christos   return r->index;
   1940  1.1  christos }
   1941  1.1  christos 
   1942  1.1  christos /* Implement tc_cfi_frame_initial_instructions, to initialize the DWARF-2
   1943  1.1  christos    unwind information for this procedure.  */
   1944  1.1  christos void
   1945  1.1  christos pru_frame_initial_instructions (void)
   1946  1.1  christos {
   1947  1.1  christos   const unsigned fp_regno = 4;
   1948  1.1  christos   cfi_add_CFA_def_cfa (fp_regno, 0);
   1949  1.1  christos }
   1950  1.1  christos 
   1951  1.1  christos bfd_boolean
   1952  1.1  christos pru_allow_local_subtract (expressionS * left,
   1953  1.1  christos 			     expressionS * right,
   1954  1.1  christos 			     segT section)
   1955  1.1  christos {
   1956  1.1  christos   /* If we are not in relaxation mode, subtraction is OK.  */
   1957  1.1  christos   if (!linkrelax)
   1958  1.1  christos     return TRUE;
   1959  1.1  christos 
   1960  1.1  christos   /* If the symbols are not in a code section then they are OK.  */
   1961  1.1  christos   if ((section->flags & SEC_CODE) == 0)
   1962  1.1  christos     return TRUE;
   1963                
   1964                  if (left->X_add_symbol == right->X_add_symbol)
   1965                    return TRUE;
   1966                
   1967                  /* We have to assume that there may be instructions between the
   1968                     two symbols and that relaxation may increase the distance between
   1969                     them.  */
   1970                  return FALSE;
   1971                }
   1972