Home | History | Annotate | Line # | Download | only in config
tc-arc.c revision 1.1.1.1.2.1
      1          1.1  christos /* tc-arc.c -- Assembler for the ARC
      2  1.1.1.1.2.1  pgoyette    Copyright (C) 1994-2015 Free Software Foundation, Inc.
      3  1.1.1.1.2.1  pgoyette 
      4  1.1.1.1.2.1  pgoyette    Contributor: Claudiu Zissulescu <claziss (at) synopsys.com>
      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.1.1.2.1  pgoyette #include "subsegs.h"
     25          1.1  christos #include "struc-symbol.h"
     26  1.1.1.1.2.1  pgoyette #include "dwarf2dbg.h"
     27          1.1  christos #include "safe-ctype.h"
     28  1.1.1.1.2.1  pgoyette 
     29          1.1  christos #include "opcode/arc.h"
     30          1.1  christos #include "elf/arc.h"
     31          1.1  christos 
     32  1.1.1.1.2.1  pgoyette /* Defines section.  */
     33          1.1  christos 
     34  1.1.1.1.2.1  pgoyette #define MAX_FLAG_NAME_LENGHT 3
     35  1.1.1.1.2.1  pgoyette #define MAX_INSN_FIXUPS      2
     36  1.1.1.1.2.1  pgoyette #define MAX_CONSTR_STR       20
     37  1.1.1.1.2.1  pgoyette 
     38  1.1.1.1.2.1  pgoyette #ifdef DEBUG
     39  1.1.1.1.2.1  pgoyette # define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args)
     40  1.1.1.1.2.1  pgoyette #else
     41  1.1.1.1.2.1  pgoyette # define pr_debug(fmt, args...)
     42  1.1.1.1.2.1  pgoyette #endif
     43  1.1.1.1.2.1  pgoyette 
     44  1.1.1.1.2.1  pgoyette #define MAJOR_OPCODE(x)  (((x) & 0xF8000000) >> 27)
     45  1.1.1.1.2.1  pgoyette #define SUB_OPCODE(x)	 (((x) & 0x003F0000) >> 16)
     46  1.1.1.1.2.1  pgoyette #define LP_INSN(x)	 ((MAJOR_OPCODE (x) == 0x4) &&	\
     47  1.1.1.1.2.1  pgoyette 			  (SUB_OPCODE (x) == 0x28))
     48  1.1.1.1.2.1  pgoyette 
     49  1.1.1.1.2.1  pgoyette /* Equal to MAX_PRECISION in atof-ieee.c.  */
     50  1.1.1.1.2.1  pgoyette #define MAX_LITTLENUMS 6
     51  1.1.1.1.2.1  pgoyette 
     52  1.1.1.1.2.1  pgoyette /* Macros section.  */
     53  1.1.1.1.2.1  pgoyette 
     54  1.1.1.1.2.1  pgoyette #define regno(x)		((x) & 0x3F)
     55  1.1.1.1.2.1  pgoyette #define is_ir_num(x)		(((x) & ~0x3F) == 0)
     56  1.1.1.1.2.1  pgoyette #define is_code_density_p(op)   (((op)->subclass == CD1 || (op)->subclass == CD2))
     57  1.1.1.1.2.1  pgoyette #define is_br_jmp_insn_p(op)    (((op)->class == BRANCH || (op)->class == JUMP))
     58  1.1.1.1.2.1  pgoyette #define is_kernel_insn_p(op)    (((op)->class == KERNEL))
     59          1.1  christos 
     60  1.1.1.1.2.1  pgoyette /* Generic assembler global variables which must be defined by all
     61  1.1.1.1.2.1  pgoyette    targets.  */
     62          1.1  christos 
     63  1.1.1.1.2.1  pgoyette /* Characters which always start a comment.  */
     64          1.1  christos const char comment_chars[] = "#;";
     65          1.1  christos 
     66  1.1.1.1.2.1  pgoyette /* Characters which start a comment at the beginning of a line.  */
     67          1.1  christos const char line_comment_chars[] = "#";
     68          1.1  christos 
     69  1.1.1.1.2.1  pgoyette /* Characters which may be used to separate multiple commands on a
     70  1.1.1.1.2.1  pgoyette    single line.  */
     71  1.1.1.1.2.1  pgoyette const char line_separator_chars[] = "`";
     72          1.1  christos 
     73  1.1.1.1.2.1  pgoyette /* Characters which are used to indicate an exponent in a floating
     74  1.1.1.1.2.1  pgoyette    point number.  */
     75          1.1  christos const char EXP_CHARS[] = "eE";
     76          1.1  christos 
     77          1.1  christos /* Chars that mean this number is a floating point constant
     78          1.1  christos    As in 0f12.456 or 0d1.2345e12.  */
     79          1.1  christos const char FLT_CHARS[] = "rRsSfFdD";
     80          1.1  christos 
     81          1.1  christos /* Byte order.  */
     82          1.1  christos extern int target_big_endian;
     83          1.1  christos const char *arc_target_format = DEFAULT_TARGET_FORMAT;
     84          1.1  christos static int byte_order = DEFAULT_BYTE_ORDER;
     85          1.1  christos 
     86  1.1.1.1.2.1  pgoyette extern int arc_get_mach (char *);
     87          1.1  christos 
     88  1.1.1.1.2.1  pgoyette /* Forward declaration.  */
     89  1.1.1.1.2.1  pgoyette static void arc_lcomm (int);
     90  1.1.1.1.2.1  pgoyette static void arc_option (int);
     91  1.1.1.1.2.1  pgoyette static void arc_extra_reloc (int);
     92          1.1  christos 
     93  1.1.1.1.2.1  pgoyette const pseudo_typeS md_pseudo_table[] =
     94  1.1.1.1.2.1  pgoyette {
     95  1.1.1.1.2.1  pgoyette   /* Make sure that .word is 32 bits.  */
     96  1.1.1.1.2.1  pgoyette   { "word", cons, 4 },
     97          1.1  christos 
     98  1.1.1.1.2.1  pgoyette   { "align",   s_align_bytes, 0 }, /* Defaulting is invalid (0).  */
     99  1.1.1.1.2.1  pgoyette   { "lcomm",   arc_lcomm, 0 },
    100  1.1.1.1.2.1  pgoyette   { "lcommon", arc_lcomm, 0 },
    101  1.1.1.1.2.1  pgoyette   { "cpu",     arc_option, 0 },
    102  1.1.1.1.2.1  pgoyette 
    103  1.1.1.1.2.1  pgoyette   { "tls_gd_ld",   arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_LD },
    104  1.1.1.1.2.1  pgoyette   { "tls_gd_call", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_CALL },
    105  1.1.1.1.2.1  pgoyette 
    106  1.1.1.1.2.1  pgoyette   { NULL, NULL, 0 }
    107  1.1.1.1.2.1  pgoyette };
    108          1.1  christos 
    109          1.1  christos const char *md_shortopts = "";
    110          1.1  christos 
    111          1.1  christos enum options
    112          1.1  christos {
    113          1.1  christos   OPTION_EB = OPTION_MD_BASE,
    114          1.1  christos   OPTION_EL,
    115  1.1.1.1.2.1  pgoyette 
    116  1.1.1.1.2.1  pgoyette   OPTION_ARC600,
    117  1.1.1.1.2.1  pgoyette   OPTION_ARC601,
    118  1.1.1.1.2.1  pgoyette   OPTION_ARC700,
    119  1.1.1.1.2.1  pgoyette   OPTION_ARCEM,
    120  1.1.1.1.2.1  pgoyette   OPTION_ARCHS,
    121  1.1.1.1.2.1  pgoyette 
    122  1.1.1.1.2.1  pgoyette   OPTION_MCPU,
    123  1.1.1.1.2.1  pgoyette   OPTION_CD,
    124  1.1.1.1.2.1  pgoyette 
    125  1.1.1.1.2.1  pgoyette   /* The following options are deprecated and provided here only for
    126  1.1.1.1.2.1  pgoyette      compatibility reasons.  */
    127  1.1.1.1.2.1  pgoyette   OPTION_USER_MODE,
    128  1.1.1.1.2.1  pgoyette   OPTION_LD_EXT_MASK,
    129  1.1.1.1.2.1  pgoyette   OPTION_SWAP,
    130  1.1.1.1.2.1  pgoyette   OPTION_NORM,
    131  1.1.1.1.2.1  pgoyette   OPTION_BARREL_SHIFT,
    132  1.1.1.1.2.1  pgoyette   OPTION_MIN_MAX,
    133  1.1.1.1.2.1  pgoyette   OPTION_NO_MPY,
    134  1.1.1.1.2.1  pgoyette   OPTION_EA,
    135  1.1.1.1.2.1  pgoyette   OPTION_MUL64,
    136  1.1.1.1.2.1  pgoyette   OPTION_SIMD,
    137  1.1.1.1.2.1  pgoyette   OPTION_SPFP,
    138  1.1.1.1.2.1  pgoyette   OPTION_DPFP,
    139  1.1.1.1.2.1  pgoyette   OPTION_XMAC_D16,
    140  1.1.1.1.2.1  pgoyette   OPTION_XMAC_24,
    141  1.1.1.1.2.1  pgoyette   OPTION_DSP_PACKA,
    142  1.1.1.1.2.1  pgoyette   OPTION_CRC,
    143  1.1.1.1.2.1  pgoyette   OPTION_DVBF,
    144  1.1.1.1.2.1  pgoyette   OPTION_TELEPHONY,
    145  1.1.1.1.2.1  pgoyette   OPTION_XYMEMORY,
    146  1.1.1.1.2.1  pgoyette   OPTION_LOCK,
    147  1.1.1.1.2.1  pgoyette   OPTION_SWAPE,
    148  1.1.1.1.2.1  pgoyette   OPTION_RTSC,
    149  1.1.1.1.2.1  pgoyette   OPTION_FPUDA
    150          1.1  christos };
    151          1.1  christos 
    152          1.1  christos struct option md_longopts[] =
    153          1.1  christos {
    154  1.1.1.1.2.1  pgoyette   { "EB",		no_argument,	   NULL, OPTION_EB },
    155  1.1.1.1.2.1  pgoyette   { "EL",		no_argument,	   NULL, OPTION_EL },
    156  1.1.1.1.2.1  pgoyette   { "mcpu",		required_argument, NULL, OPTION_MCPU },
    157  1.1.1.1.2.1  pgoyette   { "mA6",		no_argument,	   NULL, OPTION_ARC600 },
    158  1.1.1.1.2.1  pgoyette   { "mARC600",	no_argument,	   NULL, OPTION_ARC600 },
    159  1.1.1.1.2.1  pgoyette   { "mARC601",	no_argument,	   NULL, OPTION_ARC601 },
    160  1.1.1.1.2.1  pgoyette   { "mARC700",	no_argument,	   NULL, OPTION_ARC700 },
    161  1.1.1.1.2.1  pgoyette   { "mA7",		no_argument,	   NULL, OPTION_ARC700 },
    162  1.1.1.1.2.1  pgoyette   { "mEM",		no_argument,	   NULL, OPTION_ARCEM },
    163  1.1.1.1.2.1  pgoyette   { "mHS",		no_argument,	   NULL, OPTION_ARCHS },
    164  1.1.1.1.2.1  pgoyette   { "mcode-density",	no_argument,	   NULL, OPTION_CD },
    165  1.1.1.1.2.1  pgoyette 
    166  1.1.1.1.2.1  pgoyette   /* The following options are deprecated and provided here only for
    167  1.1.1.1.2.1  pgoyette      compatibility reasons.  */
    168  1.1.1.1.2.1  pgoyette   { "mav2em", no_argument, NULL, OPTION_ARCEM },
    169  1.1.1.1.2.1  pgoyette   { "mav2hs", no_argument, NULL, OPTION_ARCHS },
    170  1.1.1.1.2.1  pgoyette   { "muser-mode-only", no_argument, NULL, OPTION_USER_MODE },
    171  1.1.1.1.2.1  pgoyette   { "mld-extension-reg-mask", required_argument, NULL, OPTION_LD_EXT_MASK },
    172  1.1.1.1.2.1  pgoyette   { "mswap", no_argument, NULL, OPTION_SWAP },
    173  1.1.1.1.2.1  pgoyette   { "mnorm", no_argument, NULL, OPTION_NORM },
    174  1.1.1.1.2.1  pgoyette   { "mbarrel-shifter", no_argument, NULL, OPTION_BARREL_SHIFT },
    175  1.1.1.1.2.1  pgoyette   { "mbarrel_shifter", no_argument, NULL, OPTION_BARREL_SHIFT },
    176  1.1.1.1.2.1  pgoyette   { "mmin-max", no_argument, NULL, OPTION_MIN_MAX },
    177  1.1.1.1.2.1  pgoyette   { "mmin_max", no_argument, NULL, OPTION_MIN_MAX },
    178  1.1.1.1.2.1  pgoyette   { "mno-mpy", no_argument, NULL, OPTION_NO_MPY },
    179  1.1.1.1.2.1  pgoyette   { "mea", no_argument, NULL, OPTION_EA },
    180  1.1.1.1.2.1  pgoyette   { "mEA", no_argument, NULL, OPTION_EA },
    181  1.1.1.1.2.1  pgoyette   { "mmul64", no_argument, NULL, OPTION_MUL64 },
    182  1.1.1.1.2.1  pgoyette   { "msimd", no_argument, NULL, OPTION_SIMD},
    183  1.1.1.1.2.1  pgoyette   { "mspfp", no_argument, NULL, OPTION_SPFP},
    184  1.1.1.1.2.1  pgoyette   { "mspfp-compact", no_argument, NULL, OPTION_SPFP},
    185  1.1.1.1.2.1  pgoyette   { "mspfp_compact", no_argument, NULL, OPTION_SPFP},
    186  1.1.1.1.2.1  pgoyette   { "mspfp-fast", no_argument, NULL, OPTION_SPFP},
    187  1.1.1.1.2.1  pgoyette   { "mspfp_fast", no_argument, NULL, OPTION_SPFP},
    188  1.1.1.1.2.1  pgoyette   { "mdpfp", no_argument, NULL, OPTION_DPFP},
    189  1.1.1.1.2.1  pgoyette   { "mdpfp-compact", no_argument, NULL, OPTION_DPFP},
    190  1.1.1.1.2.1  pgoyette   { "mdpfp_compact", no_argument, NULL, OPTION_DPFP},
    191  1.1.1.1.2.1  pgoyette   { "mdpfp-fast", no_argument, NULL, OPTION_DPFP},
    192  1.1.1.1.2.1  pgoyette   { "mdpfp_fast", no_argument, NULL, OPTION_DPFP},
    193  1.1.1.1.2.1  pgoyette   { "mmac-d16", no_argument, NULL, OPTION_XMAC_D16},
    194  1.1.1.1.2.1  pgoyette   { "mmac_d16", no_argument, NULL, OPTION_XMAC_D16},
    195  1.1.1.1.2.1  pgoyette   { "mmac-24", no_argument, NULL, OPTION_XMAC_24},
    196  1.1.1.1.2.1  pgoyette   { "mmac_24", no_argument, NULL, OPTION_XMAC_24},
    197  1.1.1.1.2.1  pgoyette   { "mdsp-packa", no_argument, NULL, OPTION_DSP_PACKA},
    198  1.1.1.1.2.1  pgoyette   { "mdsp_packa", no_argument, NULL, OPTION_DSP_PACKA},
    199  1.1.1.1.2.1  pgoyette   { "mcrc", no_argument, NULL, OPTION_CRC},
    200  1.1.1.1.2.1  pgoyette   { "mdvbf", no_argument, NULL, OPTION_DVBF},
    201  1.1.1.1.2.1  pgoyette   { "mtelephony", no_argument, NULL, OPTION_TELEPHONY},
    202  1.1.1.1.2.1  pgoyette   { "mxy", no_argument, NULL, OPTION_XYMEMORY},
    203  1.1.1.1.2.1  pgoyette   { "mlock", no_argument, NULL, OPTION_LOCK},
    204  1.1.1.1.2.1  pgoyette   { "mswape", no_argument, NULL, OPTION_SWAPE},
    205  1.1.1.1.2.1  pgoyette   { "mrtsc", no_argument, NULL, OPTION_RTSC},
    206  1.1.1.1.2.1  pgoyette   { "mfpuda", no_argument, NULL, OPTION_FPUDA},
    207  1.1.1.1.2.1  pgoyette 
    208  1.1.1.1.2.1  pgoyette   { NULL,		no_argument, NULL, 0 }
    209          1.1  christos };
    210  1.1.1.1.2.1  pgoyette 
    211          1.1  christos size_t md_longopts_size = sizeof (md_longopts);
    212          1.1  christos 
    213  1.1.1.1.2.1  pgoyette /* Local data and data types.  */
    214  1.1.1.1.2.1  pgoyette 
    215  1.1.1.1.2.1  pgoyette /* Used since new relocation types are introduced in this
    216  1.1.1.1.2.1  pgoyette    file (DUMMY_RELOC_LITUSE_*).  */
    217  1.1.1.1.2.1  pgoyette typedef int extended_bfd_reloc_code_real_type;
    218  1.1.1.1.2.1  pgoyette 
    219  1.1.1.1.2.1  pgoyette struct arc_fixup
    220  1.1.1.1.2.1  pgoyette {
    221  1.1.1.1.2.1  pgoyette   expressionS exp;
    222          1.1  christos 
    223  1.1.1.1.2.1  pgoyette   extended_bfd_reloc_code_real_type reloc;
    224          1.1  christos 
    225  1.1.1.1.2.1  pgoyette   /* index into arc_operands.  */
    226  1.1.1.1.2.1  pgoyette   unsigned int opindex;
    227          1.1  christos 
    228  1.1.1.1.2.1  pgoyette   /* PC-relative, used by internals fixups.  */
    229  1.1.1.1.2.1  pgoyette   unsigned char pcrel;
    230  1.1.1.1.2.1  pgoyette 
    231  1.1.1.1.2.1  pgoyette   /* TRUE if this fixup is for LIMM operand.  */
    232  1.1.1.1.2.1  pgoyette   bfd_boolean islong;
    233  1.1.1.1.2.1  pgoyette };
    234  1.1.1.1.2.1  pgoyette 
    235  1.1.1.1.2.1  pgoyette struct arc_insn
    236          1.1  christos {
    237  1.1.1.1.2.1  pgoyette   unsigned int insn;
    238  1.1.1.1.2.1  pgoyette   int nfixups;
    239  1.1.1.1.2.1  pgoyette   struct arc_fixup fixups[MAX_INSN_FIXUPS];
    240  1.1.1.1.2.1  pgoyette   long limm;
    241  1.1.1.1.2.1  pgoyette   bfd_boolean short_insn; /* Boolean value: TRUE if current insn is
    242  1.1.1.1.2.1  pgoyette 			     short.  */
    243  1.1.1.1.2.1  pgoyette   bfd_boolean has_limm;   /* Boolean value: TRUE if limm field is
    244  1.1.1.1.2.1  pgoyette 			     valid.  */
    245  1.1.1.1.2.1  pgoyette };
    246          1.1  christos 
    247  1.1.1.1.2.1  pgoyette /* Structure to hold any last two instructions.  */
    248  1.1.1.1.2.1  pgoyette static struct arc_last_insn
    249          1.1  christos {
    250  1.1.1.1.2.1  pgoyette   /* Saved instruction opcode.  */
    251  1.1.1.1.2.1  pgoyette   const struct arc_opcode *opcode;
    252          1.1  christos 
    253  1.1.1.1.2.1  pgoyette   /* Boolean value: TRUE if current insn is short.  */
    254  1.1.1.1.2.1  pgoyette   bfd_boolean has_limm;
    255          1.1  christos 
    256  1.1.1.1.2.1  pgoyette   /* Boolean value: TRUE if current insn has delay slot.  */
    257  1.1.1.1.2.1  pgoyette   bfd_boolean has_delay_slot;
    258  1.1.1.1.2.1  pgoyette } arc_last_insns[2];
    259  1.1.1.1.2.1  pgoyette 
    260  1.1.1.1.2.1  pgoyette /* The cpu for which we are generating code.  */
    261  1.1.1.1.2.1  pgoyette static unsigned arc_target = ARC_OPCODE_BASE;
    262  1.1.1.1.2.1  pgoyette static const char *arc_target_name = "<all>";
    263  1.1.1.1.2.1  pgoyette static unsigned arc_features = 0x00;
    264          1.1  christos 
    265  1.1.1.1.2.1  pgoyette /* The default architecture.  */
    266  1.1.1.1.2.1  pgoyette static int arc_mach_type = bfd_mach_arc_arcv2;
    267          1.1  christos 
    268  1.1.1.1.2.1  pgoyette /* Non-zero if the cpu type has been explicitly specified.  */
    269  1.1.1.1.2.1  pgoyette static int mach_type_specified_p = 0;
    270          1.1  christos 
    271  1.1.1.1.2.1  pgoyette /* The hash table of instruction opcodes.  */
    272  1.1.1.1.2.1  pgoyette static struct hash_control *arc_opcode_hash;
    273          1.1  christos 
    274  1.1.1.1.2.1  pgoyette /* The hash table of register symbols.  */
    275  1.1.1.1.2.1  pgoyette static struct hash_control *arc_reg_hash;
    276  1.1.1.1.2.1  pgoyette 
    277  1.1.1.1.2.1  pgoyette /* A table of CPU names and opcode sets.  */
    278  1.1.1.1.2.1  pgoyette static const struct cpu_type
    279          1.1  christos {
    280  1.1.1.1.2.1  pgoyette   const char *name;
    281  1.1.1.1.2.1  pgoyette   unsigned flags;
    282  1.1.1.1.2.1  pgoyette   int mach;
    283  1.1.1.1.2.1  pgoyette   unsigned eflags;
    284  1.1.1.1.2.1  pgoyette   unsigned features;
    285  1.1.1.1.2.1  pgoyette }
    286  1.1.1.1.2.1  pgoyette   cpu_types[] =
    287  1.1.1.1.2.1  pgoyette {
    288  1.1.1.1.2.1  pgoyette   { "arc600", ARC_OPCODE_ARC600,  bfd_mach_arc_arc600,
    289  1.1.1.1.2.1  pgoyette     E_ARC_MACH_ARC600,  0x00},
    290  1.1.1.1.2.1  pgoyette   { "arc700", ARC_OPCODE_ARC700,  bfd_mach_arc_arc700,
    291  1.1.1.1.2.1  pgoyette     E_ARC_MACH_ARC700,  0x00},
    292  1.1.1.1.2.1  pgoyette   { "arcem",  ARC_OPCODE_ARCv2EM, bfd_mach_arc_arcv2,
    293  1.1.1.1.2.1  pgoyette     EF_ARC_CPU_ARCV2EM, 0x00},
    294  1.1.1.1.2.1  pgoyette   { "archs",  ARC_OPCODE_ARCv2HS, bfd_mach_arc_arcv2,
    295  1.1.1.1.2.1  pgoyette     EF_ARC_CPU_ARCV2HS, ARC_CD},
    296  1.1.1.1.2.1  pgoyette   { "all",    ARC_OPCODE_BASE,    bfd_mach_arc_arcv2,
    297  1.1.1.1.2.1  pgoyette     0x00, 0x00 },
    298  1.1.1.1.2.1  pgoyette   { 0, 0, 0, 0, 0 }
    299  1.1.1.1.2.1  pgoyette };
    300          1.1  christos 
    301  1.1.1.1.2.1  pgoyette struct arc_flags
    302  1.1.1.1.2.1  pgoyette {
    303  1.1.1.1.2.1  pgoyette   /* Name of the parsed flag.  */
    304  1.1.1.1.2.1  pgoyette   char name[MAX_FLAG_NAME_LENGHT+1];
    305          1.1  christos 
    306  1.1.1.1.2.1  pgoyette   /* The code of the parsed flag.  Valid when is not zero.  */
    307  1.1.1.1.2.1  pgoyette   unsigned char code;
    308  1.1.1.1.2.1  pgoyette };
    309          1.1  christos 
    310  1.1.1.1.2.1  pgoyette /* Used by the arc_reloc_op table.  Order is important.  */
    311  1.1.1.1.2.1  pgoyette #define O_gotoff  O_md1     /* @gotoff relocation.  */
    312  1.1.1.1.2.1  pgoyette #define O_gotpc   O_md2     /* @gotpc relocation.  */
    313  1.1.1.1.2.1  pgoyette #define O_plt     O_md3     /* @plt relocation.  */
    314  1.1.1.1.2.1  pgoyette #define O_sda     O_md4     /* @sda relocation.  */
    315  1.1.1.1.2.1  pgoyette #define O_pcl     O_md5     /* @pcl relocation.  */
    316  1.1.1.1.2.1  pgoyette #define O_tlsgd   O_md6     /* @tlsgd relocation.  */
    317  1.1.1.1.2.1  pgoyette #define O_tlsie   O_md7     /* @tlsie relocation.  */
    318  1.1.1.1.2.1  pgoyette #define O_tpoff9  O_md8     /* @tpoff9 relocation.  */
    319  1.1.1.1.2.1  pgoyette #define O_tpoff   O_md9     /* @tpoff relocation.  */
    320  1.1.1.1.2.1  pgoyette #define O_dtpoff9 O_md10    /* @dtpoff9 relocation.  */
    321  1.1.1.1.2.1  pgoyette #define O_dtpoff  O_md11    /* @dtpoff relocation.  */
    322  1.1.1.1.2.1  pgoyette #define O_last    O_dtpoff
    323  1.1.1.1.2.1  pgoyette 
    324  1.1.1.1.2.1  pgoyette /* Used to define a bracket as operand in tokens.  */
    325  1.1.1.1.2.1  pgoyette #define O_bracket O_md32
    326  1.1.1.1.2.1  pgoyette 
    327  1.1.1.1.2.1  pgoyette /* Dummy relocation, to be sorted out.  */
    328  1.1.1.1.2.1  pgoyette #define DUMMY_RELOC_ARC_ENTRY     (BFD_RELOC_UNUSED + 1)
    329  1.1.1.1.2.1  pgoyette 
    330  1.1.1.1.2.1  pgoyette #define USER_RELOC_P(R) ((R) >= O_gotoff && (R) <= O_last)
    331  1.1.1.1.2.1  pgoyette 
    332  1.1.1.1.2.1  pgoyette /* A table to map the spelling of a relocation operand into an appropriate
    333  1.1.1.1.2.1  pgoyette    bfd_reloc_code_real_type type.  The table is assumed to be ordered such
    334  1.1.1.1.2.1  pgoyette    that op-O_literal indexes into it.  */
    335  1.1.1.1.2.1  pgoyette #define ARC_RELOC_TABLE(op)				\
    336  1.1.1.1.2.1  pgoyette   (&arc_reloc_op[ ((!USER_RELOC_P (op))			\
    337  1.1.1.1.2.1  pgoyette 		   ? (abort (), 0)			\
    338  1.1.1.1.2.1  pgoyette 		   : (int) (op) - (int) O_gotoff) ])
    339  1.1.1.1.2.1  pgoyette 
    340  1.1.1.1.2.1  pgoyette #define DEF(NAME, RELOC, REQ)				\
    341  1.1.1.1.2.1  pgoyette   { #NAME, sizeof (#NAME)-1, O_##NAME, RELOC, REQ}
    342  1.1.1.1.2.1  pgoyette 
    343  1.1.1.1.2.1  pgoyette static const struct arc_reloc_op_tag
    344  1.1.1.1.2.1  pgoyette {
    345  1.1.1.1.2.1  pgoyette   /* String to lookup.  */
    346  1.1.1.1.2.1  pgoyette   const char *name;
    347  1.1.1.1.2.1  pgoyette   /* Size of the string.  */
    348  1.1.1.1.2.1  pgoyette   size_t length;
    349  1.1.1.1.2.1  pgoyette   /* Which operator to use.  */
    350  1.1.1.1.2.1  pgoyette   operatorT op;
    351  1.1.1.1.2.1  pgoyette   extended_bfd_reloc_code_real_type reloc;
    352  1.1.1.1.2.1  pgoyette   /* Allows complex relocation expression like identifier@reloc +
    353  1.1.1.1.2.1  pgoyette      const.  */
    354  1.1.1.1.2.1  pgoyette   unsigned int complex_expr : 1;
    355  1.1.1.1.2.1  pgoyette }
    356  1.1.1.1.2.1  pgoyette   arc_reloc_op[] =
    357  1.1.1.1.2.1  pgoyette {
    358  1.1.1.1.2.1  pgoyette   DEF (gotoff,  BFD_RELOC_ARC_GOTOFF,		1),
    359  1.1.1.1.2.1  pgoyette   DEF (gotpc,   BFD_RELOC_ARC_GOTPC32,		0),
    360  1.1.1.1.2.1  pgoyette   DEF (plt,	BFD_RELOC_ARC_PLT32,		0),
    361  1.1.1.1.2.1  pgoyette   DEF (sda,	DUMMY_RELOC_ARC_ENTRY,		1),
    362  1.1.1.1.2.1  pgoyette   DEF (pcl,	BFD_RELOC_ARC_PC32,		1),
    363  1.1.1.1.2.1  pgoyette   DEF (tlsgd,   BFD_RELOC_ARC_TLS_GD_GOT,	0),
    364  1.1.1.1.2.1  pgoyette   DEF (tlsie,   BFD_RELOC_ARC_TLS_IE_GOT,	0),
    365  1.1.1.1.2.1  pgoyette   DEF (tpoff9,  BFD_RELOC_ARC_TLS_LE_S9,	0),
    366  1.1.1.1.2.1  pgoyette   DEF (tpoff,   BFD_RELOC_ARC_TLS_LE_32,	0),
    367  1.1.1.1.2.1  pgoyette   DEF (dtpoff9, BFD_RELOC_ARC_TLS_DTPOFF_S9,	0),
    368  1.1.1.1.2.1  pgoyette   DEF (dtpoff,  BFD_RELOC_ARC_TLS_DTPOFF,	0),
    369  1.1.1.1.2.1  pgoyette };
    370          1.1  christos 
    371  1.1.1.1.2.1  pgoyette static const int arc_num_reloc_op
    372  1.1.1.1.2.1  pgoyette = sizeof (arc_reloc_op) / sizeof (*arc_reloc_op);
    373  1.1.1.1.2.1  pgoyette 
    374  1.1.1.1.2.1  pgoyette /* Flags to set in the elf header.  */
    375  1.1.1.1.2.1  pgoyette static flagword arc_eflag = 0x00;
    376          1.1  christos 
    377  1.1.1.1.2.1  pgoyette /* Pre-defined "_GLOBAL_OFFSET_TABLE_".  */
    378  1.1.1.1.2.1  pgoyette symbolS * GOT_symbol = 0;
    379          1.1  christos 
    380  1.1.1.1.2.1  pgoyette /* Set to TRUE when we assemble instructions.  */
    381  1.1.1.1.2.1  pgoyette static bfd_boolean assembling_insn = FALSE;
    382  1.1.1.1.2.1  pgoyette 
    383  1.1.1.1.2.1  pgoyette /* Functions declaration.  */
    384  1.1.1.1.2.1  pgoyette 
    385  1.1.1.1.2.1  pgoyette static void assemble_tokens (const char *, expressionS *, int,
    386  1.1.1.1.2.1  pgoyette 			     struct arc_flags *, int);
    387  1.1.1.1.2.1  pgoyette static const struct arc_opcode *find_opcode_match (const struct arc_opcode *,
    388  1.1.1.1.2.1  pgoyette 						   expressionS *, int *,
    389  1.1.1.1.2.1  pgoyette 						   struct arc_flags *,
    390  1.1.1.1.2.1  pgoyette 						   int, int *);
    391  1.1.1.1.2.1  pgoyette static void assemble_insn (const struct arc_opcode *, const expressionS *,
    392  1.1.1.1.2.1  pgoyette 			   int, const struct arc_flags *, int,
    393  1.1.1.1.2.1  pgoyette 			   struct arc_insn *);
    394  1.1.1.1.2.1  pgoyette static void emit_insn (struct arc_insn *);
    395  1.1.1.1.2.1  pgoyette static unsigned insert_operand (unsigned, const struct arc_operand *,
    396  1.1.1.1.2.1  pgoyette 				offsetT, char *, unsigned);
    397  1.1.1.1.2.1  pgoyette static const struct arc_opcode *find_special_case_flag (const char *,
    398  1.1.1.1.2.1  pgoyette 							int *,
    399  1.1.1.1.2.1  pgoyette 							struct arc_flags *);
    400  1.1.1.1.2.1  pgoyette static const struct arc_opcode *find_special_case (const char *,
    401  1.1.1.1.2.1  pgoyette 						   int *,
    402  1.1.1.1.2.1  pgoyette 						   struct arc_flags *,
    403  1.1.1.1.2.1  pgoyette 						   expressionS *, int *);
    404  1.1.1.1.2.1  pgoyette static const struct arc_opcode *find_special_case_pseudo (const char *,
    405  1.1.1.1.2.1  pgoyette 							  int *,
    406  1.1.1.1.2.1  pgoyette 							  expressionS *,
    407  1.1.1.1.2.1  pgoyette 							  int *,
    408  1.1.1.1.2.1  pgoyette 							  struct arc_flags *);
    409  1.1.1.1.2.1  pgoyette 
    410  1.1.1.1.2.1  pgoyette /* Functions implementation.  */
    411  1.1.1.1.2.1  pgoyette 
    412  1.1.1.1.2.1  pgoyette /* Like md_number_to_chars but used for limms.  The 4-byte limm value,
    413  1.1.1.1.2.1  pgoyette    is encoded as 'middle-endian' for a little-endian target.  FIXME!
    414  1.1.1.1.2.1  pgoyette    this function is used for regular 4 byte instructions as well.  */
    415          1.1  christos 
    416  1.1.1.1.2.1  pgoyette static void
    417  1.1.1.1.2.1  pgoyette md_number_to_chars_midend (char *buf, valueT val, int n)
    418  1.1.1.1.2.1  pgoyette {
    419  1.1.1.1.2.1  pgoyette   if (n == 4)
    420          1.1  christos     {
    421  1.1.1.1.2.1  pgoyette       md_number_to_chars (buf,     (val & 0xffff0000) >> 16, 2);
    422  1.1.1.1.2.1  pgoyette       md_number_to_chars (buf + 2, (val & 0xffff), 2);
    423  1.1.1.1.2.1  pgoyette     }
    424  1.1.1.1.2.1  pgoyette   else
    425          1.1  christos     {
    426  1.1.1.1.2.1  pgoyette       md_number_to_chars (buf, val, n);
    427  1.1.1.1.2.1  pgoyette     }
    428  1.1.1.1.2.1  pgoyette }
    429          1.1  christos 
    430  1.1.1.1.2.1  pgoyette /* Here ends all the ARCompact extension instruction assembling
    431  1.1.1.1.2.1  pgoyette    stuff.  */
    432          1.1  christos 
    433  1.1.1.1.2.1  pgoyette static void
    434  1.1.1.1.2.1  pgoyette arc_extra_reloc (int r_type)
    435  1.1.1.1.2.1  pgoyette {
    436  1.1.1.1.2.1  pgoyette   char *sym_name, c;
    437  1.1.1.1.2.1  pgoyette   symbolS *sym, *lab = NULL;
    438          1.1  christos 
    439  1.1.1.1.2.1  pgoyette   if (*input_line_pointer == '@')
    440  1.1.1.1.2.1  pgoyette     input_line_pointer++;
    441  1.1.1.1.2.1  pgoyette   c = get_symbol_name (&sym_name);
    442  1.1.1.1.2.1  pgoyette   sym = symbol_find_or_make (sym_name);
    443  1.1.1.1.2.1  pgoyette   restore_line_pointer (c);
    444  1.1.1.1.2.1  pgoyette   if (c == ',' && r_type == BFD_RELOC_ARC_TLS_GD_LD)
    445  1.1.1.1.2.1  pgoyette     {
    446  1.1.1.1.2.1  pgoyette       ++input_line_pointer;
    447  1.1.1.1.2.1  pgoyette       char *lab_name;
    448  1.1.1.1.2.1  pgoyette       c = get_symbol_name (&lab_name);
    449  1.1.1.1.2.1  pgoyette       lab = symbol_find_or_make (lab_name);
    450  1.1.1.1.2.1  pgoyette       restore_line_pointer (c);
    451  1.1.1.1.2.1  pgoyette     }
    452  1.1.1.1.2.1  pgoyette   fixS *fixP
    453  1.1.1.1.2.1  pgoyette     = fix_new (frag_now,	/* Which frag?  */
    454  1.1.1.1.2.1  pgoyette 	       frag_now_fix (),	/* Where in that frag?  */
    455  1.1.1.1.2.1  pgoyette 	       2,		/* size: 1, 2, or 4 usually.  */
    456  1.1.1.1.2.1  pgoyette 	       sym,		/* X_add_symbol.  */
    457  1.1.1.1.2.1  pgoyette 	       0,		/* X_add_number.  */
    458  1.1.1.1.2.1  pgoyette 	       FALSE,		/* TRUE if PC-relative relocation.  */
    459  1.1.1.1.2.1  pgoyette 	       r_type		/* Relocation type.  */);
    460  1.1.1.1.2.1  pgoyette   fixP->fx_subsy = lab;
    461  1.1.1.1.2.1  pgoyette }
    462  1.1.1.1.2.1  pgoyette 
    463  1.1.1.1.2.1  pgoyette static symbolS *
    464  1.1.1.1.2.1  pgoyette arc_lcomm_internal (int ignore ATTRIBUTE_UNUSED,
    465  1.1.1.1.2.1  pgoyette 		    symbolS *symbolP, addressT size)
    466  1.1.1.1.2.1  pgoyette {
    467  1.1.1.1.2.1  pgoyette   addressT align = 0;
    468  1.1.1.1.2.1  pgoyette   SKIP_WHITESPACE ();
    469          1.1  christos 
    470  1.1.1.1.2.1  pgoyette   if (*input_line_pointer == ',')
    471          1.1  christos     {
    472  1.1.1.1.2.1  pgoyette       align = parse_align (1);
    473          1.1  christos 
    474  1.1.1.1.2.1  pgoyette       if (align == (addressT) -1)
    475  1.1.1.1.2.1  pgoyette 	return NULL;
    476          1.1  christos     }
    477          1.1  christos   else
    478  1.1.1.1.2.1  pgoyette     {
    479  1.1.1.1.2.1  pgoyette       if (size >= 8)
    480  1.1.1.1.2.1  pgoyette 	align = 3;
    481  1.1.1.1.2.1  pgoyette       else if (size >= 4)
    482  1.1.1.1.2.1  pgoyette 	align = 2;
    483  1.1.1.1.2.1  pgoyette       else if (size >= 2)
    484  1.1.1.1.2.1  pgoyette 	align = 1;
    485  1.1.1.1.2.1  pgoyette       else
    486  1.1.1.1.2.1  pgoyette 	align = 0;
    487  1.1.1.1.2.1  pgoyette     }
    488          1.1  christos 
    489  1.1.1.1.2.1  pgoyette   bss_alloc (symbolP, size, align);
    490  1.1.1.1.2.1  pgoyette   S_CLEAR_EXTERNAL (symbolP);
    491          1.1  christos 
    492  1.1.1.1.2.1  pgoyette   return symbolP;
    493  1.1.1.1.2.1  pgoyette }
    494          1.1  christos 
    495  1.1.1.1.2.1  pgoyette static void
    496  1.1.1.1.2.1  pgoyette arc_lcomm (int ignore)
    497          1.1  christos {
    498  1.1.1.1.2.1  pgoyette   symbolS *symbolP = s_comm_internal (ignore, arc_lcomm_internal);
    499          1.1  christos 
    500  1.1.1.1.2.1  pgoyette   if (symbolP)
    501  1.1.1.1.2.1  pgoyette     symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
    502  1.1.1.1.2.1  pgoyette }
    503          1.1  christos 
    504  1.1.1.1.2.1  pgoyette /* Select the cpu we're assembling for.  */
    505          1.1  christos 
    506  1.1.1.1.2.1  pgoyette static void
    507  1.1.1.1.2.1  pgoyette arc_option (int ignore ATTRIBUTE_UNUSED)
    508  1.1.1.1.2.1  pgoyette {
    509  1.1.1.1.2.1  pgoyette   int mach = -1;
    510  1.1.1.1.2.1  pgoyette   char c;
    511  1.1.1.1.2.1  pgoyette   char *cpu;
    512          1.1  christos 
    513  1.1.1.1.2.1  pgoyette   c = get_symbol_name (&cpu);
    514  1.1.1.1.2.1  pgoyette   mach = arc_get_mach (cpu);
    515  1.1.1.1.2.1  pgoyette   restore_line_pointer (c);
    516          1.1  christos 
    517  1.1.1.1.2.1  pgoyette   if (mach == -1)
    518  1.1.1.1.2.1  pgoyette     goto bad_cpu;
    519          1.1  christos 
    520  1.1.1.1.2.1  pgoyette   if (!mach_type_specified_p)
    521          1.1  christos     {
    522  1.1.1.1.2.1  pgoyette       arc_mach_type = mach;
    523  1.1.1.1.2.1  pgoyette       if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
    524  1.1.1.1.2.1  pgoyette 	as_fatal ("could not set architecture and machine");
    525          1.1  christos 
    526  1.1.1.1.2.1  pgoyette       mach_type_specified_p = 1;
    527          1.1  christos     }
    528          1.1  christos   else
    529  1.1.1.1.2.1  pgoyette     if (arc_mach_type != mach)
    530  1.1.1.1.2.1  pgoyette       as_warn ("Command-line value overrides \".cpu\" directive");
    531          1.1  christos 
    532  1.1.1.1.2.1  pgoyette   demand_empty_rest_of_line ();
    533  1.1.1.1.2.1  pgoyette 
    534  1.1.1.1.2.1  pgoyette   return;
    535          1.1  christos 
    536  1.1.1.1.2.1  pgoyette  bad_cpu:
    537  1.1.1.1.2.1  pgoyette   as_bad ("invalid identifier for \".cpu\"");
    538  1.1.1.1.2.1  pgoyette   ignore_rest_of_line ();
    539  1.1.1.1.2.1  pgoyette }
    540          1.1  christos 
    541  1.1.1.1.2.1  pgoyette /* Smartly print an expression.  */
    542          1.1  christos 
    543  1.1.1.1.2.1  pgoyette static void
    544  1.1.1.1.2.1  pgoyette debug_exp (expressionS *t)
    545  1.1.1.1.2.1  pgoyette {
    546  1.1.1.1.2.1  pgoyette   const char *name ATTRIBUTE_UNUSED;
    547  1.1.1.1.2.1  pgoyette   const char *namemd ATTRIBUTE_UNUSED;
    548          1.1  christos 
    549  1.1.1.1.2.1  pgoyette   pr_debug ("debug_exp: ");
    550          1.1  christos 
    551  1.1.1.1.2.1  pgoyette   switch (t->X_op)
    552          1.1  christos     {
    553  1.1.1.1.2.1  pgoyette     default:			name = "unknown";		break;
    554  1.1.1.1.2.1  pgoyette     case O_illegal:		name = "O_illegal";		break;
    555  1.1.1.1.2.1  pgoyette     case O_absent:		name = "O_absent";		break;
    556  1.1.1.1.2.1  pgoyette     case O_constant:		name = "O_constant";		break;
    557  1.1.1.1.2.1  pgoyette     case O_symbol:		name = "O_symbol";		break;
    558  1.1.1.1.2.1  pgoyette     case O_symbol_rva:		name = "O_symbol_rva";		break;
    559  1.1.1.1.2.1  pgoyette     case O_register:		name = "O_register";		break;
    560  1.1.1.1.2.1  pgoyette     case O_big:			name = "O_big";			break;
    561  1.1.1.1.2.1  pgoyette     case O_uminus:		name = "O_uminus";		break;
    562  1.1.1.1.2.1  pgoyette     case O_bit_not:		name = "O_bit_not";		break;
    563  1.1.1.1.2.1  pgoyette     case O_logical_not:		name = "O_logical_not";		break;
    564  1.1.1.1.2.1  pgoyette     case O_multiply:		name = "O_multiply";		break;
    565  1.1.1.1.2.1  pgoyette     case O_divide:		name = "O_divide";		break;
    566  1.1.1.1.2.1  pgoyette     case O_modulus:		name = "O_modulus";		break;
    567  1.1.1.1.2.1  pgoyette     case O_left_shift:		name = "O_left_shift";		break;
    568  1.1.1.1.2.1  pgoyette     case O_right_shift:		name = "O_right_shift";		break;
    569  1.1.1.1.2.1  pgoyette     case O_bit_inclusive_or:	name = "O_bit_inclusive_or";	break;
    570  1.1.1.1.2.1  pgoyette     case O_bit_or_not:		name = "O_bit_or_not";		break;
    571  1.1.1.1.2.1  pgoyette     case O_bit_exclusive_or:	name = "O_bit_exclusive_or";	break;
    572  1.1.1.1.2.1  pgoyette     case O_bit_and:		name = "O_bit_and";		break;
    573  1.1.1.1.2.1  pgoyette     case O_add:			name = "O_add";			break;
    574  1.1.1.1.2.1  pgoyette     case O_subtract:		name = "O_subtract";		break;
    575  1.1.1.1.2.1  pgoyette     case O_eq:			name = "O_eq";			break;
    576  1.1.1.1.2.1  pgoyette     case O_ne:			name = "O_ne";			break;
    577  1.1.1.1.2.1  pgoyette     case O_lt:			name = "O_lt";			break;
    578  1.1.1.1.2.1  pgoyette     case O_le:			name = "O_le";			break;
    579  1.1.1.1.2.1  pgoyette     case O_ge:			name = "O_ge";			break;
    580  1.1.1.1.2.1  pgoyette     case O_gt:			name = "O_gt";			break;
    581  1.1.1.1.2.1  pgoyette     case O_logical_and:		name = "O_logical_and";		break;
    582  1.1.1.1.2.1  pgoyette     case O_logical_or:		name = "O_logical_or";		break;
    583  1.1.1.1.2.1  pgoyette     case O_index:		name = "O_index";		break;
    584  1.1.1.1.2.1  pgoyette     case O_bracket:		name = "O_bracket";		break;
    585  1.1.1.1.2.1  pgoyette     }
    586  1.1.1.1.2.1  pgoyette 
    587  1.1.1.1.2.1  pgoyette   switch (t->X_md)
    588  1.1.1.1.2.1  pgoyette     {
    589  1.1.1.1.2.1  pgoyette     default:			namemd = "unknown";		break;
    590  1.1.1.1.2.1  pgoyette     case O_gotoff:		namemd = "O_gotoff";		break;
    591  1.1.1.1.2.1  pgoyette     case O_gotpc:		namemd = "O_gotpc";		break;
    592  1.1.1.1.2.1  pgoyette     case O_plt:			namemd = "O_plt";		break;
    593  1.1.1.1.2.1  pgoyette     case O_sda:			namemd = "O_sda";		break;
    594  1.1.1.1.2.1  pgoyette     case O_pcl:			namemd = "O_pcl";		break;
    595  1.1.1.1.2.1  pgoyette     case O_tlsgd:		namemd = "O_tlsgd";		break;
    596  1.1.1.1.2.1  pgoyette     case O_tlsie:		namemd = "O_tlsie";		break;
    597  1.1.1.1.2.1  pgoyette     case O_tpoff9:		namemd = "O_tpoff9";		break;
    598  1.1.1.1.2.1  pgoyette     case O_tpoff:		namemd = "O_tpoff";		break;
    599  1.1.1.1.2.1  pgoyette     case O_dtpoff9:		namemd = "O_dtpoff9";		break;
    600  1.1.1.1.2.1  pgoyette     case O_dtpoff:		namemd = "O_dtpoff";		break;
    601  1.1.1.1.2.1  pgoyette     }
    602  1.1.1.1.2.1  pgoyette 
    603  1.1.1.1.2.1  pgoyette   pr_debug ("%s (%s, %s, %d, %s)", name,
    604  1.1.1.1.2.1  pgoyette 	    (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
    605  1.1.1.1.2.1  pgoyette 	    (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
    606  1.1.1.1.2.1  pgoyette 	    (int) t->X_add_number,
    607  1.1.1.1.2.1  pgoyette 	    (t->X_md) ? namemd : "--");
    608  1.1.1.1.2.1  pgoyette   pr_debug ("\n");
    609  1.1.1.1.2.1  pgoyette   fflush (stderr);
    610  1.1.1.1.2.1  pgoyette }
    611          1.1  christos 
    612  1.1.1.1.2.1  pgoyette /* Parse the arguments to an opcode.  */
    613          1.1  christos 
    614  1.1.1.1.2.1  pgoyette static int
    615  1.1.1.1.2.1  pgoyette tokenize_arguments (char *str,
    616  1.1.1.1.2.1  pgoyette 		    expressionS *tok,
    617  1.1.1.1.2.1  pgoyette 		    int ntok)
    618  1.1.1.1.2.1  pgoyette {
    619  1.1.1.1.2.1  pgoyette   char *old_input_line_pointer;
    620  1.1.1.1.2.1  pgoyette   bfd_boolean saw_comma = FALSE;
    621  1.1.1.1.2.1  pgoyette   bfd_boolean saw_arg = FALSE;
    622  1.1.1.1.2.1  pgoyette   int brk_lvl = 0;
    623  1.1.1.1.2.1  pgoyette   int num_args = 0;
    624  1.1.1.1.2.1  pgoyette   int i;
    625  1.1.1.1.2.1  pgoyette   size_t len;
    626  1.1.1.1.2.1  pgoyette   const struct arc_reloc_op_tag *r;
    627  1.1.1.1.2.1  pgoyette   expressionS tmpE;
    628  1.1.1.1.2.1  pgoyette   char *reloc_name, c;
    629  1.1.1.1.2.1  pgoyette 
    630  1.1.1.1.2.1  pgoyette   memset (tok, 0, sizeof (*tok) * ntok);
    631  1.1.1.1.2.1  pgoyette 
    632  1.1.1.1.2.1  pgoyette   /* Save and restore input_line_pointer around this function.  */
    633  1.1.1.1.2.1  pgoyette   old_input_line_pointer = input_line_pointer;
    634  1.1.1.1.2.1  pgoyette   input_line_pointer = str;
    635          1.1  christos 
    636  1.1.1.1.2.1  pgoyette   while (*input_line_pointer)
    637          1.1  christos     {
    638          1.1  christos       SKIP_WHITESPACE ();
    639  1.1.1.1.2.1  pgoyette       switch (*input_line_pointer)
    640          1.1  christos 	{
    641  1.1.1.1.2.1  pgoyette 	case '\0':
    642  1.1.1.1.2.1  pgoyette 	  goto fini;
    643          1.1  christos 
    644  1.1.1.1.2.1  pgoyette 	case ',':
    645  1.1.1.1.2.1  pgoyette 	  input_line_pointer++;
    646  1.1.1.1.2.1  pgoyette 	  if (saw_comma || !saw_arg)
    647  1.1.1.1.2.1  pgoyette 	    goto err;
    648  1.1.1.1.2.1  pgoyette 	  saw_comma = TRUE;
    649  1.1.1.1.2.1  pgoyette 	  break;
    650          1.1  christos 
    651  1.1.1.1.2.1  pgoyette 	case '}':
    652  1.1.1.1.2.1  pgoyette 	case ']':
    653  1.1.1.1.2.1  pgoyette 	  ++input_line_pointer;
    654  1.1.1.1.2.1  pgoyette 	  --brk_lvl;
    655  1.1.1.1.2.1  pgoyette 	  if (!saw_arg)
    656  1.1.1.1.2.1  pgoyette 	    goto err;
    657  1.1.1.1.2.1  pgoyette 	  tok->X_op = O_bracket;
    658  1.1.1.1.2.1  pgoyette 	  ++tok;
    659  1.1.1.1.2.1  pgoyette 	  ++num_args;
    660  1.1.1.1.2.1  pgoyette 	  break;
    661  1.1.1.1.2.1  pgoyette 
    662  1.1.1.1.2.1  pgoyette 	case '{':
    663  1.1.1.1.2.1  pgoyette 	case '[':
    664  1.1.1.1.2.1  pgoyette 	  input_line_pointer++;
    665  1.1.1.1.2.1  pgoyette 	  if (brk_lvl)
    666  1.1.1.1.2.1  pgoyette 	    goto err;
    667  1.1.1.1.2.1  pgoyette 	  ++brk_lvl;
    668  1.1.1.1.2.1  pgoyette 	  tok->X_op = O_bracket;
    669  1.1.1.1.2.1  pgoyette 	  ++tok;
    670  1.1.1.1.2.1  pgoyette 	  ++num_args;
    671  1.1.1.1.2.1  pgoyette 	  break;
    672  1.1.1.1.2.1  pgoyette 
    673  1.1.1.1.2.1  pgoyette 	case '@':
    674  1.1.1.1.2.1  pgoyette 	  /* We have labels, function names and relocations, all
    675  1.1.1.1.2.1  pgoyette 	     starting with @ symbol.  Sort them out.  */
    676  1.1.1.1.2.1  pgoyette 	  if (saw_arg && !saw_comma)
    677  1.1.1.1.2.1  pgoyette 	    goto err;
    678  1.1.1.1.2.1  pgoyette 
    679  1.1.1.1.2.1  pgoyette 	  /* Parse @label.  */
    680  1.1.1.1.2.1  pgoyette 	  tok->X_op = O_symbol;
    681  1.1.1.1.2.1  pgoyette 	  tok->X_md = O_absent;
    682  1.1.1.1.2.1  pgoyette 	  expression (tok);
    683  1.1.1.1.2.1  pgoyette 	  if (*input_line_pointer != '@')
    684  1.1.1.1.2.1  pgoyette 	    goto normalsymbol; /* This is not a relocation.  */
    685  1.1.1.1.2.1  pgoyette 
    686  1.1.1.1.2.1  pgoyette 	relocationsym:
    687  1.1.1.1.2.1  pgoyette 
    688  1.1.1.1.2.1  pgoyette 	  /* A relocation opernad has the following form
    689  1.1.1.1.2.1  pgoyette 	     @identifier@relocation_type.  The identifier is already
    690  1.1.1.1.2.1  pgoyette 	     in tok!  */
    691  1.1.1.1.2.1  pgoyette 	  if (tok->X_op != O_symbol)
    692          1.1  christos 	    {
    693  1.1.1.1.2.1  pgoyette 	      as_bad (_("No valid label relocation operand"));
    694  1.1.1.1.2.1  pgoyette 	      goto err;
    695          1.1  christos 	    }
    696  1.1.1.1.2.1  pgoyette 
    697  1.1.1.1.2.1  pgoyette 	  /* Parse @relocation_type.  */
    698  1.1.1.1.2.1  pgoyette 	  input_line_pointer++;
    699  1.1.1.1.2.1  pgoyette 	  c = get_symbol_name (&reloc_name);
    700  1.1.1.1.2.1  pgoyette 	  len = input_line_pointer - reloc_name;
    701  1.1.1.1.2.1  pgoyette 	  if (len == 0)
    702          1.1  christos 	    {
    703  1.1.1.1.2.1  pgoyette 	      as_bad (_("No relocation operand"));
    704  1.1.1.1.2.1  pgoyette 	      goto err;
    705          1.1  christos 	    }
    706  1.1.1.1.2.1  pgoyette 
    707  1.1.1.1.2.1  pgoyette 	  /* Go through known relocation and try to find a match.  */
    708  1.1.1.1.2.1  pgoyette 	  r = &arc_reloc_op[0];
    709  1.1.1.1.2.1  pgoyette 	  for (i = arc_num_reloc_op - 1; i >= 0; i--, r++)
    710  1.1.1.1.2.1  pgoyette 	    if (len == r->length
    711  1.1.1.1.2.1  pgoyette 		&& memcmp (reloc_name, r->name, len) == 0)
    712  1.1.1.1.2.1  pgoyette 	      break;
    713  1.1.1.1.2.1  pgoyette 	  if (i < 0)
    714          1.1  christos 	    {
    715  1.1.1.1.2.1  pgoyette 	      as_bad (_("Unknown relocation operand: @%s"), reloc_name);
    716  1.1.1.1.2.1  pgoyette 	      goto err;
    717          1.1  christos 	    }
    718          1.1  christos 
    719  1.1.1.1.2.1  pgoyette 	  *input_line_pointer = c;
    720  1.1.1.1.2.1  pgoyette 	  SKIP_WHITESPACE_AFTER_NAME ();
    721  1.1.1.1.2.1  pgoyette 	  /* Extra check for TLS: base.  */
    722  1.1.1.1.2.1  pgoyette 	  if (*input_line_pointer == '@')
    723          1.1  christos 	    {
    724  1.1.1.1.2.1  pgoyette 	      symbolS *base;
    725  1.1.1.1.2.1  pgoyette 	      if (tok->X_op_symbol != NULL
    726  1.1.1.1.2.1  pgoyette 		  || tok->X_op != O_symbol)
    727  1.1.1.1.2.1  pgoyette 		{
    728  1.1.1.1.2.1  pgoyette 		  as_bad (_("Unable to parse TLS base: %s"),
    729  1.1.1.1.2.1  pgoyette 			  input_line_pointer);
    730  1.1.1.1.2.1  pgoyette 		  goto err;
    731  1.1.1.1.2.1  pgoyette 		}
    732  1.1.1.1.2.1  pgoyette 	      input_line_pointer++;
    733  1.1.1.1.2.1  pgoyette 	      char *sym_name;
    734  1.1.1.1.2.1  pgoyette 	      c = get_symbol_name (&sym_name);
    735  1.1.1.1.2.1  pgoyette 	      base = symbol_find_or_make (sym_name);
    736  1.1.1.1.2.1  pgoyette 	      tok->X_op = O_subtract;
    737  1.1.1.1.2.1  pgoyette 	      tok->X_op_symbol = base;
    738  1.1.1.1.2.1  pgoyette 	      restore_line_pointer (c);
    739  1.1.1.1.2.1  pgoyette 	      tmpE.X_add_number = 0;
    740  1.1.1.1.2.1  pgoyette 	    }
    741  1.1.1.1.2.1  pgoyette 	  else if ((*input_line_pointer != '+')
    742  1.1.1.1.2.1  pgoyette 		   && (*input_line_pointer != '-'))
    743  1.1.1.1.2.1  pgoyette 	    {
    744  1.1.1.1.2.1  pgoyette 	      tmpE.X_add_number = 0;
    745          1.1  christos 	    }
    746          1.1  christos 	  else
    747          1.1  christos 	    {
    748  1.1.1.1.2.1  pgoyette 	      /* Parse the constant of a complex relocation expression
    749  1.1.1.1.2.1  pgoyette 		 like @identifier@reloc +/- const.  */
    750  1.1.1.1.2.1  pgoyette 	      if (! r->complex_expr)
    751          1.1  christos 		{
    752  1.1.1.1.2.1  pgoyette 		  as_bad (_("@%s is not a complex relocation."), r->name);
    753  1.1.1.1.2.1  pgoyette 		  goto err;
    754          1.1  christos 		}
    755  1.1.1.1.2.1  pgoyette 	      expression (&tmpE);
    756  1.1.1.1.2.1  pgoyette 	      if (tmpE.X_op != O_constant)
    757          1.1  christos 		{
    758  1.1.1.1.2.1  pgoyette 		  as_bad (_("Bad expression: @%s + %s."),
    759  1.1.1.1.2.1  pgoyette 			  r->name, input_line_pointer);
    760  1.1.1.1.2.1  pgoyette 		  goto err;
    761          1.1  christos 		}
    762          1.1  christos 	    }
    763          1.1  christos 
    764  1.1.1.1.2.1  pgoyette 	  tok->X_md = r->op;
    765  1.1.1.1.2.1  pgoyette 	  tok->X_add_number = tmpE.X_add_number;
    766          1.1  christos 
    767  1.1.1.1.2.1  pgoyette 	  debug_exp (tok);
    768          1.1  christos 
    769  1.1.1.1.2.1  pgoyette 	  saw_comma = FALSE;
    770  1.1.1.1.2.1  pgoyette 	  saw_arg = TRUE;
    771  1.1.1.1.2.1  pgoyette 	  tok++;
    772  1.1.1.1.2.1  pgoyette 	  num_args++;
    773  1.1.1.1.2.1  pgoyette 	  break;
    774          1.1  christos 
    775  1.1.1.1.2.1  pgoyette 	case '%':
    776  1.1.1.1.2.1  pgoyette 	  /* Can be a register.  */
    777  1.1.1.1.2.1  pgoyette 	  ++input_line_pointer;
    778  1.1.1.1.2.1  pgoyette 	  /* Fall through.  */
    779  1.1.1.1.2.1  pgoyette 	default:
    780  1.1.1.1.2.1  pgoyette 
    781  1.1.1.1.2.1  pgoyette 	  if (saw_arg && !saw_comma)
    782  1.1.1.1.2.1  pgoyette 	    goto err;
    783  1.1.1.1.2.1  pgoyette 
    784  1.1.1.1.2.1  pgoyette 	  tok->X_op = O_absent;
    785  1.1.1.1.2.1  pgoyette 	  tok->X_md = O_absent;
    786  1.1.1.1.2.1  pgoyette 	  expression (tok);
    787  1.1.1.1.2.1  pgoyette 
    788  1.1.1.1.2.1  pgoyette 	  /* Legacy: There are cases when we have
    789  1.1.1.1.2.1  pgoyette 	     identifier@relocation_type, if it is the case parse the
    790  1.1.1.1.2.1  pgoyette 	     relocation type as well.  */
    791  1.1.1.1.2.1  pgoyette 	  if (*input_line_pointer == '@')
    792  1.1.1.1.2.1  pgoyette 	    goto relocationsym;
    793  1.1.1.1.2.1  pgoyette 
    794  1.1.1.1.2.1  pgoyette 	normalsymbol:
    795  1.1.1.1.2.1  pgoyette 	  debug_exp (tok);
    796  1.1.1.1.2.1  pgoyette 
    797  1.1.1.1.2.1  pgoyette 	  if (tok->X_op == O_illegal || tok->X_op == O_absent)
    798  1.1.1.1.2.1  pgoyette 	    goto err;
    799  1.1.1.1.2.1  pgoyette 
    800  1.1.1.1.2.1  pgoyette 	  saw_comma = FALSE;
    801  1.1.1.1.2.1  pgoyette 	  saw_arg = TRUE;
    802  1.1.1.1.2.1  pgoyette 	  tok++;
    803  1.1.1.1.2.1  pgoyette 	  num_args++;
    804  1.1.1.1.2.1  pgoyette 	  break;
    805          1.1  christos 	}
    806          1.1  christos     }
    807          1.1  christos 
    808  1.1.1.1.2.1  pgoyette  fini:
    809  1.1.1.1.2.1  pgoyette   if (saw_comma || brk_lvl)
    810  1.1.1.1.2.1  pgoyette     goto err;
    811  1.1.1.1.2.1  pgoyette   input_line_pointer = old_input_line_pointer;
    812  1.1.1.1.2.1  pgoyette 
    813  1.1.1.1.2.1  pgoyette   return num_args;
    814  1.1.1.1.2.1  pgoyette 
    815  1.1.1.1.2.1  pgoyette  err:
    816  1.1.1.1.2.1  pgoyette   if (brk_lvl)
    817  1.1.1.1.2.1  pgoyette     as_bad (_("Brackets in operand field incorrect"));
    818  1.1.1.1.2.1  pgoyette   else if (saw_comma)
    819  1.1.1.1.2.1  pgoyette     as_bad (_("extra comma"));
    820  1.1.1.1.2.1  pgoyette   else if (!saw_arg)
    821  1.1.1.1.2.1  pgoyette     as_bad (_("missing argument"));
    822  1.1.1.1.2.1  pgoyette   else
    823  1.1.1.1.2.1  pgoyette     as_bad (_("missing comma or colon"));
    824  1.1.1.1.2.1  pgoyette   input_line_pointer = old_input_line_pointer;
    825  1.1.1.1.2.1  pgoyette   return -1;
    826  1.1.1.1.2.1  pgoyette }
    827          1.1  christos 
    828  1.1.1.1.2.1  pgoyette /* Parse the flags to a structure.  */
    829          1.1  christos 
    830  1.1.1.1.2.1  pgoyette static int
    831  1.1.1.1.2.1  pgoyette tokenize_flags (const char *str,
    832  1.1.1.1.2.1  pgoyette 		struct arc_flags flags[],
    833  1.1.1.1.2.1  pgoyette 		int nflg)
    834  1.1.1.1.2.1  pgoyette {
    835  1.1.1.1.2.1  pgoyette   char *old_input_line_pointer;
    836  1.1.1.1.2.1  pgoyette   bfd_boolean saw_flg = FALSE;
    837  1.1.1.1.2.1  pgoyette   bfd_boolean saw_dot = FALSE;
    838  1.1.1.1.2.1  pgoyette   int num_flags  = 0;
    839  1.1.1.1.2.1  pgoyette   size_t flgnamelen;
    840  1.1.1.1.2.1  pgoyette 
    841  1.1.1.1.2.1  pgoyette   memset (flags, 0, sizeof (*flags) * nflg);
    842  1.1.1.1.2.1  pgoyette 
    843  1.1.1.1.2.1  pgoyette   /* Save and restore input_line_pointer around this function.  */
    844  1.1.1.1.2.1  pgoyette   old_input_line_pointer = input_line_pointer;
    845  1.1.1.1.2.1  pgoyette   input_line_pointer = (char *) str;
    846  1.1.1.1.2.1  pgoyette 
    847  1.1.1.1.2.1  pgoyette   while (*input_line_pointer)
    848  1.1.1.1.2.1  pgoyette     {
    849  1.1.1.1.2.1  pgoyette       switch (*input_line_pointer)
    850  1.1.1.1.2.1  pgoyette 	{
    851  1.1.1.1.2.1  pgoyette 	case ' ':
    852  1.1.1.1.2.1  pgoyette 	case '\0':
    853  1.1.1.1.2.1  pgoyette 	  goto fini;
    854  1.1.1.1.2.1  pgoyette 
    855  1.1.1.1.2.1  pgoyette 	case '.':
    856  1.1.1.1.2.1  pgoyette 	  input_line_pointer++;
    857  1.1.1.1.2.1  pgoyette 	  if (saw_dot)
    858  1.1.1.1.2.1  pgoyette 	    goto err;
    859  1.1.1.1.2.1  pgoyette 	  saw_dot = TRUE;
    860  1.1.1.1.2.1  pgoyette 	  saw_flg = FALSE;
    861  1.1.1.1.2.1  pgoyette 	  break;
    862          1.1  christos 
    863  1.1.1.1.2.1  pgoyette 	default:
    864  1.1.1.1.2.1  pgoyette 	  if (saw_flg && !saw_dot)
    865  1.1.1.1.2.1  pgoyette 	    goto err;
    866          1.1  christos 
    867  1.1.1.1.2.1  pgoyette 	  if (num_flags >= nflg)
    868  1.1.1.1.2.1  pgoyette 	    goto err;
    869          1.1  christos 
    870  1.1.1.1.2.1  pgoyette 	  flgnamelen = strspn (input_line_pointer, "abcdefghilmnopqrstvwxz");
    871  1.1.1.1.2.1  pgoyette 	  if (flgnamelen > MAX_FLAG_NAME_LENGHT)
    872  1.1.1.1.2.1  pgoyette 	    goto err;
    873  1.1.1.1.2.1  pgoyette 
    874  1.1.1.1.2.1  pgoyette 	  memcpy (flags->name, input_line_pointer, flgnamelen);
    875  1.1.1.1.2.1  pgoyette 
    876  1.1.1.1.2.1  pgoyette 	  input_line_pointer += flgnamelen;
    877  1.1.1.1.2.1  pgoyette 	  flags++;
    878  1.1.1.1.2.1  pgoyette 	  saw_dot = FALSE;
    879  1.1.1.1.2.1  pgoyette 	  saw_flg = TRUE;
    880  1.1.1.1.2.1  pgoyette 	  num_flags++;
    881  1.1.1.1.2.1  pgoyette 	  break;
    882  1.1.1.1.2.1  pgoyette 	}
    883          1.1  christos     }
    884          1.1  christos 
    885  1.1.1.1.2.1  pgoyette  fini:
    886  1.1.1.1.2.1  pgoyette   input_line_pointer = old_input_line_pointer;
    887  1.1.1.1.2.1  pgoyette   return num_flags;
    888  1.1.1.1.2.1  pgoyette 
    889  1.1.1.1.2.1  pgoyette  err:
    890  1.1.1.1.2.1  pgoyette   if (saw_dot)
    891  1.1.1.1.2.1  pgoyette     as_bad (_("extra dot"));
    892  1.1.1.1.2.1  pgoyette   else if (!saw_flg)
    893  1.1.1.1.2.1  pgoyette     as_bad (_("unrecognized flag"));
    894  1.1.1.1.2.1  pgoyette   else
    895  1.1.1.1.2.1  pgoyette     as_bad (_("failed to parse flags"));
    896  1.1.1.1.2.1  pgoyette   input_line_pointer = old_input_line_pointer;
    897  1.1.1.1.2.1  pgoyette   return -1;
    898          1.1  christos }
    899          1.1  christos 
    900  1.1.1.1.2.1  pgoyette /* The public interface to the instruction assembler.  */
    901  1.1.1.1.2.1  pgoyette 
    902  1.1.1.1.2.1  pgoyette void
    903  1.1.1.1.2.1  pgoyette md_assemble (char *str)
    904          1.1  christos {
    905  1.1.1.1.2.1  pgoyette   char *opname;
    906  1.1.1.1.2.1  pgoyette   expressionS tok[MAX_INSN_ARGS];
    907  1.1.1.1.2.1  pgoyette   int ntok, nflg;
    908  1.1.1.1.2.1  pgoyette   size_t opnamelen;
    909  1.1.1.1.2.1  pgoyette   struct arc_flags flags[MAX_INSN_FLGS];
    910  1.1.1.1.2.1  pgoyette 
    911  1.1.1.1.2.1  pgoyette   /* Split off the opcode.  */
    912  1.1.1.1.2.1  pgoyette   opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_0123468");
    913  1.1.1.1.2.1  pgoyette   opname = xmalloc (opnamelen + 1);
    914  1.1.1.1.2.1  pgoyette   memcpy (opname, str, opnamelen);
    915  1.1.1.1.2.1  pgoyette   opname[opnamelen] = '\0';
    916          1.1  christos 
    917  1.1.1.1.2.1  pgoyette   /* Signalize we are assmbling the instructions.  */
    918  1.1.1.1.2.1  pgoyette   assembling_insn = TRUE;
    919          1.1  christos 
    920  1.1.1.1.2.1  pgoyette   /* Tokenize the flags.  */
    921  1.1.1.1.2.1  pgoyette   if ((nflg = tokenize_flags (str + opnamelen, flags, MAX_INSN_FLGS)) == -1)
    922          1.1  christos     {
    923  1.1.1.1.2.1  pgoyette       as_bad (_("syntax error"));
    924          1.1  christos       return;
    925          1.1  christos     }
    926          1.1  christos 
    927  1.1.1.1.2.1  pgoyette   /* Scan up to the end of the mnemonic which must end in space or end
    928  1.1.1.1.2.1  pgoyette      of string.  */
    929  1.1.1.1.2.1  pgoyette   str += opnamelen;
    930  1.1.1.1.2.1  pgoyette   for (; *str != '\0'; str++)
    931  1.1.1.1.2.1  pgoyette     if (*str == ' ')
    932  1.1.1.1.2.1  pgoyette       break;
    933          1.1  christos 
    934  1.1.1.1.2.1  pgoyette   /* Tokenize the rest of the line.  */
    935  1.1.1.1.2.1  pgoyette   if ((ntok = tokenize_arguments (str, tok, MAX_INSN_ARGS)) < 0)
    936          1.1  christos     {
    937  1.1.1.1.2.1  pgoyette       as_bad (_("syntax error"));
    938          1.1  christos       return;
    939          1.1  christos     }
    940          1.1  christos 
    941  1.1.1.1.2.1  pgoyette   /* Finish it off.  */
    942  1.1.1.1.2.1  pgoyette   assemble_tokens (opname, tok, ntok, flags, nflg);
    943  1.1.1.1.2.1  pgoyette   assembling_insn = FALSE;
    944  1.1.1.1.2.1  pgoyette }
    945          1.1  christos 
    946  1.1.1.1.2.1  pgoyette /* Callback to insert a register into the hash table.  */
    947          1.1  christos 
    948          1.1  christos static void
    949  1.1.1.1.2.1  pgoyette declare_register (char *name, int number)
    950          1.1  christos {
    951  1.1.1.1.2.1  pgoyette   const char *err;
    952  1.1.1.1.2.1  pgoyette   symbolS *regS = symbol_create (name, reg_section,
    953  1.1.1.1.2.1  pgoyette 				 number, &zero_address_frag);
    954          1.1  christos 
    955  1.1.1.1.2.1  pgoyette   err = hash_insert (arc_reg_hash, S_GET_NAME (regS), (void *) regS);
    956  1.1.1.1.2.1  pgoyette   if (err)
    957  1.1.1.1.2.1  pgoyette     as_fatal ("Inserting \"%s\" into register table failed: %s",
    958  1.1.1.1.2.1  pgoyette 	      name, err);
    959  1.1.1.1.2.1  pgoyette }
    960          1.1  christos 
    961  1.1.1.1.2.1  pgoyette /* Construct symbols for each of the general registers.  */
    962          1.1  christos 
    963  1.1.1.1.2.1  pgoyette static void
    964  1.1.1.1.2.1  pgoyette declare_register_set (void)
    965  1.1.1.1.2.1  pgoyette {
    966  1.1.1.1.2.1  pgoyette   int i;
    967  1.1.1.1.2.1  pgoyette   for (i = 0; i < 32; ++i)
    968          1.1  christos     {
    969  1.1.1.1.2.1  pgoyette       char name[7];
    970          1.1  christos 
    971  1.1.1.1.2.1  pgoyette       sprintf (name, "r%d", i);
    972  1.1.1.1.2.1  pgoyette       declare_register (name, i);
    973  1.1.1.1.2.1  pgoyette       if ((i & 0x01) == 0)
    974          1.1  christos 	{
    975  1.1.1.1.2.1  pgoyette 	  sprintf (name, "r%dr%d", i, i+1);
    976  1.1.1.1.2.1  pgoyette 	  declare_register (name, i);
    977          1.1  christos 	}
    978          1.1  christos     }
    979  1.1.1.1.2.1  pgoyette }
    980          1.1  christos 
    981  1.1.1.1.2.1  pgoyette /* Port-specific assembler initialization.  This function is called
    982  1.1.1.1.2.1  pgoyette    once, at assembler startup time.  */
    983          1.1  christos 
    984  1.1.1.1.2.1  pgoyette void
    985  1.1.1.1.2.1  pgoyette md_begin (void)
    986  1.1.1.1.2.1  pgoyette {
    987  1.1.1.1.2.1  pgoyette   unsigned int i;
    988          1.1  christos 
    989  1.1.1.1.2.1  pgoyette   /* The endianness can be chosen "at the factory".  */
    990  1.1.1.1.2.1  pgoyette   target_big_endian = byte_order == BIG_ENDIAN;
    991          1.1  christos 
    992  1.1.1.1.2.1  pgoyette   if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, arc_mach_type))
    993  1.1.1.1.2.1  pgoyette     as_warn (_("could not set architecture and machine"));
    994          1.1  christos 
    995  1.1.1.1.2.1  pgoyette   /* Set elf header flags.  */
    996  1.1.1.1.2.1  pgoyette   bfd_set_private_flags (stdoutput, arc_eflag);
    997          1.1  christos 
    998  1.1.1.1.2.1  pgoyette   /* Set up a hash table for the instructions.  */
    999  1.1.1.1.2.1  pgoyette   arc_opcode_hash = hash_new ();
   1000  1.1.1.1.2.1  pgoyette   if (arc_opcode_hash == NULL)
   1001  1.1.1.1.2.1  pgoyette     as_fatal (_("Virtual memory exhausted"));
   1002  1.1.1.1.2.1  pgoyette 
   1003  1.1.1.1.2.1  pgoyette   /* Initialize the hash table with the insns.  */
   1004  1.1.1.1.2.1  pgoyette   for (i = 0; i < arc_num_opcodes;)
   1005  1.1.1.1.2.1  pgoyette     {
   1006  1.1.1.1.2.1  pgoyette       const char *name, *retval;
   1007  1.1.1.1.2.1  pgoyette 
   1008  1.1.1.1.2.1  pgoyette       name = arc_opcodes[i].name;
   1009  1.1.1.1.2.1  pgoyette       retval = hash_insert (arc_opcode_hash, name, (void *) &arc_opcodes[i]);
   1010  1.1.1.1.2.1  pgoyette       if (retval)
   1011  1.1.1.1.2.1  pgoyette 	as_fatal (_("internal error: can't hash opcode '%s': %s"),
   1012  1.1.1.1.2.1  pgoyette 		  name, retval);
   1013  1.1.1.1.2.1  pgoyette 
   1014  1.1.1.1.2.1  pgoyette       while (++i < arc_num_opcodes
   1015  1.1.1.1.2.1  pgoyette 	     && (arc_opcodes[i].name == name
   1016  1.1.1.1.2.1  pgoyette 		 || !strcmp (arc_opcodes[i].name, name)))
   1017  1.1.1.1.2.1  pgoyette 	continue;
   1018          1.1  christos     }
   1019          1.1  christos 
   1020  1.1.1.1.2.1  pgoyette   /* Register declaration.  */
   1021  1.1.1.1.2.1  pgoyette   arc_reg_hash = hash_new ();
   1022  1.1.1.1.2.1  pgoyette   if (arc_reg_hash == NULL)
   1023  1.1.1.1.2.1  pgoyette     as_fatal (_("Virtual memory exhausted"));
   1024  1.1.1.1.2.1  pgoyette 
   1025  1.1.1.1.2.1  pgoyette   declare_register_set ();
   1026  1.1.1.1.2.1  pgoyette   declare_register ("gp", 26);
   1027  1.1.1.1.2.1  pgoyette   declare_register ("fp", 27);
   1028  1.1.1.1.2.1  pgoyette   declare_register ("sp", 28);
   1029  1.1.1.1.2.1  pgoyette   declare_register ("ilink", 29);
   1030  1.1.1.1.2.1  pgoyette   declare_register ("ilink1", 29);
   1031  1.1.1.1.2.1  pgoyette   declare_register ("ilink2", 30);
   1032  1.1.1.1.2.1  pgoyette   declare_register ("blink", 31);
   1033  1.1.1.1.2.1  pgoyette 
   1034  1.1.1.1.2.1  pgoyette   declare_register ("mlo", 57);
   1035  1.1.1.1.2.1  pgoyette   declare_register ("mmid", 58);
   1036  1.1.1.1.2.1  pgoyette   declare_register ("mhi", 59);
   1037          1.1  christos 
   1038  1.1.1.1.2.1  pgoyette   declare_register ("acc1", 56);
   1039  1.1.1.1.2.1  pgoyette   declare_register ("acc2", 57);
   1040          1.1  christos 
   1041  1.1.1.1.2.1  pgoyette   declare_register ("lp_count", 60);
   1042  1.1.1.1.2.1  pgoyette   declare_register ("pcl", 63);
   1043  1.1.1.1.2.1  pgoyette 
   1044  1.1.1.1.2.1  pgoyette   /* Initialize the last instructions.  */
   1045  1.1.1.1.2.1  pgoyette   memset (&arc_last_insns[0], 0, sizeof (arc_last_insns));
   1046          1.1  christos }
   1047          1.1  christos 
   1048          1.1  christos /* Write a value out to the object file, using the appropriate
   1049          1.1  christos    endianness.  */
   1050          1.1  christos 
   1051          1.1  christos void
   1052  1.1.1.1.2.1  pgoyette md_number_to_chars (char *buf,
   1053  1.1.1.1.2.1  pgoyette 		    valueT val,
   1054  1.1.1.1.2.1  pgoyette 		    int n)
   1055          1.1  christos {
   1056          1.1  christos   if (target_big_endian)
   1057          1.1  christos     number_to_chars_bigendian (buf, val, n);
   1058          1.1  christos   else
   1059          1.1  christos     number_to_chars_littleendian (buf, val, n);
   1060          1.1  christos }
   1061          1.1  christos 
   1062          1.1  christos /* Round up a section size to the appropriate boundary.  */
   1063          1.1  christos 
   1064          1.1  christos valueT
   1065  1.1.1.1.2.1  pgoyette md_section_align (segT segment,
   1066  1.1.1.1.2.1  pgoyette 		  valueT size)
   1067          1.1  christos {
   1068          1.1  christos   int align = bfd_get_section_alignment (stdoutput, segment);
   1069          1.1  christos 
   1070  1.1.1.1.2.1  pgoyette   return ((size + (1 << align) - 1) & -(1 << align));
   1071          1.1  christos }
   1072          1.1  christos 
   1073  1.1.1.1.2.1  pgoyette /* The location from which a PC relative jump should be calculated,
   1074  1.1.1.1.2.1  pgoyette    given a PC relative reloc.  */
   1075          1.1  christos 
   1076  1.1.1.1.2.1  pgoyette long
   1077  1.1.1.1.2.1  pgoyette md_pcrel_from_section (fixS *fixP,
   1078  1.1.1.1.2.1  pgoyette 		       segT sec)
   1079          1.1  christos {
   1080  1.1.1.1.2.1  pgoyette   offsetT base = fixP->fx_where + fixP->fx_frag->fr_address;
   1081          1.1  christos 
   1082  1.1.1.1.2.1  pgoyette   pr_debug ("pcrel_from_section, fx_offset = %d\n", (int) fixP->fx_offset);
   1083          1.1  christos 
   1084  1.1.1.1.2.1  pgoyette   if (fixP->fx_addsy != (symbolS *) NULL
   1085  1.1.1.1.2.1  pgoyette       && (!S_IS_DEFINED (fixP->fx_addsy)
   1086  1.1.1.1.2.1  pgoyette 	  || S_GET_SEGMENT (fixP->fx_addsy) != sec))
   1087          1.1  christos     {
   1088  1.1.1.1.2.1  pgoyette       pr_debug ("Unknown pcrel symbol: %s\n", S_GET_NAME (fixP->fx_addsy));
   1089          1.1  christos 
   1090  1.1.1.1.2.1  pgoyette       /* The symbol is undefined (or is defined but not in this section).
   1091  1.1.1.1.2.1  pgoyette 	 Let the linker figure it out.  */
   1092  1.1.1.1.2.1  pgoyette       return 0;
   1093          1.1  christos     }
   1094          1.1  christos 
   1095  1.1.1.1.2.1  pgoyette   if ((int) fixP->fx_r_type < 0)
   1096          1.1  christos     {
   1097  1.1.1.1.2.1  pgoyette       /* These are the "internal" relocations.  Align them to
   1098  1.1.1.1.2.1  pgoyette 	 32 bit boundary (PCL), for the moment.  */
   1099  1.1.1.1.2.1  pgoyette       base &= ~3;
   1100          1.1  christos     }
   1101          1.1  christos   else
   1102          1.1  christos     {
   1103  1.1.1.1.2.1  pgoyette       switch (fixP->fx_r_type)
   1104          1.1  christos 	{
   1105  1.1.1.1.2.1  pgoyette 	case BFD_RELOC_ARC_PC32:
   1106  1.1.1.1.2.1  pgoyette 	  /* The hardware calculates relative to the start of the
   1107  1.1.1.1.2.1  pgoyette 	     insn, but this relocation is relative to location of the
   1108  1.1.1.1.2.1  pgoyette 	     LIMM, compensate.  TIP: the base always needs to be
   1109  1.1.1.1.2.1  pgoyette 	     substracted by 4 as we do not support this type of PCrel
   1110  1.1.1.1.2.1  pgoyette 	     relocation for short instructions.  */
   1111  1.1.1.1.2.1  pgoyette 	  base -= fixP->fx_where - fixP->fx_dot_value;
   1112  1.1.1.1.2.1  pgoyette 	  gas_assert ((fixP->fx_where - fixP->fx_dot_value) == 4);
   1113  1.1.1.1.2.1  pgoyette 	  /* Fall through.  */
   1114  1.1.1.1.2.1  pgoyette 	case BFD_RELOC_ARC_PLT32:
   1115  1.1.1.1.2.1  pgoyette 	case BFD_RELOC_ARC_S25H_PCREL_PLT:
   1116  1.1.1.1.2.1  pgoyette 	case BFD_RELOC_ARC_S21H_PCREL_PLT:
   1117  1.1.1.1.2.1  pgoyette 	case BFD_RELOC_ARC_S25W_PCREL_PLT:
   1118  1.1.1.1.2.1  pgoyette 	case BFD_RELOC_ARC_S21W_PCREL_PLT:
   1119  1.1.1.1.2.1  pgoyette 
   1120  1.1.1.1.2.1  pgoyette 	case BFD_RELOC_ARC_S21H_PCREL:
   1121  1.1.1.1.2.1  pgoyette 	case BFD_RELOC_ARC_S25H_PCREL:
   1122  1.1.1.1.2.1  pgoyette 	case BFD_RELOC_ARC_S13_PCREL:
   1123  1.1.1.1.2.1  pgoyette 	case BFD_RELOC_ARC_S21W_PCREL:
   1124  1.1.1.1.2.1  pgoyette 	case BFD_RELOC_ARC_S25W_PCREL:
   1125  1.1.1.1.2.1  pgoyette 	  base &= ~3;
   1126  1.1.1.1.2.1  pgoyette 	  break;
   1127  1.1.1.1.2.1  pgoyette 	default:
   1128  1.1.1.1.2.1  pgoyette 	  as_bad_where (fixP->fx_file, fixP->fx_line,
   1129  1.1.1.1.2.1  pgoyette 			_("unhandled reloc %s in md_pcrel_from_section"),
   1130  1.1.1.1.2.1  pgoyette 		  bfd_get_reloc_code_name (fixP->fx_r_type));
   1131  1.1.1.1.2.1  pgoyette 	  break;
   1132          1.1  christos 	}
   1133          1.1  christos     }
   1134          1.1  christos 
   1135  1.1.1.1.2.1  pgoyette   pr_debug ("pcrel from %x + %lx = %x, symbol: %s (%x)\n",
   1136  1.1.1.1.2.1  pgoyette 	    fixP->fx_frag->fr_address, fixP->fx_where, base,
   1137  1.1.1.1.2.1  pgoyette 	    fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "(null)",
   1138  1.1.1.1.2.1  pgoyette 	    fixP->fx_addsy ? S_GET_VALUE (fixP->fx_addsy) : 0);
   1139          1.1  christos 
   1140  1.1.1.1.2.1  pgoyette   return base;
   1141          1.1  christos }
   1142          1.1  christos 
   1143  1.1.1.1.2.1  pgoyette /* Given a BFD relocation find the coresponding operand.  */
   1144          1.1  christos 
   1145  1.1.1.1.2.1  pgoyette static const struct arc_operand *
   1146  1.1.1.1.2.1  pgoyette find_operand_for_reloc (extended_bfd_reloc_code_real_type reloc)
   1147          1.1  christos {
   1148  1.1.1.1.2.1  pgoyette   unsigned i;
   1149          1.1  christos 
   1150  1.1.1.1.2.1  pgoyette   for (i = 0; i < arc_num_operands; i++)
   1151  1.1.1.1.2.1  pgoyette     if (arc_operands[i].default_reloc == reloc)
   1152  1.1.1.1.2.1  pgoyette       return  &arc_operands[i];
   1153  1.1.1.1.2.1  pgoyette   return NULL;
   1154          1.1  christos }
   1155          1.1  christos 
   1156  1.1.1.1.2.1  pgoyette /* Apply a fixup to the object code.  At this point all symbol values
   1157  1.1.1.1.2.1  pgoyette    should be fully resolved, and we attempt to completely resolve the
   1158  1.1.1.1.2.1  pgoyette    reloc.  If we can not do that, we determine the correct reloc code
   1159  1.1.1.1.2.1  pgoyette    and put it back in the fixup.  To indicate that a fixup has been
   1160  1.1.1.1.2.1  pgoyette    eliminated, set fixP->fx_done.  */
   1161          1.1  christos 
   1162          1.1  christos void
   1163  1.1.1.1.2.1  pgoyette md_apply_fix (fixS *fixP,
   1164  1.1.1.1.2.1  pgoyette 	      valueT *valP,
   1165  1.1.1.1.2.1  pgoyette 	      segT seg)
   1166  1.1.1.1.2.1  pgoyette {
   1167  1.1.1.1.2.1  pgoyette   char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
   1168  1.1.1.1.2.1  pgoyette   valueT value = *valP;
   1169  1.1.1.1.2.1  pgoyette   unsigned insn = 0;
   1170  1.1.1.1.2.1  pgoyette   symbolS *fx_addsy, *fx_subsy;
   1171  1.1.1.1.2.1  pgoyette   offsetT fx_offset;
   1172  1.1.1.1.2.1  pgoyette   segT add_symbol_segment = absolute_section;
   1173  1.1.1.1.2.1  pgoyette   segT sub_symbol_segment = absolute_section;
   1174  1.1.1.1.2.1  pgoyette   const struct arc_operand *operand = NULL;
   1175  1.1.1.1.2.1  pgoyette   extended_bfd_reloc_code_real_type reloc;
   1176  1.1.1.1.2.1  pgoyette 
   1177  1.1.1.1.2.1  pgoyette   pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
   1178  1.1.1.1.2.1  pgoyette 	    fixP->fx_file, fixP->fx_line, fixP->fx_r_type,
   1179  1.1.1.1.2.1  pgoyette 	    ((int) fixP->fx_r_type < 0) ? "Internal":
   1180  1.1.1.1.2.1  pgoyette 	    bfd_get_reloc_code_name (fixP->fx_r_type), value,
   1181  1.1.1.1.2.1  pgoyette 	    fixP->fx_offset);
   1182  1.1.1.1.2.1  pgoyette 
   1183  1.1.1.1.2.1  pgoyette   fx_addsy = fixP->fx_addsy;
   1184  1.1.1.1.2.1  pgoyette   fx_subsy = fixP->fx_subsy;
   1185  1.1.1.1.2.1  pgoyette   fx_offset = 0;
   1186  1.1.1.1.2.1  pgoyette 
   1187  1.1.1.1.2.1  pgoyette   if (fx_addsy)
   1188  1.1.1.1.2.1  pgoyette     {
   1189  1.1.1.1.2.1  pgoyette       add_symbol_segment = S_GET_SEGMENT (fx_addsy);
   1190  1.1.1.1.2.1  pgoyette     }
   1191  1.1.1.1.2.1  pgoyette 
   1192  1.1.1.1.2.1  pgoyette   if (fx_subsy
   1193  1.1.1.1.2.1  pgoyette       && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF
   1194  1.1.1.1.2.1  pgoyette       && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF_S9
   1195  1.1.1.1.2.1  pgoyette       && fixP->fx_r_type != BFD_RELOC_ARC_TLS_GD_LD)
   1196  1.1.1.1.2.1  pgoyette     {
   1197  1.1.1.1.2.1  pgoyette       resolve_symbol_value (fx_subsy);
   1198  1.1.1.1.2.1  pgoyette       sub_symbol_segment = S_GET_SEGMENT (fx_subsy);
   1199  1.1.1.1.2.1  pgoyette 
   1200  1.1.1.1.2.1  pgoyette       if (sub_symbol_segment == absolute_section)
   1201  1.1.1.1.2.1  pgoyette 	{
   1202  1.1.1.1.2.1  pgoyette 	  /* The symbol is really a constant.  */
   1203  1.1.1.1.2.1  pgoyette 	  fx_offset -= S_GET_VALUE (fx_subsy);
   1204  1.1.1.1.2.1  pgoyette 	  fx_subsy = NULL;
   1205  1.1.1.1.2.1  pgoyette 	}
   1206  1.1.1.1.2.1  pgoyette       else
   1207  1.1.1.1.2.1  pgoyette 	{
   1208  1.1.1.1.2.1  pgoyette 	  as_bad_where (fixP->fx_file, fixP->fx_line,
   1209  1.1.1.1.2.1  pgoyette 			_("can't resolve `%s' {%s section} - `%s' {%s section}"),
   1210  1.1.1.1.2.1  pgoyette 			fx_addsy ? S_GET_NAME (fx_addsy) : "0",
   1211  1.1.1.1.2.1  pgoyette 			segment_name (add_symbol_segment),
   1212  1.1.1.1.2.1  pgoyette 			S_GET_NAME (fx_subsy),
   1213  1.1.1.1.2.1  pgoyette 			segment_name (sub_symbol_segment));
   1214  1.1.1.1.2.1  pgoyette 	  return;
   1215  1.1.1.1.2.1  pgoyette 	}
   1216          1.1  christos     }
   1217  1.1.1.1.2.1  pgoyette 
   1218  1.1.1.1.2.1  pgoyette   if (fx_addsy
   1219  1.1.1.1.2.1  pgoyette       && !S_IS_WEAK (fx_addsy))
   1220          1.1  christos     {
   1221  1.1.1.1.2.1  pgoyette       if (add_symbol_segment == seg
   1222  1.1.1.1.2.1  pgoyette 	  && fixP->fx_pcrel)
   1223  1.1.1.1.2.1  pgoyette 	{
   1224  1.1.1.1.2.1  pgoyette 	  value += S_GET_VALUE (fx_addsy);
   1225  1.1.1.1.2.1  pgoyette 	  value -= md_pcrel_from_section (fixP, seg);
   1226  1.1.1.1.2.1  pgoyette 	  fx_addsy = NULL;
   1227  1.1.1.1.2.1  pgoyette 	  fixP->fx_pcrel = FALSE;
   1228  1.1.1.1.2.1  pgoyette 	}
   1229  1.1.1.1.2.1  pgoyette       else if (add_symbol_segment == absolute_section)
   1230  1.1.1.1.2.1  pgoyette 	{
   1231  1.1.1.1.2.1  pgoyette 	  value = fixP->fx_offset;
   1232  1.1.1.1.2.1  pgoyette 	  fx_offset += S_GET_VALUE (fixP->fx_addsy);
   1233  1.1.1.1.2.1  pgoyette 	  fx_addsy = NULL;
   1234  1.1.1.1.2.1  pgoyette 	  fixP->fx_pcrel = FALSE;
   1235  1.1.1.1.2.1  pgoyette 	}
   1236          1.1  christos     }
   1237          1.1  christos 
   1238  1.1.1.1.2.1  pgoyette   if (!fx_addsy)
   1239  1.1.1.1.2.1  pgoyette     fixP->fx_done = TRUE;
   1240          1.1  christos 
   1241  1.1.1.1.2.1  pgoyette   if (fixP->fx_pcrel)
   1242  1.1.1.1.2.1  pgoyette     {
   1243  1.1.1.1.2.1  pgoyette       if (fx_addsy
   1244  1.1.1.1.2.1  pgoyette 	  && ((S_IS_DEFINED (fx_addsy)
   1245  1.1.1.1.2.1  pgoyette 	       && S_GET_SEGMENT (fx_addsy) != seg)
   1246  1.1.1.1.2.1  pgoyette 	      || S_IS_WEAK (fx_addsy)))
   1247  1.1.1.1.2.1  pgoyette 	value += md_pcrel_from_section (fixP, seg);
   1248  1.1.1.1.2.1  pgoyette 
   1249  1.1.1.1.2.1  pgoyette       switch (fixP->fx_r_type)
   1250  1.1.1.1.2.1  pgoyette 	{
   1251  1.1.1.1.2.1  pgoyette 	case BFD_RELOC_ARC_32_ME:
   1252  1.1.1.1.2.1  pgoyette 	  /* This is a pc-relative value in a LIMM.  Adjust it to the
   1253  1.1.1.1.2.1  pgoyette 	     address of the instruction not to the address of the
   1254  1.1.1.1.2.1  pgoyette 	     LIMM.  Note: it is not anylonger valid this afirmation as
   1255  1.1.1.1.2.1  pgoyette 	     the linker consider ARC_PC32 a fixup to entire 64 bit
   1256  1.1.1.1.2.1  pgoyette 	     insn.  */
   1257  1.1.1.1.2.1  pgoyette 	  fixP->fx_offset += fixP->fx_frag->fr_address;
   1258  1.1.1.1.2.1  pgoyette 	  /* Fall through.  */
   1259  1.1.1.1.2.1  pgoyette 	case BFD_RELOC_32:
   1260  1.1.1.1.2.1  pgoyette 	  fixP->fx_r_type = BFD_RELOC_ARC_PC32;
   1261  1.1.1.1.2.1  pgoyette 	  /* Fall through.  */
   1262  1.1.1.1.2.1  pgoyette 	case BFD_RELOC_ARC_PC32:
   1263  1.1.1.1.2.1  pgoyette 	  /* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */
   1264  1.1.1.1.2.1  pgoyette 	  break;
   1265  1.1.1.1.2.1  pgoyette 	default:
   1266  1.1.1.1.2.1  pgoyette 	  if ((int) fixP->fx_r_type < 0)
   1267  1.1.1.1.2.1  pgoyette 	    as_fatal (_("PC relative relocation not allowed for (internal) type %d"),
   1268  1.1.1.1.2.1  pgoyette 		      fixP->fx_r_type);
   1269  1.1.1.1.2.1  pgoyette 	  break;
   1270  1.1.1.1.2.1  pgoyette 	}
   1271  1.1.1.1.2.1  pgoyette     }
   1272          1.1  christos 
   1273  1.1.1.1.2.1  pgoyette   pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
   1274  1.1.1.1.2.1  pgoyette 	    fixP->fx_file, fixP->fx_line, fixP->fx_r_type,
   1275  1.1.1.1.2.1  pgoyette 	    ((int) fixP->fx_r_type < 0) ? "Internal":
   1276  1.1.1.1.2.1  pgoyette 	    bfd_get_reloc_code_name (fixP->fx_r_type), value,
   1277  1.1.1.1.2.1  pgoyette 	    fixP->fx_offset);
   1278  1.1.1.1.2.1  pgoyette 
   1279  1.1.1.1.2.1  pgoyette 
   1280  1.1.1.1.2.1  pgoyette   /* Now check for TLS relocations.  */
   1281  1.1.1.1.2.1  pgoyette   reloc = fixP->fx_r_type;
   1282  1.1.1.1.2.1  pgoyette   switch (reloc)
   1283  1.1.1.1.2.1  pgoyette     {
   1284  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_TLS_DTPOFF:
   1285  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_TLS_LE_32:
   1286  1.1.1.1.2.1  pgoyette       fixP->fx_offset = 0;
   1287  1.1.1.1.2.1  pgoyette       /* Fall through.  */
   1288  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_TLS_GD_GOT:
   1289  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_TLS_IE_GOT:
   1290  1.1.1.1.2.1  pgoyette       S_SET_THREAD_LOCAL (fixP->fx_addsy);
   1291  1.1.1.1.2.1  pgoyette       break;
   1292          1.1  christos 
   1293  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_TLS_GD_LD:
   1294  1.1.1.1.2.1  pgoyette       gas_assert (!fixP->fx_offset);
   1295  1.1.1.1.2.1  pgoyette       if (fixP->fx_subsy)
   1296  1.1.1.1.2.1  pgoyette 	fixP->fx_offset
   1297  1.1.1.1.2.1  pgoyette 	  = (S_GET_VALUE (fixP->fx_subsy)
   1298  1.1.1.1.2.1  pgoyette 	     - fixP->fx_frag->fr_address- fixP->fx_where);
   1299  1.1.1.1.2.1  pgoyette       fixP->fx_subsy = NULL;
   1300  1.1.1.1.2.1  pgoyette       /* Fall through.  */
   1301  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_TLS_GD_CALL:
   1302  1.1.1.1.2.1  pgoyette       /* These two relocs are there just to allow ld to change the tls
   1303  1.1.1.1.2.1  pgoyette 	 model for this symbol, by patching the code.  The offset -
   1304  1.1.1.1.2.1  pgoyette 	 and scale, if any - will be installed by the linker.  */
   1305  1.1.1.1.2.1  pgoyette       S_SET_THREAD_LOCAL (fixP->fx_addsy);
   1306  1.1.1.1.2.1  pgoyette       break;
   1307  1.1.1.1.2.1  pgoyette 
   1308  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_TLS_LE_S9:
   1309  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_TLS_DTPOFF_S9:
   1310  1.1.1.1.2.1  pgoyette       as_bad (_("TLS_*_S9 relocs are not supported yet"));
   1311  1.1.1.1.2.1  pgoyette       break;
   1312          1.1  christos 
   1313  1.1.1.1.2.1  pgoyette     default:
   1314  1.1.1.1.2.1  pgoyette       break;
   1315  1.1.1.1.2.1  pgoyette     }
   1316          1.1  christos 
   1317  1.1.1.1.2.1  pgoyette   if (!fixP->fx_done)
   1318          1.1  christos     {
   1319  1.1.1.1.2.1  pgoyette       return;
   1320          1.1  christos     }
   1321          1.1  christos 
   1322  1.1.1.1.2.1  pgoyette   /* Addjust the value if we have a constant.  */
   1323  1.1.1.1.2.1  pgoyette   value += fx_offset;
   1324          1.1  christos 
   1325  1.1.1.1.2.1  pgoyette   /* For hosts with longs bigger than 32-bits make sure that the top
   1326  1.1.1.1.2.1  pgoyette      bits of a 32-bit negative value read in by the parser are set,
   1327  1.1.1.1.2.1  pgoyette      so that the correct comparisons are made.  */
   1328  1.1.1.1.2.1  pgoyette   if (value & 0x80000000)
   1329  1.1.1.1.2.1  pgoyette     value |= (-1L << 31);
   1330  1.1.1.1.2.1  pgoyette 
   1331  1.1.1.1.2.1  pgoyette   reloc = fixP->fx_r_type;
   1332  1.1.1.1.2.1  pgoyette   switch (reloc)
   1333  1.1.1.1.2.1  pgoyette     {
   1334  1.1.1.1.2.1  pgoyette     case BFD_RELOC_8:
   1335  1.1.1.1.2.1  pgoyette     case BFD_RELOC_16:
   1336  1.1.1.1.2.1  pgoyette     case BFD_RELOC_24:
   1337  1.1.1.1.2.1  pgoyette     case BFD_RELOC_32:
   1338  1.1.1.1.2.1  pgoyette     case BFD_RELOC_64:
   1339  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_32_PCREL:
   1340  1.1.1.1.2.1  pgoyette       md_number_to_chars (fixpos, value, fixP->fx_size);
   1341  1.1.1.1.2.1  pgoyette       return;
   1342          1.1  christos 
   1343  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_GOTPC32:
   1344  1.1.1.1.2.1  pgoyette       /* I cannot fix an GOTPC relocation because I need to relax it
   1345  1.1.1.1.2.1  pgoyette 	 from ld rx,[pcl,@sym@gotpc] to add rx,pcl,@sym@gotpc.  */
   1346  1.1.1.1.2.1  pgoyette       as_bad (_("Unsupported operation on reloc"));
   1347  1.1.1.1.2.1  pgoyette       return;
   1348  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_GOTOFF:
   1349  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_32_ME:
   1350  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_PC32:
   1351  1.1.1.1.2.1  pgoyette       md_number_to_chars_midend (fixpos, value, fixP->fx_size);
   1352  1.1.1.1.2.1  pgoyette       return;
   1353          1.1  christos 
   1354  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_PLT32:
   1355  1.1.1.1.2.1  pgoyette       md_number_to_chars_midend (fixpos, value, fixP->fx_size);
   1356  1.1.1.1.2.1  pgoyette       return;
   1357          1.1  christos 
   1358  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_S25H_PCREL_PLT:
   1359  1.1.1.1.2.1  pgoyette       reloc = BFD_RELOC_ARC_S25W_PCREL;
   1360  1.1.1.1.2.1  pgoyette       goto solve_plt;
   1361  1.1.1.1.2.1  pgoyette 
   1362  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_S21H_PCREL_PLT:
   1363  1.1.1.1.2.1  pgoyette       reloc = BFD_RELOC_ARC_S21H_PCREL;
   1364  1.1.1.1.2.1  pgoyette       goto solve_plt;
   1365  1.1.1.1.2.1  pgoyette 
   1366  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_S25W_PCREL_PLT:
   1367  1.1.1.1.2.1  pgoyette       reloc = BFD_RELOC_ARC_S25W_PCREL;
   1368  1.1.1.1.2.1  pgoyette       goto solve_plt;
   1369  1.1.1.1.2.1  pgoyette 
   1370  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_S21W_PCREL_PLT:
   1371  1.1.1.1.2.1  pgoyette       reloc = BFD_RELOC_ARC_S21W_PCREL;
   1372  1.1.1.1.2.1  pgoyette 
   1373  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_S25W_PCREL:
   1374  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_S21W_PCREL:
   1375  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_S21H_PCREL:
   1376  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_S25H_PCREL:
   1377  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_S13_PCREL:
   1378  1.1.1.1.2.1  pgoyette     solve_plt:
   1379  1.1.1.1.2.1  pgoyette       operand = find_operand_for_reloc (reloc);
   1380  1.1.1.1.2.1  pgoyette       gas_assert (operand);
   1381  1.1.1.1.2.1  pgoyette       break;
   1382          1.1  christos 
   1383  1.1.1.1.2.1  pgoyette     default:
   1384  1.1.1.1.2.1  pgoyette       {
   1385  1.1.1.1.2.1  pgoyette 	if ((int) fixP->fx_r_type >= 0)
   1386  1.1.1.1.2.1  pgoyette 	  as_fatal (_("unhandled relocation type %s"),
   1387  1.1.1.1.2.1  pgoyette 		    bfd_get_reloc_code_name (fixP->fx_r_type));
   1388          1.1  christos 
   1389  1.1.1.1.2.1  pgoyette 	/* The rest of these fixups needs to be completely resolved as
   1390  1.1.1.1.2.1  pgoyette 	   constants.  */
   1391  1.1.1.1.2.1  pgoyette 	if (fixP->fx_addsy != 0
   1392  1.1.1.1.2.1  pgoyette 	    && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
   1393  1.1.1.1.2.1  pgoyette 	  as_bad_where (fixP->fx_file, fixP->fx_line,
   1394  1.1.1.1.2.1  pgoyette 			_("non-absolute expression in constant field"));
   1395  1.1.1.1.2.1  pgoyette 
   1396  1.1.1.1.2.1  pgoyette 	gas_assert (-(int) fixP->fx_r_type < (int) arc_num_operands);
   1397  1.1.1.1.2.1  pgoyette 	operand = &arc_operands[-(int) fixP->fx_r_type];
   1398  1.1.1.1.2.1  pgoyette 	break;
   1399  1.1.1.1.2.1  pgoyette       }
   1400  1.1.1.1.2.1  pgoyette     }
   1401  1.1.1.1.2.1  pgoyette 
   1402  1.1.1.1.2.1  pgoyette   if (target_big_endian)
   1403  1.1.1.1.2.1  pgoyette     {
   1404  1.1.1.1.2.1  pgoyette       switch (fixP->fx_size)
   1405          1.1  christos 	{
   1406  1.1.1.1.2.1  pgoyette 	case 4:
   1407  1.1.1.1.2.1  pgoyette 	  insn = bfd_getb32 (fixpos);
   1408  1.1.1.1.2.1  pgoyette 	  break;
   1409  1.1.1.1.2.1  pgoyette 	case 2:
   1410  1.1.1.1.2.1  pgoyette 	  insn = bfd_getb16 (fixpos);
   1411  1.1.1.1.2.1  pgoyette 	  break;
   1412  1.1.1.1.2.1  pgoyette 	default:
   1413          1.1  christos 	  as_bad_where (fixP->fx_file, fixP->fx_line,
   1414  1.1.1.1.2.1  pgoyette 			_("unknown fixup size"));
   1415          1.1  christos 	}
   1416          1.1  christos     }
   1417          1.1  christos   else
   1418          1.1  christos     {
   1419  1.1.1.1.2.1  pgoyette       insn = 0;
   1420  1.1.1.1.2.1  pgoyette       switch (fixP->fx_size)
   1421          1.1  christos 	{
   1422  1.1.1.1.2.1  pgoyette 	case 4:
   1423  1.1.1.1.2.1  pgoyette 	  insn = bfd_getl16 (fixpos) << 16 | bfd_getl16 (fixpos + 2);
   1424          1.1  christos 	  break;
   1425  1.1.1.1.2.1  pgoyette 	case 2:
   1426  1.1.1.1.2.1  pgoyette 	  insn = bfd_getl16 (fixpos);
   1427          1.1  christos 	  break;
   1428          1.1  christos 	default:
   1429  1.1.1.1.2.1  pgoyette 	  as_bad_where (fixP->fx_file, fixP->fx_line,
   1430  1.1.1.1.2.1  pgoyette 			_("unknown fixup size"));
   1431          1.1  christos 	}
   1432          1.1  christos     }
   1433          1.1  christos 
   1434  1.1.1.1.2.1  pgoyette   insn = insert_operand (insn, operand, (offsetT) value,
   1435  1.1.1.1.2.1  pgoyette 			 fixP->fx_file, fixP->fx_line);
   1436  1.1.1.1.2.1  pgoyette 
   1437  1.1.1.1.2.1  pgoyette   md_number_to_chars_midend (fixpos, insn, fixP->fx_size);
   1438  1.1.1.1.2.1  pgoyette }
   1439  1.1.1.1.2.1  pgoyette 
   1440  1.1.1.1.2.1  pgoyette /* Prepare machine-dependent frags for relaxation.
   1441  1.1.1.1.2.1  pgoyette 
   1442  1.1.1.1.2.1  pgoyette    Called just before relaxation starts.  Any symbol that is now undefined
   1443  1.1.1.1.2.1  pgoyette    will not become defined.
   1444  1.1.1.1.2.1  pgoyette 
   1445  1.1.1.1.2.1  pgoyette    Return the correct fr_subtype in the frag.
   1446  1.1.1.1.2.1  pgoyette 
   1447  1.1.1.1.2.1  pgoyette    Return the initial "guess for fr_var" to caller.  The guess for fr_var
   1448  1.1.1.1.2.1  pgoyette    is *actually* the growth beyond fr_fix.  Whatever we do to grow fr_fix
   1449  1.1.1.1.2.1  pgoyette    or fr_var contributes to our returned value.
   1450  1.1.1.1.2.1  pgoyette 
   1451  1.1.1.1.2.1  pgoyette    Although it may not be explicit in the frag, pretend
   1452  1.1.1.1.2.1  pgoyette    fr_var starts with a value.  */
   1453  1.1.1.1.2.1  pgoyette 
   1454  1.1.1.1.2.1  pgoyette int
   1455  1.1.1.1.2.1  pgoyette md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
   1456  1.1.1.1.2.1  pgoyette 			       segT segment ATTRIBUTE_UNUSED)
   1457  1.1.1.1.2.1  pgoyette {
   1458  1.1.1.1.2.1  pgoyette   int growth = 4;
   1459  1.1.1.1.2.1  pgoyette 
   1460  1.1.1.1.2.1  pgoyette   fragP->fr_var = 4;
   1461  1.1.1.1.2.1  pgoyette   pr_debug ("%s:%d: md_estimate_size_before_relax: %d\n",
   1462  1.1.1.1.2.1  pgoyette 	   fragP->fr_file, fragP->fr_line, growth);
   1463  1.1.1.1.2.1  pgoyette 
   1464  1.1.1.1.2.1  pgoyette   as_fatal (_("md_estimate_size_before_relax\n"));
   1465  1.1.1.1.2.1  pgoyette   return growth;
   1466  1.1.1.1.2.1  pgoyette }
   1467  1.1.1.1.2.1  pgoyette 
   1468  1.1.1.1.2.1  pgoyette /* Translate internal representation of relocation info to BFD target
   1469  1.1.1.1.2.1  pgoyette    format.  */
   1470          1.1  christos 
   1471          1.1  christos arelent *
   1472          1.1  christos tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
   1473          1.1  christos 	      fixS *fixP)
   1474          1.1  christos {
   1475          1.1  christos   arelent *reloc;
   1476  1.1.1.1.2.1  pgoyette   bfd_reloc_code_real_type code;
   1477          1.1  christos 
   1478  1.1.1.1.2.1  pgoyette   reloc = (arelent *) xmalloc (sizeof (* reloc));
   1479          1.1  christos   reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
   1480          1.1  christos   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
   1481          1.1  christos   reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
   1482  1.1.1.1.2.1  pgoyette 
   1483  1.1.1.1.2.1  pgoyette   /* Make sure none of our internal relocations make it this far.
   1484  1.1.1.1.2.1  pgoyette      They'd better have been fully resolved by this point.  */
   1485  1.1.1.1.2.1  pgoyette   gas_assert ((int) fixP->fx_r_type > 0);
   1486  1.1.1.1.2.1  pgoyette 
   1487  1.1.1.1.2.1  pgoyette   code = fixP->fx_r_type;
   1488  1.1.1.1.2.1  pgoyette 
   1489  1.1.1.1.2.1  pgoyette   /* if we have something like add gp, pcl,
   1490  1.1.1.1.2.1  pgoyette      _GLOBAL_OFFSET_TABLE_@gotpc.  */
   1491  1.1.1.1.2.1  pgoyette   if (code == BFD_RELOC_ARC_GOTPC32
   1492  1.1.1.1.2.1  pgoyette       && GOT_symbol
   1493  1.1.1.1.2.1  pgoyette       && fixP->fx_addsy == GOT_symbol)
   1494  1.1.1.1.2.1  pgoyette     code = BFD_RELOC_ARC_GOTPC;
   1495  1.1.1.1.2.1  pgoyette 
   1496  1.1.1.1.2.1  pgoyette   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
   1497  1.1.1.1.2.1  pgoyette   if (reloc->howto == NULL)
   1498          1.1  christos     {
   1499          1.1  christos       as_bad_where (fixP->fx_file, fixP->fx_line,
   1500  1.1.1.1.2.1  pgoyette 		    _("cannot represent `%s' relocation in object file"),
   1501  1.1.1.1.2.1  pgoyette 		    bfd_get_reloc_code_name (code));
   1502          1.1  christos       return NULL;
   1503          1.1  christos     }
   1504          1.1  christos 
   1505  1.1.1.1.2.1  pgoyette   if (!fixP->fx_pcrel != !reloc->howto->pc_relative)
   1506  1.1.1.1.2.1  pgoyette     as_fatal (_("internal error? cannot generate `%s' relocation"),
   1507  1.1.1.1.2.1  pgoyette 	      bfd_get_reloc_code_name (code));
   1508          1.1  christos 
   1509  1.1.1.1.2.1  pgoyette   gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
   1510          1.1  christos 
   1511  1.1.1.1.2.1  pgoyette   if (code == BFD_RELOC_ARC_TLS_DTPOFF
   1512  1.1.1.1.2.1  pgoyette       || code ==  BFD_RELOC_ARC_TLS_DTPOFF_S9)
   1513  1.1.1.1.2.1  pgoyette     {
   1514  1.1.1.1.2.1  pgoyette       asymbol *sym
   1515  1.1.1.1.2.1  pgoyette 	= fixP->fx_subsy ? symbol_get_bfdsym (fixP->fx_subsy) : NULL;
   1516  1.1.1.1.2.1  pgoyette       /* We just want to store a 24 bit index, but we have to wait
   1517  1.1.1.1.2.1  pgoyette 	 till after write_contents has been called via
   1518  1.1.1.1.2.1  pgoyette 	 bfd_map_over_sections before we can get the index from
   1519  1.1.1.1.2.1  pgoyette 	 _bfd_elf_symbol_from_bfd_symbol.  Thus, the write_relocs
   1520  1.1.1.1.2.1  pgoyette 	 function is elf32-arc.c has to pick up the slack.
   1521  1.1.1.1.2.1  pgoyette 	 Unfortunately, this leads to problems with hosts that have
   1522  1.1.1.1.2.1  pgoyette 	 pointers wider than long (bfd_vma).  There would be various
   1523  1.1.1.1.2.1  pgoyette 	 ways to handle this, all error-prone :-(  */
   1524  1.1.1.1.2.1  pgoyette       reloc->addend = (bfd_vma) sym;
   1525  1.1.1.1.2.1  pgoyette       if ((asymbol *) reloc->addend != sym)
   1526  1.1.1.1.2.1  pgoyette 	{
   1527  1.1.1.1.2.1  pgoyette 	  as_bad ("Can't store pointer\n");
   1528  1.1.1.1.2.1  pgoyette 	  return NULL;
   1529  1.1.1.1.2.1  pgoyette 	}
   1530  1.1.1.1.2.1  pgoyette     }
   1531  1.1.1.1.2.1  pgoyette   else
   1532  1.1.1.1.2.1  pgoyette     reloc->addend = fixP->fx_offset;
   1533          1.1  christos 
   1534          1.1  christos   return reloc;
   1535          1.1  christos }
   1536          1.1  christos 
   1537  1.1.1.1.2.1  pgoyette /* Perform post-processing of machine-dependent frags after relaxation.
   1538  1.1.1.1.2.1  pgoyette    Called after relaxation is finished.
   1539  1.1.1.1.2.1  pgoyette    In:	Address of frag.
   1540  1.1.1.1.2.1  pgoyette    fr_type == rs_machine_dependent.
   1541  1.1.1.1.2.1  pgoyette    fr_subtype is what the address relaxed to.
   1542  1.1.1.1.2.1  pgoyette 
   1543  1.1.1.1.2.1  pgoyette    Out: Any fixS:s and constants are set up.  */
   1544  1.1.1.1.2.1  pgoyette 
   1545  1.1.1.1.2.1  pgoyette void
   1546  1.1.1.1.2.1  pgoyette md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
   1547  1.1.1.1.2.1  pgoyette 		 segT segment ATTRIBUTE_UNUSED,
   1548  1.1.1.1.2.1  pgoyette 		 fragS *fragP ATTRIBUTE_UNUSED)
   1549          1.1  christos {
   1550  1.1.1.1.2.1  pgoyette   pr_debug ("%s:%d: md_convert_frag, subtype: %d, fix: %d, var: %d\n",
   1551  1.1.1.1.2.1  pgoyette 	    fragP->fr_file, fragP->fr_line,
   1552  1.1.1.1.2.1  pgoyette 	    fragP->fr_subtype, fragP->fr_fix, fragP->fr_var);
   1553  1.1.1.1.2.1  pgoyette   abort ();
   1554  1.1.1.1.2.1  pgoyette }
   1555  1.1.1.1.2.1  pgoyette 
   1556  1.1.1.1.2.1  pgoyette /* We have no need to default values of symbols.  We could catch
   1557  1.1.1.1.2.1  pgoyette    register names here, but that is handled by inserting them all in
   1558  1.1.1.1.2.1  pgoyette    the symbol table to begin with.  */
   1559  1.1.1.1.2.1  pgoyette 
   1560  1.1.1.1.2.1  pgoyette symbolS *
   1561  1.1.1.1.2.1  pgoyette md_undefined_symbol (char *name)
   1562  1.1.1.1.2.1  pgoyette {
   1563  1.1.1.1.2.1  pgoyette   /* The arc abi demands that a GOT[0] should be referencible as
   1564  1.1.1.1.2.1  pgoyette      [pc+_DYNAMIC@gotpc].  Hence we convert a _DYNAMIC@gotpc to a
   1565  1.1.1.1.2.1  pgoyette      GOTPC reference to _GLOBAL_OFFSET_TABLE_.  */
   1566  1.1.1.1.2.1  pgoyette   if (((*name == '_')
   1567  1.1.1.1.2.1  pgoyette        && (*(name+1) == 'G')
   1568  1.1.1.1.2.1  pgoyette        && (strcmp (name, GLOBAL_OFFSET_TABLE_NAME) == 0))
   1569  1.1.1.1.2.1  pgoyette       || ((*name == '_')
   1570  1.1.1.1.2.1  pgoyette 	  && (*(name+1) == 'D')
   1571  1.1.1.1.2.1  pgoyette 	  && (strcmp (name, DYNAMIC_STRUCT_NAME) == 0)))
   1572  1.1.1.1.2.1  pgoyette     {
   1573  1.1.1.1.2.1  pgoyette       if (!GOT_symbol)
   1574  1.1.1.1.2.1  pgoyette 	{
   1575  1.1.1.1.2.1  pgoyette 	  if (symbol_find (name))
   1576  1.1.1.1.2.1  pgoyette 	    as_bad ("GOT already in symbol table");
   1577  1.1.1.1.2.1  pgoyette 
   1578  1.1.1.1.2.1  pgoyette 	  GOT_symbol = symbol_new (GLOBAL_OFFSET_TABLE_NAME, undefined_section,
   1579  1.1.1.1.2.1  pgoyette 				   (valueT) 0, &zero_address_frag);
   1580  1.1.1.1.2.1  pgoyette 	};
   1581  1.1.1.1.2.1  pgoyette       return GOT_symbol;
   1582  1.1.1.1.2.1  pgoyette     }
   1583  1.1.1.1.2.1  pgoyette   return NULL;
   1584  1.1.1.1.2.1  pgoyette }
   1585  1.1.1.1.2.1  pgoyette 
   1586  1.1.1.1.2.1  pgoyette /* Turn a string in input_line_pointer into a floating point constant
   1587  1.1.1.1.2.1  pgoyette    of type type, and store the appropriate bytes in *litP.  The number
   1588  1.1.1.1.2.1  pgoyette    of LITTLENUMS emitted is stored in *sizeP.  An error message is
   1589  1.1.1.1.2.1  pgoyette    returned, or NULL on OK.  */
   1590          1.1  christos 
   1591  1.1.1.1.2.1  pgoyette char *
   1592  1.1.1.1.2.1  pgoyette md_atof (int type, char *litP, int *sizeP)
   1593  1.1.1.1.2.1  pgoyette {
   1594  1.1.1.1.2.1  pgoyette   return ieee_md_atof (type, litP, sizeP, target_big_endian);
   1595  1.1.1.1.2.1  pgoyette }
   1596  1.1.1.1.2.1  pgoyette 
   1597  1.1.1.1.2.1  pgoyette /* Called for any expression that can not be recognized.  When the
   1598  1.1.1.1.2.1  pgoyette    function is called, `input_line_pointer' will point to the start of
   1599  1.1.1.1.2.1  pgoyette    the expression.  */
   1600          1.1  christos 
   1601          1.1  christos void
   1602  1.1.1.1.2.1  pgoyette md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
   1603          1.1  christos {
   1604  1.1.1.1.2.1  pgoyette   char *p = input_line_pointer;
   1605  1.1.1.1.2.1  pgoyette   if (*p == '@')
   1606  1.1.1.1.2.1  pgoyette     {
   1607  1.1.1.1.2.1  pgoyette       input_line_pointer++;
   1608  1.1.1.1.2.1  pgoyette       expressionP->X_op = O_symbol;
   1609  1.1.1.1.2.1  pgoyette       expression (expressionP);
   1610  1.1.1.1.2.1  pgoyette     }
   1611  1.1.1.1.2.1  pgoyette }
   1612          1.1  christos 
   1613  1.1.1.1.2.1  pgoyette /* This function is called from the function 'expression', it attempts
   1614  1.1.1.1.2.1  pgoyette    to parse special names (in our case register names).  It fills in
   1615  1.1.1.1.2.1  pgoyette    the expression with the identified register.  It returns TRUE if
   1616  1.1.1.1.2.1  pgoyette    it is a register and FALSE otherwise.  */
   1617  1.1.1.1.2.1  pgoyette 
   1618  1.1.1.1.2.1  pgoyette bfd_boolean
   1619  1.1.1.1.2.1  pgoyette arc_parse_name (const char *name,
   1620  1.1.1.1.2.1  pgoyette 		struct expressionS *e)
   1621  1.1.1.1.2.1  pgoyette {
   1622  1.1.1.1.2.1  pgoyette   struct symbol *sym;
   1623  1.1.1.1.2.1  pgoyette 
   1624  1.1.1.1.2.1  pgoyette   if (!assembling_insn)
   1625  1.1.1.1.2.1  pgoyette     return FALSE;
   1626  1.1.1.1.2.1  pgoyette 
   1627  1.1.1.1.2.1  pgoyette   /* Handle only registers.  */
   1628  1.1.1.1.2.1  pgoyette   if (e->X_op != O_absent)
   1629  1.1.1.1.2.1  pgoyette     return FALSE;
   1630  1.1.1.1.2.1  pgoyette 
   1631  1.1.1.1.2.1  pgoyette   sym = hash_find (arc_reg_hash, name);
   1632  1.1.1.1.2.1  pgoyette   if (sym)
   1633  1.1.1.1.2.1  pgoyette     {
   1634  1.1.1.1.2.1  pgoyette       e->X_op = O_register;
   1635  1.1.1.1.2.1  pgoyette       e->X_add_number = S_GET_VALUE (sym);
   1636  1.1.1.1.2.1  pgoyette       return TRUE;
   1637  1.1.1.1.2.1  pgoyette     }
   1638  1.1.1.1.2.1  pgoyette   return FALSE;
   1639  1.1.1.1.2.1  pgoyette }
   1640  1.1.1.1.2.1  pgoyette 
   1641  1.1.1.1.2.1  pgoyette /* md_parse_option
   1642  1.1.1.1.2.1  pgoyette    Invocation line includes a switch not recognized by the base assembler.
   1643  1.1.1.1.2.1  pgoyette    See if it's a processor-specific option.
   1644  1.1.1.1.2.1  pgoyette 
   1645  1.1.1.1.2.1  pgoyette    New options (supported) are:
   1646  1.1.1.1.2.1  pgoyette 
   1647  1.1.1.1.2.1  pgoyette    -mcpu=<cpu name>		 Assemble for selected processor
   1648  1.1.1.1.2.1  pgoyette    -EB/-mbig-endian		 Big-endian
   1649  1.1.1.1.2.1  pgoyette    -EL/-mlittle-endian		 Little-endian
   1650  1.1.1.1.2.1  pgoyette 
   1651  1.1.1.1.2.1  pgoyette    The following CPU names are recognized:
   1652  1.1.1.1.2.1  pgoyette    arc700, av2em, av2hs.  */
   1653  1.1.1.1.2.1  pgoyette 
   1654  1.1.1.1.2.1  pgoyette int
   1655  1.1.1.1.2.1  pgoyette md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
   1656  1.1.1.1.2.1  pgoyette {
   1657  1.1.1.1.2.1  pgoyette   int cpu_flags = EF_ARC_CPU_GENERIC;
   1658  1.1.1.1.2.1  pgoyette 
   1659  1.1.1.1.2.1  pgoyette   switch (c)
   1660  1.1.1.1.2.1  pgoyette     {
   1661  1.1.1.1.2.1  pgoyette     case OPTION_ARC600:
   1662  1.1.1.1.2.1  pgoyette     case OPTION_ARC601:
   1663  1.1.1.1.2.1  pgoyette       return md_parse_option (OPTION_MCPU, "arc600");
   1664  1.1.1.1.2.1  pgoyette 
   1665  1.1.1.1.2.1  pgoyette     case OPTION_ARC700:
   1666  1.1.1.1.2.1  pgoyette       return md_parse_option (OPTION_MCPU, "arc700");
   1667  1.1.1.1.2.1  pgoyette 
   1668  1.1.1.1.2.1  pgoyette     case OPTION_ARCEM:
   1669  1.1.1.1.2.1  pgoyette       return md_parse_option (OPTION_MCPU, "arcem");
   1670  1.1.1.1.2.1  pgoyette 
   1671  1.1.1.1.2.1  pgoyette     case OPTION_ARCHS:
   1672  1.1.1.1.2.1  pgoyette       return md_parse_option (OPTION_MCPU, "archs");
   1673  1.1.1.1.2.1  pgoyette 
   1674  1.1.1.1.2.1  pgoyette     case OPTION_MCPU:
   1675  1.1.1.1.2.1  pgoyette       {
   1676  1.1.1.1.2.1  pgoyette 	int i;
   1677  1.1.1.1.2.1  pgoyette 	char *s = alloca (strlen (arg) + 1);
   1678          1.1  christos 
   1679          1.1  christos 	{
   1680  1.1.1.1.2.1  pgoyette 	  char *t = s;
   1681  1.1.1.1.2.1  pgoyette 	  char *arg1 = arg;
   1682          1.1  christos 
   1683  1.1.1.1.2.1  pgoyette 	  do
   1684  1.1.1.1.2.1  pgoyette 	    *t = TOLOWER (*arg1++);
   1685  1.1.1.1.2.1  pgoyette 	  while (*t++);
   1686  1.1.1.1.2.1  pgoyette 	}
   1687  1.1.1.1.2.1  pgoyette 
   1688  1.1.1.1.2.1  pgoyette 	for (i = 0; cpu_types[i].name; ++i)
   1689  1.1.1.1.2.1  pgoyette 	  {
   1690  1.1.1.1.2.1  pgoyette 	    if (!strcmp (cpu_types[i].name, s))
   1691  1.1.1.1.2.1  pgoyette 	      {
   1692  1.1.1.1.2.1  pgoyette 		arc_target      = cpu_types[i].flags;
   1693  1.1.1.1.2.1  pgoyette 		arc_target_name = cpu_types[i].name;
   1694  1.1.1.1.2.1  pgoyette 		arc_features    = cpu_types[i].features;
   1695  1.1.1.1.2.1  pgoyette 		arc_mach_type   = cpu_types[i].mach;
   1696  1.1.1.1.2.1  pgoyette 		cpu_flags       = cpu_types[i].eflags;
   1697  1.1.1.1.2.1  pgoyette 
   1698  1.1.1.1.2.1  pgoyette 		mach_type_specified_p = 1;
   1699          1.1  christos 		break;
   1700  1.1.1.1.2.1  pgoyette 	      }
   1701  1.1.1.1.2.1  pgoyette 	  }
   1702          1.1  christos 
   1703  1.1.1.1.2.1  pgoyette 	if (!cpu_types[i].name)
   1704  1.1.1.1.2.1  pgoyette 	  {
   1705  1.1.1.1.2.1  pgoyette 	    as_fatal (_("unknown architecture: %s\n"), arg);
   1706  1.1.1.1.2.1  pgoyette 	  }
   1707  1.1.1.1.2.1  pgoyette 	break;
   1708  1.1.1.1.2.1  pgoyette       }
   1709          1.1  christos 
   1710  1.1.1.1.2.1  pgoyette     case OPTION_EB:
   1711  1.1.1.1.2.1  pgoyette       arc_target_format = "elf32-bigarc";
   1712  1.1.1.1.2.1  pgoyette       byte_order = BIG_ENDIAN;
   1713  1.1.1.1.2.1  pgoyette       break;
   1714          1.1  christos 
   1715  1.1.1.1.2.1  pgoyette     case OPTION_EL:
   1716  1.1.1.1.2.1  pgoyette       arc_target_format = "elf32-littlearc";
   1717  1.1.1.1.2.1  pgoyette       byte_order = LITTLE_ENDIAN;
   1718  1.1.1.1.2.1  pgoyette       break;
   1719          1.1  christos 
   1720  1.1.1.1.2.1  pgoyette     case OPTION_CD:
   1721  1.1.1.1.2.1  pgoyette       /* This option has an effect only on ARC EM.  */
   1722  1.1.1.1.2.1  pgoyette       if (arc_target & ARC_OPCODE_ARCv2EM)
   1723  1.1.1.1.2.1  pgoyette 	arc_features |= ARC_CD;
   1724  1.1.1.1.2.1  pgoyette       break;
   1725          1.1  christos 
   1726  1.1.1.1.2.1  pgoyette     case OPTION_USER_MODE:
   1727  1.1.1.1.2.1  pgoyette     case OPTION_LD_EXT_MASK:
   1728  1.1.1.1.2.1  pgoyette     case OPTION_SWAP:
   1729  1.1.1.1.2.1  pgoyette     case OPTION_NORM:
   1730  1.1.1.1.2.1  pgoyette     case OPTION_BARREL_SHIFT:
   1731  1.1.1.1.2.1  pgoyette     case OPTION_MIN_MAX:
   1732  1.1.1.1.2.1  pgoyette     case OPTION_NO_MPY:
   1733  1.1.1.1.2.1  pgoyette     case OPTION_EA:
   1734  1.1.1.1.2.1  pgoyette     case OPTION_MUL64:
   1735  1.1.1.1.2.1  pgoyette     case OPTION_SIMD:
   1736  1.1.1.1.2.1  pgoyette     case OPTION_SPFP:
   1737  1.1.1.1.2.1  pgoyette     case OPTION_DPFP:
   1738  1.1.1.1.2.1  pgoyette     case OPTION_XMAC_D16:
   1739  1.1.1.1.2.1  pgoyette     case OPTION_XMAC_24:
   1740  1.1.1.1.2.1  pgoyette     case OPTION_DSP_PACKA:
   1741  1.1.1.1.2.1  pgoyette     case OPTION_CRC:
   1742  1.1.1.1.2.1  pgoyette     case OPTION_DVBF:
   1743  1.1.1.1.2.1  pgoyette     case OPTION_TELEPHONY:
   1744  1.1.1.1.2.1  pgoyette     case OPTION_XYMEMORY:
   1745  1.1.1.1.2.1  pgoyette     case OPTION_LOCK:
   1746  1.1.1.1.2.1  pgoyette     case OPTION_SWAPE:
   1747  1.1.1.1.2.1  pgoyette     case OPTION_RTSC:
   1748  1.1.1.1.2.1  pgoyette     case OPTION_FPUDA:
   1749  1.1.1.1.2.1  pgoyette       /* Dummy options.  */
   1750  1.1.1.1.2.1  pgoyette       break;
   1751          1.1  christos 
   1752  1.1.1.1.2.1  pgoyette     default:
   1753  1.1.1.1.2.1  pgoyette       return 0;
   1754  1.1.1.1.2.1  pgoyette     }
   1755          1.1  christos 
   1756  1.1.1.1.2.1  pgoyette   if (cpu_flags != EF_ARC_CPU_GENERIC)
   1757  1.1.1.1.2.1  pgoyette     arc_eflag = (arc_eflag & ~EF_ARC_MACH_MSK) | cpu_flags;
   1758          1.1  christos 
   1759  1.1.1.1.2.1  pgoyette   return 1;
   1760  1.1.1.1.2.1  pgoyette }
   1761  1.1.1.1.2.1  pgoyette 
   1762  1.1.1.1.2.1  pgoyette void
   1763  1.1.1.1.2.1  pgoyette md_show_usage (FILE *stream)
   1764  1.1.1.1.2.1  pgoyette {
   1765  1.1.1.1.2.1  pgoyette   fprintf (stream, _("ARC-specific assembler options:\n"));
   1766  1.1.1.1.2.1  pgoyette 
   1767  1.1.1.1.2.1  pgoyette   fprintf (stream, "  -mcpu=<cpu name>\t  assemble for CPU <cpu name>\n");
   1768  1.1.1.1.2.1  pgoyette   fprintf (stream,
   1769  1.1.1.1.2.1  pgoyette 	   "  -mcode-density\t  enable code density option for ARC EM\n");
   1770  1.1.1.1.2.1  pgoyette 
   1771  1.1.1.1.2.1  pgoyette   fprintf (stream, _("\
   1772  1.1.1.1.2.1  pgoyette   -EB                     assemble code for a big-endian cpu\n"));
   1773  1.1.1.1.2.1  pgoyette   fprintf (stream, _("\
   1774  1.1.1.1.2.1  pgoyette   -EL                     assemble code for a little-endian cpu\n"));
   1775  1.1.1.1.2.1  pgoyette }
   1776  1.1.1.1.2.1  pgoyette 
   1777  1.1.1.1.2.1  pgoyette static void
   1778  1.1.1.1.2.1  pgoyette preprocess_operands (const struct arc_opcode *opcode,
   1779  1.1.1.1.2.1  pgoyette 		     expressionS *tok,
   1780  1.1.1.1.2.1  pgoyette 		     int ntok)
   1781  1.1.1.1.2.1  pgoyette {
   1782  1.1.1.1.2.1  pgoyette   int i;
   1783  1.1.1.1.2.1  pgoyette   size_t len;
   1784  1.1.1.1.2.1  pgoyette   const char *p;
   1785  1.1.1.1.2.1  pgoyette   unsigned j;
   1786  1.1.1.1.2.1  pgoyette   const struct arc_aux_reg *auxr;
   1787  1.1.1.1.2.1  pgoyette 
   1788  1.1.1.1.2.1  pgoyette   for (i = 0; i < ntok; i++)
   1789  1.1.1.1.2.1  pgoyette     {
   1790  1.1.1.1.2.1  pgoyette       switch (tok[i].X_op)
   1791  1.1.1.1.2.1  pgoyette 	{
   1792  1.1.1.1.2.1  pgoyette 	case O_illegal:
   1793  1.1.1.1.2.1  pgoyette 	case O_absent:
   1794  1.1.1.1.2.1  pgoyette 	  break; /* Throw and error.  */
   1795  1.1.1.1.2.1  pgoyette 
   1796  1.1.1.1.2.1  pgoyette 	case O_symbol:
   1797  1.1.1.1.2.1  pgoyette 	  if (opcode->class != AUXREG)
   1798  1.1.1.1.2.1  pgoyette 	    break;
   1799  1.1.1.1.2.1  pgoyette 	  /* Convert the symbol to a constant if possible.  */
   1800  1.1.1.1.2.1  pgoyette 	  p = S_GET_NAME (tok[i].X_add_symbol);
   1801  1.1.1.1.2.1  pgoyette 	  len = strlen (p);
   1802  1.1.1.1.2.1  pgoyette 
   1803  1.1.1.1.2.1  pgoyette 	  auxr = &arc_aux_regs[0];
   1804  1.1.1.1.2.1  pgoyette 	  for (j = 0; j < arc_num_aux_regs; j++, auxr++)
   1805  1.1.1.1.2.1  pgoyette 	    if (len == auxr->length
   1806  1.1.1.1.2.1  pgoyette 		&& strcasecmp (auxr->name, p) == 0)
   1807  1.1.1.1.2.1  pgoyette 	      {
   1808  1.1.1.1.2.1  pgoyette 		tok[i].X_op = O_constant;
   1809  1.1.1.1.2.1  pgoyette 		tok[i].X_add_number = auxr->address;
   1810  1.1.1.1.2.1  pgoyette 		break;
   1811  1.1.1.1.2.1  pgoyette 	      }
   1812  1.1.1.1.2.1  pgoyette 	  break;
   1813  1.1.1.1.2.1  pgoyette 	default:
   1814  1.1.1.1.2.1  pgoyette 	  break;
   1815          1.1  christos 	}
   1816  1.1.1.1.2.1  pgoyette     }
   1817  1.1.1.1.2.1  pgoyette }
   1818  1.1.1.1.2.1  pgoyette 
   1819  1.1.1.1.2.1  pgoyette /* Given an opcode name, pre-tockenized set of argumenst and the
   1820  1.1.1.1.2.1  pgoyette    opcode flags, take it all the way through emission.  */
   1821  1.1.1.1.2.1  pgoyette 
   1822  1.1.1.1.2.1  pgoyette static void
   1823  1.1.1.1.2.1  pgoyette assemble_tokens (const char *opname,
   1824  1.1.1.1.2.1  pgoyette 		 expressionS *tok,
   1825  1.1.1.1.2.1  pgoyette 		 int ntok,
   1826  1.1.1.1.2.1  pgoyette 		 struct arc_flags *pflags,
   1827  1.1.1.1.2.1  pgoyette 		 int nflgs)
   1828  1.1.1.1.2.1  pgoyette {
   1829  1.1.1.1.2.1  pgoyette   bfd_boolean found_something = FALSE;
   1830  1.1.1.1.2.1  pgoyette   const struct arc_opcode *opcode;
   1831  1.1.1.1.2.1  pgoyette   int cpumatch = 1;
   1832  1.1.1.1.2.1  pgoyette 
   1833  1.1.1.1.2.1  pgoyette   /* Search opcodes.  */
   1834  1.1.1.1.2.1  pgoyette   opcode = (const struct arc_opcode *) hash_find (arc_opcode_hash, opname);
   1835  1.1.1.1.2.1  pgoyette 
   1836  1.1.1.1.2.1  pgoyette   /* Couldn't find opcode conventional way, try special cases.  */
   1837  1.1.1.1.2.1  pgoyette   if (!opcode)
   1838  1.1.1.1.2.1  pgoyette     opcode = find_special_case (opname, &nflgs, pflags, tok, &ntok);
   1839  1.1.1.1.2.1  pgoyette 
   1840  1.1.1.1.2.1  pgoyette   if (opcode)
   1841  1.1.1.1.2.1  pgoyette     {
   1842  1.1.1.1.2.1  pgoyette       pr_debug ("%s:%d: assemble_tokens: %s trying opcode 0x%08X\n",
   1843  1.1.1.1.2.1  pgoyette 		frag_now->fr_file, frag_now->fr_line, opcode->name,
   1844  1.1.1.1.2.1  pgoyette 		opcode->opcode);
   1845  1.1.1.1.2.1  pgoyette 
   1846  1.1.1.1.2.1  pgoyette       preprocess_operands (opcode, tok, ntok);
   1847          1.1  christos 
   1848  1.1.1.1.2.1  pgoyette       found_something = TRUE;
   1849  1.1.1.1.2.1  pgoyette       opcode = find_opcode_match (opcode, tok, &ntok, pflags, nflgs, &cpumatch);
   1850  1.1.1.1.2.1  pgoyette       if (opcode)
   1851          1.1  christos 	{
   1852  1.1.1.1.2.1  pgoyette 	  struct arc_insn insn;
   1853  1.1.1.1.2.1  pgoyette 	  assemble_insn (opcode, tok, ntok, pflags, nflgs, &insn);
   1854  1.1.1.1.2.1  pgoyette 	  emit_insn (&insn);
   1855  1.1.1.1.2.1  pgoyette 	  return;
   1856  1.1.1.1.2.1  pgoyette 	}
   1857  1.1.1.1.2.1  pgoyette     }
   1858          1.1  christos 
   1859  1.1.1.1.2.1  pgoyette   if (found_something)
   1860  1.1.1.1.2.1  pgoyette     {
   1861  1.1.1.1.2.1  pgoyette       if (cpumatch)
   1862  1.1.1.1.2.1  pgoyette 	as_bad (_("inappropriate arguments for opcode '%s'"), opname);
   1863  1.1.1.1.2.1  pgoyette       else
   1864  1.1.1.1.2.1  pgoyette 	as_bad (_("opcode '%s' not supported for target %s"), opname,
   1865  1.1.1.1.2.1  pgoyette 		arc_target_name);
   1866  1.1.1.1.2.1  pgoyette     }
   1867  1.1.1.1.2.1  pgoyette   else
   1868  1.1.1.1.2.1  pgoyette     as_bad (_("unknown opcode '%s'"), opname);
   1869  1.1.1.1.2.1  pgoyette }
   1870          1.1  christos 
   1871  1.1.1.1.2.1  pgoyette /* Used to find special case opcode.  */
   1872          1.1  christos 
   1873  1.1.1.1.2.1  pgoyette static const struct arc_opcode *
   1874  1.1.1.1.2.1  pgoyette find_special_case (const char *opname,
   1875  1.1.1.1.2.1  pgoyette 		   int *nflgs,
   1876  1.1.1.1.2.1  pgoyette 		   struct arc_flags *pflags,
   1877  1.1.1.1.2.1  pgoyette 		   expressionS *tok,
   1878  1.1.1.1.2.1  pgoyette 		   int *ntok)
   1879  1.1.1.1.2.1  pgoyette {
   1880  1.1.1.1.2.1  pgoyette   const struct arc_opcode *opcode;
   1881          1.1  christos 
   1882  1.1.1.1.2.1  pgoyette   opcode = find_special_case_pseudo (opname, ntok, tok, nflgs, pflags);
   1883          1.1  christos 
   1884  1.1.1.1.2.1  pgoyette   if (opcode == NULL)
   1885  1.1.1.1.2.1  pgoyette     opcode = find_special_case_flag (opname, nflgs, pflags);
   1886          1.1  christos 
   1887  1.1.1.1.2.1  pgoyette   return opcode;
   1888  1.1.1.1.2.1  pgoyette }
   1889          1.1  christos 
   1890  1.1.1.1.2.1  pgoyette /* Swap operand tokens.  */
   1891          1.1  christos 
   1892  1.1.1.1.2.1  pgoyette static void
   1893  1.1.1.1.2.1  pgoyette swap_operand (expressionS *operand_array,
   1894  1.1.1.1.2.1  pgoyette 	      unsigned source,
   1895  1.1.1.1.2.1  pgoyette 	      unsigned destination)
   1896  1.1.1.1.2.1  pgoyette {
   1897  1.1.1.1.2.1  pgoyette   expressionS cpy_operand;
   1898  1.1.1.1.2.1  pgoyette   expressionS *src_operand;
   1899  1.1.1.1.2.1  pgoyette   expressionS *dst_operand;
   1900  1.1.1.1.2.1  pgoyette   size_t size;
   1901          1.1  christos 
   1902  1.1.1.1.2.1  pgoyette   if (source == destination)
   1903  1.1.1.1.2.1  pgoyette     return;
   1904  1.1.1.1.2.1  pgoyette 
   1905  1.1.1.1.2.1  pgoyette   src_operand = &operand_array[source];
   1906  1.1.1.1.2.1  pgoyette   dst_operand = &operand_array[destination];
   1907  1.1.1.1.2.1  pgoyette   size = sizeof (expressionS);
   1908  1.1.1.1.2.1  pgoyette 
   1909  1.1.1.1.2.1  pgoyette   /* Make copy of operand to swap with and swap.  */
   1910  1.1.1.1.2.1  pgoyette   memcpy (&cpy_operand, dst_operand, size);
   1911  1.1.1.1.2.1  pgoyette   memcpy (dst_operand, src_operand, size);
   1912  1.1.1.1.2.1  pgoyette   memcpy (src_operand, &cpy_operand, size);
   1913  1.1.1.1.2.1  pgoyette }
   1914  1.1.1.1.2.1  pgoyette 
   1915  1.1.1.1.2.1  pgoyette /* Check if *op matches *tok type.
   1916  1.1.1.1.2.1  pgoyette    Returns FALSE if they don't match, TRUE if they match.  */
   1917  1.1.1.1.2.1  pgoyette 
   1918  1.1.1.1.2.1  pgoyette static bfd_boolean
   1919  1.1.1.1.2.1  pgoyette pseudo_operand_match (const expressionS *tok,
   1920  1.1.1.1.2.1  pgoyette 		      const struct arc_operand_operation *op)
   1921  1.1.1.1.2.1  pgoyette {
   1922  1.1.1.1.2.1  pgoyette   offsetT min, max, val;
   1923  1.1.1.1.2.1  pgoyette   bfd_boolean ret;
   1924  1.1.1.1.2.1  pgoyette   const struct arc_operand *operand_real = &arc_operands[op->operand_idx];
   1925  1.1.1.1.2.1  pgoyette 
   1926  1.1.1.1.2.1  pgoyette   ret = FALSE;
   1927  1.1.1.1.2.1  pgoyette   switch (tok->X_op)
   1928  1.1.1.1.2.1  pgoyette     {
   1929  1.1.1.1.2.1  pgoyette     case O_constant:
   1930  1.1.1.1.2.1  pgoyette       if (operand_real->bits == 32 && (operand_real->flags & ARC_OPERAND_LIMM))
   1931  1.1.1.1.2.1  pgoyette 	ret = 1;
   1932  1.1.1.1.2.1  pgoyette       else if (!(operand_real->flags & ARC_OPERAND_IR))
   1933  1.1.1.1.2.1  pgoyette 	{
   1934  1.1.1.1.2.1  pgoyette 	  val = tok->X_add_number;
   1935  1.1.1.1.2.1  pgoyette 	  if (operand_real->flags & ARC_OPERAND_SIGNED)
   1936          1.1  christos 	    {
   1937  1.1.1.1.2.1  pgoyette 	      max = (1 << (operand_real->bits - 1)) - 1;
   1938  1.1.1.1.2.1  pgoyette 	      min = -(1 << (operand_real->bits - 1));
   1939          1.1  christos 	    }
   1940          1.1  christos 	  else
   1941          1.1  christos 	    {
   1942  1.1.1.1.2.1  pgoyette 	      max = (1 << operand_real->bits) - 1;
   1943  1.1.1.1.2.1  pgoyette 	      min = 0;
   1944          1.1  christos 	    }
   1945  1.1.1.1.2.1  pgoyette 	  if (min <= val && val <= max)
   1946  1.1.1.1.2.1  pgoyette 	    ret = TRUE;
   1947  1.1.1.1.2.1  pgoyette 	}
   1948  1.1.1.1.2.1  pgoyette       break;
   1949          1.1  christos 
   1950  1.1.1.1.2.1  pgoyette     case O_symbol:
   1951  1.1.1.1.2.1  pgoyette       /* Handle all symbols as long immediates or signed 9.  */
   1952  1.1.1.1.2.1  pgoyette       if (operand_real->flags & ARC_OPERAND_LIMM ||
   1953  1.1.1.1.2.1  pgoyette 	  ((operand_real->flags & ARC_OPERAND_SIGNED) && operand_real->bits == 9))
   1954  1.1.1.1.2.1  pgoyette 	ret = TRUE;
   1955  1.1.1.1.2.1  pgoyette       break;
   1956          1.1  christos 
   1957  1.1.1.1.2.1  pgoyette     case O_register:
   1958  1.1.1.1.2.1  pgoyette       if (operand_real->flags & ARC_OPERAND_IR)
   1959  1.1.1.1.2.1  pgoyette 	ret = TRUE;
   1960  1.1.1.1.2.1  pgoyette       break;
   1961  1.1.1.1.2.1  pgoyette 
   1962  1.1.1.1.2.1  pgoyette     case O_bracket:
   1963  1.1.1.1.2.1  pgoyette       if (operand_real->flags & ARC_OPERAND_BRAKET)
   1964  1.1.1.1.2.1  pgoyette 	ret = TRUE;
   1965  1.1.1.1.2.1  pgoyette       break;
   1966  1.1.1.1.2.1  pgoyette 
   1967  1.1.1.1.2.1  pgoyette     default:
   1968  1.1.1.1.2.1  pgoyette       /* Unknown.  */
   1969  1.1.1.1.2.1  pgoyette       break;
   1970  1.1.1.1.2.1  pgoyette     }
   1971  1.1.1.1.2.1  pgoyette   return ret;
   1972  1.1.1.1.2.1  pgoyette }
   1973  1.1.1.1.2.1  pgoyette 
   1974  1.1.1.1.2.1  pgoyette /* Find pseudo instruction in array.  */
   1975  1.1.1.1.2.1  pgoyette 
   1976  1.1.1.1.2.1  pgoyette static const struct arc_pseudo_insn *
   1977  1.1.1.1.2.1  pgoyette find_pseudo_insn (const char *opname,
   1978  1.1.1.1.2.1  pgoyette 		  int ntok,
   1979  1.1.1.1.2.1  pgoyette 		  const expressionS *tok)
   1980  1.1.1.1.2.1  pgoyette {
   1981  1.1.1.1.2.1  pgoyette   const struct arc_pseudo_insn *pseudo_insn = NULL;
   1982  1.1.1.1.2.1  pgoyette   const struct arc_operand_operation *op;
   1983  1.1.1.1.2.1  pgoyette   unsigned int i;
   1984  1.1.1.1.2.1  pgoyette   int j;
   1985  1.1.1.1.2.1  pgoyette 
   1986  1.1.1.1.2.1  pgoyette   for (i = 0; i < arc_num_pseudo_insn; ++i)
   1987  1.1.1.1.2.1  pgoyette     {
   1988  1.1.1.1.2.1  pgoyette       pseudo_insn = &arc_pseudo_insns[i];
   1989  1.1.1.1.2.1  pgoyette       if (strcmp (pseudo_insn->mnemonic_p, opname) == 0)
   1990  1.1.1.1.2.1  pgoyette 	{
   1991  1.1.1.1.2.1  pgoyette 	  op = pseudo_insn->operand;
   1992  1.1.1.1.2.1  pgoyette 	  for (j = 0; j < ntok; ++j)
   1993  1.1.1.1.2.1  pgoyette 	    if (!pseudo_operand_match (&tok[j], &op[j]))
   1994  1.1.1.1.2.1  pgoyette 	      break;
   1995  1.1.1.1.2.1  pgoyette 
   1996  1.1.1.1.2.1  pgoyette 	  /* Found the right instruction.  */
   1997  1.1.1.1.2.1  pgoyette 	  if (j == ntok)
   1998  1.1.1.1.2.1  pgoyette 	    return pseudo_insn;
   1999          1.1  christos 	}
   2000          1.1  christos     }
   2001  1.1.1.1.2.1  pgoyette   return NULL;
   2002  1.1.1.1.2.1  pgoyette }
   2003          1.1  christos 
   2004  1.1.1.1.2.1  pgoyette /* Assumes the expressionS *tok is of sufficient size.  */
   2005  1.1.1.1.2.1  pgoyette 
   2006  1.1.1.1.2.1  pgoyette static const struct arc_opcode *
   2007  1.1.1.1.2.1  pgoyette find_special_case_pseudo (const char *opname,
   2008  1.1.1.1.2.1  pgoyette 			  int *ntok,
   2009  1.1.1.1.2.1  pgoyette 			  expressionS *tok,
   2010  1.1.1.1.2.1  pgoyette 			  int *nflgs,
   2011  1.1.1.1.2.1  pgoyette 			  struct arc_flags *pflags)
   2012  1.1.1.1.2.1  pgoyette {
   2013  1.1.1.1.2.1  pgoyette   const struct arc_pseudo_insn *pseudo_insn = NULL;
   2014  1.1.1.1.2.1  pgoyette   const struct arc_operand_operation *operand_pseudo;
   2015  1.1.1.1.2.1  pgoyette   const struct arc_operand *operand_real;
   2016  1.1.1.1.2.1  pgoyette   unsigned i;
   2017  1.1.1.1.2.1  pgoyette   char construct_operand[MAX_CONSTR_STR];
   2018  1.1.1.1.2.1  pgoyette 
   2019  1.1.1.1.2.1  pgoyette   /* Find whether opname is in pseudo instruction array.  */
   2020  1.1.1.1.2.1  pgoyette   pseudo_insn = find_pseudo_insn (opname, *ntok, tok);
   2021  1.1.1.1.2.1  pgoyette 
   2022  1.1.1.1.2.1  pgoyette   if (pseudo_insn == NULL)
   2023  1.1.1.1.2.1  pgoyette     return NULL;
   2024  1.1.1.1.2.1  pgoyette 
   2025  1.1.1.1.2.1  pgoyette   /* Handle flag, Limited to one flag at the moment.  */
   2026  1.1.1.1.2.1  pgoyette   if (pseudo_insn->flag_r != NULL)
   2027  1.1.1.1.2.1  pgoyette     *nflgs += tokenize_flags (pseudo_insn->flag_r, &pflags[*nflgs],
   2028  1.1.1.1.2.1  pgoyette 			      MAX_INSN_FLGS - *nflgs);
   2029  1.1.1.1.2.1  pgoyette 
   2030  1.1.1.1.2.1  pgoyette   /* Handle operand operations.  */
   2031  1.1.1.1.2.1  pgoyette   for (i = 0; i < pseudo_insn->operand_cnt; ++i)
   2032  1.1.1.1.2.1  pgoyette     {
   2033  1.1.1.1.2.1  pgoyette       operand_pseudo = &pseudo_insn->operand[i];
   2034  1.1.1.1.2.1  pgoyette       operand_real = &arc_operands[operand_pseudo->operand_idx];
   2035  1.1.1.1.2.1  pgoyette 
   2036  1.1.1.1.2.1  pgoyette       if (operand_real->flags & ARC_OPERAND_BRAKET &&
   2037  1.1.1.1.2.1  pgoyette 	  !operand_pseudo->needs_insert)
   2038  1.1.1.1.2.1  pgoyette 	continue;
   2039  1.1.1.1.2.1  pgoyette 
   2040  1.1.1.1.2.1  pgoyette       /* Has to be inserted (i.e. this token does not exist yet).  */
   2041  1.1.1.1.2.1  pgoyette       if (operand_pseudo->needs_insert)
   2042  1.1.1.1.2.1  pgoyette 	{
   2043  1.1.1.1.2.1  pgoyette 	  if (operand_real->flags & ARC_OPERAND_BRAKET)
   2044  1.1.1.1.2.1  pgoyette 	    {
   2045  1.1.1.1.2.1  pgoyette 	      tok[i].X_op = O_bracket;
   2046  1.1.1.1.2.1  pgoyette 	      ++(*ntok);
   2047  1.1.1.1.2.1  pgoyette 	      continue;
   2048  1.1.1.1.2.1  pgoyette 	    }
   2049  1.1.1.1.2.1  pgoyette 
   2050  1.1.1.1.2.1  pgoyette 	  /* Check if operand is a register or constant and handle it
   2051  1.1.1.1.2.1  pgoyette 	     by type.  */
   2052  1.1.1.1.2.1  pgoyette 	  if (operand_real->flags & ARC_OPERAND_IR)
   2053  1.1.1.1.2.1  pgoyette 	    snprintf (construct_operand, MAX_CONSTR_STR, "r%d",
   2054  1.1.1.1.2.1  pgoyette 		      operand_pseudo->count);
   2055  1.1.1.1.2.1  pgoyette 	  else
   2056  1.1.1.1.2.1  pgoyette 	    snprintf (construct_operand, MAX_CONSTR_STR, "%d",
   2057  1.1.1.1.2.1  pgoyette 		      operand_pseudo->count);
   2058  1.1.1.1.2.1  pgoyette 
   2059  1.1.1.1.2.1  pgoyette 	  tokenize_arguments (construct_operand, &tok[i], 1);
   2060  1.1.1.1.2.1  pgoyette 	  ++(*ntok);
   2061  1.1.1.1.2.1  pgoyette 	}
   2062  1.1.1.1.2.1  pgoyette 
   2063  1.1.1.1.2.1  pgoyette       else if (operand_pseudo->count)
   2064  1.1.1.1.2.1  pgoyette 	{
   2065  1.1.1.1.2.1  pgoyette 	  /* Operand number has to be adjusted accordingly (by operand
   2066  1.1.1.1.2.1  pgoyette 	     type).  */
   2067  1.1.1.1.2.1  pgoyette 	  switch (tok[i].X_op)
   2068  1.1.1.1.2.1  pgoyette 	    {
   2069  1.1.1.1.2.1  pgoyette 	    case O_constant:
   2070  1.1.1.1.2.1  pgoyette 	      tok[i].X_add_number += operand_pseudo->count;
   2071  1.1.1.1.2.1  pgoyette 	      break;
   2072  1.1.1.1.2.1  pgoyette 
   2073  1.1.1.1.2.1  pgoyette 	    case O_symbol:
   2074  1.1.1.1.2.1  pgoyette 	      break;
   2075  1.1.1.1.2.1  pgoyette 
   2076  1.1.1.1.2.1  pgoyette 	    default:
   2077  1.1.1.1.2.1  pgoyette 	      /* Ignored.  */
   2078  1.1.1.1.2.1  pgoyette 	      break;
   2079  1.1.1.1.2.1  pgoyette 	    }
   2080  1.1.1.1.2.1  pgoyette 	}
   2081  1.1.1.1.2.1  pgoyette     }
   2082  1.1.1.1.2.1  pgoyette 
   2083  1.1.1.1.2.1  pgoyette   /* Swap operands if necessary.  Only supports one swap at the
   2084  1.1.1.1.2.1  pgoyette      moment.  */
   2085  1.1.1.1.2.1  pgoyette   for (i = 0; i < pseudo_insn->operand_cnt; ++i)
   2086  1.1.1.1.2.1  pgoyette     {
   2087  1.1.1.1.2.1  pgoyette       operand_pseudo = &pseudo_insn->operand[i];
   2088  1.1.1.1.2.1  pgoyette 
   2089  1.1.1.1.2.1  pgoyette       if (operand_pseudo->swap_operand_idx == i)
   2090  1.1.1.1.2.1  pgoyette 	continue;
   2091  1.1.1.1.2.1  pgoyette 
   2092  1.1.1.1.2.1  pgoyette       swap_operand (tok, i, operand_pseudo->swap_operand_idx);
   2093  1.1.1.1.2.1  pgoyette 
   2094  1.1.1.1.2.1  pgoyette       /* Prevent a swap back later by breaking out.  */
   2095  1.1.1.1.2.1  pgoyette       break;
   2096  1.1.1.1.2.1  pgoyette     }
   2097  1.1.1.1.2.1  pgoyette 
   2098  1.1.1.1.2.1  pgoyette   return (const struct arc_opcode *)
   2099  1.1.1.1.2.1  pgoyette     hash_find (arc_opcode_hash,	pseudo_insn->mnemonic_r);
   2100  1.1.1.1.2.1  pgoyette }
   2101  1.1.1.1.2.1  pgoyette 
   2102  1.1.1.1.2.1  pgoyette static const struct arc_opcode *
   2103  1.1.1.1.2.1  pgoyette find_special_case_flag (const char *opname,
   2104  1.1.1.1.2.1  pgoyette 			int *nflgs,
   2105  1.1.1.1.2.1  pgoyette 			struct arc_flags *pflags)
   2106  1.1.1.1.2.1  pgoyette {
   2107  1.1.1.1.2.1  pgoyette   unsigned int i;
   2108  1.1.1.1.2.1  pgoyette   const char *flagnm;
   2109  1.1.1.1.2.1  pgoyette   unsigned flag_idx, flag_arr_idx;
   2110  1.1.1.1.2.1  pgoyette   size_t flaglen, oplen;
   2111  1.1.1.1.2.1  pgoyette   const struct arc_flag_special *arc_flag_special_opcode;
   2112  1.1.1.1.2.1  pgoyette   const struct arc_opcode *opcode;
   2113  1.1.1.1.2.1  pgoyette 
   2114  1.1.1.1.2.1  pgoyette   /* Search for special case instruction.  */
   2115  1.1.1.1.2.1  pgoyette   for (i = 0; i < arc_num_flag_special; i++)
   2116  1.1.1.1.2.1  pgoyette     {
   2117  1.1.1.1.2.1  pgoyette       arc_flag_special_opcode = &arc_flag_special_cases[i];
   2118  1.1.1.1.2.1  pgoyette       oplen = strlen (arc_flag_special_opcode->name);
   2119  1.1.1.1.2.1  pgoyette 
   2120  1.1.1.1.2.1  pgoyette       if (strncmp (opname, arc_flag_special_opcode->name, oplen) != 0)
   2121  1.1.1.1.2.1  pgoyette 	continue;
   2122  1.1.1.1.2.1  pgoyette 
   2123  1.1.1.1.2.1  pgoyette       /* Found a potential special case instruction, now test for
   2124  1.1.1.1.2.1  pgoyette 	 flags.  */
   2125  1.1.1.1.2.1  pgoyette       for (flag_arr_idx = 0;; ++flag_arr_idx)
   2126  1.1.1.1.2.1  pgoyette 	{
   2127  1.1.1.1.2.1  pgoyette 	  flag_idx = arc_flag_special_opcode->flags[flag_arr_idx];
   2128  1.1.1.1.2.1  pgoyette 	  if (flag_idx == 0)
   2129  1.1.1.1.2.1  pgoyette 	    break;  /* End of array, nothing found.  */
   2130  1.1.1.1.2.1  pgoyette 
   2131  1.1.1.1.2.1  pgoyette 	  flagnm = arc_flag_operands[flag_idx].name;
   2132  1.1.1.1.2.1  pgoyette 	  flaglen = strlen (flagnm);
   2133  1.1.1.1.2.1  pgoyette 	  if (strcmp (opname + oplen, flagnm) == 0)
   2134  1.1.1.1.2.1  pgoyette 	    {
   2135  1.1.1.1.2.1  pgoyette 	      opcode = (const struct arc_opcode *)
   2136  1.1.1.1.2.1  pgoyette 		hash_find (arc_opcode_hash,
   2137  1.1.1.1.2.1  pgoyette 			   arc_flag_special_opcode->name);
   2138  1.1.1.1.2.1  pgoyette 
   2139  1.1.1.1.2.1  pgoyette 	      if (*nflgs + 1 > MAX_INSN_FLGS)
   2140  1.1.1.1.2.1  pgoyette 		break;
   2141  1.1.1.1.2.1  pgoyette 	      memcpy (pflags[*nflgs].name, flagnm, flaglen);
   2142  1.1.1.1.2.1  pgoyette 	      pflags[*nflgs].name[flaglen] = '\0';
   2143  1.1.1.1.2.1  pgoyette 	      (*nflgs)++;
   2144  1.1.1.1.2.1  pgoyette 	      return opcode;
   2145  1.1.1.1.2.1  pgoyette 	    }
   2146  1.1.1.1.2.1  pgoyette 	}
   2147  1.1.1.1.2.1  pgoyette     }
   2148  1.1.1.1.2.1  pgoyette   return NULL;
   2149  1.1.1.1.2.1  pgoyette }
   2150  1.1.1.1.2.1  pgoyette 
   2151  1.1.1.1.2.1  pgoyette /* Check whether a symbol involves a register.  */
   2152  1.1.1.1.2.1  pgoyette 
   2153  1.1.1.1.2.1  pgoyette static int
   2154  1.1.1.1.2.1  pgoyette contains_register (symbolS *sym)
   2155  1.1.1.1.2.1  pgoyette {
   2156  1.1.1.1.2.1  pgoyette   if (sym)
   2157  1.1.1.1.2.1  pgoyette   {
   2158  1.1.1.1.2.1  pgoyette     expressionS *ex = symbol_get_value_expression (sym);
   2159  1.1.1.1.2.1  pgoyette     return ((O_register == ex->X_op)
   2160  1.1.1.1.2.1  pgoyette 	    && !contains_register (ex->X_add_symbol)
   2161  1.1.1.1.2.1  pgoyette 	    && !contains_register (ex->X_op_symbol));
   2162  1.1.1.1.2.1  pgoyette   }
   2163  1.1.1.1.2.1  pgoyette   else
   2164  1.1.1.1.2.1  pgoyette     return 0;
   2165  1.1.1.1.2.1  pgoyette }
   2166  1.1.1.1.2.1  pgoyette 
   2167  1.1.1.1.2.1  pgoyette /* Returns the register number within a symbol.  */
   2168  1.1.1.1.2.1  pgoyette 
   2169  1.1.1.1.2.1  pgoyette static int
   2170  1.1.1.1.2.1  pgoyette get_register (symbolS *sym)
   2171  1.1.1.1.2.1  pgoyette {
   2172  1.1.1.1.2.1  pgoyette   if (!contains_register (sym))
   2173  1.1.1.1.2.1  pgoyette     return -1;
   2174  1.1.1.1.2.1  pgoyette 
   2175  1.1.1.1.2.1  pgoyette   expressionS *ex = symbol_get_value_expression (sym);
   2176  1.1.1.1.2.1  pgoyette   return regno (ex->X_add_number);
   2177  1.1.1.1.2.1  pgoyette }
   2178  1.1.1.1.2.1  pgoyette 
   2179  1.1.1.1.2.1  pgoyette /* Allocates a tok entry.  */
   2180  1.1.1.1.2.1  pgoyette 
   2181  1.1.1.1.2.1  pgoyette static int
   2182  1.1.1.1.2.1  pgoyette allocate_tok (expressionS *tok, int ntok, int cidx)
   2183  1.1.1.1.2.1  pgoyette {
   2184  1.1.1.1.2.1  pgoyette   if (ntok > MAX_INSN_ARGS - 2)
   2185  1.1.1.1.2.1  pgoyette     return 0; /* No space left.  */
   2186  1.1.1.1.2.1  pgoyette 
   2187  1.1.1.1.2.1  pgoyette   if (cidx > ntok)
   2188  1.1.1.1.2.1  pgoyette     return 0; /* Incorect args.  */
   2189  1.1.1.1.2.1  pgoyette 
   2190  1.1.1.1.2.1  pgoyette   memcpy (&tok[ntok+1], &tok[ntok], sizeof (*tok));
   2191  1.1.1.1.2.1  pgoyette 
   2192  1.1.1.1.2.1  pgoyette   if (cidx == ntok)
   2193  1.1.1.1.2.1  pgoyette     return 1; /* Success.  */
   2194  1.1.1.1.2.1  pgoyette   return allocate_tok (tok, ntok - 1, cidx);
   2195  1.1.1.1.2.1  pgoyette }
   2196  1.1.1.1.2.1  pgoyette 
   2197  1.1.1.1.2.1  pgoyette /* Return true if a RELOC is generic.  A generic reloc is PC-rel of a
   2198  1.1.1.1.2.1  pgoyette    simple ME relocation (e.g. RELOC_ARC_32_ME, BFD_RELOC_ARC_PC32.  */
   2199  1.1.1.1.2.1  pgoyette 
   2200  1.1.1.1.2.1  pgoyette static bfd_boolean
   2201  1.1.1.1.2.1  pgoyette generic_reloc_p (extended_bfd_reloc_code_real_type reloc)
   2202  1.1.1.1.2.1  pgoyette {
   2203  1.1.1.1.2.1  pgoyette   if (!reloc)
   2204  1.1.1.1.2.1  pgoyette     return FALSE;
   2205  1.1.1.1.2.1  pgoyette 
   2206  1.1.1.1.2.1  pgoyette   switch (reloc)
   2207  1.1.1.1.2.1  pgoyette     {
   2208  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_SDA_LDST:
   2209  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_SDA_LDST1:
   2210  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_SDA_LDST2:
   2211  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_SDA16_LD:
   2212  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_SDA16_LD1:
   2213  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_SDA16_LD2:
   2214  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_SDA16_ST2:
   2215  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_SDA32_ME:
   2216  1.1.1.1.2.1  pgoyette       return FALSE;
   2217  1.1.1.1.2.1  pgoyette     default:
   2218  1.1.1.1.2.1  pgoyette       break;
   2219  1.1.1.1.2.1  pgoyette     }
   2220  1.1.1.1.2.1  pgoyette   return TRUE;
   2221  1.1.1.1.2.1  pgoyette }
   2222  1.1.1.1.2.1  pgoyette 
   2223  1.1.1.1.2.1  pgoyette /* Search forward through all variants of an opcode looking for a
   2224  1.1.1.1.2.1  pgoyette    syntax match.  */
   2225  1.1.1.1.2.1  pgoyette 
   2226  1.1.1.1.2.1  pgoyette static const struct arc_opcode *
   2227  1.1.1.1.2.1  pgoyette find_opcode_match (const struct arc_opcode *first_opcode,
   2228  1.1.1.1.2.1  pgoyette 		   expressionS *tok,
   2229  1.1.1.1.2.1  pgoyette 		   int *pntok,
   2230  1.1.1.1.2.1  pgoyette 		   struct arc_flags *first_pflag,
   2231  1.1.1.1.2.1  pgoyette 		   int nflgs,
   2232  1.1.1.1.2.1  pgoyette 		   int *pcpumatch)
   2233  1.1.1.1.2.1  pgoyette {
   2234  1.1.1.1.2.1  pgoyette   const struct arc_opcode *opcode = first_opcode;
   2235  1.1.1.1.2.1  pgoyette   int ntok = *pntok;
   2236  1.1.1.1.2.1  pgoyette   int got_cpu_match = 0;
   2237  1.1.1.1.2.1  pgoyette   expressionS bktok[MAX_INSN_ARGS];
   2238  1.1.1.1.2.1  pgoyette   int bkntok;
   2239  1.1.1.1.2.1  pgoyette   expressionS emptyE;
   2240  1.1.1.1.2.1  pgoyette 
   2241  1.1.1.1.2.1  pgoyette   memset (&emptyE, 0, sizeof (emptyE));
   2242  1.1.1.1.2.1  pgoyette   memcpy (bktok, tok, MAX_INSN_ARGS * sizeof (*tok));
   2243  1.1.1.1.2.1  pgoyette   bkntok = ntok;
   2244  1.1.1.1.2.1  pgoyette 
   2245  1.1.1.1.2.1  pgoyette   do
   2246  1.1.1.1.2.1  pgoyette     {
   2247  1.1.1.1.2.1  pgoyette       const unsigned char *opidx;
   2248  1.1.1.1.2.1  pgoyette       const unsigned char *flgidx;
   2249  1.1.1.1.2.1  pgoyette       int tokidx = 0;
   2250  1.1.1.1.2.1  pgoyette       const expressionS *t = &emptyE;
   2251  1.1.1.1.2.1  pgoyette 
   2252  1.1.1.1.2.1  pgoyette       pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08X ",
   2253  1.1.1.1.2.1  pgoyette 		frag_now->fr_file, frag_now->fr_line, opcode->opcode);
   2254  1.1.1.1.2.1  pgoyette 
   2255  1.1.1.1.2.1  pgoyette       /* Don't match opcodes that don't exist on this
   2256  1.1.1.1.2.1  pgoyette 	 architecture.  */
   2257  1.1.1.1.2.1  pgoyette       if (!(opcode->cpu & arc_target))
   2258  1.1.1.1.2.1  pgoyette 	goto match_failed;
   2259  1.1.1.1.2.1  pgoyette 
   2260  1.1.1.1.2.1  pgoyette       if (is_code_density_p (opcode) && !(arc_features & ARC_CD))
   2261  1.1.1.1.2.1  pgoyette 	goto match_failed;
   2262  1.1.1.1.2.1  pgoyette 
   2263  1.1.1.1.2.1  pgoyette       got_cpu_match = 1;
   2264  1.1.1.1.2.1  pgoyette       pr_debug ("cpu ");
   2265  1.1.1.1.2.1  pgoyette 
   2266  1.1.1.1.2.1  pgoyette       /* Check the operands.  */
   2267  1.1.1.1.2.1  pgoyette       for (opidx = opcode->operands; *opidx; ++opidx)
   2268  1.1.1.1.2.1  pgoyette 	{
   2269  1.1.1.1.2.1  pgoyette 	  const struct arc_operand *operand = &arc_operands[*opidx];
   2270  1.1.1.1.2.1  pgoyette 
   2271  1.1.1.1.2.1  pgoyette 	  /* Only take input from real operands.  */
   2272  1.1.1.1.2.1  pgoyette 	  if ((operand->flags & ARC_OPERAND_FAKE)
   2273  1.1.1.1.2.1  pgoyette 	      && !(operand->flags & ARC_OPERAND_BRAKET))
   2274  1.1.1.1.2.1  pgoyette 	    continue;
   2275  1.1.1.1.2.1  pgoyette 
   2276  1.1.1.1.2.1  pgoyette 	  /* When we expect input, make sure we have it.  */
   2277  1.1.1.1.2.1  pgoyette 	  if (tokidx >= ntok)
   2278  1.1.1.1.2.1  pgoyette 	    goto match_failed;
   2279  1.1.1.1.2.1  pgoyette 
   2280  1.1.1.1.2.1  pgoyette 	  /* Match operand type with expression type.  */
   2281  1.1.1.1.2.1  pgoyette 	  switch (operand->flags & ARC_OPERAND_TYPECHECK_MASK)
   2282  1.1.1.1.2.1  pgoyette 	    {
   2283  1.1.1.1.2.1  pgoyette 	    case ARC_OPERAND_IR:
   2284  1.1.1.1.2.1  pgoyette 	      /* Check to be a register.  */
   2285  1.1.1.1.2.1  pgoyette 	      if ((tok[tokidx].X_op != O_register
   2286  1.1.1.1.2.1  pgoyette 		   || !is_ir_num (tok[tokidx].X_add_number))
   2287  1.1.1.1.2.1  pgoyette 		  && !(operand->flags & ARC_OPERAND_IGNORE))
   2288  1.1.1.1.2.1  pgoyette 		goto match_failed;
   2289  1.1.1.1.2.1  pgoyette 
   2290  1.1.1.1.2.1  pgoyette 	      /* If expect duplicate, make sure it is duplicate.  */
   2291  1.1.1.1.2.1  pgoyette 	      if (operand->flags & ARC_OPERAND_DUPLICATE)
   2292  1.1.1.1.2.1  pgoyette 		{
   2293  1.1.1.1.2.1  pgoyette 		  /* Check for duplicate.  */
   2294  1.1.1.1.2.1  pgoyette 		  if (t->X_op != O_register
   2295  1.1.1.1.2.1  pgoyette 		      || !is_ir_num (t->X_add_number)
   2296  1.1.1.1.2.1  pgoyette 		      || (regno (t->X_add_number) !=
   2297  1.1.1.1.2.1  pgoyette 			  regno (tok[tokidx].X_add_number)))
   2298  1.1.1.1.2.1  pgoyette 		    goto match_failed;
   2299  1.1.1.1.2.1  pgoyette 		}
   2300  1.1.1.1.2.1  pgoyette 
   2301  1.1.1.1.2.1  pgoyette 	      /* Special handling?  */
   2302  1.1.1.1.2.1  pgoyette 	      if (operand->insert)
   2303  1.1.1.1.2.1  pgoyette 		{
   2304  1.1.1.1.2.1  pgoyette 		  const char *errmsg = NULL;
   2305  1.1.1.1.2.1  pgoyette 		  (*operand->insert)(0,
   2306  1.1.1.1.2.1  pgoyette 				     regno (tok[tokidx].X_add_number),
   2307  1.1.1.1.2.1  pgoyette 				     &errmsg);
   2308  1.1.1.1.2.1  pgoyette 		  if (errmsg)
   2309  1.1.1.1.2.1  pgoyette 		    {
   2310  1.1.1.1.2.1  pgoyette 		      if (operand->flags & ARC_OPERAND_IGNORE)
   2311  1.1.1.1.2.1  pgoyette 			{
   2312  1.1.1.1.2.1  pgoyette 			  /* Missing argument, create one.  */
   2313  1.1.1.1.2.1  pgoyette 			  if (!allocate_tok (tok, ntok - 1, tokidx))
   2314  1.1.1.1.2.1  pgoyette 			    goto match_failed;
   2315  1.1.1.1.2.1  pgoyette 
   2316  1.1.1.1.2.1  pgoyette 			  tok[tokidx].X_op = O_absent;
   2317  1.1.1.1.2.1  pgoyette 			  ++ntok;
   2318  1.1.1.1.2.1  pgoyette 			}
   2319  1.1.1.1.2.1  pgoyette 		      else
   2320  1.1.1.1.2.1  pgoyette 			goto match_failed;
   2321  1.1.1.1.2.1  pgoyette 		    }
   2322  1.1.1.1.2.1  pgoyette 		}
   2323  1.1.1.1.2.1  pgoyette 
   2324  1.1.1.1.2.1  pgoyette 	      t = &tok[tokidx];
   2325  1.1.1.1.2.1  pgoyette 	      break;
   2326  1.1.1.1.2.1  pgoyette 
   2327  1.1.1.1.2.1  pgoyette 	    case ARC_OPERAND_BRAKET:
   2328  1.1.1.1.2.1  pgoyette 	      /* Check if bracket is also in opcode table as
   2329  1.1.1.1.2.1  pgoyette 		 operand.  */
   2330  1.1.1.1.2.1  pgoyette 	      if (tok[tokidx].X_op != O_bracket)
   2331  1.1.1.1.2.1  pgoyette 		goto match_failed;
   2332  1.1.1.1.2.1  pgoyette 	      break;
   2333  1.1.1.1.2.1  pgoyette 
   2334  1.1.1.1.2.1  pgoyette 	    case ARC_OPERAND_LIMM:
   2335  1.1.1.1.2.1  pgoyette 	    case ARC_OPERAND_SIGNED:
   2336  1.1.1.1.2.1  pgoyette 	    case ARC_OPERAND_UNSIGNED:
   2337  1.1.1.1.2.1  pgoyette 	      switch (tok[tokidx].X_op)
   2338  1.1.1.1.2.1  pgoyette 		{
   2339  1.1.1.1.2.1  pgoyette 		case O_illegal:
   2340  1.1.1.1.2.1  pgoyette 		case O_absent:
   2341  1.1.1.1.2.1  pgoyette 		case O_register:
   2342  1.1.1.1.2.1  pgoyette 		  goto match_failed;
   2343  1.1.1.1.2.1  pgoyette 
   2344  1.1.1.1.2.1  pgoyette 		case O_bracket:
   2345  1.1.1.1.2.1  pgoyette 		  /* Got an (too) early bracket, check if it is an
   2346  1.1.1.1.2.1  pgoyette 		     ignored operand.  N.B. This procedure works only
   2347  1.1.1.1.2.1  pgoyette 		     when bracket is the last operand!  */
   2348  1.1.1.1.2.1  pgoyette 		  if (!(operand->flags & ARC_OPERAND_IGNORE))
   2349  1.1.1.1.2.1  pgoyette 		    goto match_failed;
   2350  1.1.1.1.2.1  pgoyette 		  /* Insert the missing operand.  */
   2351  1.1.1.1.2.1  pgoyette 		  if (!allocate_tok (tok, ntok - 1, tokidx))
   2352  1.1.1.1.2.1  pgoyette 		    goto match_failed;
   2353  1.1.1.1.2.1  pgoyette 
   2354  1.1.1.1.2.1  pgoyette 		  tok[tokidx].X_op = O_absent;
   2355  1.1.1.1.2.1  pgoyette 		  ++ntok;
   2356  1.1.1.1.2.1  pgoyette 		  break;
   2357  1.1.1.1.2.1  pgoyette 
   2358  1.1.1.1.2.1  pgoyette 		case O_constant:
   2359  1.1.1.1.2.1  pgoyette 		  /* Check the range.  */
   2360  1.1.1.1.2.1  pgoyette 		  if (operand->bits != 32
   2361  1.1.1.1.2.1  pgoyette 		      && !(operand->flags & ARC_OPERAND_NCHK))
   2362  1.1.1.1.2.1  pgoyette 		    {
   2363  1.1.1.1.2.1  pgoyette 		      offsetT min, max, val;
   2364  1.1.1.1.2.1  pgoyette 		      val = tok[tokidx].X_add_number;
   2365  1.1.1.1.2.1  pgoyette 
   2366  1.1.1.1.2.1  pgoyette 		      if (operand->flags & ARC_OPERAND_SIGNED)
   2367  1.1.1.1.2.1  pgoyette 			{
   2368  1.1.1.1.2.1  pgoyette 			  max = (1 << (operand->bits - 1)) - 1;
   2369  1.1.1.1.2.1  pgoyette 			  min = -(1 << (operand->bits - 1));
   2370  1.1.1.1.2.1  pgoyette 			}
   2371  1.1.1.1.2.1  pgoyette 		      else
   2372  1.1.1.1.2.1  pgoyette 			{
   2373  1.1.1.1.2.1  pgoyette 			  max = (1 << operand->bits) - 1;
   2374  1.1.1.1.2.1  pgoyette 			  min = 0;
   2375  1.1.1.1.2.1  pgoyette 			}
   2376  1.1.1.1.2.1  pgoyette 
   2377  1.1.1.1.2.1  pgoyette 		      if (val < min || val > max)
   2378  1.1.1.1.2.1  pgoyette 			goto match_failed;
   2379  1.1.1.1.2.1  pgoyette 
   2380  1.1.1.1.2.1  pgoyette 		      /* Check alignmets.  */
   2381  1.1.1.1.2.1  pgoyette 		      if ((operand->flags & ARC_OPERAND_ALIGNED32)
   2382  1.1.1.1.2.1  pgoyette 			  && (val & 0x03))
   2383  1.1.1.1.2.1  pgoyette 			goto match_failed;
   2384  1.1.1.1.2.1  pgoyette 
   2385  1.1.1.1.2.1  pgoyette 		      if ((operand->flags & ARC_OPERAND_ALIGNED16)
   2386  1.1.1.1.2.1  pgoyette 			  && (val & 0x01))
   2387  1.1.1.1.2.1  pgoyette 			goto match_failed;
   2388  1.1.1.1.2.1  pgoyette 		    }
   2389  1.1.1.1.2.1  pgoyette 		  else if (operand->flags & ARC_OPERAND_NCHK)
   2390  1.1.1.1.2.1  pgoyette 		    {
   2391  1.1.1.1.2.1  pgoyette 		      if (operand->insert)
   2392  1.1.1.1.2.1  pgoyette 			{
   2393  1.1.1.1.2.1  pgoyette 			  const char *errmsg = NULL;
   2394  1.1.1.1.2.1  pgoyette 			  (*operand->insert)(0,
   2395  1.1.1.1.2.1  pgoyette 					     tok[tokidx].X_add_number,
   2396  1.1.1.1.2.1  pgoyette 					     &errmsg);
   2397  1.1.1.1.2.1  pgoyette 			  if (errmsg)
   2398  1.1.1.1.2.1  pgoyette 			    goto match_failed;
   2399  1.1.1.1.2.1  pgoyette 			}
   2400  1.1.1.1.2.1  pgoyette 		      else
   2401  1.1.1.1.2.1  pgoyette 			goto match_failed;
   2402  1.1.1.1.2.1  pgoyette 		    }
   2403  1.1.1.1.2.1  pgoyette 		  break;
   2404  1.1.1.1.2.1  pgoyette 
   2405  1.1.1.1.2.1  pgoyette 		case O_subtract:
   2406  1.1.1.1.2.1  pgoyette 		  /* Check if it is register range.  */
   2407  1.1.1.1.2.1  pgoyette 		  if ((tok[tokidx].X_add_number == 0)
   2408  1.1.1.1.2.1  pgoyette 		      && contains_register (tok[tokidx].X_add_symbol)
   2409  1.1.1.1.2.1  pgoyette 		      && contains_register (tok[tokidx].X_op_symbol))
   2410  1.1.1.1.2.1  pgoyette 		    {
   2411  1.1.1.1.2.1  pgoyette 		      int regs;
   2412  1.1.1.1.2.1  pgoyette 
   2413  1.1.1.1.2.1  pgoyette 		      regs = get_register (tok[tokidx].X_add_symbol);
   2414  1.1.1.1.2.1  pgoyette 		      regs <<= 16;
   2415  1.1.1.1.2.1  pgoyette 		      regs |= get_register (tok[tokidx].X_op_symbol);
   2416  1.1.1.1.2.1  pgoyette 		      if (operand->insert)
   2417  1.1.1.1.2.1  pgoyette 			{
   2418  1.1.1.1.2.1  pgoyette 			  const char *errmsg = NULL;
   2419  1.1.1.1.2.1  pgoyette 			  (*operand->insert)(0,
   2420  1.1.1.1.2.1  pgoyette 					     regs,
   2421  1.1.1.1.2.1  pgoyette 					     &errmsg);
   2422  1.1.1.1.2.1  pgoyette 			  if (errmsg)
   2423  1.1.1.1.2.1  pgoyette 			    goto match_failed;
   2424  1.1.1.1.2.1  pgoyette 			}
   2425  1.1.1.1.2.1  pgoyette 		      else
   2426  1.1.1.1.2.1  pgoyette 			goto match_failed;
   2427  1.1.1.1.2.1  pgoyette 		      break;
   2428  1.1.1.1.2.1  pgoyette 		    }
   2429  1.1.1.1.2.1  pgoyette 		default:
   2430  1.1.1.1.2.1  pgoyette 		  if (operand->default_reloc == 0)
   2431  1.1.1.1.2.1  pgoyette 		    goto match_failed; /* The operand needs relocation.  */
   2432  1.1.1.1.2.1  pgoyette 
   2433  1.1.1.1.2.1  pgoyette 		  /* Relocs requiring long immediate.  FIXME! make it
   2434  1.1.1.1.2.1  pgoyette 		     generic and move it to a function.  */
   2435  1.1.1.1.2.1  pgoyette 		  switch (tok[tokidx].X_md)
   2436  1.1.1.1.2.1  pgoyette 		    {
   2437  1.1.1.1.2.1  pgoyette 		    case O_gotoff:
   2438  1.1.1.1.2.1  pgoyette 		    case O_gotpc:
   2439  1.1.1.1.2.1  pgoyette 		    case O_pcl:
   2440  1.1.1.1.2.1  pgoyette 		    case O_tpoff:
   2441  1.1.1.1.2.1  pgoyette 		    case O_dtpoff:
   2442  1.1.1.1.2.1  pgoyette 		    case O_tlsgd:
   2443  1.1.1.1.2.1  pgoyette 		    case O_tlsie:
   2444  1.1.1.1.2.1  pgoyette 		      if (!(operand->flags & ARC_OPERAND_LIMM))
   2445  1.1.1.1.2.1  pgoyette 			goto match_failed;
   2446  1.1.1.1.2.1  pgoyette 		    case O_absent:
   2447  1.1.1.1.2.1  pgoyette 		      if (!generic_reloc_p (operand->default_reloc))
   2448  1.1.1.1.2.1  pgoyette 			goto match_failed;
   2449  1.1.1.1.2.1  pgoyette 		    default:
   2450  1.1.1.1.2.1  pgoyette 		      break;
   2451  1.1.1.1.2.1  pgoyette 		    }
   2452  1.1.1.1.2.1  pgoyette 		  break;
   2453  1.1.1.1.2.1  pgoyette 		}
   2454  1.1.1.1.2.1  pgoyette 	      /* If expect duplicate, make sure it is duplicate.  */
   2455  1.1.1.1.2.1  pgoyette 	      if (operand->flags & ARC_OPERAND_DUPLICATE)
   2456  1.1.1.1.2.1  pgoyette 		{
   2457  1.1.1.1.2.1  pgoyette 		  if (t->X_op == O_illegal
   2458  1.1.1.1.2.1  pgoyette 		      || t->X_op == O_absent
   2459  1.1.1.1.2.1  pgoyette 		      || t->X_op == O_register
   2460  1.1.1.1.2.1  pgoyette 		      || (t->X_add_number != tok[tokidx].X_add_number))
   2461  1.1.1.1.2.1  pgoyette 		    goto match_failed;
   2462  1.1.1.1.2.1  pgoyette 		}
   2463  1.1.1.1.2.1  pgoyette 	      t = &tok[tokidx];
   2464  1.1.1.1.2.1  pgoyette 	      break;
   2465  1.1.1.1.2.1  pgoyette 
   2466  1.1.1.1.2.1  pgoyette 	    default:
   2467  1.1.1.1.2.1  pgoyette 	      /* Everything else should have been fake.  */
   2468  1.1.1.1.2.1  pgoyette 	      abort ();
   2469  1.1.1.1.2.1  pgoyette 	    }
   2470  1.1.1.1.2.1  pgoyette 
   2471  1.1.1.1.2.1  pgoyette 	  ++tokidx;
   2472  1.1.1.1.2.1  pgoyette 	}
   2473  1.1.1.1.2.1  pgoyette       pr_debug ("opr ");
   2474  1.1.1.1.2.1  pgoyette 
   2475  1.1.1.1.2.1  pgoyette       /* Check the flags.  Iterate over the valid flag classes.  */
   2476  1.1.1.1.2.1  pgoyette       int lnflg = nflgs;
   2477  1.1.1.1.2.1  pgoyette 
   2478  1.1.1.1.2.1  pgoyette       for (flgidx = opcode->flags; *flgidx && lnflg; ++flgidx)
   2479  1.1.1.1.2.1  pgoyette 	{
   2480  1.1.1.1.2.1  pgoyette 	  /* Get a valid flag class.  */
   2481  1.1.1.1.2.1  pgoyette 	  const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
   2482  1.1.1.1.2.1  pgoyette 	  const unsigned *flgopridx;
   2483  1.1.1.1.2.1  pgoyette 
   2484  1.1.1.1.2.1  pgoyette 	  for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
   2485  1.1.1.1.2.1  pgoyette 	    {
   2486  1.1.1.1.2.1  pgoyette 	      const struct arc_flag_operand *flg_operand;
   2487  1.1.1.1.2.1  pgoyette 	      struct arc_flags *pflag = first_pflag;
   2488  1.1.1.1.2.1  pgoyette 	      int i;
   2489  1.1.1.1.2.1  pgoyette 
   2490  1.1.1.1.2.1  pgoyette 	      flg_operand = &arc_flag_operands[*flgopridx];
   2491  1.1.1.1.2.1  pgoyette 	      for (i = 0; i < nflgs; i++, pflag++)
   2492  1.1.1.1.2.1  pgoyette 		{
   2493  1.1.1.1.2.1  pgoyette 		  /* Match against the parsed flags.  */
   2494  1.1.1.1.2.1  pgoyette 		  if (!strcmp (flg_operand->name, pflag->name))
   2495  1.1.1.1.2.1  pgoyette 		    {
   2496  1.1.1.1.2.1  pgoyette 		      /*TODO: Check if it is duplicated.  */
   2497  1.1.1.1.2.1  pgoyette 		      pflag->code = *flgopridx;
   2498  1.1.1.1.2.1  pgoyette 		      lnflg--;
   2499  1.1.1.1.2.1  pgoyette 		      break; /* goto next flag class and parsed flag.  */
   2500  1.1.1.1.2.1  pgoyette 		    }
   2501  1.1.1.1.2.1  pgoyette 		}
   2502  1.1.1.1.2.1  pgoyette 	    }
   2503  1.1.1.1.2.1  pgoyette 	}
   2504  1.1.1.1.2.1  pgoyette       /* Did I check all the parsed flags?  */
   2505  1.1.1.1.2.1  pgoyette       if (lnflg)
   2506  1.1.1.1.2.1  pgoyette 	goto match_failed;
   2507  1.1.1.1.2.1  pgoyette 
   2508  1.1.1.1.2.1  pgoyette       pr_debug ("flg");
   2509  1.1.1.1.2.1  pgoyette       /* Possible match -- did we use all of our input?  */
   2510  1.1.1.1.2.1  pgoyette       if (tokidx == ntok)
   2511  1.1.1.1.2.1  pgoyette 	{
   2512  1.1.1.1.2.1  pgoyette 	  *pntok = ntok;
   2513  1.1.1.1.2.1  pgoyette 	  pr_debug ("\n");
   2514  1.1.1.1.2.1  pgoyette 	  return opcode;
   2515  1.1.1.1.2.1  pgoyette 	}
   2516  1.1.1.1.2.1  pgoyette 
   2517  1.1.1.1.2.1  pgoyette     match_failed:;
   2518  1.1.1.1.2.1  pgoyette       pr_debug ("\n");
   2519  1.1.1.1.2.1  pgoyette       /* Restore the original parameters.  */
   2520  1.1.1.1.2.1  pgoyette       memcpy (tok, bktok, MAX_INSN_ARGS * sizeof (*tok));
   2521  1.1.1.1.2.1  pgoyette       ntok = bkntok;
   2522  1.1.1.1.2.1  pgoyette     }
   2523  1.1.1.1.2.1  pgoyette   while (++opcode - arc_opcodes < (int) arc_num_opcodes
   2524  1.1.1.1.2.1  pgoyette 	 && !strcmp (opcode->name, first_opcode->name));
   2525  1.1.1.1.2.1  pgoyette 
   2526  1.1.1.1.2.1  pgoyette   if (*pcpumatch)
   2527  1.1.1.1.2.1  pgoyette     *pcpumatch = got_cpu_match;
   2528  1.1.1.1.2.1  pgoyette 
   2529  1.1.1.1.2.1  pgoyette   return NULL;
   2530  1.1.1.1.2.1  pgoyette }
   2531  1.1.1.1.2.1  pgoyette 
   2532  1.1.1.1.2.1  pgoyette /* Find the proper relocation for the given opcode.  */
   2533  1.1.1.1.2.1  pgoyette 
   2534  1.1.1.1.2.1  pgoyette static extended_bfd_reloc_code_real_type
   2535  1.1.1.1.2.1  pgoyette find_reloc (const char *name,
   2536  1.1.1.1.2.1  pgoyette 	    const char *opcodename,
   2537  1.1.1.1.2.1  pgoyette 	    const struct arc_flags *pflags,
   2538  1.1.1.1.2.1  pgoyette 	    int nflg,
   2539  1.1.1.1.2.1  pgoyette 	    extended_bfd_reloc_code_real_type reloc)
   2540  1.1.1.1.2.1  pgoyette {
   2541  1.1.1.1.2.1  pgoyette   unsigned int i;
   2542  1.1.1.1.2.1  pgoyette   int j;
   2543  1.1.1.1.2.1  pgoyette   bfd_boolean found_flag;
   2544  1.1.1.1.2.1  pgoyette   extended_bfd_reloc_code_real_type ret = BFD_RELOC_UNUSED;
   2545  1.1.1.1.2.1  pgoyette 
   2546  1.1.1.1.2.1  pgoyette   for (i = 0; i < arc_num_equiv_tab; i++)
   2547  1.1.1.1.2.1  pgoyette     {
   2548  1.1.1.1.2.1  pgoyette       const struct arc_reloc_equiv_tab *r = &arc_reloc_equiv[i];
   2549  1.1.1.1.2.1  pgoyette 
   2550  1.1.1.1.2.1  pgoyette       /* Find the entry.  */
   2551  1.1.1.1.2.1  pgoyette       if (strcmp (name, r->name))
   2552  1.1.1.1.2.1  pgoyette 	continue;
   2553  1.1.1.1.2.1  pgoyette       if (r->mnemonic && (strcmp (r->mnemonic, opcodename)))
   2554  1.1.1.1.2.1  pgoyette 	continue;
   2555  1.1.1.1.2.1  pgoyette       if (r->flagcode)
   2556  1.1.1.1.2.1  pgoyette 	{
   2557  1.1.1.1.2.1  pgoyette 	  if (!nflg)
   2558  1.1.1.1.2.1  pgoyette 	    continue;
   2559  1.1.1.1.2.1  pgoyette 	  found_flag = FALSE;
   2560  1.1.1.1.2.1  pgoyette 	  for (j = 0; j < nflg; j++)
   2561  1.1.1.1.2.1  pgoyette 	    if (pflags[i].code == r->flagcode)
   2562  1.1.1.1.2.1  pgoyette 	      {
   2563  1.1.1.1.2.1  pgoyette 		found_flag = TRUE;
   2564  1.1.1.1.2.1  pgoyette 		break;
   2565  1.1.1.1.2.1  pgoyette 	      }
   2566  1.1.1.1.2.1  pgoyette 	  if (!found_flag)
   2567  1.1.1.1.2.1  pgoyette 	    continue;
   2568  1.1.1.1.2.1  pgoyette 	}
   2569  1.1.1.1.2.1  pgoyette 
   2570  1.1.1.1.2.1  pgoyette       if (reloc != r->oldreloc)
   2571  1.1.1.1.2.1  pgoyette 	continue;
   2572  1.1.1.1.2.1  pgoyette       /* Found it.  */
   2573  1.1.1.1.2.1  pgoyette       ret = r->newreloc;
   2574  1.1.1.1.2.1  pgoyette       break;
   2575  1.1.1.1.2.1  pgoyette     }
   2576  1.1.1.1.2.1  pgoyette 
   2577  1.1.1.1.2.1  pgoyette   if (ret == BFD_RELOC_UNUSED)
   2578  1.1.1.1.2.1  pgoyette     as_bad (_("Unable to find %s relocation for instruction %s"),
   2579  1.1.1.1.2.1  pgoyette 	    name, opcodename);
   2580  1.1.1.1.2.1  pgoyette   return ret;
   2581  1.1.1.1.2.1  pgoyette }
   2582  1.1.1.1.2.1  pgoyette 
   2583  1.1.1.1.2.1  pgoyette /* Turn an opcode description and a set of arguments into
   2584  1.1.1.1.2.1  pgoyette    an instruction and a fixup.  */
   2585  1.1.1.1.2.1  pgoyette 
   2586  1.1.1.1.2.1  pgoyette static void
   2587  1.1.1.1.2.1  pgoyette assemble_insn (const struct arc_opcode *opcode,
   2588  1.1.1.1.2.1  pgoyette 	       const expressionS *tok,
   2589  1.1.1.1.2.1  pgoyette 	       int ntok,
   2590  1.1.1.1.2.1  pgoyette 	       const struct arc_flags *pflags,
   2591  1.1.1.1.2.1  pgoyette 	       int nflg,
   2592  1.1.1.1.2.1  pgoyette 	       struct arc_insn *insn)
   2593  1.1.1.1.2.1  pgoyette {
   2594  1.1.1.1.2.1  pgoyette   const expressionS *reloc_exp = NULL;
   2595  1.1.1.1.2.1  pgoyette   unsigned image;
   2596  1.1.1.1.2.1  pgoyette   const unsigned char *argidx;
   2597  1.1.1.1.2.1  pgoyette   int i;
   2598  1.1.1.1.2.1  pgoyette   int tokidx = 0;
   2599  1.1.1.1.2.1  pgoyette   unsigned char pcrel = 0;
   2600  1.1.1.1.2.1  pgoyette   bfd_boolean needGOTSymbol;
   2601  1.1.1.1.2.1  pgoyette   bfd_boolean has_delay_slot = FALSE;
   2602  1.1.1.1.2.1  pgoyette   extended_bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
   2603  1.1.1.1.2.1  pgoyette 
   2604  1.1.1.1.2.1  pgoyette   memset (insn, 0, sizeof (*insn));
   2605  1.1.1.1.2.1  pgoyette   image = opcode->opcode;
   2606  1.1.1.1.2.1  pgoyette 
   2607  1.1.1.1.2.1  pgoyette   pr_debug ("%s:%d: assemble_insn: %s using opcode %x\n",
   2608  1.1.1.1.2.1  pgoyette 	    frag_now->fr_file, frag_now->fr_line, opcode->name,
   2609  1.1.1.1.2.1  pgoyette 	    opcode->opcode);
   2610  1.1.1.1.2.1  pgoyette 
   2611  1.1.1.1.2.1  pgoyette   /* Handle operands.  */
   2612  1.1.1.1.2.1  pgoyette   for (argidx = opcode->operands; *argidx; ++argidx)
   2613  1.1.1.1.2.1  pgoyette     {
   2614  1.1.1.1.2.1  pgoyette       const struct arc_operand *operand = &arc_operands[*argidx];
   2615  1.1.1.1.2.1  pgoyette       const expressionS *t = (const expressionS *) 0;
   2616  1.1.1.1.2.1  pgoyette 
   2617  1.1.1.1.2.1  pgoyette       if ((operand->flags & ARC_OPERAND_FAKE)
   2618  1.1.1.1.2.1  pgoyette 	  && !(operand->flags & ARC_OPERAND_BRAKET))
   2619  1.1.1.1.2.1  pgoyette 	continue;
   2620  1.1.1.1.2.1  pgoyette 
   2621  1.1.1.1.2.1  pgoyette       if (operand->flags & ARC_OPERAND_DUPLICATE)
   2622  1.1.1.1.2.1  pgoyette 	{
   2623  1.1.1.1.2.1  pgoyette 	  /* Duplicate operand, already inserted.  */
   2624  1.1.1.1.2.1  pgoyette 	  tokidx ++;
   2625  1.1.1.1.2.1  pgoyette 	  continue;
   2626  1.1.1.1.2.1  pgoyette 	}
   2627  1.1.1.1.2.1  pgoyette 
   2628  1.1.1.1.2.1  pgoyette       if (tokidx >= ntok)
   2629  1.1.1.1.2.1  pgoyette 	{
   2630  1.1.1.1.2.1  pgoyette 	  abort ();
   2631  1.1.1.1.2.1  pgoyette 	}
   2632  1.1.1.1.2.1  pgoyette       else
   2633  1.1.1.1.2.1  pgoyette 	t = &tok[tokidx++];
   2634  1.1.1.1.2.1  pgoyette 
   2635  1.1.1.1.2.1  pgoyette       /* Regardless if we have a reloc or not mark the instruction
   2636  1.1.1.1.2.1  pgoyette 	 limm if it is the case.  */
   2637  1.1.1.1.2.1  pgoyette       if (operand->flags & ARC_OPERAND_LIMM)
   2638  1.1.1.1.2.1  pgoyette 	insn->has_limm = TRUE;
   2639  1.1.1.1.2.1  pgoyette 
   2640  1.1.1.1.2.1  pgoyette       switch (t->X_op)
   2641  1.1.1.1.2.1  pgoyette 	{
   2642  1.1.1.1.2.1  pgoyette 	case O_register:
   2643  1.1.1.1.2.1  pgoyette 	  image = insert_operand (image, operand, regno (t->X_add_number),
   2644  1.1.1.1.2.1  pgoyette 				  NULL, 0);
   2645  1.1.1.1.2.1  pgoyette 	  break;
   2646  1.1.1.1.2.1  pgoyette 
   2647  1.1.1.1.2.1  pgoyette 	case O_constant:
   2648  1.1.1.1.2.1  pgoyette 	  image = insert_operand (image, operand, t->X_add_number, NULL, 0);
   2649  1.1.1.1.2.1  pgoyette 	  reloc_exp = t;
   2650  1.1.1.1.2.1  pgoyette 	  if (operand->flags & ARC_OPERAND_LIMM)
   2651  1.1.1.1.2.1  pgoyette 	    insn->limm = t->X_add_number;
   2652  1.1.1.1.2.1  pgoyette 	  break;
   2653  1.1.1.1.2.1  pgoyette 
   2654  1.1.1.1.2.1  pgoyette 	case O_bracket:
   2655  1.1.1.1.2.1  pgoyette 	  /* Ignore brackets.  */
   2656  1.1.1.1.2.1  pgoyette 	  break;
   2657  1.1.1.1.2.1  pgoyette 
   2658  1.1.1.1.2.1  pgoyette 	case O_absent:
   2659  1.1.1.1.2.1  pgoyette 	  gas_assert (operand->flags & ARC_OPERAND_IGNORE);
   2660  1.1.1.1.2.1  pgoyette 	  break;
   2661  1.1.1.1.2.1  pgoyette 
   2662  1.1.1.1.2.1  pgoyette 	case O_subtract:
   2663  1.1.1.1.2.1  pgoyette 	  /* Maybe register range.  */
   2664  1.1.1.1.2.1  pgoyette 	  if ((t->X_add_number == 0)
   2665  1.1.1.1.2.1  pgoyette 	      && contains_register (t->X_add_symbol)
   2666  1.1.1.1.2.1  pgoyette 	      && contains_register (t->X_op_symbol))
   2667  1.1.1.1.2.1  pgoyette 	    {
   2668  1.1.1.1.2.1  pgoyette 	      int regs;
   2669  1.1.1.1.2.1  pgoyette 
   2670  1.1.1.1.2.1  pgoyette 	      regs = get_register (t->X_add_symbol);
   2671  1.1.1.1.2.1  pgoyette 	      regs <<= 16;
   2672  1.1.1.1.2.1  pgoyette 	      regs |= get_register (t->X_op_symbol);
   2673  1.1.1.1.2.1  pgoyette 	      image = insert_operand (image, operand, regs, NULL, 0);
   2674  1.1.1.1.2.1  pgoyette 	      break;
   2675  1.1.1.1.2.1  pgoyette 	    }
   2676  1.1.1.1.2.1  pgoyette 
   2677  1.1.1.1.2.1  pgoyette 	default:
   2678  1.1.1.1.2.1  pgoyette 	  /* This operand needs a relocation.  */
   2679  1.1.1.1.2.1  pgoyette 	  needGOTSymbol = FALSE;
   2680  1.1.1.1.2.1  pgoyette 
   2681  1.1.1.1.2.1  pgoyette 	  switch (t->X_md)
   2682  1.1.1.1.2.1  pgoyette 	    {
   2683  1.1.1.1.2.1  pgoyette 	    case O_plt:
   2684  1.1.1.1.2.1  pgoyette 	      needGOTSymbol = TRUE;
   2685  1.1.1.1.2.1  pgoyette 	      reloc = find_reloc ("plt", opcode->name,
   2686  1.1.1.1.2.1  pgoyette 				  pflags, nflg,
   2687  1.1.1.1.2.1  pgoyette 				  operand->default_reloc);
   2688  1.1.1.1.2.1  pgoyette 	      break;
   2689  1.1.1.1.2.1  pgoyette 
   2690  1.1.1.1.2.1  pgoyette 	    case O_gotoff:
   2691  1.1.1.1.2.1  pgoyette 	    case O_gotpc:
   2692  1.1.1.1.2.1  pgoyette 	      needGOTSymbol = TRUE;
   2693  1.1.1.1.2.1  pgoyette 	      reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
   2694  1.1.1.1.2.1  pgoyette 	      break;
   2695  1.1.1.1.2.1  pgoyette 	    case O_pcl:
   2696  1.1.1.1.2.1  pgoyette 	      reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
   2697  1.1.1.1.2.1  pgoyette 	      if (ARC_SHORT (opcode->mask))
   2698  1.1.1.1.2.1  pgoyette 		as_bad_where (frag_now->fr_file, frag_now->fr_line,
   2699  1.1.1.1.2.1  pgoyette 			      _("Unable to use @pcl relocation for insn %s"),
   2700  1.1.1.1.2.1  pgoyette 			      opcode->name);
   2701  1.1.1.1.2.1  pgoyette 	      break;
   2702  1.1.1.1.2.1  pgoyette 	    case O_sda:
   2703  1.1.1.1.2.1  pgoyette 	      reloc = find_reloc ("sda", opcode->name,
   2704  1.1.1.1.2.1  pgoyette 				  pflags, nflg,
   2705  1.1.1.1.2.1  pgoyette 				  operand->default_reloc);
   2706  1.1.1.1.2.1  pgoyette 	      break;
   2707  1.1.1.1.2.1  pgoyette 	    case O_tlsgd:
   2708  1.1.1.1.2.1  pgoyette 	    case O_tlsie:
   2709  1.1.1.1.2.1  pgoyette 	      needGOTSymbol = TRUE;
   2710  1.1.1.1.2.1  pgoyette 	      /* Fall-through.  */
   2711  1.1.1.1.2.1  pgoyette 
   2712  1.1.1.1.2.1  pgoyette 	    case O_tpoff:
   2713  1.1.1.1.2.1  pgoyette 	    case O_dtpoff:
   2714  1.1.1.1.2.1  pgoyette 	      reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
   2715  1.1.1.1.2.1  pgoyette 	      break;
   2716  1.1.1.1.2.1  pgoyette 
   2717  1.1.1.1.2.1  pgoyette 	    case O_tpoff9: /*FIXME! Check for the conditionality of
   2718  1.1.1.1.2.1  pgoyette 			     the insn.  */
   2719  1.1.1.1.2.1  pgoyette 	    case O_dtpoff9: /*FIXME! Check for the conditionality of
   2720  1.1.1.1.2.1  pgoyette 			      the insn.  */
   2721  1.1.1.1.2.1  pgoyette 	      as_bad (_("TLS_*_S9 relocs are not supported yet"));
   2722  1.1.1.1.2.1  pgoyette 	      break;
   2723  1.1.1.1.2.1  pgoyette 
   2724  1.1.1.1.2.1  pgoyette 	    default:
   2725  1.1.1.1.2.1  pgoyette 	      /* Just consider the default relocation.  */
   2726  1.1.1.1.2.1  pgoyette 	      reloc = operand->default_reloc;
   2727  1.1.1.1.2.1  pgoyette 	      break;
   2728  1.1.1.1.2.1  pgoyette 	    }
   2729  1.1.1.1.2.1  pgoyette 
   2730  1.1.1.1.2.1  pgoyette 	  if (needGOTSymbol && (GOT_symbol == NULL))
   2731  1.1.1.1.2.1  pgoyette 	    GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
   2732  1.1.1.1.2.1  pgoyette 
   2733  1.1.1.1.2.1  pgoyette 	  reloc_exp = t;
   2734  1.1.1.1.2.1  pgoyette 
   2735  1.1.1.1.2.1  pgoyette #if 0
   2736  1.1.1.1.2.1  pgoyette 	  if (reloc > 0)
   2737  1.1.1.1.2.1  pgoyette 	    {
   2738  1.1.1.1.2.1  pgoyette 	      /* sanity checks.  */
   2739  1.1.1.1.2.1  pgoyette 	      reloc_howto_type *reloc_howto
   2740  1.1.1.1.2.1  pgoyette 		= bfd_reloc_type_lookup (stdoutput,
   2741  1.1.1.1.2.1  pgoyette 					 (bfd_reloc_code_real_type) reloc);
   2742  1.1.1.1.2.1  pgoyette 	      unsigned reloc_bitsize = reloc_howto->bitsize;
   2743  1.1.1.1.2.1  pgoyette 	      if (reloc_howto->rightshift)
   2744  1.1.1.1.2.1  pgoyette 		reloc_bitsize -= reloc_howto->rightshift;
   2745  1.1.1.1.2.1  pgoyette 	      if (reloc_bitsize != operand->bits)
   2746  1.1.1.1.2.1  pgoyette 		{
   2747  1.1.1.1.2.1  pgoyette 		  as_bad (_("invalid relocation %s for field"),
   2748  1.1.1.1.2.1  pgoyette 			  bfd_get_reloc_code_name (reloc));
   2749  1.1.1.1.2.1  pgoyette 		  return;
   2750  1.1.1.1.2.1  pgoyette 		}
   2751  1.1.1.1.2.1  pgoyette 	    }
   2752  1.1.1.1.2.1  pgoyette #endif
   2753  1.1.1.1.2.1  pgoyette 	  if (insn->nfixups >= MAX_INSN_FIXUPS)
   2754  1.1.1.1.2.1  pgoyette 	    as_fatal (_("too many fixups"));
   2755  1.1.1.1.2.1  pgoyette 
   2756  1.1.1.1.2.1  pgoyette 	  struct arc_fixup *fixup;
   2757  1.1.1.1.2.1  pgoyette 	  fixup = &insn->fixups[insn->nfixups++];
   2758  1.1.1.1.2.1  pgoyette 	  fixup->exp = *t;
   2759  1.1.1.1.2.1  pgoyette 	  fixup->reloc = reloc;
   2760  1.1.1.1.2.1  pgoyette 	  pcrel = (operand->flags & ARC_OPERAND_PCREL) ? 1 : 0;
   2761  1.1.1.1.2.1  pgoyette 	  fixup->pcrel = pcrel;
   2762  1.1.1.1.2.1  pgoyette 	  fixup->islong = (operand->flags & ARC_OPERAND_LIMM) ?
   2763  1.1.1.1.2.1  pgoyette 	    TRUE : FALSE;
   2764  1.1.1.1.2.1  pgoyette 	  break;
   2765  1.1.1.1.2.1  pgoyette 	}
   2766  1.1.1.1.2.1  pgoyette     }
   2767  1.1.1.1.2.1  pgoyette 
   2768  1.1.1.1.2.1  pgoyette   /* Handle flags.  */
   2769  1.1.1.1.2.1  pgoyette   for (i = 0; i < nflg; i++)
   2770  1.1.1.1.2.1  pgoyette     {
   2771  1.1.1.1.2.1  pgoyette       const struct arc_flag_operand *flg_operand =
   2772  1.1.1.1.2.1  pgoyette 	&arc_flag_operands[pflags[i].code];
   2773  1.1.1.1.2.1  pgoyette 
   2774  1.1.1.1.2.1  pgoyette       /* Check if the instruction has a delay slot.  */
   2775  1.1.1.1.2.1  pgoyette       if (!strcmp (flg_operand->name, "d"))
   2776  1.1.1.1.2.1  pgoyette 	has_delay_slot = TRUE;
   2777  1.1.1.1.2.1  pgoyette 
   2778  1.1.1.1.2.1  pgoyette       /* There is an exceptional case when we cannot insert a flag
   2779  1.1.1.1.2.1  pgoyette 	 just as it is.  The .T flag must be handled in relation with
   2780  1.1.1.1.2.1  pgoyette 	 the relative address.  */
   2781  1.1.1.1.2.1  pgoyette       if (!strcmp (flg_operand->name, "t")
   2782  1.1.1.1.2.1  pgoyette 	  || !strcmp (flg_operand->name, "nt"))
   2783  1.1.1.1.2.1  pgoyette 	{
   2784  1.1.1.1.2.1  pgoyette 	  unsigned bitYoperand = 0;
   2785  1.1.1.1.2.1  pgoyette 	  /* FIXME! move selection bbit/brcc in arc-opc.c.  */
   2786  1.1.1.1.2.1  pgoyette 	  if (!strcmp (flg_operand->name, "t"))
   2787  1.1.1.1.2.1  pgoyette 	    if (!strcmp (opcode->name, "bbit0")
   2788  1.1.1.1.2.1  pgoyette 		|| !strcmp (opcode->name, "bbit1"))
   2789  1.1.1.1.2.1  pgoyette 	      bitYoperand = arc_NToperand;
   2790  1.1.1.1.2.1  pgoyette 	    else
   2791  1.1.1.1.2.1  pgoyette 	      bitYoperand = arc_Toperand;
   2792  1.1.1.1.2.1  pgoyette 	  else
   2793  1.1.1.1.2.1  pgoyette 	    if (!strcmp (opcode->name, "bbit0")
   2794  1.1.1.1.2.1  pgoyette 		|| !strcmp (opcode->name, "bbit1"))
   2795  1.1.1.1.2.1  pgoyette 	      bitYoperand = arc_Toperand;
   2796  1.1.1.1.2.1  pgoyette 	    else
   2797  1.1.1.1.2.1  pgoyette 	      bitYoperand = arc_NToperand;
   2798  1.1.1.1.2.1  pgoyette 
   2799  1.1.1.1.2.1  pgoyette 	  gas_assert (reloc_exp != NULL);
   2800  1.1.1.1.2.1  pgoyette 	  if (reloc_exp->X_op == O_constant)
   2801  1.1.1.1.2.1  pgoyette 	    {
   2802  1.1.1.1.2.1  pgoyette 	      /* Check if we have a constant and solved it
   2803  1.1.1.1.2.1  pgoyette 		 immediately.  */
   2804  1.1.1.1.2.1  pgoyette 	      offsetT val = reloc_exp->X_add_number;
   2805  1.1.1.1.2.1  pgoyette 	      image |= insert_operand (image, &arc_operands[bitYoperand],
   2806  1.1.1.1.2.1  pgoyette 				       val, NULL, 0);
   2807  1.1.1.1.2.1  pgoyette 	    }
   2808  1.1.1.1.2.1  pgoyette 	  else
   2809  1.1.1.1.2.1  pgoyette 	    {
   2810  1.1.1.1.2.1  pgoyette 	      struct arc_fixup *fixup;
   2811  1.1.1.1.2.1  pgoyette 
   2812  1.1.1.1.2.1  pgoyette 	      if (insn->nfixups >= MAX_INSN_FIXUPS)
   2813  1.1.1.1.2.1  pgoyette 		as_fatal (_("too many fixups"));
   2814  1.1.1.1.2.1  pgoyette 
   2815  1.1.1.1.2.1  pgoyette 	      fixup = &insn->fixups[insn->nfixups++];
   2816  1.1.1.1.2.1  pgoyette 	      fixup->exp = *reloc_exp;
   2817  1.1.1.1.2.1  pgoyette 	      fixup->reloc = -bitYoperand;
   2818  1.1.1.1.2.1  pgoyette 	      fixup->pcrel = pcrel;
   2819  1.1.1.1.2.1  pgoyette 	      fixup->islong = FALSE;
   2820  1.1.1.1.2.1  pgoyette 	    }
   2821  1.1.1.1.2.1  pgoyette 	}
   2822  1.1.1.1.2.1  pgoyette       else
   2823  1.1.1.1.2.1  pgoyette 	image |= (flg_operand->code & ((1 << flg_operand->bits) - 1))
   2824  1.1.1.1.2.1  pgoyette 	  << flg_operand->shift;
   2825  1.1.1.1.2.1  pgoyette     }
   2826  1.1.1.1.2.1  pgoyette 
   2827  1.1.1.1.2.1  pgoyette   /* Short instruction?  */
   2828  1.1.1.1.2.1  pgoyette   insn->short_insn = ARC_SHORT (opcode->mask) ? TRUE : FALSE;
   2829  1.1.1.1.2.1  pgoyette 
   2830  1.1.1.1.2.1  pgoyette   insn->insn = image;
   2831  1.1.1.1.2.1  pgoyette 
   2832  1.1.1.1.2.1  pgoyette   /* Update last insn status.  */
   2833  1.1.1.1.2.1  pgoyette   arc_last_insns[1]		   = arc_last_insns[0];
   2834  1.1.1.1.2.1  pgoyette   arc_last_insns[0].opcode	   = opcode;
   2835  1.1.1.1.2.1  pgoyette   arc_last_insns[0].has_limm	   = insn->has_limm;
   2836  1.1.1.1.2.1  pgoyette   arc_last_insns[0].has_delay_slot = has_delay_slot;
   2837  1.1.1.1.2.1  pgoyette 
   2838  1.1.1.1.2.1  pgoyette   /* Check if the current instruction is legally used.  */
   2839  1.1.1.1.2.1  pgoyette   if (arc_last_insns[1].has_delay_slot
   2840  1.1.1.1.2.1  pgoyette       && is_br_jmp_insn_p (arc_last_insns[0].opcode))
   2841  1.1.1.1.2.1  pgoyette     as_bad_where (frag_now->fr_file, frag_now->fr_line,
   2842  1.1.1.1.2.1  pgoyette 		  _("A jump/branch instruction in delay slot."));
   2843  1.1.1.1.2.1  pgoyette }
   2844  1.1.1.1.2.1  pgoyette 
   2845  1.1.1.1.2.1  pgoyette /* Actually output an instruction with its fixup.  */
   2846  1.1.1.1.2.1  pgoyette 
   2847  1.1.1.1.2.1  pgoyette static void
   2848  1.1.1.1.2.1  pgoyette emit_insn (struct arc_insn *insn)
   2849  1.1.1.1.2.1  pgoyette {
   2850  1.1.1.1.2.1  pgoyette   char *f;
   2851  1.1.1.1.2.1  pgoyette   int i;
   2852  1.1.1.1.2.1  pgoyette 
   2853  1.1.1.1.2.1  pgoyette   pr_debug ("Emit insn : 0x%x\n", insn->insn);
   2854  1.1.1.1.2.1  pgoyette   pr_debug ("\tShort   : 0x%d\n", insn->short_insn);
   2855  1.1.1.1.2.1  pgoyette   pr_debug ("\tLong imm: 0x%lx\n", insn->limm);
   2856  1.1.1.1.2.1  pgoyette 
   2857  1.1.1.1.2.1  pgoyette   /* Write out the instruction.  */
   2858  1.1.1.1.2.1  pgoyette   if (insn->short_insn)
   2859  1.1.1.1.2.1  pgoyette     {
   2860  1.1.1.1.2.1  pgoyette       if (insn->has_limm)
   2861  1.1.1.1.2.1  pgoyette 	{
   2862  1.1.1.1.2.1  pgoyette 	  f = frag_more (6);
   2863  1.1.1.1.2.1  pgoyette 	  md_number_to_chars (f, insn->insn, 2);
   2864  1.1.1.1.2.1  pgoyette 	  md_number_to_chars_midend (f + 2, insn->limm, 4);
   2865  1.1.1.1.2.1  pgoyette 	  dwarf2_emit_insn (6);
   2866  1.1.1.1.2.1  pgoyette 	}
   2867  1.1.1.1.2.1  pgoyette       else
   2868  1.1.1.1.2.1  pgoyette 	{
   2869  1.1.1.1.2.1  pgoyette 	  f = frag_more (2);
   2870  1.1.1.1.2.1  pgoyette 	  md_number_to_chars (f, insn->insn, 2);
   2871  1.1.1.1.2.1  pgoyette 	  dwarf2_emit_insn (2);
   2872  1.1.1.1.2.1  pgoyette 	}
   2873  1.1.1.1.2.1  pgoyette     }
   2874  1.1.1.1.2.1  pgoyette   else
   2875  1.1.1.1.2.1  pgoyette     {
   2876  1.1.1.1.2.1  pgoyette       if (insn->has_limm)
   2877  1.1.1.1.2.1  pgoyette 	{
   2878  1.1.1.1.2.1  pgoyette 	  f = frag_more (8);
   2879  1.1.1.1.2.1  pgoyette 	  md_number_to_chars_midend (f, insn->insn, 4);
   2880  1.1.1.1.2.1  pgoyette 	  md_number_to_chars_midend (f + 4, insn->limm, 4);
   2881  1.1.1.1.2.1  pgoyette 	  dwarf2_emit_insn (8);
   2882  1.1.1.1.2.1  pgoyette 	}
   2883  1.1.1.1.2.1  pgoyette       else
   2884  1.1.1.1.2.1  pgoyette 	{
   2885  1.1.1.1.2.1  pgoyette 	  f = frag_more (4);
   2886  1.1.1.1.2.1  pgoyette 	  md_number_to_chars_midend (f, insn->insn, 4);
   2887  1.1.1.1.2.1  pgoyette 	  dwarf2_emit_insn (4);
   2888  1.1.1.1.2.1  pgoyette 	}
   2889  1.1.1.1.2.1  pgoyette     }
   2890  1.1.1.1.2.1  pgoyette 
   2891  1.1.1.1.2.1  pgoyette   /* Apply the fixups in order.  */
   2892  1.1.1.1.2.1  pgoyette   for (i = 0; i < insn->nfixups; i++)
   2893  1.1.1.1.2.1  pgoyette     {
   2894  1.1.1.1.2.1  pgoyette       struct arc_fixup *fixup = &insn->fixups[i];
   2895  1.1.1.1.2.1  pgoyette       int size, pcrel, offset = 0;
   2896  1.1.1.1.2.1  pgoyette 
   2897  1.1.1.1.2.1  pgoyette       /*FIXME! the reloc size is wrong in the BFD file.  When it will
   2898  1.1.1.1.2.1  pgoyette 	be fixed please delete me.  */
   2899  1.1.1.1.2.1  pgoyette       size = (insn->short_insn && !fixup->islong) ? 2 : 4;
   2900  1.1.1.1.2.1  pgoyette 
   2901  1.1.1.1.2.1  pgoyette       if (fixup->islong)
   2902  1.1.1.1.2.1  pgoyette 	offset = (insn->short_insn) ? 2 : 4;
   2903  1.1.1.1.2.1  pgoyette 
   2904  1.1.1.1.2.1  pgoyette       /* Some fixups are only used internally, thus no howto.  */
   2905  1.1.1.1.2.1  pgoyette       if ((int) fixup->reloc < 0)
   2906  1.1.1.1.2.1  pgoyette 	{
   2907  1.1.1.1.2.1  pgoyette 	  /*FIXME! the reloc size is wrong in the BFD file.  When it
   2908  1.1.1.1.2.1  pgoyette 	    will be fixed please enable me.
   2909  1.1.1.1.2.1  pgoyette 	    size = (insn->short_insn && !fixup->islong) ? 2 : 4; */
   2910  1.1.1.1.2.1  pgoyette 	  pcrel = fixup->pcrel;
   2911  1.1.1.1.2.1  pgoyette 	}
   2912  1.1.1.1.2.1  pgoyette       else
   2913  1.1.1.1.2.1  pgoyette 	{
   2914  1.1.1.1.2.1  pgoyette 	  reloc_howto_type *reloc_howto =
   2915  1.1.1.1.2.1  pgoyette 	    bfd_reloc_type_lookup (stdoutput,
   2916  1.1.1.1.2.1  pgoyette 				   (bfd_reloc_code_real_type) fixup->reloc);
   2917  1.1.1.1.2.1  pgoyette 	  gas_assert (reloc_howto);
   2918  1.1.1.1.2.1  pgoyette 	  /*FIXME! the reloc size is wrong in the BFD file.  When it
   2919  1.1.1.1.2.1  pgoyette 	    will be fixed please enable me.
   2920  1.1.1.1.2.1  pgoyette 	    size = bfd_get_reloc_size (reloc_howto); */
   2921  1.1.1.1.2.1  pgoyette 	  pcrel = reloc_howto->pc_relative;
   2922  1.1.1.1.2.1  pgoyette 	}
   2923  1.1.1.1.2.1  pgoyette 
   2924  1.1.1.1.2.1  pgoyette       pr_debug ("%s:%d: emit_insn: new %s fixup (PCrel:%s) of size %d @ offset %d\n",
   2925  1.1.1.1.2.1  pgoyette 		frag_now->fr_file, frag_now->fr_line,
   2926  1.1.1.1.2.1  pgoyette 		(fixup->reloc < 0) ? "Internal" :
   2927  1.1.1.1.2.1  pgoyette 		bfd_get_reloc_code_name (fixup->reloc),
   2928  1.1.1.1.2.1  pgoyette 		pcrel ? "Y" : "N",
   2929  1.1.1.1.2.1  pgoyette 		size, offset);
   2930  1.1.1.1.2.1  pgoyette       fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
   2931  1.1.1.1.2.1  pgoyette 		   size, &fixup->exp, pcrel, fixup->reloc);
   2932  1.1.1.1.2.1  pgoyette 
   2933  1.1.1.1.2.1  pgoyette       /* Check for ZOLs, and update symbol info if any.  */
   2934  1.1.1.1.2.1  pgoyette       if (LP_INSN (insn->insn))
   2935  1.1.1.1.2.1  pgoyette 	{
   2936  1.1.1.1.2.1  pgoyette 	  gas_assert (fixup->exp.X_add_symbol);
   2937  1.1.1.1.2.1  pgoyette 	  ARC_SET_FLAG (fixup->exp.X_add_symbol, ARC_FLAG_ZOL);
   2938  1.1.1.1.2.1  pgoyette 	}
   2939  1.1.1.1.2.1  pgoyette     }
   2940  1.1.1.1.2.1  pgoyette }
   2941  1.1.1.1.2.1  pgoyette 
   2942  1.1.1.1.2.1  pgoyette /* Insert an operand value into an instruction.  */
   2943  1.1.1.1.2.1  pgoyette 
   2944  1.1.1.1.2.1  pgoyette static unsigned
   2945  1.1.1.1.2.1  pgoyette insert_operand (unsigned insn,
   2946  1.1.1.1.2.1  pgoyette 		const struct arc_operand *operand,
   2947  1.1.1.1.2.1  pgoyette 		offsetT val,
   2948  1.1.1.1.2.1  pgoyette 		char *file,
   2949  1.1.1.1.2.1  pgoyette 		unsigned line)
   2950  1.1.1.1.2.1  pgoyette {
   2951  1.1.1.1.2.1  pgoyette   offsetT min = 0, max = 0;
   2952  1.1.1.1.2.1  pgoyette 
   2953  1.1.1.1.2.1  pgoyette   if (operand->bits != 32
   2954  1.1.1.1.2.1  pgoyette       && !(operand->flags & ARC_OPERAND_NCHK)
   2955  1.1.1.1.2.1  pgoyette       && !(operand->flags & ARC_OPERAND_FAKE))
   2956  1.1.1.1.2.1  pgoyette     {
   2957  1.1.1.1.2.1  pgoyette       if (operand->flags & ARC_OPERAND_SIGNED)
   2958  1.1.1.1.2.1  pgoyette 	{
   2959  1.1.1.1.2.1  pgoyette 	  max = (1 << (operand->bits - 1)) - 1;
   2960  1.1.1.1.2.1  pgoyette 	  min = -(1 << (operand->bits - 1));
   2961  1.1.1.1.2.1  pgoyette 	}
   2962  1.1.1.1.2.1  pgoyette       else
   2963  1.1.1.1.2.1  pgoyette 	{
   2964  1.1.1.1.2.1  pgoyette 	  max = (1 << operand->bits) - 1;
   2965  1.1.1.1.2.1  pgoyette 	  min = 0;
   2966  1.1.1.1.2.1  pgoyette 	}
   2967  1.1.1.1.2.1  pgoyette 
   2968  1.1.1.1.2.1  pgoyette       if (val < min || val > max)
   2969  1.1.1.1.2.1  pgoyette 	as_bad_value_out_of_range (_("operand"),
   2970  1.1.1.1.2.1  pgoyette 				   val, min, max, file, line);
   2971  1.1.1.1.2.1  pgoyette     }
   2972  1.1.1.1.2.1  pgoyette 
   2973  1.1.1.1.2.1  pgoyette   pr_debug ("insert field: %ld <= %ld <= %ld in 0x%08x\n",
   2974  1.1.1.1.2.1  pgoyette 	    min, val, max, insn);
   2975  1.1.1.1.2.1  pgoyette 
   2976  1.1.1.1.2.1  pgoyette   if ((operand->flags & ARC_OPERAND_ALIGNED32)
   2977  1.1.1.1.2.1  pgoyette       && (val & 0x03))
   2978  1.1.1.1.2.1  pgoyette     as_bad_where (file, line,
   2979  1.1.1.1.2.1  pgoyette 		  _("Unaligned operand. Needs to be 32bit aligned"));
   2980  1.1.1.1.2.1  pgoyette 
   2981  1.1.1.1.2.1  pgoyette   if ((operand->flags & ARC_OPERAND_ALIGNED16)
   2982  1.1.1.1.2.1  pgoyette       && (val & 0x01))
   2983  1.1.1.1.2.1  pgoyette     as_bad_where (file, line,
   2984  1.1.1.1.2.1  pgoyette 		  _("Unaligned operand. Needs to be 16bit aligned"));
   2985  1.1.1.1.2.1  pgoyette 
   2986  1.1.1.1.2.1  pgoyette   if (operand->insert)
   2987  1.1.1.1.2.1  pgoyette     {
   2988  1.1.1.1.2.1  pgoyette       const char *errmsg = NULL;
   2989  1.1.1.1.2.1  pgoyette 
   2990  1.1.1.1.2.1  pgoyette       insn = (*operand->insert) (insn, val, &errmsg);
   2991  1.1.1.1.2.1  pgoyette       if (errmsg)
   2992  1.1.1.1.2.1  pgoyette 	as_warn_where (file, line, "%s", errmsg);
   2993  1.1.1.1.2.1  pgoyette     }
   2994  1.1.1.1.2.1  pgoyette   else
   2995  1.1.1.1.2.1  pgoyette     {
   2996  1.1.1.1.2.1  pgoyette       if (operand->flags & ARC_OPERAND_TRUNCATE)
   2997  1.1.1.1.2.1  pgoyette 	{
   2998  1.1.1.1.2.1  pgoyette 	  if (operand->flags & ARC_OPERAND_ALIGNED32)
   2999  1.1.1.1.2.1  pgoyette 	    val >>= 2;
   3000  1.1.1.1.2.1  pgoyette 	  if (operand->flags & ARC_OPERAND_ALIGNED16)
   3001  1.1.1.1.2.1  pgoyette 	    val >>= 1;
   3002  1.1.1.1.2.1  pgoyette 	}
   3003  1.1.1.1.2.1  pgoyette       insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
   3004  1.1.1.1.2.1  pgoyette     }
   3005  1.1.1.1.2.1  pgoyette   return insn;
   3006  1.1.1.1.2.1  pgoyette }
   3007  1.1.1.1.2.1  pgoyette 
   3008  1.1.1.1.2.1  pgoyette void
   3009  1.1.1.1.2.1  pgoyette arc_handle_align (fragS* fragP)
   3010  1.1.1.1.2.1  pgoyette {
   3011  1.1.1.1.2.1  pgoyette   if ((fragP)->fr_type == rs_align_code)
   3012  1.1.1.1.2.1  pgoyette     {
   3013  1.1.1.1.2.1  pgoyette       char *dest = (fragP)->fr_literal + (fragP)->fr_fix;
   3014  1.1.1.1.2.1  pgoyette       valueT count = ((fragP)->fr_next->fr_address
   3015  1.1.1.1.2.1  pgoyette 		      - (fragP)->fr_address - (fragP)->fr_fix);
   3016  1.1.1.1.2.1  pgoyette 
   3017  1.1.1.1.2.1  pgoyette       (fragP)->fr_var = 2;
   3018  1.1.1.1.2.1  pgoyette 
   3019  1.1.1.1.2.1  pgoyette       if (count & 1)/* Padding in the gap till the next 2-byte
   3020  1.1.1.1.2.1  pgoyette 		       boundary with 0s.  */
   3021  1.1.1.1.2.1  pgoyette 	{
   3022  1.1.1.1.2.1  pgoyette 	  (fragP)->fr_fix++;
   3023  1.1.1.1.2.1  pgoyette 	  *dest++ = 0;
   3024  1.1.1.1.2.1  pgoyette 	}
   3025  1.1.1.1.2.1  pgoyette       /* Writing nop_s.  */
   3026  1.1.1.1.2.1  pgoyette       md_number_to_chars (dest, NOP_OPCODE_S, 2);
   3027  1.1.1.1.2.1  pgoyette     }
   3028  1.1.1.1.2.1  pgoyette }
   3029  1.1.1.1.2.1  pgoyette 
   3030  1.1.1.1.2.1  pgoyette /* Here we decide which fixups can be adjusted to make them relative
   3031  1.1.1.1.2.1  pgoyette    to the beginning of the section instead of the symbol.  Basically
   3032  1.1.1.1.2.1  pgoyette    we need to make sure that the dynamic relocations are done
   3033  1.1.1.1.2.1  pgoyette    correctly, so in some cases we force the original symbol to be
   3034  1.1.1.1.2.1  pgoyette    used.  */
   3035  1.1.1.1.2.1  pgoyette 
   3036  1.1.1.1.2.1  pgoyette int
   3037  1.1.1.1.2.1  pgoyette tc_arc_fix_adjustable (fixS *fixP)
   3038  1.1.1.1.2.1  pgoyette {
   3039  1.1.1.1.2.1  pgoyette 
   3040  1.1.1.1.2.1  pgoyette   /* Prevent all adjustments to global symbols.  */
   3041  1.1.1.1.2.1  pgoyette   if (S_IS_EXTERNAL (fixP->fx_addsy))
   3042  1.1.1.1.2.1  pgoyette     return 0;
   3043  1.1.1.1.2.1  pgoyette   if (S_IS_WEAK (fixP->fx_addsy))
   3044  1.1.1.1.2.1  pgoyette     return 0;
   3045  1.1.1.1.2.1  pgoyette 
   3046  1.1.1.1.2.1  pgoyette   /* Adjust_reloc_syms doesn't know about the GOT.  */
   3047  1.1.1.1.2.1  pgoyette   switch (fixP->fx_r_type)
   3048  1.1.1.1.2.1  pgoyette     {
   3049  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_GOTPC32:
   3050  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_PLT32:
   3051  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_S25H_PCREL_PLT:
   3052  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_S21H_PCREL_PLT:
   3053  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_S25W_PCREL_PLT:
   3054  1.1.1.1.2.1  pgoyette     case BFD_RELOC_ARC_S21W_PCREL_PLT:
   3055  1.1.1.1.2.1  pgoyette       return 0;
   3056  1.1.1.1.2.1  pgoyette 
   3057  1.1.1.1.2.1  pgoyette     default:
   3058  1.1.1.1.2.1  pgoyette       break;
   3059  1.1.1.1.2.1  pgoyette     }
   3060  1.1.1.1.2.1  pgoyette 
   3061  1.1.1.1.2.1  pgoyette   return 0; /* FIXME! return 1, fix it in the linker.  */
   3062  1.1.1.1.2.1  pgoyette }
   3063  1.1.1.1.2.1  pgoyette 
   3064  1.1.1.1.2.1  pgoyette /* Compute the reloc type of an expression EXP.  */
   3065  1.1.1.1.2.1  pgoyette 
   3066  1.1.1.1.2.1  pgoyette static void
   3067  1.1.1.1.2.1  pgoyette arc_check_reloc (expressionS *exp,
   3068  1.1.1.1.2.1  pgoyette 		 bfd_reloc_code_real_type *r_type_p)
   3069  1.1.1.1.2.1  pgoyette {
   3070  1.1.1.1.2.1  pgoyette   if (*r_type_p == BFD_RELOC_32
   3071  1.1.1.1.2.1  pgoyette       && exp->X_op == O_subtract
   3072  1.1.1.1.2.1  pgoyette       && exp->X_op_symbol != NULL
   3073  1.1.1.1.2.1  pgoyette       && exp->X_op_symbol->bsym->section == now_seg)
   3074  1.1.1.1.2.1  pgoyette     *r_type_p = BFD_RELOC_ARC_32_PCREL;
   3075  1.1.1.1.2.1  pgoyette }
   3076  1.1.1.1.2.1  pgoyette 
   3077  1.1.1.1.2.1  pgoyette 
   3078  1.1.1.1.2.1  pgoyette /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG.  */
   3079  1.1.1.1.2.1  pgoyette 
   3080  1.1.1.1.2.1  pgoyette void
   3081  1.1.1.1.2.1  pgoyette arc_cons_fix_new (fragS *frag,
   3082  1.1.1.1.2.1  pgoyette 		  int off,
   3083  1.1.1.1.2.1  pgoyette 		  int size,
   3084  1.1.1.1.2.1  pgoyette 		  expressionS *exp,
   3085  1.1.1.1.2.1  pgoyette 		  bfd_reloc_code_real_type r_type)
   3086  1.1.1.1.2.1  pgoyette {
   3087  1.1.1.1.2.1  pgoyette   r_type = BFD_RELOC_UNUSED;
   3088  1.1.1.1.2.1  pgoyette 
   3089  1.1.1.1.2.1  pgoyette   switch (size)
   3090  1.1.1.1.2.1  pgoyette     {
   3091  1.1.1.1.2.1  pgoyette     case 1:
   3092  1.1.1.1.2.1  pgoyette       r_type = BFD_RELOC_8;
   3093  1.1.1.1.2.1  pgoyette       break;
   3094  1.1.1.1.2.1  pgoyette 
   3095  1.1.1.1.2.1  pgoyette     case 2:
   3096  1.1.1.1.2.1  pgoyette       r_type = BFD_RELOC_16;
   3097  1.1.1.1.2.1  pgoyette       break;
   3098  1.1.1.1.2.1  pgoyette 
   3099  1.1.1.1.2.1  pgoyette     case 3:
   3100  1.1.1.1.2.1  pgoyette       r_type = BFD_RELOC_24;
   3101  1.1.1.1.2.1  pgoyette       break;
   3102  1.1.1.1.2.1  pgoyette 
   3103  1.1.1.1.2.1  pgoyette     case 4:
   3104  1.1.1.1.2.1  pgoyette       r_type = BFD_RELOC_32;
   3105  1.1.1.1.2.1  pgoyette       arc_check_reloc (exp, &r_type);
   3106  1.1.1.1.2.1  pgoyette       break;
   3107  1.1.1.1.2.1  pgoyette 
   3108  1.1.1.1.2.1  pgoyette     case 8:
   3109  1.1.1.1.2.1  pgoyette       r_type = BFD_RELOC_64;
   3110  1.1.1.1.2.1  pgoyette       break;
   3111  1.1.1.1.2.1  pgoyette 
   3112  1.1.1.1.2.1  pgoyette     default:
   3113  1.1.1.1.2.1  pgoyette       as_bad (_("unsupported BFD relocation size %u"), size);
   3114  1.1.1.1.2.1  pgoyette       r_type = BFD_RELOC_UNUSED;
   3115  1.1.1.1.2.1  pgoyette     }
   3116  1.1.1.1.2.1  pgoyette 
   3117  1.1.1.1.2.1  pgoyette   fix_new_exp (frag, off, size, exp, 0, r_type);
   3118  1.1.1.1.2.1  pgoyette }
   3119  1.1.1.1.2.1  pgoyette 
   3120  1.1.1.1.2.1  pgoyette /* The actual routine that checks the ZOL conditions.  */
   3121  1.1.1.1.2.1  pgoyette 
   3122  1.1.1.1.2.1  pgoyette static void
   3123  1.1.1.1.2.1  pgoyette check_zol (symbolS *s)
   3124  1.1.1.1.2.1  pgoyette {
   3125  1.1.1.1.2.1  pgoyette   switch (arc_mach_type)
   3126  1.1.1.1.2.1  pgoyette     {
   3127  1.1.1.1.2.1  pgoyette     case bfd_mach_arc_arcv2:
   3128  1.1.1.1.2.1  pgoyette       if (arc_target & ARC_OPCODE_ARCv2EM)
   3129  1.1.1.1.2.1  pgoyette 	return;
   3130  1.1.1.1.2.1  pgoyette 
   3131  1.1.1.1.2.1  pgoyette       if (is_br_jmp_insn_p (arc_last_insns[0].opcode)
   3132  1.1.1.1.2.1  pgoyette 	  || arc_last_insns[1].has_delay_slot)
   3133  1.1.1.1.2.1  pgoyette 	as_bad (_("Jump/Branch instruction detected at the end of the ZOL label @%s"),
   3134  1.1.1.1.2.1  pgoyette 		S_GET_NAME (s));
   3135  1.1.1.1.2.1  pgoyette 
   3136  1.1.1.1.2.1  pgoyette       break;
   3137  1.1.1.1.2.1  pgoyette     case bfd_mach_arc_arc600:
   3138  1.1.1.1.2.1  pgoyette 
   3139  1.1.1.1.2.1  pgoyette       if (is_kernel_insn_p (arc_last_insns[0].opcode))
   3140  1.1.1.1.2.1  pgoyette 	as_bad (_("Kernel instruction detected at the end of the ZOL label @%s"),
   3141  1.1.1.1.2.1  pgoyette 		S_GET_NAME (s));
   3142  1.1.1.1.2.1  pgoyette 
   3143  1.1.1.1.2.1  pgoyette       if (arc_last_insns[0].has_limm
   3144  1.1.1.1.2.1  pgoyette 	  && is_br_jmp_insn_p (arc_last_insns[0].opcode))
   3145  1.1.1.1.2.1  pgoyette 	as_bad (_("A jump instruction with long immediate detected at the \
   3146  1.1.1.1.2.1  pgoyette end of the ZOL label @%s"), S_GET_NAME (s));
   3147  1.1.1.1.2.1  pgoyette 
   3148  1.1.1.1.2.1  pgoyette       /* Fall through.  */
   3149  1.1.1.1.2.1  pgoyette     case bfd_mach_arc_arc700:
   3150  1.1.1.1.2.1  pgoyette       if (arc_last_insns[0].has_delay_slot)
   3151  1.1.1.1.2.1  pgoyette 	as_bad (_("An illegal use of delay slot detected at the end of the ZOL label @%s"),
   3152  1.1.1.1.2.1  pgoyette 		S_GET_NAME (s));
   3153  1.1.1.1.2.1  pgoyette 
   3154  1.1.1.1.2.1  pgoyette       break;
   3155  1.1.1.1.2.1  pgoyette     default:
   3156  1.1.1.1.2.1  pgoyette       break;
   3157  1.1.1.1.2.1  pgoyette     }
   3158  1.1.1.1.2.1  pgoyette }
   3159  1.1.1.1.2.1  pgoyette 
   3160  1.1.1.1.2.1  pgoyette /* If ZOL end check the last two instruction for illegals.  */
   3161  1.1.1.1.2.1  pgoyette void
   3162  1.1.1.1.2.1  pgoyette arc_frob_label (symbolS * sym)
   3163  1.1.1.1.2.1  pgoyette {
   3164  1.1.1.1.2.1  pgoyette   if (ARC_GET_FLAG (sym) & ARC_FLAG_ZOL)
   3165  1.1.1.1.2.1  pgoyette     check_zol (sym);
   3166  1.1.1.1.2.1  pgoyette 
   3167  1.1.1.1.2.1  pgoyette   dwarf2_emit_label (sym);
   3168          1.1  christos }
   3169