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