1 1.1 skrll /* tc-arc.c -- Assembler for the ARC 2 1.1.1.11 christos Copyright (C) 1994-2026 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.1.3 christos #include "dwarf2dbg.h" 26 1.1.1.5 christos #include "dw2gencfi.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.1.6 christos #include "opcode/arc-attrs.h" 31 1.1 skrll #include "elf/arc.h" 32 1.1.1.5 christos #include "../opcodes/arc-ext.h" 33 1.1 skrll 34 1.1.1.3 christos /* Defines section. */ 35 1.1 skrll 36 1.1.1.3 christos #define MAX_INSN_FIXUPS 2 37 1.1.1.3 christos #define MAX_CONSTR_STR 20 38 1.1.1.5 christos #define FRAG_MAX_GROWTH 8 39 1.1.1.3 christos 40 1.1.1.3 christos #ifdef DEBUG 41 1.1.1.3 christos # define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args) 42 1.1.1.3 christos #else 43 1.1.1.3 christos # define pr_debug(fmt, args...) 44 1.1.1.3 christos #endif 45 1.1.1.3 christos 46 1.1.1.3 christos #define MAJOR_OPCODE(x) (((x) & 0xF8000000) >> 27) 47 1.1.1.3 christos #define SUB_OPCODE(x) (((x) & 0x003F0000) >> 16) 48 1.1.1.6 christos #define LP_INSN(x) ((MAJOR_OPCODE (x) == 0x4) \ 49 1.1.1.6 christos && (SUB_OPCODE (x) == 0x28)) 50 1.1.1.3 christos 51 1.1.1.5 christos #ifndef TARGET_WITH_CPU 52 1.1.1.9 christos #define TARGET_WITH_CPU "hs38_linux" 53 1.1.1.5 christos #endif /* TARGET_WITH_CPU */ 54 1.1.1.5 christos 55 1.1.1.6 christos #define ARC_GET_FLAG(s) (*symbol_get_tc (s)) 56 1.1.1.6 christos #define ARC_SET_FLAG(s,v) (*symbol_get_tc (s) |= (v)) 57 1.1.1.6 christos #define streq(a, b) (strcmp (a, b) == 0) 58 1.1.1.6 christos 59 1.1.1.5 christos /* Enum used to enumerate the relaxable ins operands. */ 60 1.1.1.5 christos enum rlx_operand_type 61 1.1.1.5 christos { 62 1.1.1.5 christos EMPTY = 0, 63 1.1.1.5 christos REGISTER, 64 1.1.1.5 christos REGISTER_S, /* Register for short instruction(s). */ 65 1.1.1.5 christos REGISTER_NO_GP, /* Is a register but not gp register specifically. */ 66 1.1.1.5 christos REGISTER_DUP, /* Duplication of previous operand of type register. */ 67 1.1.1.5 christos IMMEDIATE, 68 1.1.1.5 christos BRACKET 69 1.1.1.5 christos }; 70 1.1.1.5 christos 71 1.1.1.5 christos enum arc_rlx_types 72 1.1.1.5 christos { 73 1.1.1.5 christos ARC_RLX_NONE = 0, 74 1.1.1.5 christos ARC_RLX_BL_S, 75 1.1.1.5 christos ARC_RLX_BL, 76 1.1.1.5 christos ARC_RLX_B_S, 77 1.1.1.5 christos ARC_RLX_B, 78 1.1.1.5 christos ARC_RLX_ADD_U3, 79 1.1.1.5 christos ARC_RLX_ADD_U6, 80 1.1.1.5 christos ARC_RLX_ADD_LIMM, 81 1.1.1.5 christos ARC_RLX_LD_U7, 82 1.1.1.5 christos ARC_RLX_LD_S9, 83 1.1.1.5 christos ARC_RLX_LD_LIMM, 84 1.1.1.5 christos ARC_RLX_MOV_U8, 85 1.1.1.5 christos ARC_RLX_MOV_S12, 86 1.1.1.5 christos ARC_RLX_MOV_LIMM, 87 1.1.1.5 christos ARC_RLX_SUB_U3, 88 1.1.1.5 christos ARC_RLX_SUB_U6, 89 1.1.1.5 christos ARC_RLX_SUB_LIMM, 90 1.1.1.5 christos ARC_RLX_MPY_U6, 91 1.1.1.5 christos ARC_RLX_MPY_LIMM, 92 1.1.1.5 christos ARC_RLX_MOV_RU6, 93 1.1.1.5 christos ARC_RLX_MOV_RLIMM, 94 1.1.1.5 christos ARC_RLX_ADD_RRU6, 95 1.1.1.5 christos ARC_RLX_ADD_RRLIMM, 96 1.1.1.5 christos }; 97 1.1.1.5 christos 98 1.1.1.3 christos /* Macros section. */ 99 1.1.1.3 christos 100 1.1.1.3 christos #define regno(x) ((x) & 0x3F) 101 1.1.1.3 christos #define is_ir_num(x) (((x) & ~0x3F) == 0) 102 1.1.1.5 christos #define is_code_density_p(sc) (((sc) == CD1 || (sc) == CD2)) 103 1.1.1.5 christos #define is_spfp_p(op) (((sc) == SPX)) 104 1.1.1.5 christos #define is_dpfp_p(op) (((sc) == DPX)) 105 1.1.1.5 christos #define is_fpuda_p(op) (((sc) == DPA)) 106 1.1.1.6 christos #define is_br_jmp_insn_p(op) (((op)->insn_class == BRANCH \ 107 1.1.1.6 christos || (op)->insn_class == JUMP \ 108 1.1.1.6 christos || (op)->insn_class == BRCC \ 109 1.1.1.6 christos || (op)->insn_class == BBIT0 \ 110 1.1.1.6 christos || (op)->insn_class == BBIT1 \ 111 1.1.1.6 christos || (op)->insn_class == BI \ 112 1.1.1.10 christos || (op)->insn_class == DBNZ \ 113 1.1.1.6 christos || (op)->insn_class == EI \ 114 1.1.1.6 christos || (op)->insn_class == ENTER \ 115 1.1.1.6 christos || (op)->insn_class == JLI \ 116 1.1.1.6 christos || (op)->insn_class == LOOP \ 117 1.1.1.6 christos || (op)->insn_class == LEAVE \ 118 1.1.1.6 christos )) 119 1.1.1.5 christos #define is_kernel_insn_p(op) (((op)->insn_class == KERNEL)) 120 1.1.1.5 christos #define is_nps400_p(op) (((sc) == NPS400)) 121 1.1 skrll 122 1.1.1.3 christos /* Generic assembler global variables which must be defined by all 123 1.1.1.3 christos targets. */ 124 1.1 skrll 125 1.1.1.3 christos /* Characters which always start a comment. */ 126 1.1 skrll const char comment_chars[] = "#;"; 127 1.1 skrll 128 1.1.1.3 christos /* Characters which start a comment at the beginning of a line. */ 129 1.1 skrll const char line_comment_chars[] = "#"; 130 1.1 skrll 131 1.1.1.3 christos /* Characters which may be used to separate multiple commands on a 132 1.1.1.3 christos single line. */ 133 1.1.1.3 christos const char line_separator_chars[] = "`"; 134 1.1 skrll 135 1.1.1.3 christos /* Characters which are used to indicate an exponent in a floating 136 1.1.1.3 christos point number. */ 137 1.1 skrll const char EXP_CHARS[] = "eE"; 138 1.1 skrll 139 1.1 skrll /* Chars that mean this number is a floating point constant 140 1.1 skrll As in 0f12.456 or 0d1.2345e12. */ 141 1.1 skrll const char FLT_CHARS[] = "rRsSfFdD"; 142 1.1 skrll 143 1.1 skrll /* Byte order. */ 144 1.1 skrll extern int target_big_endian; 145 1.1 skrll const char *arc_target_format = DEFAULT_TARGET_FORMAT; 146 1.1 skrll static int byte_order = DEFAULT_BYTE_ORDER; 147 1.1 skrll 148 1.1.1.5 christos /* Arc extension section. */ 149 1.1.1.5 christos static segT arcext_section; 150 1.1.1.5 christos 151 1.1.1.5 christos /* By default relaxation is disabled. */ 152 1.1.1.5 christos static int relaxation_state = 0; 153 1.1.1.5 christos 154 1.1.1.3 christos extern int arc_get_mach (char *); 155 1.1 skrll 156 1.1.1.5 christos /* Forward declarations. */ 157 1.1.1.3 christos static void arc_lcomm (int); 158 1.1.1.3 christos static void arc_option (int); 159 1.1.1.3 christos static void arc_extra_reloc (int); 160 1.1.1.5 christos static void arc_extinsn (int); 161 1.1.1.5 christos static void arc_extcorereg (int); 162 1.1.1.6 christos static void arc_attribute (int); 163 1.1 skrll 164 1.1.1.3 christos const pseudo_typeS md_pseudo_table[] = 165 1.1.1.3 christos { 166 1.1.1.3 christos /* Make sure that .word is 32 bits. */ 167 1.1.1.3 christos { "word", cons, 4 }, 168 1.1 skrll 169 1.1.1.3 christos { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0). */ 170 1.1.1.3 christos { "lcomm", arc_lcomm, 0 }, 171 1.1.1.3 christos { "lcommon", arc_lcomm, 0 }, 172 1.1.1.3 christos { "cpu", arc_option, 0 }, 173 1.1.1.3 christos 174 1.1.1.6 christos { "arc_attribute", arc_attribute, 0 }, 175 1.1.1.5 christos { "extinstruction", arc_extinsn, 0 }, 176 1.1.1.5 christos { "extcoreregister", arc_extcorereg, EXT_CORE_REGISTER }, 177 1.1.1.5 christos { "extauxregister", arc_extcorereg, EXT_AUX_REGISTER }, 178 1.1.1.5 christos { "extcondcode", arc_extcorereg, EXT_COND_CODE }, 179 1.1.1.5 christos 180 1.1.1.3 christos { "tls_gd_ld", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_LD }, 181 1.1.1.3 christos { "tls_gd_call", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_CALL }, 182 1.1.1.3 christos 183 1.1.1.3 christos { NULL, NULL, 0 } 184 1.1.1.3 christos }; 185 1.1 skrll 186 1.1.1.10 christos const char md_shortopts[] = ""; 187 1.1 skrll 188 1.1 skrll enum options 189 1.1 skrll { 190 1.1 skrll OPTION_EB = OPTION_MD_BASE, 191 1.1 skrll OPTION_EL, 192 1.1.1.3 christos 193 1.1.1.3 christos OPTION_ARC600, 194 1.1.1.3 christos OPTION_ARC601, 195 1.1.1.3 christos OPTION_ARC700, 196 1.1.1.3 christos OPTION_ARCEM, 197 1.1.1.3 christos OPTION_ARCHS, 198 1.1.1.3 christos 199 1.1.1.3 christos OPTION_MCPU, 200 1.1.1.3 christos OPTION_CD, 201 1.1.1.5 christos OPTION_RELAX, 202 1.1.1.5 christos OPTION_NPS400, 203 1.1.1.5 christos 204 1.1.1.5 christos OPTION_SPFP, 205 1.1.1.5 christos OPTION_DPFP, 206 1.1.1.5 christos OPTION_FPUDA, 207 1.1.1.3 christos 208 1.1.1.3 christos /* The following options are deprecated and provided here only for 209 1.1.1.3 christos compatibility reasons. */ 210 1.1.1.3 christos OPTION_USER_MODE, 211 1.1.1.3 christos OPTION_LD_EXT_MASK, 212 1.1.1.3 christos OPTION_SWAP, 213 1.1.1.3 christos OPTION_NORM, 214 1.1.1.3 christos OPTION_BARREL_SHIFT, 215 1.1.1.3 christos OPTION_MIN_MAX, 216 1.1.1.3 christos OPTION_NO_MPY, 217 1.1.1.3 christos OPTION_EA, 218 1.1.1.3 christos OPTION_MUL64, 219 1.1.1.3 christos OPTION_SIMD, 220 1.1.1.3 christos OPTION_XMAC_D16, 221 1.1.1.3 christos OPTION_XMAC_24, 222 1.1.1.3 christos OPTION_DSP_PACKA, 223 1.1.1.3 christos OPTION_CRC, 224 1.1.1.3 christos OPTION_DVBF, 225 1.1.1.3 christos OPTION_TELEPHONY, 226 1.1.1.3 christos OPTION_XYMEMORY, 227 1.1.1.3 christos OPTION_LOCK, 228 1.1.1.3 christos OPTION_SWAPE, 229 1.1.1.5 christos OPTION_RTSC 230 1.1 skrll }; 231 1.1 skrll 232 1.1.1.10 christos const struct option md_longopts[] = 233 1.1 skrll { 234 1.1.1.3 christos { "EB", no_argument, NULL, OPTION_EB }, 235 1.1.1.3 christos { "EL", no_argument, NULL, OPTION_EL }, 236 1.1.1.3 christos { "mcpu", required_argument, NULL, OPTION_MCPU }, 237 1.1.1.3 christos { "mA6", no_argument, NULL, OPTION_ARC600 }, 238 1.1.1.5 christos { "mARC600", no_argument, NULL, OPTION_ARC600 }, 239 1.1.1.5 christos { "mARC601", no_argument, NULL, OPTION_ARC601 }, 240 1.1.1.5 christos { "mARC700", no_argument, NULL, OPTION_ARC700 }, 241 1.1.1.3 christos { "mA7", no_argument, NULL, OPTION_ARC700 }, 242 1.1.1.3 christos { "mEM", no_argument, NULL, OPTION_ARCEM }, 243 1.1.1.3 christos { "mHS", no_argument, NULL, OPTION_ARCHS }, 244 1.1.1.3 christos { "mcode-density", no_argument, NULL, OPTION_CD }, 245 1.1.1.5 christos { "mrelax", no_argument, NULL, OPTION_RELAX }, 246 1.1.1.5 christos { "mnps400", no_argument, NULL, OPTION_NPS400 }, 247 1.1.1.5 christos 248 1.1.1.5 christos /* Floating point options */ 249 1.1.1.5 christos { "mspfp", no_argument, NULL, OPTION_SPFP}, 250 1.1.1.5 christos { "mspfp-compact", no_argument, NULL, OPTION_SPFP}, 251 1.1.1.5 christos { "mspfp_compact", no_argument, NULL, OPTION_SPFP}, 252 1.1.1.5 christos { "mspfp-fast", no_argument, NULL, OPTION_SPFP}, 253 1.1.1.5 christos { "mspfp_fast", no_argument, NULL, OPTION_SPFP}, 254 1.1.1.5 christos { "mdpfp", no_argument, NULL, OPTION_DPFP}, 255 1.1.1.5 christos { "mdpfp-compact", no_argument, NULL, OPTION_DPFP}, 256 1.1.1.5 christos { "mdpfp_compact", no_argument, NULL, OPTION_DPFP}, 257 1.1.1.5 christos { "mdpfp-fast", no_argument, NULL, OPTION_DPFP}, 258 1.1.1.5 christos { "mdpfp_fast", no_argument, NULL, OPTION_DPFP}, 259 1.1.1.5 christos { "mfpuda", no_argument, NULL, OPTION_FPUDA}, 260 1.1.1.3 christos 261 1.1.1.3 christos /* The following options are deprecated and provided here only for 262 1.1.1.3 christos compatibility reasons. */ 263 1.1.1.3 christos { "mav2em", no_argument, NULL, OPTION_ARCEM }, 264 1.1.1.3 christos { "mav2hs", no_argument, NULL, OPTION_ARCHS }, 265 1.1.1.3 christos { "muser-mode-only", no_argument, NULL, OPTION_USER_MODE }, 266 1.1.1.3 christos { "mld-extension-reg-mask", required_argument, NULL, OPTION_LD_EXT_MASK }, 267 1.1.1.3 christos { "mswap", no_argument, NULL, OPTION_SWAP }, 268 1.1.1.3 christos { "mnorm", no_argument, NULL, OPTION_NORM }, 269 1.1.1.3 christos { "mbarrel-shifter", no_argument, NULL, OPTION_BARREL_SHIFT }, 270 1.1.1.3 christos { "mbarrel_shifter", no_argument, NULL, OPTION_BARREL_SHIFT }, 271 1.1.1.3 christos { "mmin-max", no_argument, NULL, OPTION_MIN_MAX }, 272 1.1.1.3 christos { "mmin_max", no_argument, NULL, OPTION_MIN_MAX }, 273 1.1.1.3 christos { "mno-mpy", no_argument, NULL, OPTION_NO_MPY }, 274 1.1.1.3 christos { "mea", no_argument, NULL, OPTION_EA }, 275 1.1.1.3 christos { "mEA", no_argument, NULL, OPTION_EA }, 276 1.1.1.3 christos { "mmul64", no_argument, NULL, OPTION_MUL64 }, 277 1.1.1.3 christos { "msimd", no_argument, NULL, OPTION_SIMD}, 278 1.1.1.3 christos { "mmac-d16", no_argument, NULL, OPTION_XMAC_D16}, 279 1.1.1.3 christos { "mmac_d16", no_argument, NULL, OPTION_XMAC_D16}, 280 1.1.1.3 christos { "mmac-24", no_argument, NULL, OPTION_XMAC_24}, 281 1.1.1.3 christos { "mmac_24", no_argument, NULL, OPTION_XMAC_24}, 282 1.1.1.3 christos { "mdsp-packa", no_argument, NULL, OPTION_DSP_PACKA}, 283 1.1.1.3 christos { "mdsp_packa", no_argument, NULL, OPTION_DSP_PACKA}, 284 1.1.1.3 christos { "mcrc", no_argument, NULL, OPTION_CRC}, 285 1.1.1.3 christos { "mdvbf", no_argument, NULL, OPTION_DVBF}, 286 1.1.1.3 christos { "mtelephony", no_argument, NULL, OPTION_TELEPHONY}, 287 1.1.1.3 christos { "mxy", no_argument, NULL, OPTION_XYMEMORY}, 288 1.1.1.3 christos { "mlock", no_argument, NULL, OPTION_LOCK}, 289 1.1.1.3 christos { "mswape", no_argument, NULL, OPTION_SWAPE}, 290 1.1.1.3 christos { "mrtsc", no_argument, NULL, OPTION_RTSC}, 291 1.1.1.3 christos 292 1.1.1.3 christos { NULL, no_argument, NULL, 0 } 293 1.1 skrll }; 294 1.1.1.3 christos 295 1.1.1.10 christos const size_t md_longopts_size = sizeof (md_longopts); 296 1.1 skrll 297 1.1.1.3 christos /* Local data and data types. */ 298 1.1.1.3 christos 299 1.1.1.3 christos /* Used since new relocation types are introduced in this 300 1.1.1.3 christos file (DUMMY_RELOC_LITUSE_*). */ 301 1.1.1.3 christos typedef int extended_bfd_reloc_code_real_type; 302 1.1.1.3 christos 303 1.1.1.3 christos struct arc_fixup 304 1.1.1.3 christos { 305 1.1.1.3 christos expressionS exp; 306 1.1 skrll 307 1.1.1.3 christos extended_bfd_reloc_code_real_type reloc; 308 1.1 skrll 309 1.1.1.3 christos /* index into arc_operands. */ 310 1.1.1.3 christos unsigned int opindex; 311 1.1 skrll 312 1.1.1.3 christos /* PC-relative, used by internals fixups. */ 313 1.1.1.3 christos unsigned char pcrel; 314 1.1.1.3 christos 315 1.1.1.3 christos /* TRUE if this fixup is for LIMM operand. */ 316 1.1.1.8 christos bool islong; 317 1.1.1.3 christos }; 318 1.1.1.3 christos 319 1.1.1.3 christos struct arc_insn 320 1.1 skrll { 321 1.1.1.6 christos unsigned long long int insn; 322 1.1.1.3 christos int nfixups; 323 1.1.1.3 christos struct arc_fixup fixups[MAX_INSN_FIXUPS]; 324 1.1.1.3 christos long limm; 325 1.1.1.8 christos unsigned int len; /* Length of instruction in bytes. */ 326 1.1.1.8 christos bool has_limm; /* Boolean value: TRUE if limm field is valid. */ 327 1.1.1.8 christos bool relax; /* Boolean value: TRUE if needs relaxation. */ 328 1.1.1.3 christos }; 329 1.1 skrll 330 1.1.1.3 christos /* Structure to hold any last two instructions. */ 331 1.1.1.3 christos static struct arc_last_insn 332 1.1 skrll { 333 1.1.1.3 christos /* Saved instruction opcode. */ 334 1.1.1.3 christos const struct arc_opcode *opcode; 335 1.1 skrll 336 1.1.1.3 christos /* Boolean value: TRUE if current insn is short. */ 337 1.1.1.8 christos bool has_limm; 338 1.1 skrll 339 1.1.1.3 christos /* Boolean value: TRUE if current insn has delay slot. */ 340 1.1.1.8 christos bool has_delay_slot; 341 1.1.1.3 christos } arc_last_insns[2]; 342 1.1.1.3 christos 343 1.1.1.5 christos /* Extension instruction suffix classes. */ 344 1.1.1.5 christos typedef struct 345 1.1.1.5 christos { 346 1.1.1.5 christos const char *name; 347 1.1.1.5 christos int len; 348 1.1.1.5 christos int attr_class; 349 1.1.1.5 christos } attributes_t; 350 1.1.1.5 christos 351 1.1.1.5 christos static const attributes_t suffixclass[] = 352 1.1.1.5 christos { 353 1.1.1.5 christos { "SUFFIX_FLAG", 11, ARC_SUFFIX_FLAG }, 354 1.1.1.5 christos { "SUFFIX_COND", 11, ARC_SUFFIX_COND }, 355 1.1.1.5 christos { "SUFFIX_NONE", 11, ARC_SUFFIX_NONE } 356 1.1.1.5 christos }; 357 1.1.1.5 christos 358 1.1.1.5 christos /* Extension instruction syntax classes. */ 359 1.1.1.5 christos static const attributes_t syntaxclass[] = 360 1.1.1.5 christos { 361 1.1.1.5 christos { "SYNTAX_3OP", 10, ARC_SYNTAX_3OP }, 362 1.1.1.5 christos { "SYNTAX_2OP", 10, ARC_SYNTAX_2OP }, 363 1.1.1.5 christos { "SYNTAX_1OP", 10, ARC_SYNTAX_1OP }, 364 1.1.1.5 christos { "SYNTAX_NOP", 10, ARC_SYNTAX_NOP } 365 1.1.1.5 christos }; 366 1.1.1.5 christos 367 1.1.1.5 christos /* Extension instruction syntax classes modifiers. */ 368 1.1.1.5 christos static const attributes_t syntaxclassmod[] = 369 1.1.1.5 christos { 370 1.1.1.5 christos { "OP1_IMM_IMPLIED" , 15, ARC_OP1_IMM_IMPLIED }, 371 1.1.1.5 christos { "OP1_MUST_BE_IMM" , 15, ARC_OP1_MUST_BE_IMM } 372 1.1.1.5 christos }; 373 1.1.1.5 christos 374 1.1.1.5 christos /* Extension register type. */ 375 1.1.1.5 christos typedef struct 376 1.1.1.5 christos { 377 1.1.1.5 christos char *name; 378 1.1.1.5 christos int number; 379 1.1.1.5 christos int imode; 380 1.1.1.5 christos } extRegister_t; 381 1.1.1.5 christos 382 1.1.1.5 christos /* A structure to hold the additional conditional codes. */ 383 1.1.1.5 christos static struct 384 1.1.1.5 christos { 385 1.1.1.5 christos struct arc_flag_operand *arc_ext_condcode; 386 1.1.1.5 christos int size; 387 1.1.1.5 christos } ext_condcode = { NULL, 0 }; 388 1.1.1.5 christos 389 1.1.1.5 christos /* Structure to hold an entry in ARC_OPCODE_HASH. */ 390 1.1.1.5 christos struct arc_opcode_hash_entry 391 1.1.1.5 christos { 392 1.1.1.5 christos /* The number of pointers in the OPCODE list. */ 393 1.1.1.5 christos size_t count; 394 1.1.1.5 christos 395 1.1.1.5 christos /* Points to a list of opcode pointers. */ 396 1.1.1.5 christos const struct arc_opcode **opcode; 397 1.1.1.5 christos }; 398 1.1.1.5 christos 399 1.1.1.5 christos /* Structure used for iterating through an arc_opcode_hash_entry. */ 400 1.1.1.5 christos struct arc_opcode_hash_entry_iterator 401 1.1.1.5 christos { 402 1.1.1.5 christos /* Index into the OPCODE element of the arc_opcode_hash_entry. */ 403 1.1.1.5 christos size_t index; 404 1.1.1.5 christos 405 1.1.1.5 christos /* The specific ARC_OPCODE from the ARC_OPCODES table that was last 406 1.1.1.5 christos returned by this iterator. */ 407 1.1.1.5 christos const struct arc_opcode *opcode; 408 1.1.1.5 christos }; 409 1.1.1.5 christos 410 1.1.1.5 christos /* Forward declaration. */ 411 1.1.1.5 christos static void assemble_insn 412 1.1.1.5 christos (const struct arc_opcode *, const expressionS *, int, 413 1.1.1.5 christos const struct arc_flags *, int, struct arc_insn *); 414 1.1.1.5 christos 415 1.1.1.6 christos /* The selection of the machine type can come from different sources. This 416 1.1.1.6 christos enum is used to track how the selection was made in order to perform 417 1.1.1.6 christos error checks. */ 418 1.1.1.6 christos enum mach_selection_type 419 1.1.1.6 christos { 420 1.1.1.6 christos MACH_SELECTION_NONE, 421 1.1.1.6 christos MACH_SELECTION_FROM_DEFAULT, 422 1.1.1.6 christos MACH_SELECTION_FROM_CPU_DIRECTIVE, 423 1.1.1.6 christos MACH_SELECTION_FROM_COMMAND_LINE 424 1.1.1.6 christos }; 425 1.1 skrll 426 1.1.1.6 christos /* How the current machine type was selected. */ 427 1.1.1.6 christos static enum mach_selection_type mach_selection_mode = MACH_SELECTION_NONE; 428 1.1 skrll 429 1.1.1.3 christos /* The hash table of instruction opcodes. */ 430 1.1.1.8 christos static htab_t arc_opcode_hash; 431 1.1 skrll 432 1.1.1.3 christos /* The hash table of register symbols. */ 433 1.1.1.8 christos static htab_t arc_reg_hash; 434 1.1.1.3 christos 435 1.1.1.5 christos /* The hash table of aux register symbols. */ 436 1.1.1.8 christos static htab_t arc_aux_hash; 437 1.1.1.5 christos 438 1.1.1.6 christos /* The hash table of address types. */ 439 1.1.1.8 christos static htab_t arc_addrtype_hash; 440 1.1.1.6 christos 441 1.1.1.6 christos #define ARC_CPU_TYPE_A6xx(NAME,EXTRA) \ 442 1.1.1.6 christos { #NAME, ARC_OPCODE_ARC600, bfd_mach_arc_arc600, \ 443 1.1.1.6 christos E_ARC_MACH_ARC600, EXTRA} 444 1.1.1.6 christos #define ARC_CPU_TYPE_A7xx(NAME,EXTRA) \ 445 1.1.1.6 christos { #NAME, ARC_OPCODE_ARC700, bfd_mach_arc_arc700, \ 446 1.1.1.6 christos E_ARC_MACH_ARC700, EXTRA} 447 1.1.1.6 christos #define ARC_CPU_TYPE_AV2EM(NAME,EXTRA) \ 448 1.1.1.6 christos { #NAME, ARC_OPCODE_ARCv2EM, bfd_mach_arc_arcv2, \ 449 1.1.1.6 christos EF_ARC_CPU_ARCV2EM, EXTRA} 450 1.1.1.6 christos #define ARC_CPU_TYPE_AV2HS(NAME,EXTRA) \ 451 1.1.1.6 christos { #NAME, ARC_OPCODE_ARCv2HS, bfd_mach_arc_arcv2, \ 452 1.1.1.6 christos EF_ARC_CPU_ARCV2HS, EXTRA} 453 1.1.1.6 christos #define ARC_CPU_TYPE_NONE \ 454 1.1.1.6 christos { 0, 0, 0, 0, 0 } 455 1.1.1.6 christos 456 1.1.1.3 christos /* A table of CPU names and opcode sets. */ 457 1.1.1.3 christos static const struct cpu_type 458 1.1 skrll { 459 1.1.1.3 christos const char *name; 460 1.1.1.3 christos unsigned flags; 461 1.1.1.3 christos int mach; 462 1.1.1.3 christos unsigned eflags; 463 1.1.1.3 christos unsigned features; 464 1.1.1.3 christos } 465 1.1.1.3 christos cpu_types[] = 466 1.1.1.3 christos { 467 1.1.1.6 christos #include "elf/arc-cpu.def" 468 1.1.1.3 christos }; 469 1.1 skrll 470 1.1.1.6 christos /* Information about the cpu/variant we're assembling for. */ 471 1.1.1.6 christos static struct cpu_type selected_cpu = { 0, 0, 0, E_ARC_OSABI_CURRENT, 0 }; 472 1.1.1.6 christos 473 1.1.1.7 christos /* TRUE if current assembly code uses RF16 only registers. */ 474 1.1.1.8 christos static bool rf16_only = true; 475 1.1.1.7 christos 476 1.1.1.6 christos /* MPY option. */ 477 1.1.1.6 christos static unsigned mpy_option = 0; 478 1.1.1.6 christos 479 1.1.1.6 christos /* Use PIC. */ 480 1.1.1.6 christos static unsigned pic_option = 0; 481 1.1.1.6 christos 482 1.1.1.6 christos /* Use small data. */ 483 1.1.1.6 christos static unsigned sda_option = 0; 484 1.1.1.6 christos 485 1.1.1.6 christos /* Use TLS. */ 486 1.1.1.6 christos static unsigned tls_option = 0; 487 1.1.1.6 christos 488 1.1.1.6 christos /* Command line given features. */ 489 1.1.1.6 christos static unsigned cl_features = 0; 490 1.1.1.6 christos 491 1.1.1.3 christos /* Used by the arc_reloc_op table. Order is important. */ 492 1.1.1.3 christos #define O_gotoff O_md1 /* @gotoff relocation. */ 493 1.1.1.3 christos #define O_gotpc O_md2 /* @gotpc relocation. */ 494 1.1.1.3 christos #define O_plt O_md3 /* @plt relocation. */ 495 1.1.1.3 christos #define O_sda O_md4 /* @sda relocation. */ 496 1.1.1.3 christos #define O_pcl O_md5 /* @pcl relocation. */ 497 1.1.1.3 christos #define O_tlsgd O_md6 /* @tlsgd relocation. */ 498 1.1.1.3 christos #define O_tlsie O_md7 /* @tlsie relocation. */ 499 1.1.1.3 christos #define O_tpoff9 O_md8 /* @tpoff9 relocation. */ 500 1.1.1.3 christos #define O_tpoff O_md9 /* @tpoff relocation. */ 501 1.1.1.3 christos #define O_dtpoff9 O_md10 /* @dtpoff9 relocation. */ 502 1.1.1.3 christos #define O_dtpoff O_md11 /* @dtpoff relocation. */ 503 1.1.1.3 christos #define O_last O_dtpoff 504 1.1.1.3 christos 505 1.1.1.3 christos /* Used to define a bracket as operand in tokens. */ 506 1.1.1.3 christos #define O_bracket O_md32 507 1.1.1.3 christos 508 1.1.1.6 christos /* Used to define a colon as an operand in tokens. */ 509 1.1.1.6 christos #define O_colon O_md31 510 1.1.1.6 christos 511 1.1.1.6 christos /* Used to define address types in nps400. */ 512 1.1.1.6 christos #define O_addrtype O_md30 513 1.1.1.6 christos 514 1.1.1.3 christos /* Dummy relocation, to be sorted out. */ 515 1.1.1.3 christos #define DUMMY_RELOC_ARC_ENTRY (BFD_RELOC_UNUSED + 1) 516 1.1.1.3 christos 517 1.1.1.3 christos #define USER_RELOC_P(R) ((R) >= O_gotoff && (R) <= O_last) 518 1.1.1.3 christos 519 1.1.1.3 christos /* A table to map the spelling of a relocation operand into an appropriate 520 1.1.1.3 christos bfd_reloc_code_real_type type. The table is assumed to be ordered such 521 1.1.1.3 christos that op-O_literal indexes into it. */ 522 1.1.1.3 christos #define ARC_RELOC_TABLE(op) \ 523 1.1.1.3 christos (&arc_reloc_op[ ((!USER_RELOC_P (op)) \ 524 1.1.1.3 christos ? (abort (), 0) \ 525 1.1.1.10 christos : (op) - O_gotoff) ]) 526 1.1.1.3 christos 527 1.1.1.3 christos #define DEF(NAME, RELOC, REQ) \ 528 1.1.1.3 christos { #NAME, sizeof (#NAME)-1, O_##NAME, RELOC, REQ} 529 1.1.1.3 christos 530 1.1.1.3 christos static const struct arc_reloc_op_tag 531 1.1.1.3 christos { 532 1.1.1.3 christos /* String to lookup. */ 533 1.1.1.3 christos const char *name; 534 1.1.1.3 christos /* Size of the string. */ 535 1.1.1.3 christos size_t length; 536 1.1.1.3 christos /* Which operator to use. */ 537 1.1.1.3 christos operatorT op; 538 1.1.1.3 christos extended_bfd_reloc_code_real_type reloc; 539 1.1.1.3 christos /* Allows complex relocation expression like identifier@reloc + 540 1.1.1.3 christos const. */ 541 1.1.1.3 christos unsigned int complex_expr : 1; 542 1.1.1.3 christos } 543 1.1.1.3 christos arc_reloc_op[] = 544 1.1.1.3 christos { 545 1.1.1.3 christos DEF (gotoff, BFD_RELOC_ARC_GOTOFF, 1), 546 1.1.1.3 christos DEF (gotpc, BFD_RELOC_ARC_GOTPC32, 0), 547 1.1.1.11 christos DEF (plt, BFD_RELOC_32_PLT_PCREL, 0), 548 1.1.1.3 christos DEF (sda, DUMMY_RELOC_ARC_ENTRY, 1), 549 1.1.1.11 christos DEF (pcl, BFD_RELOC_32_PCREL, 1), 550 1.1.1.3 christos DEF (tlsgd, BFD_RELOC_ARC_TLS_GD_GOT, 0), 551 1.1.1.3 christos DEF (tlsie, BFD_RELOC_ARC_TLS_IE_GOT, 0), 552 1.1.1.3 christos DEF (tpoff9, BFD_RELOC_ARC_TLS_LE_S9, 0), 553 1.1.1.5 christos DEF (tpoff, BFD_RELOC_ARC_TLS_LE_32, 1), 554 1.1.1.3 christos DEF (dtpoff9, BFD_RELOC_ARC_TLS_DTPOFF_S9, 0), 555 1.1.1.6 christos DEF (dtpoff, BFD_RELOC_ARC_TLS_DTPOFF, 1), 556 1.1.1.3 christos }; 557 1.1 skrll 558 1.1.1.3 christos static const int arc_num_reloc_op 559 1.1.1.3 christos = sizeof (arc_reloc_op) / sizeof (*arc_reloc_op); 560 1.1.1.3 christos 561 1.1.1.5 christos /* Structure for relaxable instruction that have to be swapped with a 562 1.1.1.5 christos smaller alternative instruction. */ 563 1.1.1.5 christos struct arc_relaxable_ins 564 1.1.1.5 christos { 565 1.1.1.5 christos /* Mnemonic that should be checked. */ 566 1.1.1.5 christos const char *mnemonic_r; 567 1.1.1.5 christos 568 1.1.1.5 christos /* Operands that should be checked. 569 1.1.1.5 christos Indexes of operands from operand array. */ 570 1.1.1.5 christos enum rlx_operand_type operands[6]; 571 1.1.1.5 christos 572 1.1.1.5 christos /* Flags that should be checked. */ 573 1.1.1.5 christos unsigned flag_classes[5]; 574 1.1.1.5 christos 575 1.1.1.5 christos /* Mnemonic (smaller) alternative to be used later for relaxation. */ 576 1.1.1.5 christos const char *mnemonic_alt; 577 1.1.1.5 christos 578 1.1.1.5 christos /* Index of operand that generic relaxation has to check. */ 579 1.1.1.5 christos unsigned opcheckidx; 580 1.1.1.5 christos 581 1.1.1.5 christos /* Base subtype index used. */ 582 1.1.1.5 christos enum arc_rlx_types subtype; 583 1.1.1.5 christos }; 584 1.1.1.5 christos 585 1.1.1.5 christos #define RELAX_TABLE_ENTRY(BITS, ISSIGNED, SIZE, NEXT) \ 586 1.1.1.5 christos { (ISSIGNED) ? ((1 << ((BITS) - 1)) - 1) : ((1 << (BITS)) - 1), \ 587 1.1.1.5 christos (ISSIGNED) ? -(1 << ((BITS) - 1)) : 0, \ 588 1.1.1.5 christos (SIZE), \ 589 1.1.1.5 christos (NEXT) } \ 590 1.1.1.5 christos 591 1.1.1.5 christos #define RELAX_TABLE_ENTRY_MAX(ISSIGNED, SIZE, NEXT) \ 592 1.1.1.5 christos { (ISSIGNED) ? 0x7FFFFFFF : 0xFFFFFFFF, \ 593 1.1.1.5 christos (ISSIGNED) ? -(0x7FFFFFFF) : 0, \ 594 1.1.1.5 christos (SIZE), \ 595 1.1.1.5 christos (NEXT) } \ 596 1.1.1.5 christos 597 1.1.1.5 christos 598 1.1.1.5 christos /* ARC relaxation table. */ 599 1.1.1.5 christos const relax_typeS md_relax_table[] = 600 1.1.1.5 christos { 601 1.1.1.5 christos /* Fake entry. */ 602 1.1.1.5 christos {0, 0, 0, 0}, 603 1.1.1.5 christos 604 1.1.1.5 christos /* BL_S s13 -> 605 1.1.1.5 christos BL s25. */ 606 1.1.1.6 christos RELAX_TABLE_ENTRY (13, 1, 2, ARC_RLX_BL), 607 1.1.1.6 christos RELAX_TABLE_ENTRY (25, 1, 4, ARC_RLX_NONE), 608 1.1.1.5 christos 609 1.1.1.5 christos /* B_S s10 -> 610 1.1.1.5 christos B s25. */ 611 1.1.1.6 christos RELAX_TABLE_ENTRY (10, 1, 2, ARC_RLX_B), 612 1.1.1.6 christos RELAX_TABLE_ENTRY (25, 1, 4, ARC_RLX_NONE), 613 1.1.1.5 christos 614 1.1.1.5 christos /* ADD_S c,b, u3 -> 615 1.1.1.5 christos ADD<.f> a,b,u6 -> 616 1.1.1.5 christos ADD<.f> a,b,limm. */ 617 1.1.1.6 christos RELAX_TABLE_ENTRY (3, 0, 2, ARC_RLX_ADD_U6), 618 1.1.1.6 christos RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_ADD_LIMM), 619 1.1.1.6 christos RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE), 620 1.1.1.5 christos 621 1.1.1.5 christos /* LD_S a, [b, u7] -> 622 1.1.1.5 christos LD<zz><.x><.aa><.di> a, [b, s9] -> 623 1.1.1.5 christos LD<zz><.x><.aa><.di> a, [b, limm] */ 624 1.1.1.6 christos RELAX_TABLE_ENTRY (7, 0, 2, ARC_RLX_LD_S9), 625 1.1.1.6 christos RELAX_TABLE_ENTRY (9, 1, 4, ARC_RLX_LD_LIMM), 626 1.1.1.6 christos RELAX_TABLE_ENTRY_MAX (1, 8, ARC_RLX_NONE), 627 1.1.1.5 christos 628 1.1.1.5 christos /* MOV_S b, u8 -> 629 1.1.1.5 christos MOV<.f> b, s12 -> 630 1.1.1.5 christos MOV<.f> b, limm. */ 631 1.1.1.6 christos RELAX_TABLE_ENTRY (8, 0, 2, ARC_RLX_MOV_S12), 632 1.1.1.6 christos RELAX_TABLE_ENTRY (8, 0, 4, ARC_RLX_MOV_LIMM), 633 1.1.1.6 christos RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE), 634 1.1.1.5 christos 635 1.1.1.5 christos /* SUB_S c, b, u3 -> 636 1.1.1.5 christos SUB<.f> a, b, u6 -> 637 1.1.1.5 christos SUB<.f> a, b, limm. */ 638 1.1.1.6 christos RELAX_TABLE_ENTRY (3, 0, 2, ARC_RLX_SUB_U6), 639 1.1.1.6 christos RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_SUB_LIMM), 640 1.1.1.6 christos RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE), 641 1.1.1.5 christos 642 1.1.1.5 christos /* MPY<.f> a, b, u6 -> 643 1.1.1.5 christos MPY<.f> a, b, limm. */ 644 1.1.1.6 christos RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_MPY_LIMM), 645 1.1.1.6 christos RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE), 646 1.1.1.5 christos 647 1.1.1.5 christos /* MOV<.f><.cc> b, u6 -> 648 1.1.1.5 christos MOV<.f><.cc> b, limm. */ 649 1.1.1.6 christos RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_MOV_RLIMM), 650 1.1.1.6 christos RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE), 651 1.1.1.5 christos 652 1.1.1.5 christos /* ADD<.f><.cc> b, b, u6 -> 653 1.1.1.5 christos ADD<.f><.cc> b, b, limm. */ 654 1.1.1.6 christos RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_ADD_RRLIMM), 655 1.1.1.6 christos RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE), 656 1.1.1.5 christos }; 657 1.1.1.5 christos 658 1.1.1.5 christos /* Order of this table's entries matters! */ 659 1.1.1.5 christos const struct arc_relaxable_ins arc_relaxable_insns[] = 660 1.1.1.5 christos { 661 1.1.1.5 christos { "bl", { IMMEDIATE }, { 0 }, "bl_s", 0, ARC_RLX_BL_S }, 662 1.1.1.5 christos { "b", { IMMEDIATE }, { 0 }, "b_s", 0, ARC_RLX_B_S }, 663 1.1.1.5 christos { "add", { REGISTER, REGISTER_DUP, IMMEDIATE }, { 5, 1, 0 }, "add", 664 1.1.1.5 christos 2, ARC_RLX_ADD_RRU6}, 665 1.1.1.5 christos { "add", { REGISTER_S, REGISTER_S, IMMEDIATE }, { 0 }, "add_s", 2, 666 1.1.1.5 christos ARC_RLX_ADD_U3 }, 667 1.1.1.5 christos { "add", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "add", 2, 668 1.1.1.5 christos ARC_RLX_ADD_U6 }, 669 1.1.1.5 christos { "ld", { REGISTER_S, BRACKET, REGISTER_S, IMMEDIATE, BRACKET }, 670 1.1.1.5 christos { 0 }, "ld_s", 3, ARC_RLX_LD_U7 }, 671 1.1.1.5 christos { "ld", { REGISTER, BRACKET, REGISTER_NO_GP, IMMEDIATE, BRACKET }, 672 1.1.1.5 christos { 11, 4, 14, 17, 0 }, "ld", 3, ARC_RLX_LD_S9 }, 673 1.1.1.5 christos { "mov", { REGISTER_S, IMMEDIATE }, { 0 }, "mov_s", 1, ARC_RLX_MOV_U8 }, 674 1.1.1.5 christos { "mov", { REGISTER, IMMEDIATE }, { 5, 0 }, "mov", 1, ARC_RLX_MOV_S12 }, 675 1.1.1.5 christos { "mov", { REGISTER, IMMEDIATE }, { 5, 1, 0 },"mov", 1, ARC_RLX_MOV_RU6 }, 676 1.1.1.5 christos { "sub", { REGISTER_S, REGISTER_S, IMMEDIATE }, { 0 }, "sub_s", 2, 677 1.1.1.5 christos ARC_RLX_SUB_U3 }, 678 1.1.1.5 christos { "sub", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "sub", 2, 679 1.1.1.5 christos ARC_RLX_SUB_U6 }, 680 1.1.1.5 christos { "mpy", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "mpy", 2, 681 1.1.1.5 christos ARC_RLX_MPY_U6 }, 682 1.1.1.5 christos }; 683 1.1.1.5 christos 684 1.1.1.5 christos const unsigned arc_num_relaxable_ins = ARRAY_SIZE (arc_relaxable_insns); 685 1.1.1.5 christos 686 1.1.1.3 christos /* Pre-defined "_GLOBAL_OFFSET_TABLE_". */ 687 1.1.1.3 christos symbolS * GOT_symbol = 0; 688 1.1 skrll 689 1.1.1.11 christos /* Set to TRUE for a special parsing action when assembling instructions. */ 690 1.1.1.8 christos static bool assembling_insn = false; 691 1.1.1.3 christos 692 1.1.1.6 christos /* List with attributes set explicitly. */ 693 1.1.1.8 christos static bool attributes_set_explicitly[NUM_KNOWN_OBJ_ATTRIBUTES]; 694 1.1.1.6 christos 695 1.1.1.5 christos /* Functions implementation. */ 696 1.1.1.3 christos 697 1.1.1.5 christos /* Return a pointer to ARC_OPCODE_HASH_ENTRY that identifies all 698 1.1.1.5 christos ARC_OPCODE entries in ARC_OPCODE_HASH that match NAME, or NULL if there 699 1.1.1.5 christos are no matching entries in ARC_OPCODE_HASH. */ 700 1.1.1.5 christos 701 1.1.1.5 christos static const struct arc_opcode_hash_entry * 702 1.1.1.5 christos arc_find_opcode (const char *name) 703 1.1.1.5 christos { 704 1.1.1.5 christos const struct arc_opcode_hash_entry *entry; 705 1.1.1.5 christos 706 1.1.1.8 christos entry = str_hash_find (arc_opcode_hash, name); 707 1.1.1.5 christos return entry; 708 1.1.1.5 christos } 709 1.1.1.5 christos 710 1.1.1.5 christos /* Initialise the iterator ITER. */ 711 1.1.1.5 christos 712 1.1.1.5 christos static void 713 1.1.1.5 christos arc_opcode_hash_entry_iterator_init (struct arc_opcode_hash_entry_iterator *iter) 714 1.1.1.5 christos { 715 1.1.1.5 christos iter->index = 0; 716 1.1.1.5 christos iter->opcode = NULL; 717 1.1.1.5 christos } 718 1.1.1.5 christos 719 1.1.1.5 christos /* Return the next ARC_OPCODE from ENTRY, using ITER to hold state between 720 1.1.1.5 christos calls to this function. Return NULL when all ARC_OPCODE entries have 721 1.1.1.5 christos been returned. */ 722 1.1.1.5 christos 723 1.1.1.5 christos static const struct arc_opcode * 724 1.1.1.5 christos arc_opcode_hash_entry_iterator_next (const struct arc_opcode_hash_entry *entry, 725 1.1.1.5 christos struct arc_opcode_hash_entry_iterator *iter) 726 1.1.1.5 christos { 727 1.1.1.5 christos if (iter->opcode == NULL && iter->index == 0) 728 1.1.1.5 christos { 729 1.1.1.5 christos gas_assert (entry->count > 0); 730 1.1.1.5 christos iter->opcode = entry->opcode[iter->index]; 731 1.1.1.5 christos } 732 1.1.1.5 christos else if (iter->opcode != NULL) 733 1.1.1.5 christos { 734 1.1.1.5 christos const char *old_name = iter->opcode->name; 735 1.1.1.5 christos 736 1.1.1.5 christos iter->opcode++; 737 1.1.1.5 christos if (iter->opcode->name == NULL 738 1.1.1.5 christos || strcmp (old_name, iter->opcode->name) != 0) 739 1.1.1.5 christos { 740 1.1.1.5 christos iter->index++; 741 1.1.1.5 christos if (iter->index == entry->count) 742 1.1.1.5 christos iter->opcode = NULL; 743 1.1.1.5 christos else 744 1.1.1.5 christos iter->opcode = entry->opcode[iter->index]; 745 1.1.1.5 christos } 746 1.1.1.5 christos } 747 1.1.1.5 christos 748 1.1.1.5 christos return iter->opcode; 749 1.1.1.5 christos } 750 1.1.1.5 christos 751 1.1.1.5 christos /* Insert an opcode into opcode hash structure. */ 752 1.1.1.5 christos 753 1.1.1.5 christos static void 754 1.1.1.5 christos arc_insert_opcode (const struct arc_opcode *opcode) 755 1.1.1.5 christos { 756 1.1.1.8 christos const char *name; 757 1.1.1.5 christos struct arc_opcode_hash_entry *entry; 758 1.1.1.5 christos name = opcode->name; 759 1.1.1.5 christos 760 1.1.1.8 christos entry = str_hash_find (arc_opcode_hash, name); 761 1.1.1.5 christos if (entry == NULL) 762 1.1.1.5 christos { 763 1.1.1.5 christos entry = XNEW (struct arc_opcode_hash_entry); 764 1.1.1.5 christos entry->count = 0; 765 1.1.1.5 christos entry->opcode = NULL; 766 1.1.1.5 christos 767 1.1.1.8 christos if (str_hash_insert (arc_opcode_hash, name, entry, 0) != NULL) 768 1.1.1.8 christos as_fatal (_("duplicate %s"), name); 769 1.1.1.5 christos } 770 1.1.1.5 christos 771 1.1.1.5 christos entry->opcode = XRESIZEVEC (const struct arc_opcode *, entry->opcode, 772 1.1.1.5 christos entry->count + 1); 773 1.1.1.5 christos 774 1.1.1.5 christos entry->opcode[entry->count] = opcode; 775 1.1.1.5 christos entry->count++; 776 1.1.1.5 christos } 777 1.1.1.3 christos 778 1.1.1.9 christos static void 779 1.1.1.9 christos arc_opcode_free (void *elt) 780 1.1.1.9 christos { 781 1.1.1.10 christos string_tuple_t *tuple = elt; 782 1.1.1.9 christos struct arc_opcode_hash_entry *entry = (void *) tuple->value; 783 1.1.1.9 christos free (entry->opcode); 784 1.1.1.9 christos free (entry); 785 1.1.1.9 christos free (tuple); 786 1.1.1.9 christos } 787 1.1.1.3 christos 788 1.1.1.6 christos /* Like md_number_to_chars but for middle-endian values. The 4-byte limm 789 1.1.1.6 christos value, is encoded as 'middle-endian' for a little-endian target. This 790 1.1.1.6 christos function is used for regular 4, 6, and 8 byte instructions as well. */ 791 1.1 skrll 792 1.1.1.3 christos static void 793 1.1.1.6 christos md_number_to_chars_midend (char *buf, unsigned long long val, int n) 794 1.1.1.3 christos { 795 1.1.1.6 christos switch (n) 796 1.1 skrll { 797 1.1.1.6 christos case 2: 798 1.1.1.6 christos md_number_to_chars (buf, val, n); 799 1.1.1.6 christos break; 800 1.1.1.6 christos case 6: 801 1.1.1.7 christos md_number_to_chars (buf, (val & 0xffff00000000ull) >> 32, 2); 802 1.1.1.6 christos md_number_to_chars_midend (buf + 2, (val & 0xffffffff), 4); 803 1.1.1.6 christos break; 804 1.1.1.6 christos case 4: 805 1.1.1.3 christos md_number_to_chars (buf, (val & 0xffff0000) >> 16, 2); 806 1.1.1.3 christos md_number_to_chars (buf + 2, (val & 0xffff), 2); 807 1.1.1.6 christos break; 808 1.1.1.6 christos case 8: 809 1.1.1.7 christos md_number_to_chars_midend (buf, (val & 0xffffffff00000000ull) >> 32, 4); 810 1.1.1.6 christos md_number_to_chars_midend (buf + 4, (val & 0xffffffff), 4); 811 1.1.1.6 christos break; 812 1.1.1.6 christos default: 813 1.1.1.6 christos abort (); 814 1.1.1.3 christos } 815 1.1.1.6 christos } 816 1.1.1.6 christos 817 1.1.1.6 christos /* Check if a feature is allowed for a specific CPU. */ 818 1.1.1.6 christos 819 1.1.1.6 christos static void 820 1.1.1.6 christos arc_check_feature (void) 821 1.1.1.6 christos { 822 1.1.1.6 christos unsigned i; 823 1.1.1.6 christos 824 1.1.1.6 christos if (!selected_cpu.features 825 1.1.1.6 christos || !selected_cpu.name) 826 1.1.1.6 christos return; 827 1.1.1.6 christos 828 1.1.1.6 christos for (i = 0; i < ARRAY_SIZE (feature_list); i++) 829 1.1.1.6 christos if ((selected_cpu.features & feature_list[i].feature) 830 1.1.1.6 christos && !(selected_cpu.flags & feature_list[i].cpus)) 831 1.1.1.6 christos as_bad (_("invalid %s option for %s cpu"), feature_list[i].name, 832 1.1.1.6 christos selected_cpu.name); 833 1.1.1.6 christos 834 1.1.1.6 christos for (i = 0; i < ARRAY_SIZE (conflict_list); i++) 835 1.1.1.6 christos if ((selected_cpu.features & conflict_list[i]) == conflict_list[i]) 836 1.1.1.6 christos as_bad(_("conflicting ISA extension attributes.")); 837 1.1.1.3 christos } 838 1.1 skrll 839 1.1.1.5 christos /* Select an appropriate entry from CPU_TYPES based on ARG and initialise 840 1.1.1.6 christos the relevant static global variables. Parameter SEL describes where 841 1.1.1.6 christos this selection originated from. */ 842 1.1.1.5 christos 843 1.1.1.5 christos static void 844 1.1.1.6 christos arc_select_cpu (const char *arg, enum mach_selection_type sel) 845 1.1.1.5 christos { 846 1.1.1.5 christos int i; 847 1.1.1.7 christos static struct cpu_type old_cpu = { 0, 0, 0, E_ARC_OSABI_CURRENT, 0 }; 848 1.1.1.5 christos 849 1.1.1.6 christos /* We should only set a default if we've not made a selection from some 850 1.1.1.6 christos other source. */ 851 1.1.1.6 christos gas_assert (sel != MACH_SELECTION_FROM_DEFAULT 852 1.1.1.6 christos || mach_selection_mode == MACH_SELECTION_NONE); 853 1.1.1.6 christos 854 1.1.1.6 christos if ((mach_selection_mode == MACH_SELECTION_FROM_CPU_DIRECTIVE) 855 1.1.1.6 christos && (sel == MACH_SELECTION_FROM_CPU_DIRECTIVE)) 856 1.1.1.6 christos as_bad (_("Multiple .cpu directives found")); 857 1.1.1.6 christos 858 1.1.1.6 christos /* Look for a matching entry in CPU_TYPES array. */ 859 1.1.1.5 christos for (i = 0; cpu_types[i].name; ++i) 860 1.1.1.5 christos { 861 1.1.1.5 christos if (!strcasecmp (cpu_types[i].name, arg)) 862 1.1.1.5 christos { 863 1.1.1.6 christos /* If a previous selection was made on the command line, then we 864 1.1.1.6 christos allow later selections on the command line to override earlier 865 1.1.1.6 christos ones. However, a selection from a '.cpu NAME' directive must 866 1.1.1.6 christos match the command line selection, or we give a warning. */ 867 1.1.1.6 christos if (mach_selection_mode == MACH_SELECTION_FROM_COMMAND_LINE) 868 1.1.1.6 christos { 869 1.1.1.6 christos gas_assert (sel == MACH_SELECTION_FROM_COMMAND_LINE 870 1.1.1.6 christos || sel == MACH_SELECTION_FROM_CPU_DIRECTIVE); 871 1.1.1.6 christos if (sel == MACH_SELECTION_FROM_CPU_DIRECTIVE 872 1.1.1.6 christos && selected_cpu.mach != cpu_types[i].mach) 873 1.1.1.6 christos { 874 1.1.1.6 christos as_warn (_("Command-line value overrides \".cpu\" directive")); 875 1.1.1.6 christos } 876 1.1.1.6 christos return; 877 1.1.1.6 christos } 878 1.1.1.6 christos /* Initialise static global data about selected machine type. */ 879 1.1.1.6 christos selected_cpu.flags = cpu_types[i].flags; 880 1.1.1.6 christos selected_cpu.name = cpu_types[i].name; 881 1.1.1.6 christos selected_cpu.features = cpu_types[i].features | cl_features; 882 1.1.1.6 christos selected_cpu.mach = cpu_types[i].mach; 883 1.1.1.6 christos selected_cpu.eflags = ((selected_cpu.eflags & ~EF_ARC_MACH_MSK) 884 1.1.1.6 christos | cpu_types[i].eflags); 885 1.1.1.5 christos break; 886 1.1.1.5 christos } 887 1.1.1.5 christos } 888 1.1.1.5 christos 889 1.1.1.5 christos if (!cpu_types[i].name) 890 1.1.1.5 christos as_fatal (_("unknown architecture: %s\n"), arg); 891 1.1.1.6 christos 892 1.1.1.6 christos /* Check if set features are compatible with the chosen CPU. */ 893 1.1.1.6 christos arc_check_feature (); 894 1.1.1.6 christos 895 1.1.1.7 christos /* If we change the CPU, we need to re-init the bfd. */ 896 1.1.1.7 christos if (mach_selection_mode != MACH_SELECTION_NONE 897 1.1.1.7 christos && (old_cpu.mach != selected_cpu.mach)) 898 1.1.1.7 christos { 899 1.1.1.7 christos bfd_find_target (arc_target_format, stdoutput); 900 1.1.1.7 christos if (! bfd_set_arch_mach (stdoutput, bfd_arch_arc, selected_cpu.mach)) 901 1.1.1.7 christos as_warn (_("Could not set architecture and machine")); 902 1.1.1.7 christos } 903 1.1.1.7 christos 904 1.1.1.6 christos mach_selection_mode = sel; 905 1.1.1.7 christos old_cpu = selected_cpu; 906 1.1.1.5 christos } 907 1.1.1.5 christos 908 1.1.1.3 christos /* Here ends all the ARCompact extension instruction assembling 909 1.1.1.3 christos stuff. */ 910 1.1 skrll 911 1.1.1.3 christos static void 912 1.1.1.3 christos arc_extra_reloc (int r_type) 913 1.1.1.3 christos { 914 1.1.1.3 christos char *sym_name, c; 915 1.1.1.3 christos symbolS *sym, *lab = NULL; 916 1.1 skrll 917 1.1.1.3 christos if (*input_line_pointer == '@') 918 1.1.1.3 christos input_line_pointer++; 919 1.1.1.3 christos c = get_symbol_name (&sym_name); 920 1.1.1.3 christos sym = symbol_find_or_make (sym_name); 921 1.1.1.3 christos restore_line_pointer (c); 922 1.1.1.3 christos if (c == ',' && r_type == BFD_RELOC_ARC_TLS_GD_LD) 923 1.1.1.3 christos { 924 1.1.1.3 christos ++input_line_pointer; 925 1.1.1.3 christos char *lab_name; 926 1.1.1.3 christos c = get_symbol_name (&lab_name); 927 1.1.1.3 christos lab = symbol_find_or_make (lab_name); 928 1.1.1.3 christos restore_line_pointer (c); 929 1.1.1.3 christos } 930 1.1.1.5 christos 931 1.1.1.5 christos /* These relocations exist as a mechanism for the compiler to tell the 932 1.1.1.5 christos linker how to patch the code if the tls model is optimised. However, 933 1.1.1.5 christos the relocation itself does not require any space within the assembler 934 1.1.1.5 christos fragment, and so we pass a size of 0. 935 1.1.1.5 christos 936 1.1.1.5 christos The lines that generate these relocations look like this: 937 1.1.1.5 christos 938 1.1.1.5 christos .tls_gd_ld @.tdata`bl __tls_get_addr@plt 939 1.1.1.5 christos 940 1.1.1.5 christos The '.tls_gd_ld @.tdata' is processed first and generates the 941 1.1.1.5 christos additional relocation, while the 'bl __tls_get_addr@plt' is processed 942 1.1.1.5 christos second and generates the additional branch. 943 1.1.1.5 christos 944 1.1.1.5 christos It is possible that the additional relocation generated by the 945 1.1.1.5 christos '.tls_gd_ld @.tdata' will be attached at the very end of one fragment, 946 1.1.1.5 christos while the 'bl __tls_get_addr@plt' will be generated as the first thing 947 1.1.1.5 christos in the next fragment. This will be fine; both relocations will still 948 1.1.1.5 christos appear to be at the same address in the generated object file. 949 1.1.1.5 christos However, this only works as the additional relocation is generated 950 1.1.1.5 christos with size of 0 bytes. */ 951 1.1.1.3 christos fixS *fixP 952 1.1.1.3 christos = fix_new (frag_now, /* Which frag? */ 953 1.1.1.3 christos frag_now_fix (), /* Where in that frag? */ 954 1.1.1.5 christos 0, /* size: 1, 2, or 4 usually. */ 955 1.1.1.3 christos sym, /* X_add_symbol. */ 956 1.1.1.3 christos 0, /* X_add_number. */ 957 1.1.1.8 christos false, /* TRUE if PC-relative relocation. */ 958 1.1.1.3 christos r_type /* Relocation type. */); 959 1.1.1.3 christos fixP->fx_subsy = lab; 960 1.1.1.3 christos } 961 1.1.1.3 christos 962 1.1.1.3 christos static symbolS * 963 1.1.1.3 christos arc_lcomm_internal (int ignore ATTRIBUTE_UNUSED, 964 1.1.1.3 christos symbolS *symbolP, addressT size) 965 1.1.1.3 christos { 966 1.1.1.3 christos addressT align = 0; 967 1.1.1.3 christos SKIP_WHITESPACE (); 968 1.1 skrll 969 1.1.1.3 christos if (*input_line_pointer == ',') 970 1.1 skrll { 971 1.1.1.3 christos align = parse_align (1); 972 1.1 skrll 973 1.1.1.3 christos if (align == (addressT) -1) 974 1.1.1.3 christos return NULL; 975 1.1 skrll } 976 1.1 skrll else 977 1.1.1.3 christos { 978 1.1.1.3 christos if (size >= 8) 979 1.1.1.3 christos align = 3; 980 1.1.1.3 christos else if (size >= 4) 981 1.1.1.3 christos align = 2; 982 1.1.1.3 christos else if (size >= 2) 983 1.1.1.3 christos align = 1; 984 1.1.1.3 christos else 985 1.1.1.3 christos align = 0; 986 1.1.1.3 christos } 987 1.1 skrll 988 1.1.1.3 christos bss_alloc (symbolP, size, align); 989 1.1.1.3 christos S_CLEAR_EXTERNAL (symbolP); 990 1.1 skrll 991 1.1.1.3 christos return symbolP; 992 1.1.1.3 christos } 993 1.1 skrll 994 1.1.1.3 christos static void 995 1.1.1.3 christos arc_lcomm (int ignore) 996 1.1 skrll { 997 1.1.1.3 christos symbolS *symbolP = s_comm_internal (ignore, arc_lcomm_internal); 998 1.1 skrll 999 1.1.1.3 christos if (symbolP) 1000 1.1.1.3 christos symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT; 1001 1.1.1.3 christos } 1002 1.1 skrll 1003 1.1.1.3 christos /* Select the cpu we're assembling for. */ 1004 1.1 skrll 1005 1.1.1.3 christos static void 1006 1.1.1.3 christos arc_option (int ignore ATTRIBUTE_UNUSED) 1007 1.1.1.3 christos { 1008 1.1.1.3 christos char c; 1009 1.1.1.3 christos char *cpu; 1010 1.1.1.6 christos const char *cpu_name; 1011 1.1 skrll 1012 1.1.1.3 christos c = get_symbol_name (&cpu); 1013 1.1 skrll 1014 1.1.1.6 christos cpu_name = cpu; 1015 1.1.1.6 christos if ((!strcmp ("ARC600", cpu)) 1016 1.1.1.6 christos || (!strcmp ("ARC601", cpu)) 1017 1.1.1.6 christos || (!strcmp ("A6", cpu))) 1018 1.1.1.6 christos cpu_name = "arc600"; 1019 1.1.1.6 christos else if ((!strcmp ("ARC700", cpu)) 1020 1.1.1.6 christos || (!strcmp ("A7", cpu))) 1021 1.1.1.6 christos cpu_name = "arc700"; 1022 1.1.1.6 christos else if (!strcmp ("EM", cpu)) 1023 1.1.1.6 christos cpu_name = "arcem"; 1024 1.1.1.6 christos else if (!strcmp ("HS", cpu)) 1025 1.1.1.6 christos cpu_name = "archs"; 1026 1.1.1.6 christos else if (!strcmp ("NPS400", cpu)) 1027 1.1.1.6 christos cpu_name = "nps400"; 1028 1.1 skrll 1029 1.1.1.6 christos arc_select_cpu (cpu_name, MACH_SELECTION_FROM_CPU_DIRECTIVE); 1030 1.1 skrll 1031 1.1.1.5 christos restore_line_pointer (c); 1032 1.1.1.3 christos demand_empty_rest_of_line (); 1033 1.1.1.3 christos } 1034 1.1 skrll 1035 1.1.1.3 christos /* Smartly print an expression. */ 1036 1.1 skrll 1037 1.1.1.3 christos static void 1038 1.1.1.3 christos debug_exp (expressionS *t) 1039 1.1.1.3 christos { 1040 1.1.1.3 christos const char *name ATTRIBUTE_UNUSED; 1041 1.1.1.3 christos const char *namemd ATTRIBUTE_UNUSED; 1042 1.1 skrll 1043 1.1.1.3 christos pr_debug ("debug_exp: "); 1044 1.1 skrll 1045 1.1.1.3 christos switch (t->X_op) 1046 1.1 skrll { 1047 1.1.1.3 christos default: name = "unknown"; break; 1048 1.1.1.3 christos case O_illegal: name = "O_illegal"; break; 1049 1.1.1.3 christos case O_absent: name = "O_absent"; break; 1050 1.1.1.3 christos case O_constant: name = "O_constant"; break; 1051 1.1.1.3 christos case O_symbol: name = "O_symbol"; break; 1052 1.1.1.3 christos case O_symbol_rva: name = "O_symbol_rva"; break; 1053 1.1.1.3 christos case O_register: name = "O_register"; break; 1054 1.1.1.3 christos case O_big: name = "O_big"; break; 1055 1.1.1.3 christos case O_uminus: name = "O_uminus"; break; 1056 1.1.1.3 christos case O_bit_not: name = "O_bit_not"; break; 1057 1.1.1.3 christos case O_logical_not: name = "O_logical_not"; break; 1058 1.1.1.3 christos case O_multiply: name = "O_multiply"; break; 1059 1.1.1.3 christos case O_divide: name = "O_divide"; break; 1060 1.1.1.3 christos case O_modulus: name = "O_modulus"; break; 1061 1.1.1.3 christos case O_left_shift: name = "O_left_shift"; break; 1062 1.1.1.3 christos case O_right_shift: name = "O_right_shift"; break; 1063 1.1.1.3 christos case O_bit_inclusive_or: name = "O_bit_inclusive_or"; break; 1064 1.1.1.3 christos case O_bit_or_not: name = "O_bit_or_not"; break; 1065 1.1.1.3 christos case O_bit_exclusive_or: name = "O_bit_exclusive_or"; break; 1066 1.1.1.3 christos case O_bit_and: name = "O_bit_and"; break; 1067 1.1.1.3 christos case O_add: name = "O_add"; break; 1068 1.1.1.3 christos case O_subtract: name = "O_subtract"; break; 1069 1.1.1.3 christos case O_eq: name = "O_eq"; break; 1070 1.1.1.3 christos case O_ne: name = "O_ne"; break; 1071 1.1.1.3 christos case O_lt: name = "O_lt"; break; 1072 1.1.1.3 christos case O_le: name = "O_le"; break; 1073 1.1.1.3 christos case O_ge: name = "O_ge"; break; 1074 1.1.1.3 christos case O_gt: name = "O_gt"; break; 1075 1.1.1.3 christos case O_logical_and: name = "O_logical_and"; break; 1076 1.1.1.3 christos case O_logical_or: name = "O_logical_or"; break; 1077 1.1.1.3 christos case O_index: name = "O_index"; break; 1078 1.1.1.3 christos case O_bracket: name = "O_bracket"; break; 1079 1.1.1.6 christos case O_colon: name = "O_colon"; break; 1080 1.1.1.6 christos case O_addrtype: name = "O_addrtype"; break; 1081 1.1.1.3 christos } 1082 1.1.1.3 christos 1083 1.1.1.3 christos switch (t->X_md) 1084 1.1.1.3 christos { 1085 1.1.1.3 christos default: namemd = "unknown"; break; 1086 1.1.1.3 christos case O_gotoff: namemd = "O_gotoff"; break; 1087 1.1.1.3 christos case O_gotpc: namemd = "O_gotpc"; break; 1088 1.1.1.3 christos case O_plt: namemd = "O_plt"; break; 1089 1.1.1.3 christos case O_sda: namemd = "O_sda"; break; 1090 1.1.1.3 christos case O_pcl: namemd = "O_pcl"; break; 1091 1.1.1.3 christos case O_tlsgd: namemd = "O_tlsgd"; break; 1092 1.1.1.3 christos case O_tlsie: namemd = "O_tlsie"; break; 1093 1.1.1.3 christos case O_tpoff9: namemd = "O_tpoff9"; break; 1094 1.1.1.3 christos case O_tpoff: namemd = "O_tpoff"; break; 1095 1.1.1.3 christos case O_dtpoff9: namemd = "O_dtpoff9"; break; 1096 1.1.1.3 christos case O_dtpoff: namemd = "O_dtpoff"; break; 1097 1.1.1.3 christos } 1098 1.1.1.3 christos 1099 1.1.1.3 christos pr_debug ("%s (%s, %s, %d, %s)", name, 1100 1.1.1.3 christos (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--", 1101 1.1.1.3 christos (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--", 1102 1.1.1.3 christos (int) t->X_add_number, 1103 1.1.1.3 christos (t->X_md) ? namemd : "--"); 1104 1.1.1.3 christos pr_debug ("\n"); 1105 1.1.1.3 christos fflush (stderr); 1106 1.1.1.3 christos } 1107 1.1 skrll 1108 1.1.1.7 christos /* Helper for parsing an argument, used for sorting out the relocation 1109 1.1.1.7 christos type. */ 1110 1.1.1.7 christos 1111 1.1.1.7 christos static void 1112 1.1.1.7 christos parse_reloc_symbol (expressionS *resultP) 1113 1.1.1.7 christos { 1114 1.1.1.7 christos char *reloc_name, c, *sym_name; 1115 1.1.1.7 christos size_t len; 1116 1.1.1.7 christos int i; 1117 1.1.1.7 christos const struct arc_reloc_op_tag *r; 1118 1.1.1.7 christos expressionS right; 1119 1.1.1.7 christos symbolS *base; 1120 1.1.1.7 christos 1121 1.1.1.7 christos /* A relocation operand has the following form 1122 1.1.1.7 christos @identifier@relocation_type. The identifier is already in 1123 1.1.1.7 christos tok! */ 1124 1.1.1.7 christos if (resultP->X_op != O_symbol) 1125 1.1.1.7 christos { 1126 1.1.1.7 christos as_bad (_("No valid label relocation operand")); 1127 1.1.1.7 christos resultP->X_op = O_illegal; 1128 1.1.1.7 christos return; 1129 1.1.1.7 christos } 1130 1.1.1.7 christos 1131 1.1.1.7 christos /* Parse @relocation_type. */ 1132 1.1.1.7 christos input_line_pointer++; 1133 1.1.1.7 christos c = get_symbol_name (&reloc_name); 1134 1.1.1.7 christos len = input_line_pointer - reloc_name; 1135 1.1.1.7 christos if (len == 0) 1136 1.1.1.7 christos { 1137 1.1.1.7 christos as_bad (_("No relocation operand")); 1138 1.1.1.7 christos resultP->X_op = O_illegal; 1139 1.1.1.7 christos return; 1140 1.1.1.7 christos } 1141 1.1.1.7 christos 1142 1.1.1.7 christos /* Go through known relocation and try to find a match. */ 1143 1.1.1.7 christos r = &arc_reloc_op[0]; 1144 1.1.1.7 christos for (i = arc_num_reloc_op - 1; i >= 0; i--, r++) 1145 1.1.1.7 christos if (len == r->length 1146 1.1.1.7 christos && memcmp (reloc_name, r->name, len) == 0) 1147 1.1.1.7 christos break; 1148 1.1.1.7 christos if (i < 0) 1149 1.1.1.7 christos { 1150 1.1.1.7 christos as_bad (_("Unknown relocation operand: @%s"), reloc_name); 1151 1.1.1.7 christos resultP->X_op = O_illegal; 1152 1.1.1.7 christos return; 1153 1.1.1.7 christos } 1154 1.1.1.7 christos 1155 1.1.1.10 christos restore_line_pointer (c); 1156 1.1.1.10 christos SKIP_WHITESPACE (); 1157 1.1.1.7 christos /* Extra check for TLS: base. */ 1158 1.1.1.7 christos if (*input_line_pointer == '@') 1159 1.1.1.7 christos { 1160 1.1.1.7 christos if (resultP->X_op_symbol != NULL 1161 1.1.1.7 christos || resultP->X_op != O_symbol) 1162 1.1.1.7 christos { 1163 1.1.1.7 christos as_bad (_("Unable to parse TLS base: %s"), 1164 1.1.1.7 christos input_line_pointer); 1165 1.1.1.7 christos resultP->X_op = O_illegal; 1166 1.1.1.7 christos return; 1167 1.1.1.7 christos } 1168 1.1.1.7 christos input_line_pointer++; 1169 1.1.1.7 christos c = get_symbol_name (&sym_name); 1170 1.1.1.7 christos base = symbol_find_or_make (sym_name); 1171 1.1.1.7 christos resultP->X_op = O_subtract; 1172 1.1.1.7 christos resultP->X_op_symbol = base; 1173 1.1.1.7 christos restore_line_pointer (c); 1174 1.1.1.7 christos right.X_add_number = 0; 1175 1.1.1.7 christos } 1176 1.1.1.7 christos 1177 1.1.1.7 christos if ((*input_line_pointer != '+') 1178 1.1.1.7 christos && (*input_line_pointer != '-')) 1179 1.1.1.7 christos right.X_add_number = 0; 1180 1.1.1.7 christos else 1181 1.1.1.7 christos { 1182 1.1.1.7 christos /* Parse the constant of a complex relocation expression 1183 1.1.1.7 christos like @identifier@reloc +/- const. */ 1184 1.1.1.7 christos if (! r->complex_expr) 1185 1.1.1.7 christos { 1186 1.1.1.7 christos as_bad (_("@%s is not a complex relocation."), r->name); 1187 1.1.1.7 christos resultP->X_op = O_illegal; 1188 1.1.1.7 christos return; 1189 1.1.1.7 christos } 1190 1.1.1.7 christos expression (&right); 1191 1.1.1.7 christos if (right.X_op != O_constant) 1192 1.1.1.7 christos { 1193 1.1.1.7 christos as_bad (_("Bad expression: @%s + %s."), 1194 1.1.1.7 christos r->name, input_line_pointer); 1195 1.1.1.7 christos resultP->X_op = O_illegal; 1196 1.1.1.7 christos return; 1197 1.1.1.7 christos } 1198 1.1.1.7 christos } 1199 1.1.1.7 christos 1200 1.1.1.7 christos resultP->X_md = r->op; 1201 1.1.1.7 christos resultP->X_add_number = right.X_add_number; 1202 1.1.1.7 christos } 1203 1.1.1.7 christos 1204 1.1.1.3 christos /* Parse the arguments to an opcode. */ 1205 1.1 skrll 1206 1.1.1.3 christos static int 1207 1.1.1.3 christos tokenize_arguments (char *str, 1208 1.1.1.3 christos expressionS *tok, 1209 1.1.1.3 christos int ntok) 1210 1.1.1.3 christos { 1211 1.1.1.3 christos char *old_input_line_pointer; 1212 1.1.1.8 christos bool saw_comma = false; 1213 1.1.1.8 christos bool saw_arg = false; 1214 1.1.1.3 christos int brk_lvl = 0; 1215 1.1.1.3 christos int num_args = 0; 1216 1.1.1.3 christos 1217 1.1.1.3 christos memset (tok, 0, sizeof (*tok) * ntok); 1218 1.1.1.3 christos 1219 1.1.1.3 christos /* Save and restore input_line_pointer around this function. */ 1220 1.1.1.3 christos old_input_line_pointer = input_line_pointer; 1221 1.1.1.3 christos input_line_pointer = str; 1222 1.1 skrll 1223 1.1.1.3 christos while (*input_line_pointer) 1224 1.1 skrll { 1225 1.1 skrll SKIP_WHITESPACE (); 1226 1.1.1.3 christos switch (*input_line_pointer) 1227 1.1 skrll { 1228 1.1.1.3 christos case '\0': 1229 1.1.1.3 christos goto fini; 1230 1.1 skrll 1231 1.1.1.3 christos case ',': 1232 1.1.1.3 christos input_line_pointer++; 1233 1.1.1.3 christos if (saw_comma || !saw_arg) 1234 1.1.1.3 christos goto err; 1235 1.1.1.8 christos saw_comma = true; 1236 1.1.1.3 christos break; 1237 1.1 skrll 1238 1.1.1.3 christos case '}': 1239 1.1.1.3 christos case ']': 1240 1.1.1.3 christos ++input_line_pointer; 1241 1.1.1.3 christos --brk_lvl; 1242 1.1.1.5 christos if (!saw_arg || num_args == ntok) 1243 1.1.1.3 christos goto err; 1244 1.1.1.3 christos tok->X_op = O_bracket; 1245 1.1.1.3 christos ++tok; 1246 1.1.1.3 christos ++num_args; 1247 1.1.1.3 christos break; 1248 1.1.1.3 christos 1249 1.1.1.3 christos case '{': 1250 1.1.1.3 christos case '[': 1251 1.1.1.3 christos input_line_pointer++; 1252 1.1.1.5 christos if (brk_lvl || num_args == ntok) 1253 1.1.1.3 christos goto err; 1254 1.1.1.3 christos ++brk_lvl; 1255 1.1.1.3 christos tok->X_op = O_bracket; 1256 1.1.1.3 christos ++tok; 1257 1.1.1.3 christos ++num_args; 1258 1.1.1.3 christos break; 1259 1.1.1.3 christos 1260 1.1.1.6 christos case ':': 1261 1.1.1.6 christos input_line_pointer++; 1262 1.1.1.6 christos if (!saw_arg || num_args == ntok) 1263 1.1.1.6 christos goto err; 1264 1.1.1.6 christos tok->X_op = O_colon; 1265 1.1.1.8 christos saw_arg = false; 1266 1.1.1.6 christos ++tok; 1267 1.1.1.6 christos ++num_args; 1268 1.1.1.6 christos break; 1269 1.1.1.6 christos 1270 1.1.1.3 christos case '@': 1271 1.1.1.3 christos /* We have labels, function names and relocations, all 1272 1.1.1.3 christos starting with @ symbol. Sort them out. */ 1273 1.1.1.5 christos if ((saw_arg && !saw_comma) || num_args == ntok) 1274 1.1.1.3 christos goto err; 1275 1.1.1.3 christos 1276 1.1.1.3 christos /* Parse @label. */ 1277 1.1.1.7 christos input_line_pointer++; 1278 1.1.1.3 christos expression (tok); 1279 1.1.1.11 christos tok->X_md = O_absent; 1280 1.1.1.3 christos 1281 1.1.1.3 christos if (*input_line_pointer == '@') 1282 1.1.1.7 christos parse_reloc_symbol (tok); 1283 1.1 skrll 1284 1.1.1.3 christos debug_exp (tok); 1285 1.1 skrll 1286 1.1.1.7 christos if (tok->X_op == O_illegal 1287 1.1.1.7 christos || tok->X_op == O_absent 1288 1.1.1.7 christos || num_args == ntok) 1289 1.1.1.7 christos goto err; 1290 1.1.1.7 christos 1291 1.1.1.8 christos saw_comma = false; 1292 1.1.1.8 christos saw_arg = true; 1293 1.1.1.3 christos tok++; 1294 1.1.1.3 christos num_args++; 1295 1.1.1.3 christos break; 1296 1.1 skrll 1297 1.1.1.3 christos case '%': 1298 1.1.1.3 christos /* Can be a register. */ 1299 1.1.1.3 christos ++input_line_pointer; 1300 1.1.1.3 christos /* Fall through. */ 1301 1.1.1.3 christos default: 1302 1.1.1.3 christos 1303 1.1.1.5 christos if ((saw_arg && !saw_comma) || num_args == ntok) 1304 1.1.1.3 christos goto err; 1305 1.1.1.3 christos 1306 1.1.1.11 christos /* Tell arc_parse_name to do its job. */ 1307 1.1.1.11 christos assembling_insn = true; 1308 1.1.1.3 christos expression (tok); 1309 1.1.1.11 christos assembling_insn = false; 1310 1.1.1.11 christos tok->X_md = O_absent; 1311 1.1.1.3 christos 1312 1.1.1.3 christos /* Legacy: There are cases when we have 1313 1.1.1.3 christos identifier@relocation_type, if it is the case parse the 1314 1.1.1.3 christos relocation type as well. */ 1315 1.1.1.3 christos if (*input_line_pointer == '@') 1316 1.1.1.7 christos parse_reloc_symbol (tok); 1317 1.1.1.9 christos else 1318 1.1.1.9 christos resolve_register (tok); 1319 1.1.1.3 christos 1320 1.1.1.3 christos debug_exp (tok); 1321 1.1.1.3 christos 1322 1.1.1.5 christos if (tok->X_op == O_illegal 1323 1.1.1.5 christos || tok->X_op == O_absent 1324 1.1.1.5 christos || num_args == ntok) 1325 1.1.1.3 christos goto err; 1326 1.1.1.3 christos 1327 1.1.1.8 christos saw_comma = false; 1328 1.1.1.8 christos saw_arg = true; 1329 1.1.1.3 christos tok++; 1330 1.1.1.3 christos num_args++; 1331 1.1.1.3 christos break; 1332 1.1 skrll } 1333 1.1 skrll } 1334 1.1 skrll 1335 1.1.1.3 christos fini: 1336 1.1.1.3 christos if (saw_comma || brk_lvl) 1337 1.1.1.3 christos goto err; 1338 1.1.1.3 christos input_line_pointer = old_input_line_pointer; 1339 1.1.1.3 christos 1340 1.1.1.3 christos return num_args; 1341 1.1.1.3 christos 1342 1.1.1.3 christos err: 1343 1.1.1.3 christos if (brk_lvl) 1344 1.1.1.3 christos as_bad (_("Brackets in operand field incorrect")); 1345 1.1.1.3 christos else if (saw_comma) 1346 1.1.1.3 christos as_bad (_("extra comma")); 1347 1.1.1.3 christos else if (!saw_arg) 1348 1.1.1.3 christos as_bad (_("missing argument")); 1349 1.1.1.3 christos else 1350 1.1.1.3 christos as_bad (_("missing comma or colon")); 1351 1.1.1.3 christos input_line_pointer = old_input_line_pointer; 1352 1.1.1.3 christos return -1; 1353 1.1.1.3 christos } 1354 1.1 skrll 1355 1.1.1.3 christos /* Parse the flags to a structure. */ 1356 1.1 skrll 1357 1.1.1.3 christos static int 1358 1.1.1.3 christos tokenize_flags (const char *str, 1359 1.1.1.3 christos struct arc_flags flags[], 1360 1.1.1.3 christos int nflg) 1361 1.1.1.3 christos { 1362 1.1.1.3 christos char *old_input_line_pointer; 1363 1.1.1.8 christos bool saw_flg = false; 1364 1.1.1.8 christos bool saw_dot = false; 1365 1.1.1.3 christos int num_flags = 0; 1366 1.1.1.3 christos size_t flgnamelen; 1367 1.1.1.3 christos 1368 1.1.1.3 christos memset (flags, 0, sizeof (*flags) * nflg); 1369 1.1.1.3 christos 1370 1.1.1.3 christos /* Save and restore input_line_pointer around this function. */ 1371 1.1.1.3 christos old_input_line_pointer = input_line_pointer; 1372 1.1.1.3 christos input_line_pointer = (char *) str; 1373 1.1.1.3 christos 1374 1.1.1.3 christos while (*input_line_pointer) 1375 1.1.1.3 christos { 1376 1.1.1.3 christos switch (*input_line_pointer) 1377 1.1.1.3 christos { 1378 1.1.1.3 christos case '.': 1379 1.1.1.3 christos input_line_pointer++; 1380 1.1.1.3 christos if (saw_dot) 1381 1.1.1.3 christos goto err; 1382 1.1.1.8 christos saw_dot = true; 1383 1.1.1.8 christos saw_flg = false; 1384 1.1.1.3 christos break; 1385 1.1 skrll 1386 1.1.1.3 christos default: 1387 1.1.1.10 christos if (is_end_of_stmt (*input_line_pointer) 1388 1.1.1.10 christos || is_whitespace (*input_line_pointer)) 1389 1.1.1.10 christos goto fini; 1390 1.1.1.10 christos 1391 1.1.1.3 christos if (saw_flg && !saw_dot) 1392 1.1.1.3 christos goto err; 1393 1.1 skrll 1394 1.1.1.3 christos if (num_flags >= nflg) 1395 1.1.1.3 christos goto err; 1396 1.1 skrll 1397 1.1.1.5 christos flgnamelen = strspn (input_line_pointer, 1398 1.1.1.5 christos "abcdefghijklmnopqrstuvwxyz0123456789"); 1399 1.1.1.5 christos if (flgnamelen > MAX_FLAG_NAME_LENGTH) 1400 1.1.1.3 christos goto err; 1401 1.1.1.3 christos 1402 1.1.1.3 christos memcpy (flags->name, input_line_pointer, flgnamelen); 1403 1.1.1.3 christos 1404 1.1.1.3 christos input_line_pointer += flgnamelen; 1405 1.1.1.3 christos flags++; 1406 1.1.1.8 christos saw_dot = false; 1407 1.1.1.8 christos saw_flg = true; 1408 1.1.1.3 christos num_flags++; 1409 1.1.1.3 christos break; 1410 1.1.1.3 christos } 1411 1.1 skrll } 1412 1.1 skrll 1413 1.1.1.3 christos fini: 1414 1.1.1.3 christos input_line_pointer = old_input_line_pointer; 1415 1.1.1.3 christos return num_flags; 1416 1.1.1.3 christos 1417 1.1.1.3 christos err: 1418 1.1.1.3 christos if (saw_dot) 1419 1.1.1.3 christos as_bad (_("extra dot")); 1420 1.1.1.3 christos else if (!saw_flg) 1421 1.1.1.3 christos as_bad (_("unrecognized flag")); 1422 1.1.1.3 christos else 1423 1.1.1.3 christos as_bad (_("failed to parse flags")); 1424 1.1.1.3 christos input_line_pointer = old_input_line_pointer; 1425 1.1.1.3 christos return -1; 1426 1.1 skrll } 1427 1.1 skrll 1428 1.1.1.5 christos /* Apply the fixups in order. */ 1429 1.1.1.3 christos 1430 1.1.1.5 christos static void 1431 1.1.1.5 christos apply_fixups (struct arc_insn *insn, fragS *fragP, int fix) 1432 1.1 skrll { 1433 1.1.1.5 christos int i; 1434 1.1 skrll 1435 1.1.1.5 christos for (i = 0; i < insn->nfixups; i++) 1436 1.1 skrll { 1437 1.1.1.5 christos struct arc_fixup *fixup = &insn->fixups[i]; 1438 1.1.1.5 christos int size, pcrel, offset = 0; 1439 1.1 skrll 1440 1.1.1.5 christos /* FIXME! the reloc size is wrong in the BFD file. 1441 1.1.1.5 christos When it is fixed please delete me. */ 1442 1.1.1.6 christos size = ((insn->len == 2) && !fixup->islong) ? 2 : 4; 1443 1.1 skrll 1444 1.1.1.5 christos if (fixup->islong) 1445 1.1.1.6 christos offset = insn->len; 1446 1.1 skrll 1447 1.1.1.5 christos /* Some fixups are only used internally, thus no howto. */ 1448 1.1.1.10 christos if (fixup->reloc == 0) 1449 1.1.1.5 christos as_fatal (_("Unhandled reloc type")); 1450 1.1 skrll 1451 1.1.1.5 christos if ((int) fixup->reloc < 0) 1452 1.1.1.5 christos { 1453 1.1.1.5 christos /* FIXME! the reloc size is wrong in the BFD file. 1454 1.1.1.5 christos When it is fixed please enable me. 1455 1.1.1.6 christos size = ((insn->len == 2 && !fixup->islong) ? 2 : 4; */ 1456 1.1.1.5 christos pcrel = fixup->pcrel; 1457 1.1.1.5 christos } 1458 1.1.1.5 christos else 1459 1.1.1.5 christos { 1460 1.1.1.5 christos reloc_howto_type *reloc_howto = 1461 1.1.1.10 christos bfd_reloc_type_lookup (stdoutput, fixup->reloc); 1462 1.1.1.5 christos gas_assert (reloc_howto); 1463 1.1 skrll 1464 1.1.1.5 christos /* FIXME! the reloc size is wrong in the BFD file. 1465 1.1.1.5 christos When it is fixed please enable me. 1466 1.1.1.5 christos size = bfd_get_reloc_size (reloc_howto); */ 1467 1.1.1.5 christos pcrel = reloc_howto->pc_relative; 1468 1.1.1.5 christos } 1469 1.1 skrll 1470 1.1.1.5 christos pr_debug ("%s:%d: apply_fixups: new %s fixup (PCrel:%s) of size %d @ \ 1471 1.1.1.5 christos offset %d + %d\n", 1472 1.1.1.5 christos fragP->fr_file, fragP->fr_line, 1473 1.1.1.5 christos (fixup->reloc < 0) ? "Internal" : 1474 1.1.1.5 christos bfd_get_reloc_code_name (fixup->reloc), 1475 1.1.1.5 christos pcrel ? "Y" : "N", 1476 1.1.1.5 christos size, fix, offset); 1477 1.1.1.5 christos fix_new_exp (fragP, fix + offset, 1478 1.1.1.5 christos size, &fixup->exp, pcrel, fixup->reloc); 1479 1.1 skrll 1480 1.1.1.5 christos /* Check for ZOLs, and update symbol info if any. */ 1481 1.1.1.5 christos if (LP_INSN (insn->insn)) 1482 1.1 skrll { 1483 1.1.1.5 christos gas_assert (fixup->exp.X_add_symbol); 1484 1.1.1.5 christos ARC_SET_FLAG (fixup->exp.X_add_symbol, ARC_FLAG_ZOL); 1485 1.1 skrll } 1486 1.1 skrll } 1487 1.1.1.3 christos } 1488 1.1 skrll 1489 1.1.1.5 christos /* Actually output an instruction with its fixup. */ 1490 1.1 skrll 1491 1.1.1.5 christos static void 1492 1.1.1.8 christos emit_insn0 (struct arc_insn *insn, char *where, bool relax) 1493 1.1.1.3 christos { 1494 1.1.1.5 christos char *f = where; 1495 1.1.1.6 christos size_t total_len; 1496 1.1 skrll 1497 1.1.1.6 christos pr_debug ("Emit insn : 0x%llx\n", insn->insn); 1498 1.1.1.8 christos pr_debug ("\tLength : %d\n", insn->len); 1499 1.1.1.5 christos pr_debug ("\tLong imm: 0x%lx\n", insn->limm); 1500 1.1 skrll 1501 1.1.1.5 christos /* Write out the instruction. */ 1502 1.1.1.6 christos total_len = insn->len + (insn->has_limm ? 4 : 0); 1503 1.1.1.6 christos if (!relax) 1504 1.1.1.6 christos f = frag_more (total_len); 1505 1.1.1.6 christos 1506 1.1.1.6 christos md_number_to_chars_midend(f, insn->insn, insn->len); 1507 1.1.1.6 christos 1508 1.1.1.6 christos if (insn->has_limm) 1509 1.1.1.6 christos md_number_to_chars_midend (f + insn->len, insn->limm, 4); 1510 1.1.1.6 christos dwarf2_emit_insn (total_len); 1511 1.1 skrll 1512 1.1.1.5 christos if (!relax) 1513 1.1.1.5 christos apply_fixups (insn, frag_now, (f - frag_now->fr_literal)); 1514 1.1.1.5 christos } 1515 1.1.1.3 christos 1516 1.1.1.5 christos static void 1517 1.1.1.5 christos emit_insn1 (struct arc_insn *insn) 1518 1.1.1.5 christos { 1519 1.1.1.5 christos /* How frag_var's args are currently configured: 1520 1.1.1.5 christos - rs_machine_dependent, to dictate it's a relaxation frag. 1521 1.1.1.5 christos - FRAG_MAX_GROWTH, maximum size of instruction 1522 1.1.1.5 christos - 0, variable size that might grow...unused by generic relaxation. 1523 1.1.1.5 christos - frag_now->fr_subtype, fr_subtype starting value, set previously. 1524 1.1.1.5 christos - s, opand expression. 1525 1.1.1.5 christos - 0, offset but it's unused. 1526 1.1.1.5 christos - 0, opcode but it's unused. */ 1527 1.1.1.5 christos symbolS *s = make_expr_symbol (&insn->fixups[0].exp); 1528 1.1.1.5 christos frag_now->tc_frag_data.pcrel = insn->fixups[0].pcrel; 1529 1.1.1.5 christos 1530 1.1.1.5 christos if (frag_room () < FRAG_MAX_GROWTH) 1531 1.1.1.5 christos { 1532 1.1.1.5 christos /* Handle differently when frag literal memory is exhausted. 1533 1.1.1.5 christos This is used because when there's not enough memory left in 1534 1.1.1.5 christos the current frag, a new frag is created and the information 1535 1.1.1.5 christos we put into frag_now->tc_frag_data is disregarded. */ 1536 1.1.1.5 christos 1537 1.1.1.5 christos struct arc_relax_type relax_info_copy; 1538 1.1.1.5 christos relax_substateT subtype = frag_now->fr_subtype; 1539 1.1.1.5 christos 1540 1.1.1.5 christos memcpy (&relax_info_copy, &frag_now->tc_frag_data, 1541 1.1.1.5 christos sizeof (struct arc_relax_type)); 1542 1.1 skrll 1543 1.1.1.5 christos frag_wane (frag_now); 1544 1.1.1.5 christos frag_grow (FRAG_MAX_GROWTH); 1545 1.1 skrll 1546 1.1.1.5 christos memcpy (&frag_now->tc_frag_data, &relax_info_copy, 1547 1.1.1.5 christos sizeof (struct arc_relax_type)); 1548 1.1.1.3 christos 1549 1.1.1.5 christos frag_var (rs_machine_dependent, FRAG_MAX_GROWTH, 0, 1550 1.1.1.5 christos subtype, s, 0, 0); 1551 1.1.1.5 christos } 1552 1.1.1.5 christos else 1553 1.1.1.5 christos frag_var (rs_machine_dependent, FRAG_MAX_GROWTH, 0, 1554 1.1.1.5 christos frag_now->fr_subtype, s, 0, 0); 1555 1.1 skrll } 1556 1.1 skrll 1557 1.1.1.5 christos static void 1558 1.1.1.5 christos emit_insn (struct arc_insn *insn) 1559 1.1 skrll { 1560 1.1.1.5 christos if (insn->relax) 1561 1.1.1.5 christos emit_insn1 (insn); 1562 1.1 skrll else 1563 1.1.1.8 christos emit_insn0 (insn, NULL, false); 1564 1.1 skrll } 1565 1.1 skrll 1566 1.1.1.5 christos /* Check whether a symbol involves a register. */ 1567 1.1 skrll 1568 1.1.1.8 christos static bool 1569 1.1.1.5 christos contains_register (symbolS *sym) 1570 1.1 skrll { 1571 1.1.1.5 christos if (sym) 1572 1.1.1.5 christos { 1573 1.1.1.5 christos expressionS *ex = symbol_get_value_expression (sym); 1574 1.1.1.5 christos 1575 1.1.1.5 christos return ((O_register == ex->X_op) 1576 1.1.1.5 christos && !contains_register (ex->X_add_symbol) 1577 1.1.1.5 christos && !contains_register (ex->X_op_symbol)); 1578 1.1.1.5 christos } 1579 1.1 skrll 1580 1.1.1.8 christos return false; 1581 1.1 skrll } 1582 1.1 skrll 1583 1.1.1.5 christos /* Returns the register number within a symbol. */ 1584 1.1 skrll 1585 1.1.1.5 christos static int 1586 1.1.1.5 christos get_register (symbolS *sym) 1587 1.1 skrll { 1588 1.1.1.5 christos if (!contains_register (sym)) 1589 1.1.1.5 christos return -1; 1590 1.1 skrll 1591 1.1.1.5 christos expressionS *ex = symbol_get_value_expression (sym); 1592 1.1.1.5 christos return regno (ex->X_add_number); 1593 1.1.1.5 christos } 1594 1.1 skrll 1595 1.1.1.5 christos /* Return true if a RELOC is generic. A generic reloc is PC-rel of a 1596 1.1.1.11 christos simple ME relocation (e.g. RELOC_ARC_32_ME, BFD_RELOC_32_PCREL. */ 1597 1.1 skrll 1598 1.1.1.8 christos static bool 1599 1.1.1.5 christos generic_reloc_p (extended_bfd_reloc_code_real_type reloc) 1600 1.1.1.5 christos { 1601 1.1.1.5 christos if (!reloc) 1602 1.1.1.8 christos return false; 1603 1.1 skrll 1604 1.1.1.5 christos switch (reloc) 1605 1.1 skrll { 1606 1.1.1.5 christos case BFD_RELOC_ARC_SDA_LDST: 1607 1.1.1.5 christos case BFD_RELOC_ARC_SDA_LDST1: 1608 1.1.1.5 christos case BFD_RELOC_ARC_SDA_LDST2: 1609 1.1.1.5 christos case BFD_RELOC_ARC_SDA16_LD: 1610 1.1.1.5 christos case BFD_RELOC_ARC_SDA16_LD1: 1611 1.1.1.5 christos case BFD_RELOC_ARC_SDA16_LD2: 1612 1.1.1.5 christos case BFD_RELOC_ARC_SDA16_ST2: 1613 1.1.1.5 christos case BFD_RELOC_ARC_SDA32_ME: 1614 1.1.1.8 christos return false; 1615 1.1.1.5 christos default: 1616 1.1.1.8 christos return true; 1617 1.1 skrll } 1618 1.1 skrll } 1619 1.1 skrll 1620 1.1.1.5 christos /* Allocates a tok entry. */ 1621 1.1 skrll 1622 1.1.1.5 christos static int 1623 1.1.1.5 christos allocate_tok (expressionS *tok, int ntok, int cidx) 1624 1.1 skrll { 1625 1.1.1.5 christos if (ntok > MAX_INSN_ARGS - 2) 1626 1.1.1.5 christos return 0; /* No space left. */ 1627 1.1 skrll 1628 1.1.1.5 christos if (cidx > ntok) 1629 1.1.1.6 christos return 0; /* Incorrect args. */ 1630 1.1.1.5 christos 1631 1.1.1.5 christos memcpy (&tok[ntok+1], &tok[ntok], sizeof (*tok)); 1632 1.1.1.5 christos 1633 1.1.1.5 christos if (cidx == ntok) 1634 1.1.1.5 christos return 1; /* Success. */ 1635 1.1.1.5 christos return allocate_tok (tok, ntok - 1, cidx); 1636 1.1 skrll } 1637 1.1 skrll 1638 1.1.1.5 christos /* Check if an particular ARC feature is enabled. */ 1639 1.1 skrll 1640 1.1.1.8 christos static bool 1641 1.1.1.5 christos check_cpu_feature (insn_subclass_t sc) 1642 1.1.1.3 christos { 1643 1.1.1.6 christos if (is_code_density_p (sc) && !(selected_cpu.features & CD)) 1644 1.1.1.8 christos return false; 1645 1.1.1.3 christos 1646 1.1.1.6 christos if (is_spfp_p (sc) && !(selected_cpu.features & SPX)) 1647 1.1.1.8 christos return false; 1648 1.1.1.3 christos 1649 1.1.1.6 christos if (is_dpfp_p (sc) && !(selected_cpu.features & DPX)) 1650 1.1.1.8 christos return false; 1651 1.1.1.3 christos 1652 1.1.1.6 christos if (is_fpuda_p (sc) && !(selected_cpu.features & DPA)) 1653 1.1.1.8 christos return false; 1654 1.1.1.3 christos 1655 1.1.1.6 christos if (is_nps400_p (sc) && !(selected_cpu.features & NPS400)) 1656 1.1.1.8 christos return false; 1657 1.1.1.3 christos 1658 1.1.1.8 christos return true; 1659 1.1.1.5 christos } 1660 1.1.1.5 christos 1661 1.1.1.5 christos /* Parse the flags described by FIRST_PFLAG and NFLGS against the flag 1662 1.1.1.5 christos operands in OPCODE. Stores the matching OPCODES into the FIRST_PFLAG 1663 1.1.1.5 christos array and returns TRUE if the flag operands all match, otherwise, 1664 1.1.1.5 christos returns FALSE, in which case the FIRST_PFLAG array may have been 1665 1.1.1.5 christos modified. */ 1666 1.1.1.5 christos 1667 1.1.1.8 christos static bool 1668 1.1.1.5 christos parse_opcode_flags (const struct arc_opcode *opcode, 1669 1.1.1.5 christos int nflgs, 1670 1.1.1.5 christos struct arc_flags *first_pflag) 1671 1.1.1.5 christos { 1672 1.1.1.5 christos int lnflg, i; 1673 1.1.1.5 christos const unsigned char *flgidx; 1674 1.1.1.5 christos 1675 1.1.1.5 christos lnflg = nflgs; 1676 1.1.1.5 christos for (i = 0; i < nflgs; i++) 1677 1.1.1.5 christos first_pflag[i].flgp = NULL; 1678 1.1.1.5 christos 1679 1.1.1.5 christos /* Check the flags. Iterate over the valid flag classes. */ 1680 1.1.1.5 christos for (flgidx = opcode->flags; *flgidx; ++flgidx) 1681 1.1.1.5 christos { 1682 1.1.1.5 christos /* Get a valid flag class. */ 1683 1.1.1.5 christos const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx]; 1684 1.1.1.5 christos const unsigned *flgopridx; 1685 1.1.1.5 christos int cl_matches = 0; 1686 1.1.1.5 christos struct arc_flags *pflag = NULL; 1687 1.1.1.5 christos 1688 1.1.1.6 christos /* Check if opcode has implicit flag classes. */ 1689 1.1.1.6 christos if (cl_flags->flag_class & F_CLASS_IMPLICIT) 1690 1.1.1.6 christos continue; 1691 1.1.1.6 christos 1692 1.1.1.5 christos /* Check for extension conditional codes. */ 1693 1.1.1.5 christos if (ext_condcode.arc_ext_condcode 1694 1.1.1.5 christos && cl_flags->flag_class & F_CLASS_EXTEND) 1695 1.1.1.5 christos { 1696 1.1.1.5 christos struct arc_flag_operand *pf = ext_condcode.arc_ext_condcode; 1697 1.1.1.5 christos while (pf->name) 1698 1.1.1.5 christos { 1699 1.1.1.5 christos pflag = first_pflag; 1700 1.1.1.5 christos for (i = 0; i < nflgs; i++, pflag++) 1701 1.1.1.5 christos { 1702 1.1.1.5 christos if (!strcmp (pf->name, pflag->name)) 1703 1.1.1.5 christos { 1704 1.1.1.5 christos if (pflag->flgp != NULL) 1705 1.1.1.8 christos return false; 1706 1.1.1.5 christos /* Found it. */ 1707 1.1.1.5 christos cl_matches++; 1708 1.1.1.5 christos pflag->flgp = pf; 1709 1.1.1.5 christos lnflg--; 1710 1.1.1.5 christos break; 1711 1.1.1.5 christos } 1712 1.1.1.5 christos } 1713 1.1.1.5 christos pf++; 1714 1.1.1.5 christos } 1715 1.1.1.5 christos } 1716 1.1.1.5 christos 1717 1.1.1.5 christos for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx) 1718 1.1.1.5 christos { 1719 1.1.1.5 christos const struct arc_flag_operand *flg_operand; 1720 1.1.1.5 christos 1721 1.1.1.5 christos pflag = first_pflag; 1722 1.1.1.5 christos flg_operand = &arc_flag_operands[*flgopridx]; 1723 1.1.1.5 christos for (i = 0; i < nflgs; i++, pflag++) 1724 1.1.1.5 christos { 1725 1.1.1.5 christos /* Match against the parsed flags. */ 1726 1.1.1.5 christos if (!strcmp (flg_operand->name, pflag->name)) 1727 1.1.1.5 christos { 1728 1.1.1.5 christos if (pflag->flgp != NULL) 1729 1.1.1.8 christos return false; 1730 1.1.1.5 christos cl_matches++; 1731 1.1.1.5 christos pflag->flgp = flg_operand; 1732 1.1.1.5 christos lnflg--; 1733 1.1.1.5 christos break; /* goto next flag class and parsed flag. */ 1734 1.1.1.5 christos } 1735 1.1.1.5 christos } 1736 1.1.1.5 christos } 1737 1.1.1.5 christos 1738 1.1.1.5 christos if ((cl_flags->flag_class & F_CLASS_REQUIRED) && cl_matches == 0) 1739 1.1.1.8 christos return false; 1740 1.1.1.5 christos if ((cl_flags->flag_class & F_CLASS_OPTIONAL) && cl_matches > 1) 1741 1.1.1.8 christos return false; 1742 1.1 skrll } 1743 1.1.1.3 christos 1744 1.1.1.5 christos /* Did I check all the parsed flags? */ 1745 1.1.1.8 christos return lnflg == 0; 1746 1.1.1.5 christos } 1747 1.1.1.5 christos 1748 1.1.1.5 christos 1749 1.1.1.5 christos /* Search forward through all variants of an opcode looking for a 1750 1.1.1.5 christos syntax match. */ 1751 1.1.1.5 christos 1752 1.1.1.5 christos static const struct arc_opcode * 1753 1.1.1.5 christos find_opcode_match (const struct arc_opcode_hash_entry *entry, 1754 1.1.1.5 christos expressionS *tok, 1755 1.1.1.5 christos int *pntok, 1756 1.1.1.5 christos struct arc_flags *first_pflag, 1757 1.1.1.5 christos int nflgs, 1758 1.1.1.6 christos int *pcpumatch, 1759 1.1.1.6 christos const char **errmsg) 1760 1.1.1.5 christos { 1761 1.1.1.5 christos const struct arc_opcode *opcode; 1762 1.1.1.5 christos struct arc_opcode_hash_entry_iterator iter; 1763 1.1.1.5 christos int ntok = *pntok; 1764 1.1.1.5 christos int got_cpu_match = 0; 1765 1.1.1.5 christos expressionS bktok[MAX_INSN_ARGS]; 1766 1.1.1.8 christos int bkntok, maxerridx = 0; 1767 1.1.1.5 christos expressionS emptyE; 1768 1.1.1.8 christos const char *tmpmsg = NULL; 1769 1.1.1.5 christos 1770 1.1.1.5 christos arc_opcode_hash_entry_iterator_init (&iter); 1771 1.1.1.5 christos memset (&emptyE, 0, sizeof (emptyE)); 1772 1.1.1.5 christos memcpy (bktok, tok, MAX_INSN_ARGS * sizeof (*tok)); 1773 1.1.1.5 christos bkntok = ntok; 1774 1.1.1.5 christos 1775 1.1.1.5 christos for (opcode = arc_opcode_hash_entry_iterator_next (entry, &iter); 1776 1.1.1.5 christos opcode != NULL; 1777 1.1.1.5 christos opcode = arc_opcode_hash_entry_iterator_next (entry, &iter)) 1778 1.1 skrll { 1779 1.1.1.5 christos const unsigned char *opidx; 1780 1.1.1.5 christos int tokidx = 0; 1781 1.1.1.5 christos const expressionS *t = &emptyE; 1782 1.1.1.5 christos 1783 1.1.1.6 christos pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08llX ", 1784 1.1.1.5 christos frag_now->fr_file, frag_now->fr_line, opcode->opcode); 1785 1.1.1.5 christos 1786 1.1.1.5 christos /* Don't match opcodes that don't exist on this 1787 1.1.1.5 christos architecture. */ 1788 1.1.1.6 christos if (!(opcode->cpu & selected_cpu.flags)) 1789 1.1.1.5 christos goto match_failed; 1790 1.1.1.5 christos 1791 1.1.1.5 christos if (!check_cpu_feature (opcode->subclass)) 1792 1.1.1.5 christos goto match_failed; 1793 1.1.1.5 christos 1794 1.1.1.5 christos got_cpu_match = 1; 1795 1.1.1.5 christos pr_debug ("cpu "); 1796 1.1.1.5 christos 1797 1.1.1.5 christos /* Check the operands. */ 1798 1.1.1.5 christos for (opidx = opcode->operands; *opidx; ++opidx) 1799 1.1.1.3 christos { 1800 1.1.1.5 christos const struct arc_operand *operand = &arc_operands[*opidx]; 1801 1.1.1.5 christos 1802 1.1.1.5 christos /* Only take input from real operands. */ 1803 1.1.1.6 christos if (ARC_OPERAND_IS_FAKE (operand)) 1804 1.1.1.5 christos continue; 1805 1.1.1.5 christos 1806 1.1.1.5 christos /* When we expect input, make sure we have it. */ 1807 1.1.1.5 christos if (tokidx >= ntok) 1808 1.1.1.5 christos goto match_failed; 1809 1.1.1.5 christos 1810 1.1.1.5 christos /* Match operand type with expression type. */ 1811 1.1.1.5 christos switch (operand->flags & ARC_OPERAND_TYPECHECK_MASK) 1812 1.1.1.5 christos { 1813 1.1.1.6 christos case ARC_OPERAND_ADDRTYPE: 1814 1.1.1.6 christos { 1815 1.1.1.8 christos tmpmsg = NULL; 1816 1.1.1.6 christos 1817 1.1.1.6 christos /* Check to be an address type. */ 1818 1.1.1.6 christos if (tok[tokidx].X_op != O_addrtype) 1819 1.1.1.6 christos goto match_failed; 1820 1.1.1.6 christos 1821 1.1.1.6 christos /* All address type operands need to have an insert 1822 1.1.1.6 christos method in order to check that we have the correct 1823 1.1.1.6 christos address type. */ 1824 1.1.1.6 christos gas_assert (operand->insert != NULL); 1825 1.1.1.6 christos (*operand->insert) (0, tok[tokidx].X_add_number, 1826 1.1.1.8 christos &tmpmsg); 1827 1.1.1.8 christos if (tmpmsg != NULL) 1828 1.1.1.6 christos goto match_failed; 1829 1.1.1.6 christos } 1830 1.1.1.6 christos break; 1831 1.1.1.6 christos 1832 1.1.1.5 christos case ARC_OPERAND_IR: 1833 1.1.1.5 christos /* Check to be a register. */ 1834 1.1.1.5 christos if ((tok[tokidx].X_op != O_register 1835 1.1.1.5 christos || !is_ir_num (tok[tokidx].X_add_number)) 1836 1.1.1.5 christos && !(operand->flags & ARC_OPERAND_IGNORE)) 1837 1.1.1.5 christos goto match_failed; 1838 1.1.1.5 christos 1839 1.1.1.5 christos /* If expect duplicate, make sure it is duplicate. */ 1840 1.1.1.5 christos if (operand->flags & ARC_OPERAND_DUPLICATE) 1841 1.1.1.5 christos { 1842 1.1.1.5 christos /* Check for duplicate. */ 1843 1.1.1.5 christos if (t->X_op != O_register 1844 1.1.1.5 christos || !is_ir_num (t->X_add_number) 1845 1.1.1.5 christos || (regno (t->X_add_number) != 1846 1.1.1.5 christos regno (tok[tokidx].X_add_number))) 1847 1.1.1.5 christos goto match_failed; 1848 1.1.1.5 christos } 1849 1.1.1.5 christos 1850 1.1.1.5 christos /* Special handling? */ 1851 1.1.1.5 christos if (operand->insert) 1852 1.1.1.5 christos { 1853 1.1.1.8 christos tmpmsg = NULL; 1854 1.1.1.5 christos (*operand->insert)(0, 1855 1.1.1.5 christos regno (tok[tokidx].X_add_number), 1856 1.1.1.8 christos &tmpmsg); 1857 1.1.1.8 christos if (tmpmsg) 1858 1.1.1.5 christos { 1859 1.1.1.5 christos if (operand->flags & ARC_OPERAND_IGNORE) 1860 1.1.1.5 christos { 1861 1.1.1.5 christos /* Missing argument, create one. */ 1862 1.1.1.5 christos if (!allocate_tok (tok, ntok - 1, tokidx)) 1863 1.1.1.5 christos goto match_failed; 1864 1.1.1.5 christos 1865 1.1.1.5 christos tok[tokidx].X_op = O_absent; 1866 1.1.1.5 christos ++ntok; 1867 1.1.1.5 christos } 1868 1.1.1.5 christos else 1869 1.1.1.5 christos goto match_failed; 1870 1.1.1.5 christos } 1871 1.1.1.5 christos } 1872 1.1.1.5 christos 1873 1.1.1.5 christos t = &tok[tokidx]; 1874 1.1.1.5 christos break; 1875 1.1.1.5 christos 1876 1.1.1.5 christos case ARC_OPERAND_BRAKET: 1877 1.1.1.5 christos /* Check if bracket is also in opcode table as 1878 1.1.1.5 christos operand. */ 1879 1.1.1.5 christos if (tok[tokidx].X_op != O_bracket) 1880 1.1.1.5 christos goto match_failed; 1881 1.1.1.5 christos break; 1882 1.1.1.5 christos 1883 1.1.1.6 christos case ARC_OPERAND_COLON: 1884 1.1.1.6 christos /* Check if colon is also in opcode table as operand. */ 1885 1.1.1.6 christos if (tok[tokidx].X_op != O_colon) 1886 1.1.1.6 christos goto match_failed; 1887 1.1.1.6 christos break; 1888 1.1.1.6 christos 1889 1.1.1.5 christos case ARC_OPERAND_LIMM: 1890 1.1.1.5 christos case ARC_OPERAND_SIGNED: 1891 1.1.1.5 christos case ARC_OPERAND_UNSIGNED: 1892 1.1.1.5 christos switch (tok[tokidx].X_op) 1893 1.1.1.5 christos { 1894 1.1.1.5 christos case O_illegal: 1895 1.1.1.5 christos case O_absent: 1896 1.1.1.5 christos case O_register: 1897 1.1.1.5 christos goto match_failed; 1898 1.1.1.5 christos 1899 1.1.1.5 christos case O_bracket: 1900 1.1.1.5 christos /* Got an (too) early bracket, check if it is an 1901 1.1.1.5 christos ignored operand. N.B. This procedure works only 1902 1.1.1.5 christos when bracket is the last operand! */ 1903 1.1.1.5 christos if (!(operand->flags & ARC_OPERAND_IGNORE)) 1904 1.1.1.5 christos goto match_failed; 1905 1.1.1.5 christos /* Insert the missing operand. */ 1906 1.1.1.5 christos if (!allocate_tok (tok, ntok - 1, tokidx)) 1907 1.1.1.5 christos goto match_failed; 1908 1.1.1.5 christos 1909 1.1.1.5 christos tok[tokidx].X_op = O_absent; 1910 1.1.1.5 christos ++ntok; 1911 1.1.1.5 christos break; 1912 1.1.1.5 christos 1913 1.1.1.5 christos case O_symbol: 1914 1.1.1.5 christos { 1915 1.1.1.5 christos const char *p; 1916 1.1.1.7 christos char *tmpp, *pp; 1917 1.1.1.5 christos const struct arc_aux_reg *auxr; 1918 1.1.1.5 christos 1919 1.1.1.5 christos if (opcode->insn_class != AUXREG) 1920 1.1.1.5 christos goto de_fault; 1921 1.1.1.5 christos p = S_GET_NAME (tok[tokidx].X_add_symbol); 1922 1.1.1.5 christos 1923 1.1.1.7 christos /* For compatibility reasons, an aux register can 1924 1.1.1.7 christos be spelled with upper or lower case 1925 1.1.1.7 christos letters. */ 1926 1.1.1.7 christos tmpp = strdup (p); 1927 1.1.1.7 christos for (pp = tmpp; *pp; ++pp) *pp = TOLOWER (*pp); 1928 1.1.1.7 christos 1929 1.1.1.8 christos auxr = str_hash_find (arc_aux_hash, tmpp); 1930 1.1.1.5 christos if (auxr) 1931 1.1.1.5 christos { 1932 1.1.1.5 christos /* We modify the token array here, safe in the 1933 1.1.1.5 christos knowledge, that if this was the wrong 1934 1.1.1.5 christos choice then the original contents will be 1935 1.1.1.5 christos restored from BKTOK. */ 1936 1.1.1.5 christos tok[tokidx].X_op = O_constant; 1937 1.1.1.5 christos tok[tokidx].X_add_number = auxr->address; 1938 1.1.1.5 christos ARC_SET_FLAG (tok[tokidx].X_add_symbol, ARC_FLAG_AUX); 1939 1.1.1.5 christos } 1940 1.1.1.7 christos free (tmpp); 1941 1.1.1.5 christos 1942 1.1.1.5 christos if (tok[tokidx].X_op != O_constant) 1943 1.1.1.5 christos goto de_fault; 1944 1.1.1.5 christos } 1945 1.1.1.6 christos /* Fall through. */ 1946 1.1.1.5 christos case O_constant: 1947 1.1.1.5 christos /* Check the range. */ 1948 1.1.1.5 christos if (operand->bits != 32 1949 1.1.1.5 christos && !(operand->flags & ARC_OPERAND_NCHK)) 1950 1.1.1.5 christos { 1951 1.1.1.5 christos offsetT min, max, val; 1952 1.1.1.5 christos val = tok[tokidx].X_add_number; 1953 1.1.1.5 christos 1954 1.1.1.5 christos if (operand->flags & ARC_OPERAND_SIGNED) 1955 1.1.1.5 christos { 1956 1.1.1.5 christos max = (1 << (operand->bits - 1)) - 1; 1957 1.1.1.5 christos min = -(1 << (operand->bits - 1)); 1958 1.1.1.5 christos } 1959 1.1.1.5 christos else 1960 1.1.1.5 christos { 1961 1.1.1.5 christos max = (1 << operand->bits) - 1; 1962 1.1.1.5 christos min = 0; 1963 1.1.1.5 christos } 1964 1.1.1.5 christos 1965 1.1.1.5 christos if (val < min || val > max) 1966 1.1.1.8 christos { 1967 1.1.1.8 christos tmpmsg = _("immediate is out of bounds"); 1968 1.1.1.8 christos goto match_failed; 1969 1.1.1.8 christos } 1970 1.1.1.5 christos 1971 1.1.1.6 christos /* Check alignments. */ 1972 1.1.1.5 christos if ((operand->flags & ARC_OPERAND_ALIGNED32) 1973 1.1.1.5 christos && (val & 0x03)) 1974 1.1.1.8 christos { 1975 1.1.1.8 christos tmpmsg = _("immediate is not 32bit aligned"); 1976 1.1.1.8 christos goto match_failed; 1977 1.1.1.8 christos } 1978 1.1.1.5 christos 1979 1.1.1.5 christos if ((operand->flags & ARC_OPERAND_ALIGNED16) 1980 1.1.1.5 christos && (val & 0x01)) 1981 1.1.1.8 christos { 1982 1.1.1.8 christos tmpmsg = _("immediate is not 16bit aligned"); 1983 1.1.1.8 christos goto match_failed; 1984 1.1.1.8 christos } 1985 1.1.1.5 christos } 1986 1.1.1.5 christos else if (operand->flags & ARC_OPERAND_NCHK) 1987 1.1.1.5 christos { 1988 1.1.1.5 christos if (operand->insert) 1989 1.1.1.5 christos { 1990 1.1.1.8 christos tmpmsg = NULL; 1991 1.1.1.5 christos (*operand->insert)(0, 1992 1.1.1.5 christos tok[tokidx].X_add_number, 1993 1.1.1.8 christos &tmpmsg); 1994 1.1.1.8 christos if (tmpmsg) 1995 1.1.1.5 christos goto match_failed; 1996 1.1.1.5 christos } 1997 1.1.1.5 christos else if (!(operand->flags & ARC_OPERAND_IGNORE)) 1998 1.1.1.5 christos goto match_failed; 1999 1.1.1.5 christos } 2000 1.1.1.5 christos break; 2001 1.1.1.5 christos 2002 1.1.1.5 christos case O_subtract: 2003 1.1.1.5 christos /* Check if it is register range. */ 2004 1.1.1.5 christos if ((tok[tokidx].X_add_number == 0) 2005 1.1.1.5 christos && contains_register (tok[tokidx].X_add_symbol) 2006 1.1.1.5 christos && contains_register (tok[tokidx].X_op_symbol)) 2007 1.1.1.5 christos { 2008 1.1.1.5 christos int regs; 2009 1.1.1.5 christos 2010 1.1.1.5 christos regs = get_register (tok[tokidx].X_add_symbol); 2011 1.1.1.5 christos regs <<= 16; 2012 1.1.1.5 christos regs |= get_register (tok[tokidx].X_op_symbol); 2013 1.1.1.5 christos if (operand->insert) 2014 1.1.1.5 christos { 2015 1.1.1.8 christos tmpmsg = NULL; 2016 1.1.1.5 christos (*operand->insert)(0, 2017 1.1.1.5 christos regs, 2018 1.1.1.8 christos &tmpmsg); 2019 1.1.1.8 christos if (tmpmsg) 2020 1.1.1.5 christos goto match_failed; 2021 1.1.1.5 christos } 2022 1.1.1.5 christos else 2023 1.1.1.5 christos goto match_failed; 2024 1.1.1.5 christos break; 2025 1.1.1.5 christos } 2026 1.1.1.6 christos /* Fall through. */ 2027 1.1.1.5 christos default: 2028 1.1.1.5 christos de_fault: 2029 1.1.1.5 christos if (operand->default_reloc == 0) 2030 1.1.1.5 christos goto match_failed; /* The operand needs relocation. */ 2031 1.1.1.5 christos 2032 1.1.1.5 christos /* Relocs requiring long immediate. FIXME! make it 2033 1.1.1.5 christos generic and move it to a function. */ 2034 1.1.1.5 christos switch (tok[tokidx].X_md) 2035 1.1.1.5 christos { 2036 1.1.1.5 christos case O_gotoff: 2037 1.1.1.5 christos case O_gotpc: 2038 1.1.1.5 christos case O_pcl: 2039 1.1.1.5 christos case O_tpoff: 2040 1.1.1.5 christos case O_dtpoff: 2041 1.1.1.5 christos case O_tlsgd: 2042 1.1.1.5 christos case O_tlsie: 2043 1.1.1.5 christos if (!(operand->flags & ARC_OPERAND_LIMM)) 2044 1.1.1.5 christos goto match_failed; 2045 1.1.1.6 christos /* Fall through. */ 2046 1.1.1.5 christos case O_absent: 2047 1.1.1.5 christos if (!generic_reloc_p (operand->default_reloc)) 2048 1.1.1.5 christos goto match_failed; 2049 1.1.1.6 christos break; 2050 1.1.1.5 christos default: 2051 1.1.1.5 christos break; 2052 1.1.1.5 christos } 2053 1.1.1.5 christos break; 2054 1.1.1.5 christos } 2055 1.1.1.5 christos /* If expect duplicate, make sure it is duplicate. */ 2056 1.1.1.5 christos if (operand->flags & ARC_OPERAND_DUPLICATE) 2057 1.1.1.5 christos { 2058 1.1.1.5 christos if (t->X_op == O_illegal 2059 1.1.1.5 christos || t->X_op == O_absent 2060 1.1.1.5 christos || t->X_op == O_register 2061 1.1.1.5 christos || (t->X_add_number != tok[tokidx].X_add_number)) 2062 1.1.1.8 christos { 2063 1.1.1.8 christos tmpmsg = _("operand is not duplicate of the " 2064 1.1.1.8 christos "previous one"); 2065 1.1.1.8 christos goto match_failed; 2066 1.1.1.8 christos } 2067 1.1.1.5 christos } 2068 1.1.1.5 christos t = &tok[tokidx]; 2069 1.1.1.5 christos break; 2070 1.1.1.5 christos 2071 1.1.1.5 christos default: 2072 1.1.1.5 christos /* Everything else should have been fake. */ 2073 1.1.1.5 christos abort (); 2074 1.1.1.5 christos } 2075 1.1.1.5 christos 2076 1.1.1.5 christos ++tokidx; 2077 1.1.1.3 christos } 2078 1.1.1.5 christos pr_debug ("opr "); 2079 1.1.1.5 christos 2080 1.1.1.5 christos /* Setup ready for flag parsing. */ 2081 1.1.1.5 christos if (!parse_opcode_flags (opcode, nflgs, first_pflag)) 2082 1.1.1.8 christos { 2083 1.1.1.8 christos tmpmsg = _("flag mismatch"); 2084 1.1.1.8 christos goto match_failed; 2085 1.1.1.8 christos } 2086 1.1.1.5 christos 2087 1.1.1.5 christos pr_debug ("flg"); 2088 1.1.1.5 christos /* Possible match -- did we use all of our input? */ 2089 1.1.1.5 christos if (tokidx == ntok) 2090 1.1.1.3 christos { 2091 1.1.1.5 christos *pntok = ntok; 2092 1.1.1.5 christos pr_debug ("\n"); 2093 1.1.1.5 christos return opcode; 2094 1.1.1.3 christos } 2095 1.1.1.8 christos tmpmsg = _("too many arguments"); 2096 1.1.1.5 christos 2097 1.1.1.5 christos match_failed:; 2098 1.1.1.5 christos pr_debug ("\n"); 2099 1.1.1.5 christos /* Restore the original parameters. */ 2100 1.1.1.5 christos memcpy (tok, bktok, MAX_INSN_ARGS * sizeof (*tok)); 2101 1.1.1.5 christos ntok = bkntok; 2102 1.1.1.8 christos if (tokidx >= maxerridx 2103 1.1.1.8 christos && tmpmsg) 2104 1.1.1.8 christos { 2105 1.1.1.8 christos maxerridx = tokidx; 2106 1.1.1.8 christos *errmsg = tmpmsg; 2107 1.1.1.8 christos } 2108 1.1 skrll } 2109 1.1 skrll 2110 1.1.1.5 christos if (*pcpumatch) 2111 1.1.1.5 christos *pcpumatch = got_cpu_match; 2112 1.1 skrll 2113 1.1.1.5 christos return NULL; 2114 1.1.1.5 christos } 2115 1.1.1.3 christos 2116 1.1.1.5 christos /* Swap operand tokens. */ 2117 1.1 skrll 2118 1.1.1.5 christos static void 2119 1.1.1.5 christos swap_operand (expressionS *operand_array, 2120 1.1.1.5 christos unsigned source, 2121 1.1.1.5 christos unsigned destination) 2122 1.1.1.5 christos { 2123 1.1.1.5 christos expressionS cpy_operand; 2124 1.1.1.5 christos expressionS *src_operand; 2125 1.1.1.5 christos expressionS *dst_operand; 2126 1.1.1.5 christos size_t size; 2127 1.1.1.3 christos 2128 1.1.1.5 christos if (source == destination) 2129 1.1.1.5 christos return; 2130 1.1.1.3 christos 2131 1.1.1.5 christos src_operand = &operand_array[source]; 2132 1.1.1.5 christos dst_operand = &operand_array[destination]; 2133 1.1.1.5 christos size = sizeof (expressionS); 2134 1.1.1.5 christos 2135 1.1.1.5 christos /* Make copy of operand to swap with and swap. */ 2136 1.1.1.5 christos memcpy (&cpy_operand, dst_operand, size); 2137 1.1.1.5 christos memcpy (dst_operand, src_operand, size); 2138 1.1.1.5 christos memcpy (src_operand, &cpy_operand, size); 2139 1.1.1.5 christos } 2140 1.1.1.5 christos 2141 1.1.1.5 christos /* Check if *op matches *tok type. 2142 1.1.1.5 christos Returns FALSE if they don't match, TRUE if they match. */ 2143 1.1.1.5 christos 2144 1.1.1.8 christos static bool 2145 1.1.1.5 christos pseudo_operand_match (const expressionS *tok, 2146 1.1.1.5 christos const struct arc_operand_operation *op) 2147 1.1.1.5 christos { 2148 1.1.1.5 christos offsetT min, max, val; 2149 1.1.1.8 christos bool ret; 2150 1.1.1.5 christos const struct arc_operand *operand_real = &arc_operands[op->operand_idx]; 2151 1.1.1.5 christos 2152 1.1.1.8 christos ret = false; 2153 1.1.1.5 christos switch (tok->X_op) 2154 1.1.1.3 christos { 2155 1.1.1.5 christos case O_constant: 2156 1.1.1.5 christos if (operand_real->bits == 32 && (operand_real->flags & ARC_OPERAND_LIMM)) 2157 1.1.1.5 christos ret = 1; 2158 1.1.1.5 christos else if (!(operand_real->flags & ARC_OPERAND_IR)) 2159 1.1.1.5 christos { 2160 1.1.1.5 christos val = tok->X_add_number + op->count; 2161 1.1.1.5 christos if (operand_real->flags & ARC_OPERAND_SIGNED) 2162 1.1.1.5 christos { 2163 1.1.1.5 christos max = (1 << (operand_real->bits - 1)) - 1; 2164 1.1.1.5 christos min = -(1 << (operand_real->bits - 1)); 2165 1.1.1.5 christos } 2166 1.1.1.5 christos else 2167 1.1.1.5 christos { 2168 1.1.1.5 christos max = (1 << operand_real->bits) - 1; 2169 1.1.1.5 christos min = 0; 2170 1.1.1.5 christos } 2171 1.1.1.5 christos if (min <= val && val <= max) 2172 1.1.1.8 christos ret = true; 2173 1.1.1.5 christos } 2174 1.1.1.5 christos break; 2175 1.1.1.5 christos 2176 1.1.1.5 christos case O_symbol: 2177 1.1.1.5 christos /* Handle all symbols as long immediates or signed 9. */ 2178 1.1.1.6 christos if (operand_real->flags & ARC_OPERAND_LIMM 2179 1.1.1.6 christos || ((operand_real->flags & ARC_OPERAND_SIGNED) 2180 1.1.1.6 christos && operand_real->bits == 9)) 2181 1.1.1.8 christos ret = true; 2182 1.1.1.3 christos break; 2183 1.1 skrll 2184 1.1.1.5 christos case O_register: 2185 1.1.1.5 christos if (operand_real->flags & ARC_OPERAND_IR) 2186 1.1.1.8 christos ret = true; 2187 1.1.1.3 christos break; 2188 1.1.1.3 christos 2189 1.1.1.5 christos case O_bracket: 2190 1.1.1.5 christos if (operand_real->flags & ARC_OPERAND_BRAKET) 2191 1.1.1.8 christos ret = true; 2192 1.1.1.3 christos break; 2193 1.1 skrll 2194 1.1.1.3 christos default: 2195 1.1.1.5 christos /* Unknown. */ 2196 1.1.1.3 christos break; 2197 1.1.1.3 christos } 2198 1.1.1.5 christos return ret; 2199 1.1.1.5 christos } 2200 1.1 skrll 2201 1.1.1.5 christos /* Find pseudo instruction in array. */ 2202 1.1.1.5 christos 2203 1.1.1.5 christos static const struct arc_pseudo_insn * 2204 1.1.1.5 christos find_pseudo_insn (const char *opname, 2205 1.1.1.5 christos int ntok, 2206 1.1.1.5 christos const expressionS *tok) 2207 1.1.1.5 christos { 2208 1.1.1.5 christos const struct arc_pseudo_insn *pseudo_insn = NULL; 2209 1.1.1.5 christos const struct arc_operand_operation *op; 2210 1.1.1.5 christos unsigned int i; 2211 1.1.1.5 christos int j; 2212 1.1.1.5 christos 2213 1.1.1.5 christos for (i = 0; i < arc_num_pseudo_insn; ++i) 2214 1.1 skrll { 2215 1.1.1.5 christos pseudo_insn = &arc_pseudo_insns[i]; 2216 1.1.1.5 christos if (strcmp (pseudo_insn->mnemonic_p, opname) == 0) 2217 1.1.1.5 christos { 2218 1.1.1.5 christos op = pseudo_insn->operand; 2219 1.1.1.5 christos for (j = 0; j < ntok; ++j) 2220 1.1.1.5 christos if (!pseudo_operand_match (&tok[j], &op[j])) 2221 1.1.1.5 christos break; 2222 1.1.1.5 christos 2223 1.1.1.5 christos /* Found the right instruction. */ 2224 1.1.1.5 christos if (j == ntok) 2225 1.1.1.5 christos return pseudo_insn; 2226 1.1.1.5 christos } 2227 1.1 skrll } 2228 1.1.1.5 christos return NULL; 2229 1.1.1.5 christos } 2230 1.1 skrll 2231 1.1.1.5 christos /* Assumes the expressionS *tok is of sufficient size. */ 2232 1.1 skrll 2233 1.1.1.5 christos static const struct arc_opcode_hash_entry * 2234 1.1.1.5 christos find_special_case_pseudo (const char *opname, 2235 1.1.1.5 christos int *ntok, 2236 1.1.1.5 christos expressionS *tok, 2237 1.1.1.5 christos int *nflgs, 2238 1.1.1.5 christos struct arc_flags *pflags) 2239 1.1.1.5 christos { 2240 1.1.1.5 christos const struct arc_pseudo_insn *pseudo_insn = NULL; 2241 1.1.1.5 christos const struct arc_operand_operation *operand_pseudo; 2242 1.1.1.5 christos const struct arc_operand *operand_real; 2243 1.1.1.5 christos unsigned i; 2244 1.1.1.5 christos char construct_operand[MAX_CONSTR_STR]; 2245 1.1.1.3 christos 2246 1.1.1.5 christos /* Find whether opname is in pseudo instruction array. */ 2247 1.1.1.5 christos pseudo_insn = find_pseudo_insn (opname, *ntok, tok); 2248 1.1 skrll 2249 1.1.1.5 christos if (pseudo_insn == NULL) 2250 1.1.1.5 christos return NULL; 2251 1.1 skrll 2252 1.1.1.5 christos /* Handle flag, Limited to one flag at the moment. */ 2253 1.1.1.5 christos if (pseudo_insn->flag_r != NULL) 2254 1.1.1.5 christos *nflgs += tokenize_flags (pseudo_insn->flag_r, &pflags[*nflgs], 2255 1.1.1.5 christos MAX_INSN_FLGS - *nflgs); 2256 1.1 skrll 2257 1.1.1.5 christos /* Handle operand operations. */ 2258 1.1.1.5 christos for (i = 0; i < pseudo_insn->operand_cnt; ++i) 2259 1.1.1.5 christos { 2260 1.1.1.5 christos operand_pseudo = &pseudo_insn->operand[i]; 2261 1.1.1.5 christos operand_real = &arc_operands[operand_pseudo->operand_idx]; 2262 1.1.1.3 christos 2263 1.1.1.6 christos if (operand_real->flags & ARC_OPERAND_BRAKET 2264 1.1.1.6 christos && !operand_pseudo->needs_insert) 2265 1.1.1.5 christos continue; 2266 1.1.1.3 christos 2267 1.1.1.5 christos /* Has to be inserted (i.e. this token does not exist yet). */ 2268 1.1.1.5 christos if (operand_pseudo->needs_insert) 2269 1.1.1.5 christos { 2270 1.1.1.5 christos if (operand_real->flags & ARC_OPERAND_BRAKET) 2271 1.1.1.5 christos { 2272 1.1.1.5 christos tok[i].X_op = O_bracket; 2273 1.1.1.5 christos ++(*ntok); 2274 1.1.1.5 christos continue; 2275 1.1.1.5 christos } 2276 1.1.1.3 christos 2277 1.1.1.5 christos /* Check if operand is a register or constant and handle it 2278 1.1.1.5 christos by type. */ 2279 1.1.1.5 christos if (operand_real->flags & ARC_OPERAND_IR) 2280 1.1.1.5 christos snprintf (construct_operand, MAX_CONSTR_STR, "r%d", 2281 1.1.1.5 christos operand_pseudo->count); 2282 1.1.1.5 christos else 2283 1.1.1.5 christos snprintf (construct_operand, MAX_CONSTR_STR, "%d", 2284 1.1.1.5 christos operand_pseudo->count); 2285 1.1.1.3 christos 2286 1.1.1.5 christos tokenize_arguments (construct_operand, &tok[i], 1); 2287 1.1.1.5 christos ++(*ntok); 2288 1.1.1.5 christos } 2289 1.1 skrll 2290 1.1.1.5 christos else if (operand_pseudo->count) 2291 1.1.1.5 christos { 2292 1.1.1.5 christos /* Operand number has to be adjusted accordingly (by operand 2293 1.1.1.5 christos type). */ 2294 1.1.1.5 christos switch (tok[i].X_op) 2295 1.1.1.5 christos { 2296 1.1.1.5 christos case O_constant: 2297 1.1.1.5 christos tok[i].X_add_number += operand_pseudo->count; 2298 1.1.1.5 christos break; 2299 1.1 skrll 2300 1.1.1.5 christos case O_symbol: 2301 1.1.1.5 christos break; 2302 1.1.1.3 christos 2303 1.1.1.5 christos default: 2304 1.1.1.5 christos /* Ignored. */ 2305 1.1.1.5 christos break; 2306 1.1.1.5 christos } 2307 1.1.1.5 christos } 2308 1.1.1.3 christos } 2309 1.1.1.3 christos 2310 1.1.1.5 christos /* Swap operands if necessary. Only supports one swap at the 2311 1.1.1.5 christos moment. */ 2312 1.1.1.5 christos for (i = 0; i < pseudo_insn->operand_cnt; ++i) 2313 1.1.1.3 christos { 2314 1.1.1.5 christos operand_pseudo = &pseudo_insn->operand[i]; 2315 1.1.1.5 christos 2316 1.1.1.5 christos if (operand_pseudo->swap_operand_idx == i) 2317 1.1.1.5 christos continue; 2318 1.1.1.5 christos 2319 1.1.1.5 christos swap_operand (tok, i, operand_pseudo->swap_operand_idx); 2320 1.1.1.5 christos 2321 1.1.1.5 christos /* Prevent a swap back later by breaking out. */ 2322 1.1.1.5 christos break; 2323 1.1 skrll } 2324 1.1.1.5 christos 2325 1.1.1.5 christos return arc_find_opcode (pseudo_insn->mnemonic_r); 2326 1.1.1.5 christos } 2327 1.1.1.5 christos 2328 1.1.1.5 christos static const struct arc_opcode_hash_entry * 2329 1.1.1.5 christos find_special_case_flag (const char *opname, 2330 1.1.1.5 christos int *nflgs, 2331 1.1.1.5 christos struct arc_flags *pflags) 2332 1.1.1.5 christos { 2333 1.1.1.5 christos unsigned int i; 2334 1.1.1.5 christos const char *flagnm; 2335 1.1.1.5 christos unsigned flag_idx, flag_arr_idx; 2336 1.1.1.5 christos size_t flaglen, oplen; 2337 1.1.1.5 christos const struct arc_flag_special *arc_flag_special_opcode; 2338 1.1.1.5 christos const struct arc_opcode_hash_entry *entry; 2339 1.1.1.5 christos 2340 1.1.1.5 christos /* Search for special case instruction. */ 2341 1.1.1.5 christos for (i = 0; i < arc_num_flag_special; i++) 2342 1.1 skrll { 2343 1.1.1.5 christos arc_flag_special_opcode = &arc_flag_special_cases[i]; 2344 1.1.1.5 christos oplen = strlen (arc_flag_special_opcode->name); 2345 1.1.1.5 christos 2346 1.1.1.5 christos if (strncmp (opname, arc_flag_special_opcode->name, oplen) != 0) 2347 1.1.1.5 christos continue; 2348 1.1.1.5 christos 2349 1.1.1.5 christos /* Found a potential special case instruction, now test for 2350 1.1.1.5 christos flags. */ 2351 1.1.1.5 christos for (flag_arr_idx = 0;; ++flag_arr_idx) 2352 1.1 skrll { 2353 1.1.1.5 christos flag_idx = arc_flag_special_opcode->flags[flag_arr_idx]; 2354 1.1.1.5 christos if (flag_idx == 0) 2355 1.1.1.5 christos break; /* End of array, nothing found. */ 2356 1.1.1.5 christos 2357 1.1.1.5 christos flagnm = arc_flag_operands[flag_idx].name; 2358 1.1.1.5 christos flaglen = strlen (flagnm); 2359 1.1.1.5 christos if (strcmp (opname + oplen, flagnm) == 0) 2360 1.1.1.5 christos { 2361 1.1.1.5 christos entry = arc_find_opcode (arc_flag_special_opcode->name); 2362 1.1.1.5 christos 2363 1.1.1.5 christos if (*nflgs + 1 > MAX_INSN_FLGS) 2364 1.1.1.5 christos break; 2365 1.1.1.5 christos memcpy (pflags[*nflgs].name, flagnm, flaglen); 2366 1.1.1.5 christos pflags[*nflgs].name[flaglen] = '\0'; 2367 1.1.1.5 christos (*nflgs)++; 2368 1.1.1.5 christos return entry; 2369 1.1.1.5 christos } 2370 1.1 skrll } 2371 1.1 skrll } 2372 1.1.1.5 christos return NULL; 2373 1.1.1.5 christos } 2374 1.1 skrll 2375 1.1.1.5 christos /* Used to find special case opcode. */ 2376 1.1 skrll 2377 1.1.1.5 christos static const struct arc_opcode_hash_entry * 2378 1.1.1.5 christos find_special_case (const char *opname, 2379 1.1.1.5 christos int *nflgs, 2380 1.1.1.5 christos struct arc_flags *pflags, 2381 1.1.1.5 christos expressionS *tok, 2382 1.1.1.5 christos int *ntok) 2383 1.1 skrll { 2384 1.1.1.5 christos const struct arc_opcode_hash_entry *entry; 2385 1.1 skrll 2386 1.1.1.5 christos entry = find_special_case_pseudo (opname, ntok, tok, nflgs, pflags); 2387 1.1.1.3 christos 2388 1.1.1.5 christos if (entry == NULL) 2389 1.1.1.5 christos entry = find_special_case_flag (opname, nflgs, pflags); 2390 1.1.1.3 christos 2391 1.1.1.5 christos return entry; 2392 1.1.1.5 christos } 2393 1.1.1.3 christos 2394 1.1.1.6 christos /* Autodetect cpu attribute list. */ 2395 1.1.1.6 christos 2396 1.1.1.6 christos static void 2397 1.1.1.6 christos autodetect_attributes (const struct arc_opcode *opcode, 2398 1.1.1.6 christos const expressionS *tok, 2399 1.1.1.6 christos int ntok) 2400 1.1.1.6 christos { 2401 1.1.1.6 christos unsigned i; 2402 1.1.1.6 christos struct mpy_type 2403 1.1.1.6 christos { 2404 1.1.1.6 christos unsigned feature; 2405 1.1.1.6 christos unsigned encoding; 2406 1.1.1.6 christos } mpy_list[] = {{ MPY1E, 1 }, { MPY6E, 6 }, { MPY7E, 7 }, { MPY8E, 8 }, 2407 1.1.1.6 christos { MPY9E, 9 }}; 2408 1.1.1.6 christos 2409 1.1.1.6 christos for (i = 0; i < ARRAY_SIZE (feature_list); i++) 2410 1.1.1.6 christos if (opcode->subclass == feature_list[i].feature) 2411 1.1.1.6 christos selected_cpu.features |= feature_list[i].feature; 2412 1.1.1.6 christos 2413 1.1.1.6 christos for (i = 0; i < ARRAY_SIZE (mpy_list); i++) 2414 1.1.1.6 christos if (opcode->subclass == mpy_list[i].feature) 2415 1.1.1.6 christos mpy_option = mpy_list[i].encoding; 2416 1.1.1.6 christos 2417 1.1.1.6 christos for (i = 0; i < (unsigned) ntok; i++) 2418 1.1.1.6 christos { 2419 1.1.1.6 christos switch (tok[i].X_md) 2420 1.1.1.6 christos { 2421 1.1.1.6 christos case O_gotoff: 2422 1.1.1.6 christos case O_gotpc: 2423 1.1.1.6 christos case O_plt: 2424 1.1.1.6 christos pic_option = 2; 2425 1.1.1.6 christos break; 2426 1.1.1.6 christos case O_sda: 2427 1.1.1.6 christos sda_option = 2; 2428 1.1.1.6 christos break; 2429 1.1.1.6 christos case O_tlsgd: 2430 1.1.1.6 christos case O_tlsie: 2431 1.1.1.6 christos case O_tpoff9: 2432 1.1.1.6 christos case O_tpoff: 2433 1.1.1.6 christos case O_dtpoff9: 2434 1.1.1.6 christos case O_dtpoff: 2435 1.1.1.6 christos tls_option = 1; 2436 1.1.1.6 christos break; 2437 1.1.1.6 christos default: 2438 1.1.1.6 christos break; 2439 1.1.1.6 christos } 2440 1.1.1.7 christos 2441 1.1.1.7 christos switch (tok[i].X_op) 2442 1.1.1.7 christos { 2443 1.1.1.7 christos case O_register: 2444 1.1.1.7 christos if ((tok[i].X_add_number >= 4 && tok[i].X_add_number <= 9) 2445 1.1.1.7 christos || (tok[i].X_add_number >= 16 && tok[i].X_add_number <= 25)) 2446 1.1.1.8 christos rf16_only = false; 2447 1.1.1.7 christos break; 2448 1.1.1.7 christos default: 2449 1.1.1.7 christos break; 2450 1.1.1.7 christos } 2451 1.1.1.6 christos } 2452 1.1.1.6 christos } 2453 1.1.1.6 christos 2454 1.1.1.5 christos /* Given an opcode name, pre-tockenized set of argumenst and the 2455 1.1.1.5 christos opcode flags, take it all the way through emission. */ 2456 1.1 skrll 2457 1.1.1.5 christos static void 2458 1.1.1.5 christos assemble_tokens (const char *opname, 2459 1.1.1.5 christos expressionS *tok, 2460 1.1.1.5 christos int ntok, 2461 1.1.1.5 christos struct arc_flags *pflags, 2462 1.1.1.5 christos int nflgs) 2463 1.1.1.5 christos { 2464 1.1.1.8 christos bool found_something = false; 2465 1.1.1.5 christos const struct arc_opcode_hash_entry *entry; 2466 1.1.1.5 christos int cpumatch = 1; 2467 1.1.1.6 christos const char *errmsg = NULL; 2468 1.1 skrll 2469 1.1.1.5 christos /* Search opcodes. */ 2470 1.1.1.5 christos entry = arc_find_opcode (opname); 2471 1.1 skrll 2472 1.1.1.5 christos /* Couldn't find opcode conventional way, try special cases. */ 2473 1.1.1.5 christos if (entry == NULL) 2474 1.1.1.5 christos entry = find_special_case (opname, &nflgs, pflags, tok, &ntok); 2475 1.1.1.5 christos 2476 1.1.1.5 christos if (entry != NULL) 2477 1.1.1.3 christos { 2478 1.1.1.5 christos const struct arc_opcode *opcode; 2479 1.1.1.5 christos 2480 1.1.1.5 christos pr_debug ("%s:%d: assemble_tokens: %s\n", 2481 1.1.1.5 christos frag_now->fr_file, frag_now->fr_line, opname); 2482 1.1.1.8 christos found_something = true; 2483 1.1.1.5 christos opcode = find_opcode_match (entry, tok, &ntok, pflags, 2484 1.1.1.6 christos nflgs, &cpumatch, &errmsg); 2485 1.1.1.5 christos if (opcode != NULL) 2486 1.1.1.3 christos { 2487 1.1.1.5 christos struct arc_insn insn; 2488 1.1.1.5 christos 2489 1.1.1.6 christos autodetect_attributes (opcode, tok, ntok); 2490 1.1.1.5 christos assemble_insn (opcode, tok, ntok, pflags, nflgs, &insn); 2491 1.1.1.5 christos emit_insn (&insn); 2492 1.1.1.5 christos return; 2493 1.1.1.3 christos } 2494 1.1.1.3 christos } 2495 1.1 skrll 2496 1.1.1.5 christos if (found_something) 2497 1.1.1.5 christos { 2498 1.1.1.5 christos if (cpumatch) 2499 1.1.1.6 christos if (errmsg) 2500 1.1.1.6 christos as_bad (_("%s for instruction '%s'"), errmsg, opname); 2501 1.1.1.6 christos else 2502 1.1.1.6 christos as_bad (_("inappropriate arguments for opcode '%s'"), opname); 2503 1.1.1.5 christos else 2504 1.1.1.5 christos as_bad (_("opcode '%s' not supported for target %s"), opname, 2505 1.1.1.6 christos selected_cpu.name); 2506 1.1.1.5 christos } 2507 1.1.1.5 christos else 2508 1.1.1.5 christos as_bad (_("unknown opcode '%s'"), opname); 2509 1.1 skrll } 2510 1.1 skrll 2511 1.1.1.5 christos /* The public interface to the instruction assembler. */ 2512 1.1.1.3 christos 2513 1.1.1.3 christos void 2514 1.1.1.5 christos md_assemble (char *str) 2515 1.1 skrll { 2516 1.1.1.5 christos char *opname; 2517 1.1.1.5 christos expressionS tok[MAX_INSN_ARGS]; 2518 1.1.1.5 christos int ntok, nflg; 2519 1.1.1.5 christos size_t opnamelen; 2520 1.1.1.5 christos struct arc_flags flags[MAX_INSN_FLGS]; 2521 1.1.1.3 christos 2522 1.1.1.5 christos /* Split off the opcode. */ 2523 1.1.1.9 christos opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_0123456789"); 2524 1.1.1.5 christos opname = xmemdup0 (str, opnamelen); 2525 1.1.1.3 christos 2526 1.1.1.5 christos /* Tokenize the flags. */ 2527 1.1.1.5 christos if ((nflg = tokenize_flags (str + opnamelen, flags, MAX_INSN_FLGS)) == -1) 2528 1.1.1.5 christos { 2529 1.1.1.5 christos as_bad (_("syntax error")); 2530 1.1.1.5 christos return; 2531 1.1.1.3 christos } 2532 1.1.1.3 christos 2533 1.1.1.5 christos /* Scan up to the end of the mnemonic which must end in space or end 2534 1.1.1.5 christos of string. */ 2535 1.1.1.5 christos str += opnamelen; 2536 1.1.1.10 christos for (; !is_end_of_stmt (*str); str++) 2537 1.1.1.10 christos if (is_whitespace (*str)) 2538 1.1.1.5 christos break; 2539 1.1 skrll 2540 1.1.1.5 christos /* Tokenize the rest of the line. */ 2541 1.1.1.5 christos if ((ntok = tokenize_arguments (str, tok, MAX_INSN_ARGS)) < 0) 2542 1.1.1.3 christos { 2543 1.1.1.5 christos as_bad (_("syntax error")); 2544 1.1.1.5 christos return; 2545 1.1.1.3 christos } 2546 1.1.1.5 christos 2547 1.1.1.5 christos /* Finish it off. */ 2548 1.1.1.5 christos assemble_tokens (opname, tok, ntok, flags, nflg); 2549 1.1.1.3 christos } 2550 1.1 skrll 2551 1.1.1.5 christos /* Callback to insert a register into the hash table. */ 2552 1.1.1.3 christos 2553 1.1.1.5 christos static void 2554 1.1.1.5 christos declare_register (const char *name, int number) 2555 1.1.1.3 christos { 2556 1.1.1.5 christos symbolS *regS = symbol_create (name, reg_section, 2557 1.1.1.8 christos &zero_address_frag, number); 2558 1.1.1.3 christos 2559 1.1.1.8 christos if (str_hash_insert (arc_reg_hash, S_GET_NAME (regS), regS, 0) != NULL) 2560 1.1.1.8 christos as_fatal (_("duplicate %s"), name); 2561 1.1.1.5 christos } 2562 1.1.1.3 christos 2563 1.1.1.5 christos /* Construct symbols for each of the general registers. */ 2564 1.1.1.3 christos 2565 1.1.1.5 christos static void 2566 1.1.1.5 christos declare_register_set (void) 2567 1.1.1.5 christos { 2568 1.1.1.5 christos int i; 2569 1.1.1.5 christos for (i = 0; i < 64; ++i) 2570 1.1.1.3 christos { 2571 1.1.1.8 christos char name[32]; 2572 1.1.1.5 christos 2573 1.1.1.5 christos sprintf (name, "r%d", i); 2574 1.1.1.5 christos declare_register (name, i); 2575 1.1.1.5 christos if ((i & 0x01) == 0) 2576 1.1.1.5 christos { 2577 1.1.1.5 christos sprintf (name, "r%dr%d", i, i+1); 2578 1.1.1.5 christos declare_register (name, i); 2579 1.1.1.5 christos } 2580 1.1.1.3 christos } 2581 1.1.1.3 christos } 2582 1.1.1.3 christos 2583 1.1.1.6 christos /* Construct a symbol for an address type. */ 2584 1.1.1.6 christos 2585 1.1.1.6 christos static void 2586 1.1.1.6 christos declare_addrtype (const char *name, int number) 2587 1.1.1.6 christos { 2588 1.1.1.6 christos symbolS *addrtypeS = symbol_create (name, undefined_section, 2589 1.1.1.8 christos &zero_address_frag, number); 2590 1.1.1.6 christos 2591 1.1.1.8 christos if (str_hash_insert (arc_addrtype_hash, S_GET_NAME (addrtypeS), addrtypeS, 0)) 2592 1.1.1.8 christos as_fatal (_("duplicate %s"), name); 2593 1.1.1.6 christos } 2594 1.1.1.6 christos 2595 1.1.1.5 christos /* Port-specific assembler initialization. This function is called 2596 1.1.1.5 christos once, at assembler startup time. */ 2597 1.1.1.5 christos 2598 1.1.1.5 christos void 2599 1.1.1.5 christos md_begin (void) 2600 1.1.1.5 christos { 2601 1.1.1.5 christos const struct arc_opcode *opcode = arc_opcodes; 2602 1.1.1.5 christos 2603 1.1.1.6 christos if (mach_selection_mode == MACH_SELECTION_NONE) 2604 1.1.1.6 christos arc_select_cpu (TARGET_WITH_CPU, MACH_SELECTION_FROM_DEFAULT); 2605 1.1.1.3 christos 2606 1.1.1.5 christos /* The endianness can be chosen "at the factory". */ 2607 1.1.1.5 christos target_big_endian = byte_order == BIG_ENDIAN; 2608 1.1.1.3 christos 2609 1.1.1.6 christos if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, selected_cpu.mach)) 2610 1.1.1.5 christos as_warn (_("could not set architecture and machine")); 2611 1.1.1.3 christos 2612 1.1.1.5 christos /* Set elf header flags. */ 2613 1.1.1.6 christos bfd_set_private_flags (stdoutput, selected_cpu.eflags); 2614 1.1.1.3 christos 2615 1.1.1.5 christos /* Set up a hash table for the instructions. */ 2616 1.1.1.9 christos arc_opcode_hash = htab_create_alloc (16, hash_string_tuple, eq_string_tuple, 2617 1.1.1.9 christos arc_opcode_free, xcalloc, free); 2618 1.1.1.3 christos 2619 1.1.1.5 christos /* Initialize the hash table with the insns. */ 2620 1.1.1.5 christos do 2621 1.1.1.3 christos { 2622 1.1.1.5 christos const char *name = opcode->name; 2623 1.1.1.3 christos 2624 1.1.1.5 christos arc_insert_opcode (opcode); 2625 1.1.1.3 christos 2626 1.1.1.5 christos while (++opcode && opcode->name 2627 1.1.1.5 christos && (opcode->name == name 2628 1.1.1.5 christos || !strcmp (opcode->name, name))) 2629 1.1.1.5 christos continue; 2630 1.1.1.5 christos }while (opcode->name); 2631 1.1.1.3 christos 2632 1.1.1.5 christos /* Register declaration. */ 2633 1.1.1.8 christos arc_reg_hash = str_htab_create (); 2634 1.1.1.3 christos 2635 1.1.1.5 christos declare_register_set (); 2636 1.1.1.5 christos declare_register ("gp", 26); 2637 1.1.1.5 christos declare_register ("fp", 27); 2638 1.1.1.5 christos declare_register ("sp", 28); 2639 1.1.1.5 christos declare_register ("ilink", 29); 2640 1.1.1.5 christos declare_register ("ilink1", 29); 2641 1.1.1.5 christos declare_register ("ilink2", 30); 2642 1.1.1.5 christos declare_register ("blink", 31); 2643 1.1 skrll 2644 1.1.1.5 christos /* XY memory registers. */ 2645 1.1.1.5 christos declare_register ("x0_u0", 32); 2646 1.1.1.5 christos declare_register ("x0_u1", 33); 2647 1.1.1.5 christos declare_register ("x1_u0", 34); 2648 1.1.1.5 christos declare_register ("x1_u1", 35); 2649 1.1.1.5 christos declare_register ("x2_u0", 36); 2650 1.1.1.5 christos declare_register ("x2_u1", 37); 2651 1.1.1.5 christos declare_register ("x3_u0", 38); 2652 1.1.1.5 christos declare_register ("x3_u1", 39); 2653 1.1.1.5 christos declare_register ("y0_u0", 40); 2654 1.1.1.5 christos declare_register ("y0_u1", 41); 2655 1.1.1.5 christos declare_register ("y1_u0", 42); 2656 1.1.1.5 christos declare_register ("y1_u1", 43); 2657 1.1.1.5 christos declare_register ("y2_u0", 44); 2658 1.1.1.5 christos declare_register ("y2_u1", 45); 2659 1.1.1.5 christos declare_register ("y3_u0", 46); 2660 1.1.1.5 christos declare_register ("y3_u1", 47); 2661 1.1.1.5 christos declare_register ("x0_nu", 48); 2662 1.1.1.5 christos declare_register ("x1_nu", 49); 2663 1.1.1.5 christos declare_register ("x2_nu", 50); 2664 1.1.1.5 christos declare_register ("x3_nu", 51); 2665 1.1.1.5 christos declare_register ("y0_nu", 52); 2666 1.1.1.5 christos declare_register ("y1_nu", 53); 2667 1.1.1.5 christos declare_register ("y2_nu", 54); 2668 1.1.1.5 christos declare_register ("y3_nu", 55); 2669 1.1 skrll 2670 1.1.1.5 christos declare_register ("mlo", 57); 2671 1.1.1.5 christos declare_register ("mmid", 58); 2672 1.1.1.5 christos declare_register ("mhi", 59); 2673 1.1.1.3 christos 2674 1.1.1.5 christos declare_register ("acc1", 56); 2675 1.1.1.5 christos declare_register ("acc2", 57); 2676 1.1.1.3 christos 2677 1.1.1.5 christos declare_register ("lp_count", 60); 2678 1.1.1.5 christos declare_register ("pcl", 63); 2679 1.1 skrll 2680 1.1.1.5 christos /* Initialize the last instructions. */ 2681 1.1.1.5 christos memset (&arc_last_insns[0], 0, sizeof (arc_last_insns)); 2682 1.1 skrll 2683 1.1.1.5 christos /* Aux register declaration. */ 2684 1.1.1.8 christos arc_aux_hash = str_htab_create (); 2685 1.1 skrll 2686 1.1.1.5 christos const struct arc_aux_reg *auxr = &arc_aux_regs[0]; 2687 1.1.1.5 christos unsigned int i; 2688 1.1.1.5 christos for (i = 0; i < arc_num_aux_regs; i++, auxr++) 2689 1.1.1.5 christos { 2690 1.1.1.6 christos if (!(auxr->cpu & selected_cpu.flags)) 2691 1.1.1.5 christos continue; 2692 1.1 skrll 2693 1.1.1.5 christos if ((auxr->subclass != NONE) 2694 1.1.1.5 christos && !check_cpu_feature (auxr->subclass)) 2695 1.1.1.5 christos continue; 2696 1.1 skrll 2697 1.1.1.8 christos if (str_hash_insert (arc_aux_hash, auxr->name, auxr, 0) != 0) 2698 1.1.1.8 christos as_fatal (_("duplicate %s"), auxr->name); 2699 1.1.1.3 christos } 2700 1.1.1.6 christos 2701 1.1.1.6 christos /* Address type declaration. */ 2702 1.1.1.8 christos arc_addrtype_hash = str_htab_create (); 2703 1.1.1.6 christos 2704 1.1.1.6 christos declare_addrtype ("bd", ARC_NPS400_ADDRTYPE_BD); 2705 1.1.1.6 christos declare_addrtype ("jid", ARC_NPS400_ADDRTYPE_JID); 2706 1.1.1.6 christos declare_addrtype ("lbd", ARC_NPS400_ADDRTYPE_LBD); 2707 1.1.1.6 christos declare_addrtype ("mbd", ARC_NPS400_ADDRTYPE_MBD); 2708 1.1.1.6 christos declare_addrtype ("sd", ARC_NPS400_ADDRTYPE_SD); 2709 1.1.1.6 christos declare_addrtype ("sm", ARC_NPS400_ADDRTYPE_SM); 2710 1.1.1.6 christos declare_addrtype ("xa", ARC_NPS400_ADDRTYPE_XA); 2711 1.1.1.6 christos declare_addrtype ("xd", ARC_NPS400_ADDRTYPE_XD); 2712 1.1.1.6 christos declare_addrtype ("cd", ARC_NPS400_ADDRTYPE_CD); 2713 1.1.1.6 christos declare_addrtype ("cbd", ARC_NPS400_ADDRTYPE_CBD); 2714 1.1.1.6 christos declare_addrtype ("cjid", ARC_NPS400_ADDRTYPE_CJID); 2715 1.1.1.6 christos declare_addrtype ("clbd", ARC_NPS400_ADDRTYPE_CLBD); 2716 1.1.1.6 christos declare_addrtype ("cm", ARC_NPS400_ADDRTYPE_CM); 2717 1.1.1.6 christos declare_addrtype ("csd", ARC_NPS400_ADDRTYPE_CSD); 2718 1.1.1.6 christos declare_addrtype ("cxa", ARC_NPS400_ADDRTYPE_CXA); 2719 1.1.1.6 christos declare_addrtype ("cxd", ARC_NPS400_ADDRTYPE_CXD); 2720 1.1.1.3 christos } 2721 1.1.1.3 christos 2722 1.1.1.9 christos void 2723 1.1.1.9 christos arc_md_end (void) 2724 1.1.1.9 christos { 2725 1.1.1.9 christos htab_delete (arc_opcode_hash); 2726 1.1.1.9 christos htab_delete (arc_reg_hash); 2727 1.1.1.9 christos htab_delete (arc_aux_hash); 2728 1.1.1.9 christos htab_delete (arc_addrtype_hash); 2729 1.1.1.9 christos } 2730 1.1.1.9 christos 2731 1.1.1.5 christos /* Write a value out to the object file, using the appropriate 2732 1.1.1.5 christos endianness. */ 2733 1.1.1.5 christos 2734 1.1.1.3 christos void 2735 1.1.1.5 christos md_number_to_chars (char *buf, 2736 1.1.1.5 christos valueT val, 2737 1.1.1.5 christos int n) 2738 1.1.1.3 christos { 2739 1.1.1.5 christos if (target_big_endian) 2740 1.1.1.5 christos number_to_chars_bigendian (buf, val, n); 2741 1.1.1.5 christos else 2742 1.1.1.5 christos number_to_chars_littleendian (buf, val, n); 2743 1.1.1.5 christos } 2744 1.1.1.3 christos 2745 1.1.1.5 christos /* Round up a section size to the appropriate boundary. */ 2746 1.1.1.3 christos 2747 1.1.1.5 christos valueT 2748 1.1.1.5 christos md_section_align (segT segment, 2749 1.1.1.5 christos valueT size) 2750 1.1.1.5 christos { 2751 1.1.1.7 christos int align = bfd_section_alignment (segment); 2752 1.1.1.5 christos 2753 1.1.1.5 christos return ((size + (1 << align) - 1) & (-((valueT) 1 << align))); 2754 1.1.1.3 christos } 2755 1.1.1.3 christos 2756 1.1.1.5 christos /* The location from which a PC relative jump should be calculated, 2757 1.1.1.5 christos given a PC relative reloc. */ 2758 1.1.1.5 christos 2759 1.1.1.5 christos long 2760 1.1.1.5 christos md_pcrel_from_section (fixS *fixP, 2761 1.1.1.5 christos segT sec) 2762 1.1.1.3 christos { 2763 1.1.1.5 christos offsetT base = fixP->fx_where + fixP->fx_frag->fr_address; 2764 1.1.1.5 christos 2765 1.1.1.5 christos pr_debug ("pcrel_from_section, fx_offset = %d\n", (int) fixP->fx_offset); 2766 1.1.1.5 christos 2767 1.1.1.10 christos if (fixP->fx_addsy != NULL 2768 1.1.1.5 christos && (!S_IS_DEFINED (fixP->fx_addsy) 2769 1.1.1.5 christos || S_GET_SEGMENT (fixP->fx_addsy) != sec)) 2770 1.1.1.5 christos { 2771 1.1.1.5 christos pr_debug ("Unknown pcrel symbol: %s\n", S_GET_NAME (fixP->fx_addsy)); 2772 1.1.1.5 christos 2773 1.1.1.5 christos /* The symbol is undefined (or is defined but not in this section). 2774 1.1.1.5 christos Let the linker figure it out. */ 2775 1.1.1.5 christos return 0; 2776 1.1.1.5 christos } 2777 1.1.1.3 christos 2778 1.1.1.5 christos if ((int) fixP->fx_r_type < 0) 2779 1.1.1.5 christos { 2780 1.1.1.5 christos /* These are the "internal" relocations. Align them to 2781 1.1.1.5 christos 32 bit boundary (PCL), for the moment. */ 2782 1.1.1.5 christos base &= ~3; 2783 1.1.1.5 christos } 2784 1.1.1.5 christos else 2785 1.1.1.3 christos { 2786 1.1.1.5 christos switch (fixP->fx_r_type) 2787 1.1.1.3 christos { 2788 1.1.1.11 christos case BFD_RELOC_32_PCREL: 2789 1.1.1.5 christos /* The hardware calculates relative to the start of the 2790 1.1.1.5 christos insn, but this relocation is relative to location of the 2791 1.1.1.5 christos LIMM, compensate. The base always needs to be 2792 1.1.1.6 christos subtracted by 4 as we do not support this type of PCrel 2793 1.1.1.5 christos relocation for short instructions. */ 2794 1.1.1.5 christos base -= 4; 2795 1.1.1.5 christos /* Fall through. */ 2796 1.1.1.11 christos case BFD_RELOC_32_PLT_PCREL: 2797 1.1.1.5 christos case BFD_RELOC_ARC_S25H_PCREL_PLT: 2798 1.1.1.5 christos case BFD_RELOC_ARC_S21H_PCREL_PLT: 2799 1.1.1.5 christos case BFD_RELOC_ARC_S25W_PCREL_PLT: 2800 1.1.1.5 christos case BFD_RELOC_ARC_S21W_PCREL_PLT: 2801 1.1.1.3 christos 2802 1.1.1.5 christos case BFD_RELOC_ARC_S21H_PCREL: 2803 1.1.1.5 christos case BFD_RELOC_ARC_S25H_PCREL: 2804 1.1.1.5 christos case BFD_RELOC_ARC_S13_PCREL: 2805 1.1.1.5 christos case BFD_RELOC_ARC_S21W_PCREL: 2806 1.1.1.5 christos case BFD_RELOC_ARC_S25W_PCREL: 2807 1.1.1.5 christos base &= ~3; 2808 1.1.1.3 christos break; 2809 1.1.1.3 christos default: 2810 1.1.1.5 christos as_bad_where (fixP->fx_file, fixP->fx_line, 2811 1.1.1.5 christos _("unhandled reloc %s in md_pcrel_from_section"), 2812 1.1.1.5 christos bfd_get_reloc_code_name (fixP->fx_r_type)); 2813 1.1.1.3 christos break; 2814 1.1 skrll } 2815 1.1.1.3 christos } 2816 1.1.1.5 christos 2817 1.1.1.9 christos pr_debug ("pcrel from %" PRIx64 " + %lx = %" PRIx64 ", " 2818 1.1.1.9 christos "symbol: %s (%" PRIx64 ")\n", 2819 1.1.1.9 christos (uint64_t) fixP->fx_frag->fr_address, fixP->fx_where, (uint64_t) base, 2820 1.1.1.5 christos fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "(null)", 2821 1.1.1.9 christos fixP->fx_addsy ? (uint64_t) S_GET_VALUE (fixP->fx_addsy) : (uint64_t) 0); 2822 1.1.1.5 christos 2823 1.1.1.5 christos return base; 2824 1.1.1.3 christos } 2825 1.1.1.3 christos 2826 1.1.1.6 christos /* Given a BFD relocation find the corresponding operand. */ 2827 1.1.1.3 christos 2828 1.1.1.5 christos static const struct arc_operand * 2829 1.1.1.5 christos find_operand_for_reloc (extended_bfd_reloc_code_real_type reloc) 2830 1.1.1.3 christos { 2831 1.1.1.5 christos unsigned i; 2832 1.1.1.3 christos 2833 1.1.1.5 christos for (i = 0; i < arc_num_operands; i++) 2834 1.1.1.5 christos if (arc_operands[i].default_reloc == reloc) 2835 1.1.1.5 christos return &arc_operands[i]; 2836 1.1.1.5 christos return NULL; 2837 1.1.1.5 christos } 2838 1.1 skrll 2839 1.1.1.5 christos /* Insert an operand value into an instruction. */ 2840 1.1.1.3 christos 2841 1.1.1.6 christos static unsigned long long 2842 1.1.1.6 christos insert_operand (unsigned long long insn, 2843 1.1.1.5 christos const struct arc_operand *operand, 2844 1.1.1.6 christos long long val, 2845 1.1.1.5 christos const char *file, 2846 1.1.1.5 christos unsigned line) 2847 1.1.1.5 christos { 2848 1.1.1.5 christos offsetT min = 0, max = 0; 2849 1.1.1.3 christos 2850 1.1.1.5 christos if (operand->bits != 32 2851 1.1.1.5 christos && !(operand->flags & ARC_OPERAND_NCHK) 2852 1.1.1.5 christos && !(operand->flags & ARC_OPERAND_FAKE)) 2853 1.1.1.5 christos { 2854 1.1.1.5 christos if (operand->flags & ARC_OPERAND_SIGNED) 2855 1.1 skrll { 2856 1.1.1.5 christos max = (1 << (operand->bits - 1)) - 1; 2857 1.1.1.5 christos min = -(1 << (operand->bits - 1)); 2858 1.1.1.3 christos } 2859 1.1.1.3 christos else 2860 1.1.1.5 christos { 2861 1.1.1.5 christos max = (1 << operand->bits) - 1; 2862 1.1.1.5 christos min = 0; 2863 1.1.1.5 christos } 2864 1.1.1.5 christos 2865 1.1.1.5 christos if (val < min || val > max) 2866 1.1.1.5 christos as_bad_value_out_of_range (_("operand"), 2867 1.1.1.5 christos val, min, max, file, line); 2868 1.1.1.3 christos } 2869 1.1 skrll 2870 1.1.1.6 christos pr_debug ("insert field: %ld <= %lld <= %ld in 0x%08llx\n", 2871 1.1.1.5 christos min, val, max, insn); 2872 1.1 skrll 2873 1.1.1.5 christos if ((operand->flags & ARC_OPERAND_ALIGNED32) 2874 1.1.1.5 christos && (val & 0x03)) 2875 1.1.1.5 christos as_bad_where (file, line, 2876 1.1.1.5 christos _("Unaligned operand. Needs to be 32bit aligned")); 2877 1.1 skrll 2878 1.1.1.5 christos if ((operand->flags & ARC_OPERAND_ALIGNED16) 2879 1.1.1.5 christos && (val & 0x01)) 2880 1.1.1.5 christos as_bad_where (file, line, 2881 1.1.1.5 christos _("Unaligned operand. Needs to be 16bit aligned")); 2882 1.1 skrll 2883 1.1.1.5 christos if (operand->insert) 2884 1.1.1.5 christos { 2885 1.1.1.5 christos const char *errmsg = NULL; 2886 1.1 skrll 2887 1.1.1.5 christos insn = (*operand->insert) (insn, val, &errmsg); 2888 1.1.1.5 christos if (errmsg) 2889 1.1.1.5 christos as_warn_where (file, line, "%s", errmsg); 2890 1.1.1.5 christos } 2891 1.1.1.5 christos else 2892 1.1.1.5 christos { 2893 1.1.1.5 christos if (operand->flags & ARC_OPERAND_TRUNCATE) 2894 1.1.1.5 christos { 2895 1.1.1.5 christos if (operand->flags & ARC_OPERAND_ALIGNED32) 2896 1.1.1.5 christos val >>= 2; 2897 1.1.1.5 christos if (operand->flags & ARC_OPERAND_ALIGNED16) 2898 1.1.1.5 christos val >>= 1; 2899 1.1.1.5 christos } 2900 1.1.1.5 christos insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift); 2901 1.1.1.5 christos } 2902 1.1.1.5 christos return insn; 2903 1.1.1.3 christos } 2904 1.1 skrll 2905 1.1.1.5 christos /* Apply a fixup to the object code. At this point all symbol values 2906 1.1.1.5 christos should be fully resolved, and we attempt to completely resolve the 2907 1.1.1.5 christos reloc. If we can not do that, we determine the correct reloc code 2908 1.1.1.5 christos and put it back in the fixup. To indicate that a fixup has been 2909 1.1.1.5 christos eliminated, set fixP->fx_done. */ 2910 1.1 skrll 2911 1.1.1.5 christos void 2912 1.1.1.5 christos md_apply_fix (fixS *fixP, 2913 1.1.1.5 christos valueT *valP, 2914 1.1.1.5 christos segT seg) 2915 1.1.1.3 christos { 2916 1.1.1.5 christos char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where; 2917 1.1.1.5 christos valueT value = *valP; 2918 1.1.1.5 christos unsigned insn = 0; 2919 1.1.1.5 christos symbolS *fx_addsy, *fx_subsy; 2920 1.1.1.5 christos offsetT fx_offset; 2921 1.1.1.5 christos segT add_symbol_segment = absolute_section; 2922 1.1.1.5 christos segT sub_symbol_segment = absolute_section; 2923 1.1.1.5 christos const struct arc_operand *operand = NULL; 2924 1.1.1.5 christos extended_bfd_reloc_code_real_type reloc; 2925 1.1 skrll 2926 1.1.1.5 christos pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n", 2927 1.1.1.5 christos fixP->fx_file, fixP->fx_line, fixP->fx_r_type, 2928 1.1.1.5 christos ((int) fixP->fx_r_type < 0) ? "Internal": 2929 1.1.1.5 christos bfd_get_reloc_code_name (fixP->fx_r_type), value, 2930 1.1.1.5 christos fixP->fx_offset); 2931 1.1.1.3 christos 2932 1.1.1.5 christos fx_addsy = fixP->fx_addsy; 2933 1.1.1.5 christos fx_subsy = fixP->fx_subsy; 2934 1.1.1.5 christos fx_offset = 0; 2935 1.1.1.3 christos 2936 1.1.1.5 christos if (fx_addsy) 2937 1.1.1.5 christos { 2938 1.1.1.5 christos add_symbol_segment = S_GET_SEGMENT (fx_addsy); 2939 1.1.1.5 christos } 2940 1.1 skrll 2941 1.1.1.5 christos if (fx_subsy 2942 1.1.1.5 christos && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF 2943 1.1.1.5 christos && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF_S9 2944 1.1.1.5 christos && fixP->fx_r_type != BFD_RELOC_ARC_TLS_GD_LD) 2945 1.1.1.5 christos { 2946 1.1.1.5 christos resolve_symbol_value (fx_subsy); 2947 1.1.1.5 christos sub_symbol_segment = S_GET_SEGMENT (fx_subsy); 2948 1.1.1.3 christos 2949 1.1.1.5 christos if (sub_symbol_segment == absolute_section) 2950 1.1.1.5 christos { 2951 1.1.1.5 christos /* The symbol is really a constant. */ 2952 1.1.1.5 christos fx_offset -= S_GET_VALUE (fx_subsy); 2953 1.1.1.5 christos fx_subsy = NULL; 2954 1.1.1.5 christos } 2955 1.1.1.5 christos else 2956 1.1.1.5 christos { 2957 1.1.1.8 christos as_bad_subtract (fixP); 2958 1.1.1.5 christos return; 2959 1.1.1.5 christos } 2960 1.1.1.5 christos } 2961 1.1.1.3 christos 2962 1.1.1.5 christos if (fx_addsy 2963 1.1.1.5 christos && !S_IS_WEAK (fx_addsy)) 2964 1.1.1.3 christos { 2965 1.1.1.5 christos if (add_symbol_segment == seg 2966 1.1.1.5 christos && fixP->fx_pcrel) 2967 1.1.1.3 christos { 2968 1.1.1.5 christos value += S_GET_VALUE (fx_addsy); 2969 1.1.1.5 christos value -= md_pcrel_from_section (fixP, seg); 2970 1.1.1.5 christos fx_addsy = NULL; 2971 1.1.1.8 christos fixP->fx_pcrel = false; 2972 1.1.1.3 christos } 2973 1.1.1.5 christos else if (add_symbol_segment == absolute_section) 2974 1.1.1.5 christos { 2975 1.1.1.5 christos value = fixP->fx_offset; 2976 1.1.1.5 christos fx_offset += S_GET_VALUE (fixP->fx_addsy); 2977 1.1.1.5 christos fx_addsy = NULL; 2978 1.1.1.8 christos fixP->fx_pcrel = false; 2979 1.1.1.5 christos } 2980 1.1.1.5 christos } 2981 1.1 skrll 2982 1.1.1.5 christos if (!fx_addsy) 2983 1.1.1.8 christos fixP->fx_done = true; 2984 1.1.1.3 christos 2985 1.1.1.5 christos if (fixP->fx_pcrel) 2986 1.1.1.5 christos { 2987 1.1.1.5 christos if (fx_addsy 2988 1.1.1.5 christos && ((S_IS_DEFINED (fx_addsy) 2989 1.1.1.5 christos && S_GET_SEGMENT (fx_addsy) != seg) 2990 1.1.1.5 christos || S_IS_WEAK (fx_addsy))) 2991 1.1.1.5 christos value += md_pcrel_from_section (fixP, seg); 2992 1.1.1.3 christos 2993 1.1.1.5 christos switch (fixP->fx_r_type) 2994 1.1.1.5 christos { 2995 1.1.1.5 christos case BFD_RELOC_ARC_32_ME: 2996 1.1.1.5 christos /* This is a pc-relative value in a LIMM. Adjust it to the 2997 1.1.1.5 christos address of the instruction not to the address of the 2998 1.1.1.6 christos LIMM. Note: it is not any longer valid this affirmation as 2999 1.1.1.5 christos the linker consider ARC_PC32 a fixup to entire 64 bit 3000 1.1.1.5 christos insn. */ 3001 1.1.1.5 christos fixP->fx_offset += fixP->fx_frag->fr_address; 3002 1.1.1.5 christos /* Fall through. */ 3003 1.1.1.5 christos case BFD_RELOC_32: 3004 1.1.1.11 christos fixP->fx_r_type = BFD_RELOC_32_PCREL; 3005 1.1.1.5 christos /* Fall through. */ 3006 1.1.1.11 christos case BFD_RELOC_32_PCREL: 3007 1.1.1.5 christos /* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */ 3008 1.1.1.5 christos break; 3009 1.1.1.5 christos default: 3010 1.1.1.5 christos if ((int) fixP->fx_r_type < 0) 3011 1.1.1.6 christos as_bad_where (fixP->fx_file, fixP->fx_line, 3012 1.1.1.6 christos _("PC relative relocation not allowed for (internal)" 3013 1.1.1.6 christos " type %d"), 3014 1.1.1.6 christos fixP->fx_r_type); 3015 1.1.1.5 christos break; 3016 1.1.1.5 christos } 3017 1.1.1.3 christos } 3018 1.1.1.3 christos 3019 1.1.1.5 christos pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n", 3020 1.1.1.5 christos fixP->fx_file, fixP->fx_line, fixP->fx_r_type, 3021 1.1.1.5 christos ((int) fixP->fx_r_type < 0) ? "Internal": 3022 1.1.1.5 christos bfd_get_reloc_code_name (fixP->fx_r_type), value, 3023 1.1.1.5 christos fixP->fx_offset); 3024 1.1.1.3 christos 3025 1.1.1.3 christos 3026 1.1.1.5 christos /* Now check for TLS relocations. */ 3027 1.1.1.5 christos reloc = fixP->fx_r_type; 3028 1.1.1.5 christos switch (reloc) 3029 1.1.1.3 christos { 3030 1.1.1.5 christos case BFD_RELOC_ARC_TLS_DTPOFF: 3031 1.1.1.5 christos case BFD_RELOC_ARC_TLS_LE_32: 3032 1.1.1.5 christos if (fixP->fx_done) 3033 1.1.1.5 christos break; 3034 1.1.1.5 christos /* Fall through. */ 3035 1.1.1.5 christos case BFD_RELOC_ARC_TLS_GD_GOT: 3036 1.1.1.5 christos case BFD_RELOC_ARC_TLS_IE_GOT: 3037 1.1.1.5 christos S_SET_THREAD_LOCAL (fixP->fx_addsy); 3038 1.1.1.5 christos break; 3039 1.1.1.3 christos 3040 1.1.1.5 christos case BFD_RELOC_ARC_TLS_GD_LD: 3041 1.1.1.5 christos gas_assert (!fixP->fx_offset); 3042 1.1.1.5 christos if (fixP->fx_subsy) 3043 1.1.1.5 christos fixP->fx_offset 3044 1.1.1.5 christos = (S_GET_VALUE (fixP->fx_subsy) 3045 1.1.1.5 christos - fixP->fx_frag->fr_address- fixP->fx_where); 3046 1.1.1.5 christos fixP->fx_subsy = NULL; 3047 1.1.1.5 christos /* Fall through. */ 3048 1.1.1.5 christos case BFD_RELOC_ARC_TLS_GD_CALL: 3049 1.1.1.5 christos /* These two relocs are there just to allow ld to change the tls 3050 1.1.1.5 christos model for this symbol, by patching the code. The offset - 3051 1.1.1.5 christos and scale, if any - will be installed by the linker. */ 3052 1.1.1.5 christos S_SET_THREAD_LOCAL (fixP->fx_addsy); 3053 1.1.1.5 christos break; 3054 1.1 skrll 3055 1.1.1.5 christos case BFD_RELOC_ARC_TLS_LE_S9: 3056 1.1.1.5 christos case BFD_RELOC_ARC_TLS_DTPOFF_S9: 3057 1.1.1.5 christos as_bad (_("TLS_*_S9 relocs are not supported yet")); 3058 1.1.1.5 christos break; 3059 1.1.1.3 christos 3060 1.1.1.5 christos default: 3061 1.1.1.5 christos break; 3062 1.1.1.5 christos } 3063 1.1.1.3 christos 3064 1.1.1.5 christos if (!fixP->fx_done) 3065 1.1.1.5 christos { 3066 1.1.1.5 christos return; 3067 1.1.1.5 christos } 3068 1.1.1.3 christos 3069 1.1.1.6 christos /* Adjust the value if we have a constant. */ 3070 1.1.1.5 christos value += fx_offset; 3071 1.1.1.3 christos 3072 1.1.1.5 christos /* For hosts with longs bigger than 32-bits make sure that the top 3073 1.1.1.5 christos bits of a 32-bit negative value read in by the parser are set, 3074 1.1.1.5 christos so that the correct comparisons are made. */ 3075 1.1.1.5 christos if (value & 0x80000000) 3076 1.1.1.5 christos value |= (-1UL << 31); 3077 1.1.1.3 christos 3078 1.1.1.5 christos reloc = fixP->fx_r_type; 3079 1.1.1.5 christos switch (reloc) 3080 1.1.1.3 christos { 3081 1.1.1.5 christos case BFD_RELOC_8: 3082 1.1.1.5 christos case BFD_RELOC_16: 3083 1.1.1.5 christos case BFD_RELOC_24: 3084 1.1.1.5 christos case BFD_RELOC_32: 3085 1.1.1.5 christos case BFD_RELOC_64: 3086 1.1.1.5 christos case BFD_RELOC_ARC_32_PCREL: 3087 1.1.1.5 christos md_number_to_chars (fixpos, value, fixP->fx_size); 3088 1.1.1.5 christos return; 3089 1.1.1.3 christos 3090 1.1.1.5 christos case BFD_RELOC_ARC_GOTPC32: 3091 1.1.1.5 christos /* I cannot fix an GOTPC relocation because I need to relax it 3092 1.1.1.5 christos from ld rx,[pcl,@sym@gotpc] to add rx,pcl,@sym@gotpc. */ 3093 1.1.1.5 christos as_bad (_("Unsupported operation on reloc")); 3094 1.1.1.5 christos return; 3095 1.1.1.3 christos 3096 1.1.1.5 christos case BFD_RELOC_ARC_TLS_DTPOFF: 3097 1.1.1.5 christos case BFD_RELOC_ARC_TLS_LE_32: 3098 1.1.1.5 christos gas_assert (!fixP->fx_addsy); 3099 1.1.1.5 christos gas_assert (!fixP->fx_subsy); 3100 1.1.1.6 christos /* Fall through. */ 3101 1.1.1.3 christos 3102 1.1.1.5 christos case BFD_RELOC_ARC_GOTOFF: 3103 1.1.1.5 christos case BFD_RELOC_ARC_32_ME: 3104 1.1.1.11 christos case BFD_RELOC_32_PCREL: 3105 1.1.1.5 christos md_number_to_chars_midend (fixpos, value, fixP->fx_size); 3106 1.1.1.5 christos return; 3107 1.1.1.3 christos 3108 1.1.1.11 christos case BFD_RELOC_32_PLT_PCREL: 3109 1.1.1.5 christos md_number_to_chars_midend (fixpos, value, fixP->fx_size); 3110 1.1.1.5 christos return; 3111 1.1.1.3 christos 3112 1.1.1.5 christos case BFD_RELOC_ARC_S25H_PCREL_PLT: 3113 1.1.1.5 christos reloc = BFD_RELOC_ARC_S25W_PCREL; 3114 1.1.1.5 christos goto solve_plt; 3115 1.1.1.3 christos 3116 1.1.1.5 christos case BFD_RELOC_ARC_S21H_PCREL_PLT: 3117 1.1.1.5 christos reloc = BFD_RELOC_ARC_S21H_PCREL; 3118 1.1.1.5 christos goto solve_plt; 3119 1.1.1.3 christos 3120 1.1.1.5 christos case BFD_RELOC_ARC_S25W_PCREL_PLT: 3121 1.1.1.5 christos reloc = BFD_RELOC_ARC_S25W_PCREL; 3122 1.1.1.5 christos goto solve_plt; 3123 1.1.1.3 christos 3124 1.1.1.5 christos case BFD_RELOC_ARC_S21W_PCREL_PLT: 3125 1.1.1.5 christos reloc = BFD_RELOC_ARC_S21W_PCREL; 3126 1.1.1.6 christos /* Fall through. */ 3127 1.1.1.3 christos 3128 1.1.1.5 christos case BFD_RELOC_ARC_S25W_PCREL: 3129 1.1.1.5 christos case BFD_RELOC_ARC_S21W_PCREL: 3130 1.1.1.5 christos case BFD_RELOC_ARC_S21H_PCREL: 3131 1.1.1.5 christos case BFD_RELOC_ARC_S25H_PCREL: 3132 1.1.1.5 christos case BFD_RELOC_ARC_S13_PCREL: 3133 1.1.1.5 christos solve_plt: 3134 1.1.1.5 christos operand = find_operand_for_reloc (reloc); 3135 1.1.1.5 christos gas_assert (operand); 3136 1.1.1.5 christos break; 3137 1.1.1.3 christos 3138 1.1.1.5 christos default: 3139 1.1.1.5 christos { 3140 1.1.1.5 christos if ((int) fixP->fx_r_type >= 0) 3141 1.1.1.5 christos as_fatal (_("unhandled relocation type %s"), 3142 1.1.1.5 christos bfd_get_reloc_code_name (fixP->fx_r_type)); 3143 1.1.1.3 christos 3144 1.1.1.5 christos /* The rest of these fixups needs to be completely resolved as 3145 1.1.1.5 christos constants. */ 3146 1.1.1.5 christos if (fixP->fx_addsy != 0 3147 1.1.1.5 christos && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section) 3148 1.1.1.5 christos as_bad_where (fixP->fx_file, fixP->fx_line, 3149 1.1.1.5 christos _("non-absolute expression in constant field")); 3150 1.1.1.5 christos 3151 1.1.1.5 christos gas_assert (-(int) fixP->fx_r_type < (int) arc_num_operands); 3152 1.1.1.5 christos operand = &arc_operands[-(int) fixP->fx_r_type]; 3153 1.1.1.5 christos break; 3154 1.1.1.5 christos } 3155 1.1.1.3 christos } 3156 1.1.1.3 christos 3157 1.1.1.5 christos if (target_big_endian) 3158 1.1.1.5 christos { 3159 1.1.1.5 christos switch (fixP->fx_size) 3160 1.1.1.5 christos { 3161 1.1.1.5 christos case 4: 3162 1.1.1.5 christos insn = bfd_getb32 (fixpos); 3163 1.1.1.5 christos break; 3164 1.1.1.5 christos case 2: 3165 1.1.1.5 christos insn = bfd_getb16 (fixpos); 3166 1.1.1.5 christos break; 3167 1.1.1.5 christos default: 3168 1.1.1.5 christos as_bad_where (fixP->fx_file, fixP->fx_line, 3169 1.1.1.5 christos _("unknown fixup size")); 3170 1.1.1.5 christos } 3171 1.1.1.5 christos } 3172 1.1.1.5 christos else 3173 1.1.1.5 christos { 3174 1.1.1.5 christos insn = 0; 3175 1.1.1.5 christos switch (fixP->fx_size) 3176 1.1.1.5 christos { 3177 1.1.1.5 christos case 4: 3178 1.1.1.5 christos insn = bfd_getl16 (fixpos) << 16 | bfd_getl16 (fixpos + 2); 3179 1.1.1.5 christos break; 3180 1.1.1.5 christos case 2: 3181 1.1.1.5 christos insn = bfd_getl16 (fixpos); 3182 1.1.1.5 christos break; 3183 1.1.1.5 christos default: 3184 1.1.1.5 christos as_bad_where (fixP->fx_file, fixP->fx_line, 3185 1.1.1.5 christos _("unknown fixup size")); 3186 1.1.1.5 christos } 3187 1.1.1.5 christos } 3188 1.1.1.3 christos 3189 1.1.1.5 christos insn = insert_operand (insn, operand, (offsetT) value, 3190 1.1.1.5 christos fixP->fx_file, fixP->fx_line); 3191 1.1.1.3 christos 3192 1.1.1.5 christos md_number_to_chars_midend (fixpos, insn, fixP->fx_size); 3193 1.1.1.5 christos } 3194 1.1.1.3 christos 3195 1.1.1.5 christos /* Prepare machine-dependent frags for relaxation. 3196 1.1.1.3 christos 3197 1.1.1.5 christos Called just before relaxation starts. Any symbol that is now undefined 3198 1.1.1.5 christos will not become defined. 3199 1.1.1.3 christos 3200 1.1.1.5 christos Return the correct fr_subtype in the frag. 3201 1.1.1.3 christos 3202 1.1.1.5 christos Return the initial "guess for fr_var" to caller. The guess for fr_var 3203 1.1.1.5 christos is *actually* the growth beyond fr_fix. Whatever we do to grow fr_fix 3204 1.1.1.5 christos or fr_var contributes to our returned value. 3205 1.1.1.3 christos 3206 1.1.1.5 christos Although it may not be explicit in the frag, pretend 3207 1.1.1.5 christos fr_var starts with a value. */ 3208 1.1.1.3 christos 3209 1.1.1.5 christos int 3210 1.1.1.5 christos md_estimate_size_before_relax (fragS *fragP, 3211 1.1.1.5 christos segT segment) 3212 1.1.1.3 christos { 3213 1.1.1.5 christos int growth; 3214 1.1.1.5 christos 3215 1.1.1.5 christos /* If the symbol is not located within the same section AND it's not 3216 1.1.1.5 christos an absolute section, use the maximum. OR if the symbol is a 3217 1.1.1.5 christos constant AND the insn is by nature not pc-rel, use the maximum. 3218 1.1.1.5 christos OR if the symbol is being equated against another symbol, use the 3219 1.1.1.5 christos maximum. OR if the symbol is weak use the maximum. */ 3220 1.1.1.5 christos if ((S_GET_SEGMENT (fragP->fr_symbol) != segment 3221 1.1.1.5 christos && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section) 3222 1.1.1.5 christos || (symbol_constant_p (fragP->fr_symbol) 3223 1.1.1.5 christos && !fragP->tc_frag_data.pcrel) 3224 1.1.1.5 christos || symbol_equated_p (fragP->fr_symbol) 3225 1.1.1.5 christos || S_IS_WEAK (fragP->fr_symbol)) 3226 1.1.1.5 christos { 3227 1.1.1.5 christos while (md_relax_table[fragP->fr_subtype].rlx_more != ARC_RLX_NONE) 3228 1.1.1.5 christos ++fragP->fr_subtype; 3229 1.1.1.5 christos } 3230 1.1.1.3 christos 3231 1.1.1.5 christos growth = md_relax_table[fragP->fr_subtype].rlx_length; 3232 1.1.1.5 christos fragP->fr_var = growth; 3233 1.1.1.3 christos 3234 1.1.1.5 christos pr_debug ("%s:%d: md_estimate_size_before_relax: %d\n", 3235 1.1.1.5 christos fragP->fr_file, fragP->fr_line, growth); 3236 1.1.1.3 christos 3237 1.1.1.5 christos return growth; 3238 1.1.1.3 christos } 3239 1.1.1.3 christos 3240 1.1.1.5 christos /* Translate internal representation of relocation info to BFD target 3241 1.1.1.5 christos format. */ 3242 1.1.1.3 christos 3243 1.1.1.5 christos arelent * 3244 1.1.1.5 christos tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, 3245 1.1.1.5 christos fixS *fixP) 3246 1.1.1.3 christos { 3247 1.1.1.5 christos arelent *reloc; 3248 1.1.1.5 christos bfd_reloc_code_real_type code; 3249 1.1.1.3 christos 3250 1.1.1.10 christos reloc = notes_alloc (sizeof (arelent)); 3251 1.1.1.10 christos reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *)); 3252 1.1.1.5 christos *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy); 3253 1.1.1.5 christos reloc->address = fixP->fx_frag->fr_address + fixP->fx_where; 3254 1.1.1.3 christos 3255 1.1.1.5 christos /* Make sure none of our internal relocations make it this far. 3256 1.1.1.5 christos They'd better have been fully resolved by this point. */ 3257 1.1.1.5 christos gas_assert ((int) fixP->fx_r_type > 0); 3258 1.1.1.3 christos 3259 1.1.1.5 christos code = fixP->fx_r_type; 3260 1.1.1.3 christos 3261 1.1.1.5 christos /* if we have something like add gp, pcl, 3262 1.1.1.5 christos _GLOBAL_OFFSET_TABLE_@gotpc. */ 3263 1.1.1.5 christos if (code == BFD_RELOC_ARC_GOTPC32 3264 1.1.1.5 christos && GOT_symbol 3265 1.1.1.5 christos && fixP->fx_addsy == GOT_symbol) 3266 1.1.1.5 christos code = BFD_RELOC_ARC_GOTPC; 3267 1.1.1.3 christos 3268 1.1.1.5 christos reloc->howto = bfd_reloc_type_lookup (stdoutput, code); 3269 1.1.1.5 christos if (reloc->howto == NULL) 3270 1.1.1.5 christos { 3271 1.1.1.5 christos as_bad_where (fixP->fx_file, fixP->fx_line, 3272 1.1.1.5 christos _("cannot represent `%s' relocation in object file"), 3273 1.1.1.5 christos bfd_get_reloc_code_name (code)); 3274 1.1.1.5 christos return NULL; 3275 1.1.1.5 christos } 3276 1.1.1.3 christos 3277 1.1.1.5 christos if (!fixP->fx_pcrel != !reloc->howto->pc_relative) 3278 1.1.1.5 christos as_fatal (_("internal error? cannot generate `%s' relocation"), 3279 1.1.1.5 christos bfd_get_reloc_code_name (code)); 3280 1.1.1.5 christos 3281 1.1.1.5 christos gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative); 3282 1.1.1.5 christos 3283 1.1.1.6 christos reloc->addend = fixP->fx_offset; 3284 1.1.1.5 christos 3285 1.1.1.5 christos return reloc; 3286 1.1.1.3 christos } 3287 1.1.1.3 christos 3288 1.1.1.5 christos /* Perform post-processing of machine-dependent frags after relaxation. 3289 1.1.1.5 christos Called after relaxation is finished. 3290 1.1.1.5 christos In: Address of frag. 3291 1.1.1.5 christos fr_type == rs_machine_dependent. 3292 1.1.1.5 christos fr_subtype is what the address relaxed to. 3293 1.1.1.3 christos 3294 1.1.1.5 christos Out: Any fixS:s and constants are set up. */ 3295 1.1.1.5 christos 3296 1.1.1.5 christos void 3297 1.1.1.5 christos md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, 3298 1.1.1.5 christos segT segment ATTRIBUTE_UNUSED, 3299 1.1.1.5 christos fragS *fragP) 3300 1.1.1.3 christos { 3301 1.1.1.5 christos const relax_typeS *table_entry; 3302 1.1.1.5 christos char *dest; 3303 1.1.1.5 christos const struct arc_opcode *opcode; 3304 1.1.1.5 christos struct arc_insn insn; 3305 1.1.1.5 christos int size, fix; 3306 1.1.1.5 christos struct arc_relax_type *relax_arg = &fragP->tc_frag_data; 3307 1.1.1.5 christos 3308 1.1.1.7 christos fix = fragP->fr_fix; 3309 1.1.1.5 christos dest = fragP->fr_literal + fix; 3310 1.1.1.5 christos table_entry = TC_GENERIC_RELAX_TABLE + fragP->fr_subtype; 3311 1.1.1.3 christos 3312 1.1.1.5 christos pr_debug ("%s:%d: md_convert_frag, subtype: %d, fix: %d, " 3313 1.1.1.9 christos "var: %" PRId64 "\n", 3314 1.1.1.5 christos fragP->fr_file, fragP->fr_line, 3315 1.1.1.9 christos fragP->fr_subtype, fix, (int64_t) fragP->fr_var); 3316 1.1.1.3 christos 3317 1.1.1.5 christos if (fragP->fr_subtype <= 0 3318 1.1.1.5 christos && fragP->fr_subtype >= arc_num_relax_opcodes) 3319 1.1.1.5 christos as_fatal (_("no relaxation found for this instruction.")); 3320 1.1.1.3 christos 3321 1.1.1.5 christos opcode = &arc_relax_opcodes[fragP->fr_subtype]; 3322 1.1.1.3 christos 3323 1.1.1.5 christos assemble_insn (opcode, relax_arg->tok, relax_arg->ntok, relax_arg->pflags, 3324 1.1.1.5 christos relax_arg->nflg, &insn); 3325 1.1.1.3 christos 3326 1.1.1.5 christos apply_fixups (&insn, fragP, fix); 3327 1.1.1.3 christos 3328 1.1.1.6 christos size = insn.len + (insn.has_limm ? 4 : 0); 3329 1.1.1.5 christos gas_assert (table_entry->rlx_length == size); 3330 1.1.1.8 christos emit_insn0 (&insn, dest, true); 3331 1.1.1.3 christos 3332 1.1.1.5 christos fragP->fr_fix += table_entry->rlx_length; 3333 1.1.1.5 christos fragP->fr_var = 0; 3334 1.1.1.5 christos } 3335 1.1.1.5 christos 3336 1.1.1.5 christos /* We have no need to default values of symbols. We could catch 3337 1.1.1.5 christos register names here, but that is handled by inserting them all in 3338 1.1.1.5 christos the symbol table to begin with. */ 3339 1.1.1.5 christos 3340 1.1.1.5 christos symbolS * 3341 1.1.1.5 christos md_undefined_symbol (char *name) 3342 1.1.1.5 christos { 3343 1.1.1.5 christos /* The arc abi demands that a GOT[0] should be referencible as 3344 1.1.1.5 christos [pc+_DYNAMIC@gotpc]. Hence we convert a _DYNAMIC@gotpc to a 3345 1.1.1.5 christos GOTPC reference to _GLOBAL_OFFSET_TABLE_. */ 3346 1.1.1.5 christos if (((*name == '_') 3347 1.1.1.5 christos && (*(name+1) == 'G') 3348 1.1.1.6 christos && (strcmp (name, GLOBAL_OFFSET_TABLE_NAME) == 0))) 3349 1.1.1.5 christos { 3350 1.1.1.5 christos if (!GOT_symbol) 3351 1.1.1.3 christos { 3352 1.1.1.5 christos if (symbol_find (name)) 3353 1.1.1.5 christos as_bad ("GOT already in symbol table"); 3354 1.1.1.3 christos 3355 1.1.1.5 christos GOT_symbol = symbol_new (GLOBAL_OFFSET_TABLE_NAME, undefined_section, 3356 1.1.1.8 christos &zero_address_frag, 0); 3357 1.1.1.5 christos }; 3358 1.1.1.5 christos return GOT_symbol; 3359 1.1.1.5 christos } 3360 1.1.1.5 christos return NULL; 3361 1.1.1.5 christos } 3362 1.1.1.3 christos 3363 1.1.1.5 christos /* Turn a string in input_line_pointer into a floating point constant 3364 1.1.1.5 christos of type type, and store the appropriate bytes in *litP. The number 3365 1.1.1.5 christos of LITTLENUMS emitted is stored in *sizeP. An error message is 3366 1.1.1.5 christos returned, or NULL on OK. */ 3367 1.1.1.3 christos 3368 1.1.1.5 christos const char * 3369 1.1.1.5 christos md_atof (int type, char *litP, int *sizeP) 3370 1.1.1.5 christos { 3371 1.1.1.5 christos return ieee_md_atof (type, litP, sizeP, target_big_endian); 3372 1.1.1.5 christos } 3373 1.1.1.3 christos 3374 1.1.1.5 christos /* Called for any expression that can not be recognized. When the 3375 1.1.1.5 christos function is called, `input_line_pointer' will point to the start of 3376 1.1.1.7 christos the expression. We use it when we have complex operations like 3377 1.1.1.7 christos @label1 - @label2. */ 3378 1.1.1.3 christos 3379 1.1.1.5 christos void 3380 1.1.1.7 christos md_operand (expressionS *expressionP) 3381 1.1.1.5 christos { 3382 1.1.1.5 christos char *p = input_line_pointer; 3383 1.1.1.5 christos if (*p == '@') 3384 1.1.1.5 christos { 3385 1.1.1.5 christos input_line_pointer++; 3386 1.1.1.5 christos expression (expressionP); 3387 1.1.1.11 christos expressionP->X_md = O_absent; 3388 1.1.1.5 christos } 3389 1.1.1.5 christos } 3390 1.1.1.3 christos 3391 1.1.1.5 christos /* This function is called from the function 'expression', it attempts 3392 1.1.1.5 christos to parse special names (in our case register names). It fills in 3393 1.1.1.5 christos the expression with the identified register. It returns TRUE if 3394 1.1.1.5 christos it is a register and FALSE otherwise. */ 3395 1.1.1.5 christos 3396 1.1.1.8 christos bool 3397 1.1.1.5 christos arc_parse_name (const char *name, 3398 1.1.1.5 christos struct expressionS *e) 3399 1.1.1.5 christos { 3400 1.1.1.5 christos struct symbol *sym; 3401 1.1.1.5 christos 3402 1.1.1.5 christos if (!assembling_insn) 3403 1.1.1.8 christos return false; 3404 1.1.1.3 christos 3405 1.1.1.8 christos sym = str_hash_find (arc_reg_hash, name); 3406 1.1.1.5 christos if (sym) 3407 1.1.1.5 christos { 3408 1.1.1.5 christos e->X_op = O_register; 3409 1.1.1.5 christos e->X_add_number = S_GET_VALUE (sym); 3410 1.1.1.8 christos return true; 3411 1.1.1.5 christos } 3412 1.1.1.6 christos 3413 1.1.1.8 christos sym = str_hash_find (arc_addrtype_hash, name); 3414 1.1.1.6 christos if (sym) 3415 1.1.1.6 christos { 3416 1.1.1.6 christos e->X_op = O_addrtype; 3417 1.1.1.6 christos e->X_add_number = S_GET_VALUE (sym); 3418 1.1.1.8 christos return true; 3419 1.1.1.6 christos } 3420 1.1.1.6 christos 3421 1.1.1.8 christos return false; 3422 1.1.1.5 christos } 3423 1.1.1.3 christos 3424 1.1.1.5 christos /* md_parse_option 3425 1.1.1.5 christos Invocation line includes a switch not recognized by the base assembler. 3426 1.1.1.5 christos See if it's a processor-specific option. 3427 1.1.1.3 christos 3428 1.1.1.5 christos New options (supported) are: 3429 1.1.1.3 christos 3430 1.1.1.5 christos -mcpu=<cpu name> Assemble for selected processor 3431 1.1.1.5 christos -EB/-mbig-endian Big-endian 3432 1.1.1.5 christos -EL/-mlittle-endian Little-endian 3433 1.1.1.5 christos -mrelax Enable relaxation 3434 1.1.1.3 christos 3435 1.1.1.5 christos The following CPU names are recognized: 3436 1.1.1.5 christos arc600, arc700, arcem, archs, nps400. */ 3437 1.1.1.3 christos 3438 1.1.1.5 christos int 3439 1.1.1.5 christos md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED) 3440 1.1.1.5 christos { 3441 1.1.1.5 christos switch (c) 3442 1.1.1.5 christos { 3443 1.1.1.5 christos case OPTION_ARC600: 3444 1.1.1.5 christos case OPTION_ARC601: 3445 1.1.1.5 christos return md_parse_option (OPTION_MCPU, "arc600"); 3446 1.1.1.3 christos 3447 1.1.1.5 christos case OPTION_ARC700: 3448 1.1.1.5 christos return md_parse_option (OPTION_MCPU, "arc700"); 3449 1.1.1.3 christos 3450 1.1.1.5 christos case OPTION_ARCEM: 3451 1.1.1.5 christos return md_parse_option (OPTION_MCPU, "arcem"); 3452 1.1.1.3 christos 3453 1.1.1.5 christos case OPTION_ARCHS: 3454 1.1.1.5 christos return md_parse_option (OPTION_MCPU, "archs"); 3455 1.1.1.3 christos 3456 1.1.1.5 christos case OPTION_MCPU: 3457 1.1.1.5 christos { 3458 1.1.1.6 christos arc_select_cpu (arg, MACH_SELECTION_FROM_COMMAND_LINE); 3459 1.1.1.5 christos break; 3460 1.1.1.5 christos } 3461 1.1.1.3 christos 3462 1.1.1.5 christos case OPTION_EB: 3463 1.1.1.5 christos arc_target_format = "elf32-bigarc"; 3464 1.1.1.5 christos byte_order = BIG_ENDIAN; 3465 1.1.1.5 christos break; 3466 1.1.1.3 christos 3467 1.1.1.5 christos case OPTION_EL: 3468 1.1.1.5 christos arc_target_format = "elf32-littlearc"; 3469 1.1.1.5 christos byte_order = LITTLE_ENDIAN; 3470 1.1.1.5 christos break; 3471 1.1.1.3 christos 3472 1.1.1.5 christos case OPTION_CD: 3473 1.1.1.6 christos selected_cpu.features |= CD; 3474 1.1.1.6 christos cl_features |= CD; 3475 1.1.1.6 christos arc_check_feature (); 3476 1.1.1.5 christos break; 3477 1.1.1.3 christos 3478 1.1.1.5 christos case OPTION_RELAX: 3479 1.1.1.5 christos relaxation_state = 1; 3480 1.1.1.5 christos break; 3481 1.1.1.3 christos 3482 1.1.1.5 christos case OPTION_NPS400: 3483 1.1.1.6 christos selected_cpu.features |= NPS400; 3484 1.1.1.6 christos cl_features |= NPS400; 3485 1.1.1.6 christos arc_check_feature (); 3486 1.1.1.5 christos break; 3487 1.1.1.3 christos 3488 1.1.1.5 christos case OPTION_SPFP: 3489 1.1.1.6 christos selected_cpu.features |= SPX; 3490 1.1.1.6 christos cl_features |= SPX; 3491 1.1.1.6 christos arc_check_feature (); 3492 1.1.1.5 christos break; 3493 1.1.1.3 christos 3494 1.1.1.5 christos case OPTION_DPFP: 3495 1.1.1.6 christos selected_cpu.features |= DPX; 3496 1.1.1.6 christos cl_features |= DPX; 3497 1.1.1.6 christos arc_check_feature (); 3498 1.1.1.5 christos break; 3499 1.1.1.3 christos 3500 1.1.1.5 christos case OPTION_FPUDA: 3501 1.1.1.6 christos selected_cpu.features |= DPA; 3502 1.1.1.6 christos cl_features |= DPA; 3503 1.1.1.6 christos arc_check_feature (); 3504 1.1.1.5 christos break; 3505 1.1.1.3 christos 3506 1.1.1.5 christos /* Dummy options are accepted but have no effect. */ 3507 1.1.1.5 christos case OPTION_USER_MODE: 3508 1.1.1.5 christos case OPTION_LD_EXT_MASK: 3509 1.1.1.5 christos case OPTION_SWAP: 3510 1.1.1.5 christos case OPTION_NORM: 3511 1.1.1.5 christos case OPTION_BARREL_SHIFT: 3512 1.1.1.5 christos case OPTION_MIN_MAX: 3513 1.1.1.5 christos case OPTION_NO_MPY: 3514 1.1.1.5 christos case OPTION_EA: 3515 1.1.1.5 christos case OPTION_MUL64: 3516 1.1.1.5 christos case OPTION_SIMD: 3517 1.1.1.5 christos case OPTION_XMAC_D16: 3518 1.1.1.5 christos case OPTION_XMAC_24: 3519 1.1.1.5 christos case OPTION_DSP_PACKA: 3520 1.1.1.5 christos case OPTION_CRC: 3521 1.1.1.5 christos case OPTION_DVBF: 3522 1.1.1.5 christos case OPTION_TELEPHONY: 3523 1.1.1.5 christos case OPTION_XYMEMORY: 3524 1.1.1.5 christos case OPTION_LOCK: 3525 1.1.1.5 christos case OPTION_SWAPE: 3526 1.1.1.5 christos case OPTION_RTSC: 3527 1.1.1.5 christos break; 3528 1.1.1.3 christos 3529 1.1.1.5 christos default: 3530 1.1.1.5 christos return 0; 3531 1.1.1.3 christos } 3532 1.1.1.3 christos 3533 1.1.1.5 christos return 1; 3534 1.1.1.5 christos } 3535 1.1.1.5 christos 3536 1.1.1.6 christos /* Display the list of cpu names for use in the help text. */ 3537 1.1.1.6 christos 3538 1.1.1.6 christos static void 3539 1.1.1.6 christos arc_show_cpu_list (FILE *stream) 3540 1.1.1.6 christos { 3541 1.1.1.6 christos int i, offset; 3542 1.1.1.6 christos static const char *space_buf = " "; 3543 1.1.1.6 christos 3544 1.1.1.6 christos fprintf (stream, "%s", space_buf); 3545 1.1.1.6 christos offset = strlen (space_buf); 3546 1.1.1.6 christos for (i = 0; cpu_types[i].name != NULL; ++i) 3547 1.1.1.6 christos { 3548 1.1.1.8 christos bool last = (cpu_types[i + 1].name == NULL); 3549 1.1.1.6 christos 3550 1.1.1.6 christos /* If displaying the new cpu name string, and the ', ' (for all 3551 1.1.1.6 christos but the last one) will take us past a target width of 80 3552 1.1.1.6 christos characters, then it's time for a new line. */ 3553 1.1.1.6 christos if (offset + strlen (cpu_types[i].name) + (last ? 0 : 2) > 80) 3554 1.1.1.6 christos { 3555 1.1.1.6 christos fprintf (stream, "\n%s", space_buf); 3556 1.1.1.6 christos offset = strlen (space_buf); 3557 1.1.1.6 christos } 3558 1.1.1.6 christos 3559 1.1.1.6 christos fprintf (stream, "%s%s", cpu_types[i].name, (last ? "\n" : ", ")); 3560 1.1.1.6 christos offset += strlen (cpu_types [i].name) + (last ? 0 : 2); 3561 1.1.1.6 christos } 3562 1.1.1.6 christos } 3563 1.1.1.6 christos 3564 1.1.1.5 christos void 3565 1.1.1.5 christos md_show_usage (FILE *stream) 3566 1.1.1.5 christos { 3567 1.1.1.5 christos fprintf (stream, _("ARC-specific assembler options:\n")); 3568 1.1.1.5 christos 3569 1.1.1.6 christos fprintf (stream, " -mcpu=<cpu name>\t (default: %s), assemble for" 3570 1.1.1.6 christos " CPU <cpu name>, one of:\n", TARGET_WITH_CPU); 3571 1.1.1.6 christos arc_show_cpu_list (stream); 3572 1.1.1.6 christos fprintf (stream, "\n"); 3573 1.1.1.5 christos fprintf (stream, " -mA6/-mARC600/-mARC601 same as -mcpu=arc600\n"); 3574 1.1.1.5 christos fprintf (stream, " -mA7/-mARC700\t\t same as -mcpu=arc700\n"); 3575 1.1.1.5 christos fprintf (stream, " -mEM\t\t\t same as -mcpu=arcem\n"); 3576 1.1.1.5 christos fprintf (stream, " -mHS\t\t\t same as -mcpu=archs\n"); 3577 1.1.1.5 christos 3578 1.1.1.5 christos fprintf (stream, " -mnps400\t\t enable NPS-400 extended instructions\n"); 3579 1.1.1.6 christos fprintf (stream, " -mspfp\t\t enable single-precision floating point" 3580 1.1.1.6 christos " instructions\n"); 3581 1.1.1.6 christos fprintf (stream, " -mdpfp\t\t enable double-precision floating point" 3582 1.1.1.6 christos " instructions\n"); 3583 1.1.1.5 christos fprintf (stream, " -mfpuda\t\t enable double-precision assist floating " 3584 1.1.1.5 christos "point\n\t\t\t instructions for ARC EM\n"); 3585 1.1.1.5 christos 3586 1.1.1.5 christos fprintf (stream, 3587 1.1.1.5 christos " -mcode-density\t enable code density option for ARC EM\n"); 3588 1.1.1.5 christos 3589 1.1.1.5 christos fprintf (stream, _("\ 3590 1.1.1.5 christos -EB assemble code for a big-endian cpu\n")); 3591 1.1.1.5 christos fprintf (stream, _("\ 3592 1.1.1.5 christos -EL assemble code for a little-endian cpu\n")); 3593 1.1.1.5 christos fprintf (stream, _("\ 3594 1.1.1.5 christos -mrelax enable relaxation\n")); 3595 1.1.1.5 christos 3596 1.1.1.5 christos fprintf (stream, _("The following ARC-specific assembler options are " 3597 1.1.1.5 christos "deprecated and are accepted\nfor compatibility only:\n")); 3598 1.1.1.3 christos 3599 1.1.1.5 christos fprintf (stream, _(" -mEA\n" 3600 1.1.1.5 christos " -mbarrel-shifter\n" 3601 1.1.1.5 christos " -mbarrel_shifter\n" 3602 1.1.1.5 christos " -mcrc\n" 3603 1.1.1.5 christos " -mdsp-packa\n" 3604 1.1.1.5 christos " -mdsp_packa\n" 3605 1.1.1.5 christos " -mdvbf\n" 3606 1.1.1.5 christos " -mld-extension-reg-mask\n" 3607 1.1.1.5 christos " -mlock\n" 3608 1.1.1.5 christos " -mmac-24\n" 3609 1.1.1.5 christos " -mmac-d16\n" 3610 1.1.1.5 christos " -mmac_24\n" 3611 1.1.1.5 christos " -mmac_d16\n" 3612 1.1.1.5 christos " -mmin-max\n" 3613 1.1.1.5 christos " -mmin_max\n" 3614 1.1.1.5 christos " -mmul64\n" 3615 1.1.1.5 christos " -mno-mpy\n" 3616 1.1.1.5 christos " -mnorm\n" 3617 1.1.1.5 christos " -mrtsc\n" 3618 1.1.1.5 christos " -msimd\n" 3619 1.1.1.5 christos " -mswap\n" 3620 1.1.1.5 christos " -mswape\n" 3621 1.1.1.5 christos " -mtelephony\n" 3622 1.1.1.5 christos " -muser-mode-only\n" 3623 1.1.1.5 christos " -mxy\n")); 3624 1.1.1.3 christos } 3625 1.1.1.3 christos 3626 1.1.1.3 christos /* Find the proper relocation for the given opcode. */ 3627 1.1.1.3 christos 3628 1.1.1.3 christos static extended_bfd_reloc_code_real_type 3629 1.1.1.3 christos find_reloc (const char *name, 3630 1.1.1.3 christos const char *opcodename, 3631 1.1.1.3 christos const struct arc_flags *pflags, 3632 1.1.1.3 christos int nflg, 3633 1.1.1.3 christos extended_bfd_reloc_code_real_type reloc) 3634 1.1.1.3 christos { 3635 1.1.1.3 christos unsigned int i; 3636 1.1.1.3 christos int j; 3637 1.1.1.8 christos bool found_flag, tmp; 3638 1.1.1.3 christos extended_bfd_reloc_code_real_type ret = BFD_RELOC_UNUSED; 3639 1.1.1.3 christos 3640 1.1.1.3 christos for (i = 0; i < arc_num_equiv_tab; i++) 3641 1.1.1.3 christos { 3642 1.1.1.3 christos const struct arc_reloc_equiv_tab *r = &arc_reloc_equiv[i]; 3643 1.1.1.3 christos 3644 1.1.1.3 christos /* Find the entry. */ 3645 1.1.1.3 christos if (strcmp (name, r->name)) 3646 1.1.1.3 christos continue; 3647 1.1.1.3 christos if (r->mnemonic && (strcmp (r->mnemonic, opcodename))) 3648 1.1.1.3 christos continue; 3649 1.1.1.5 christos if (r->flags[0]) 3650 1.1.1.3 christos { 3651 1.1.1.3 christos if (!nflg) 3652 1.1.1.3 christos continue; 3653 1.1.1.8 christos found_flag = false; 3654 1.1.1.10 christos const unsigned *psflg = r->flags; 3655 1.1.1.5 christos do 3656 1.1.1.5 christos { 3657 1.1.1.8 christos tmp = false; 3658 1.1.1.5 christos for (j = 0; j < nflg; j++) 3659 1.1.1.5 christos if (!strcmp (pflags[j].name, 3660 1.1.1.5 christos arc_flag_operands[*psflg].name)) 3661 1.1.1.5 christos { 3662 1.1.1.8 christos tmp = true; 3663 1.1.1.5 christos break; 3664 1.1.1.5 christos } 3665 1.1.1.5 christos if (!tmp) 3666 1.1.1.5 christos { 3667 1.1.1.8 christos found_flag = false; 3668 1.1.1.5 christos break; 3669 1.1.1.5 christos } 3670 1.1.1.5 christos else 3671 1.1.1.5 christos { 3672 1.1.1.8 christos found_flag = true; 3673 1.1.1.5 christos } 3674 1.1.1.5 christos ++ psflg; 3675 1.1.1.5 christos } while (*psflg); 3676 1.1.1.5 christos 3677 1.1.1.3 christos if (!found_flag) 3678 1.1.1.3 christos continue; 3679 1.1.1.3 christos } 3680 1.1.1.3 christos 3681 1.1.1.3 christos if (reloc != r->oldreloc) 3682 1.1.1.3 christos continue; 3683 1.1.1.3 christos /* Found it. */ 3684 1.1.1.3 christos ret = r->newreloc; 3685 1.1.1.3 christos break; 3686 1.1.1.3 christos } 3687 1.1.1.3 christos 3688 1.1.1.3 christos if (ret == BFD_RELOC_UNUSED) 3689 1.1.1.3 christos as_bad (_("Unable to find %s relocation for instruction %s"), 3690 1.1.1.3 christos name, opcodename); 3691 1.1.1.3 christos return ret; 3692 1.1.1.3 christos } 3693 1.1.1.3 christos 3694 1.1.1.5 christos /* All the symbol types that are allowed to be used for 3695 1.1.1.5 christos relaxation. */ 3696 1.1.1.5 christos 3697 1.1.1.8 christos static bool 3698 1.1.1.5 christos may_relax_expr (expressionS tok) 3699 1.1.1.5 christos { 3700 1.1.1.5 christos /* Check if we have unrelaxable relocs. */ 3701 1.1.1.5 christos switch (tok.X_md) 3702 1.1.1.5 christos { 3703 1.1.1.5 christos default: 3704 1.1.1.5 christos break; 3705 1.1.1.5 christos case O_plt: 3706 1.1.1.8 christos return false; 3707 1.1.1.5 christos } 3708 1.1.1.5 christos 3709 1.1.1.5 christos switch (tok.X_op) 3710 1.1.1.5 christos { 3711 1.1.1.5 christos case O_symbol: 3712 1.1.1.5 christos case O_multiply: 3713 1.1.1.5 christos case O_divide: 3714 1.1.1.5 christos case O_modulus: 3715 1.1.1.5 christos case O_add: 3716 1.1.1.5 christos case O_subtract: 3717 1.1.1.5 christos break; 3718 1.1.1.5 christos 3719 1.1.1.5 christos default: 3720 1.1.1.8 christos return false; 3721 1.1.1.5 christos } 3722 1.1.1.8 christos return true; 3723 1.1.1.5 christos } 3724 1.1.1.5 christos 3725 1.1.1.5 christos /* Checks if flags are in line with relaxable insn. */ 3726 1.1.1.5 christos 3727 1.1.1.8 christos static bool 3728 1.1.1.5 christos relaxable_flag (const struct arc_relaxable_ins *ins, 3729 1.1.1.5 christos const struct arc_flags *pflags, 3730 1.1.1.5 christos int nflgs) 3731 1.1.1.5 christos { 3732 1.1.1.5 christos unsigned flag_class, 3733 1.1.1.5 christos flag, 3734 1.1.1.5 christos flag_class_idx = 0, 3735 1.1.1.5 christos flag_idx = 0; 3736 1.1.1.5 christos 3737 1.1.1.5 christos const struct arc_flag_operand *flag_opand; 3738 1.1.1.5 christos int i, counttrue = 0; 3739 1.1.1.5 christos 3740 1.1.1.5 christos /* Iterate through flags classes. */ 3741 1.1.1.5 christos while ((flag_class = ins->flag_classes[flag_class_idx]) != 0) 3742 1.1.1.5 christos { 3743 1.1.1.5 christos /* Iterate through flags in flag class. */ 3744 1.1.1.5 christos while ((flag = arc_flag_classes[flag_class].flags[flag_idx]) 3745 1.1.1.5 christos != 0) 3746 1.1.1.5 christos { 3747 1.1.1.5 christos flag_opand = &arc_flag_operands[flag]; 3748 1.1.1.5 christos /* Iterate through flags in ins to compare. */ 3749 1.1.1.5 christos for (i = 0; i < nflgs; ++i) 3750 1.1.1.5 christos { 3751 1.1.1.5 christos if (strcmp (flag_opand->name, pflags[i].name) == 0) 3752 1.1.1.5 christos ++counttrue; 3753 1.1.1.5 christos } 3754 1.1.1.5 christos 3755 1.1.1.5 christos ++flag_idx; 3756 1.1.1.5 christos } 3757 1.1.1.5 christos 3758 1.1.1.5 christos ++flag_class_idx; 3759 1.1.1.5 christos flag_idx = 0; 3760 1.1.1.5 christos } 3761 1.1.1.5 christos 3762 1.1.1.5 christos /* If counttrue == nflgs, then all flags have been found. */ 3763 1.1.1.8 christos return counttrue == nflgs; 3764 1.1.1.5 christos } 3765 1.1.1.5 christos 3766 1.1.1.5 christos /* Checks if operands are in line with relaxable insn. */ 3767 1.1.1.5 christos 3768 1.1.1.8 christos static bool 3769 1.1.1.5 christos relaxable_operand (const struct arc_relaxable_ins *ins, 3770 1.1.1.5 christos const expressionS *tok, 3771 1.1.1.5 christos int ntok) 3772 1.1.1.5 christos { 3773 1.1.1.5 christos const enum rlx_operand_type *operand = &ins->operands[0]; 3774 1.1.1.5 christos int i = 0; 3775 1.1.1.5 christos 3776 1.1.1.5 christos while (*operand != EMPTY) 3777 1.1.1.5 christos { 3778 1.1.1.5 christos const expressionS *epr = &tok[i]; 3779 1.1.1.5 christos 3780 1.1.1.5 christos if (i != 0 && i >= ntok) 3781 1.1.1.8 christos return false; 3782 1.1.1.5 christos 3783 1.1.1.5 christos switch (*operand) 3784 1.1.1.5 christos { 3785 1.1.1.5 christos case IMMEDIATE: 3786 1.1.1.5 christos if (!(epr->X_op == O_multiply 3787 1.1.1.5 christos || epr->X_op == O_divide 3788 1.1.1.5 christos || epr->X_op == O_modulus 3789 1.1.1.5 christos || epr->X_op == O_add 3790 1.1.1.5 christos || epr->X_op == O_subtract 3791 1.1.1.5 christos || epr->X_op == O_symbol)) 3792 1.1.1.8 christos return false; 3793 1.1.1.5 christos break; 3794 1.1.1.5 christos 3795 1.1.1.5 christos case REGISTER_DUP: 3796 1.1.1.5 christos if ((i <= 0) 3797 1.1.1.5 christos || (epr->X_add_number != tok[i - 1].X_add_number)) 3798 1.1.1.8 christos return false; 3799 1.1.1.5 christos /* Fall through. */ 3800 1.1.1.5 christos case REGISTER: 3801 1.1.1.5 christos if (epr->X_op != O_register) 3802 1.1.1.8 christos return false; 3803 1.1.1.5 christos break; 3804 1.1.1.5 christos 3805 1.1.1.5 christos case REGISTER_S: 3806 1.1.1.5 christos if (epr->X_op != O_register) 3807 1.1.1.8 christos return false; 3808 1.1.1.5 christos 3809 1.1.1.5 christos switch (epr->X_add_number) 3810 1.1.1.5 christos { 3811 1.1.1.5 christos case 0: case 1: case 2: case 3: 3812 1.1.1.5 christos case 12: case 13: case 14: case 15: 3813 1.1.1.5 christos break; 3814 1.1.1.5 christos default: 3815 1.1.1.8 christos return false; 3816 1.1.1.5 christos } 3817 1.1.1.5 christos break; 3818 1.1.1.5 christos 3819 1.1.1.5 christos case REGISTER_NO_GP: 3820 1.1.1.5 christos if ((epr->X_op != O_register) 3821 1.1.1.5 christos || (epr->X_add_number == 26)) /* 26 is the gp register. */ 3822 1.1.1.8 christos return false; 3823 1.1.1.5 christos break; 3824 1.1.1.5 christos 3825 1.1.1.5 christos case BRACKET: 3826 1.1.1.5 christos if (epr->X_op != O_bracket) 3827 1.1.1.8 christos return false; 3828 1.1.1.5 christos break; 3829 1.1.1.5 christos 3830 1.1.1.5 christos default: 3831 1.1.1.5 christos /* Don't understand, bail out. */ 3832 1.1.1.8 christos return false; 3833 1.1.1.5 christos break; 3834 1.1.1.5 christos } 3835 1.1.1.5 christos 3836 1.1.1.5 christos ++i; 3837 1.1.1.5 christos operand = &ins->operands[i]; 3838 1.1.1.5 christos } 3839 1.1.1.5 christos 3840 1.1.1.8 christos return i == ntok; 3841 1.1.1.5 christos } 3842 1.1.1.5 christos 3843 1.1.1.5 christos /* Return TRUE if this OPDCODE is a candidate for relaxation. */ 3844 1.1.1.5 christos 3845 1.1.1.8 christos static bool 3846 1.1.1.5 christos relax_insn_p (const struct arc_opcode *opcode, 3847 1.1.1.5 christos const expressionS *tok, 3848 1.1.1.5 christos int ntok, 3849 1.1.1.5 christos const struct arc_flags *pflags, 3850 1.1.1.5 christos int nflg) 3851 1.1.1.5 christos { 3852 1.1.1.5 christos unsigned i; 3853 1.1.1.8 christos bool rv = false; 3854 1.1.1.5 christos 3855 1.1.1.5 christos /* Check the relaxation table. */ 3856 1.1.1.5 christos for (i = 0; i < arc_num_relaxable_ins && relaxation_state; ++i) 3857 1.1.1.5 christos { 3858 1.1.1.5 christos const struct arc_relaxable_ins *arc_rlx_ins = &arc_relaxable_insns[i]; 3859 1.1.1.5 christos 3860 1.1.1.5 christos if ((strcmp (opcode->name, arc_rlx_ins->mnemonic_r) == 0) 3861 1.1.1.5 christos && may_relax_expr (tok[arc_rlx_ins->opcheckidx]) 3862 1.1.1.5 christos && relaxable_operand (arc_rlx_ins, tok, ntok) 3863 1.1.1.5 christos && relaxable_flag (arc_rlx_ins, pflags, nflg)) 3864 1.1.1.5 christos { 3865 1.1.1.8 christos rv = true; 3866 1.1.1.5 christos frag_now->fr_subtype = arc_relaxable_insns[i].subtype; 3867 1.1.1.5 christos memcpy (&frag_now->tc_frag_data.tok, tok, 3868 1.1.1.5 christos sizeof (expressionS) * ntok); 3869 1.1.1.5 christos memcpy (&frag_now->tc_frag_data.pflags, pflags, 3870 1.1.1.5 christos sizeof (struct arc_flags) * nflg); 3871 1.1.1.5 christos frag_now->tc_frag_data.nflg = nflg; 3872 1.1.1.5 christos frag_now->tc_frag_data.ntok = ntok; 3873 1.1.1.5 christos break; 3874 1.1.1.5 christos } 3875 1.1.1.5 christos } 3876 1.1.1.5 christos 3877 1.1.1.5 christos return rv; 3878 1.1.1.5 christos } 3879 1.1.1.5 christos 3880 1.1.1.3 christos /* Turn an opcode description and a set of arguments into 3881 1.1.1.3 christos an instruction and a fixup. */ 3882 1.1.1.3 christos 3883 1.1.1.3 christos static void 3884 1.1.1.3 christos assemble_insn (const struct arc_opcode *opcode, 3885 1.1.1.3 christos const expressionS *tok, 3886 1.1.1.3 christos int ntok, 3887 1.1.1.3 christos const struct arc_flags *pflags, 3888 1.1.1.3 christos int nflg, 3889 1.1.1.3 christos struct arc_insn *insn) 3890 1.1.1.3 christos { 3891 1.1.1.3 christos const expressionS *reloc_exp = NULL; 3892 1.1.1.6 christos unsigned long long image; 3893 1.1.1.3 christos const unsigned char *argidx; 3894 1.1.1.3 christos int i; 3895 1.1.1.3 christos int tokidx = 0; 3896 1.1.1.3 christos unsigned char pcrel = 0; 3897 1.1.1.8 christos bool needGOTSymbol; 3898 1.1.1.8 christos bool has_delay_slot = false; 3899 1.1.1.3 christos extended_bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED; 3900 1.1.1.3 christos 3901 1.1.1.3 christos memset (insn, 0, sizeof (*insn)); 3902 1.1.1.3 christos image = opcode->opcode; 3903 1.1.1.3 christos 3904 1.1.1.6 christos pr_debug ("%s:%d: assemble_insn: %s using opcode %llx\n", 3905 1.1.1.3 christos frag_now->fr_file, frag_now->fr_line, opcode->name, 3906 1.1.1.3 christos opcode->opcode); 3907 1.1.1.3 christos 3908 1.1.1.3 christos /* Handle operands. */ 3909 1.1.1.3 christos for (argidx = opcode->operands; *argidx; ++argidx) 3910 1.1.1.3 christos { 3911 1.1.1.3 christos const struct arc_operand *operand = &arc_operands[*argidx]; 3912 1.1.1.10 christos const expressionS *t = NULL; 3913 1.1.1.3 christos 3914 1.1.1.6 christos if (ARC_OPERAND_IS_FAKE (operand)) 3915 1.1.1.3 christos continue; 3916 1.1.1.3 christos 3917 1.1.1.3 christos if (operand->flags & ARC_OPERAND_DUPLICATE) 3918 1.1.1.3 christos { 3919 1.1.1.3 christos /* Duplicate operand, already inserted. */ 3920 1.1.1.3 christos tokidx ++; 3921 1.1.1.3 christos continue; 3922 1.1.1.3 christos } 3923 1.1.1.3 christos 3924 1.1.1.3 christos if (tokidx >= ntok) 3925 1.1.1.3 christos { 3926 1.1.1.3 christos abort (); 3927 1.1.1.3 christos } 3928 1.1.1.3 christos else 3929 1.1.1.3 christos t = &tok[tokidx++]; 3930 1.1.1.3 christos 3931 1.1.1.3 christos /* Regardless if we have a reloc or not mark the instruction 3932 1.1.1.3 christos limm if it is the case. */ 3933 1.1.1.3 christos if (operand->flags & ARC_OPERAND_LIMM) 3934 1.1.1.8 christos insn->has_limm = true; 3935 1.1.1.3 christos 3936 1.1.1.3 christos switch (t->X_op) 3937 1.1.1.3 christos { 3938 1.1.1.3 christos case O_register: 3939 1.1.1.3 christos image = insert_operand (image, operand, regno (t->X_add_number), 3940 1.1.1.3 christos NULL, 0); 3941 1.1.1.3 christos break; 3942 1.1.1.3 christos 3943 1.1.1.3 christos case O_constant: 3944 1.1.1.3 christos image = insert_operand (image, operand, t->X_add_number, NULL, 0); 3945 1.1.1.3 christos reloc_exp = t; 3946 1.1.1.3 christos if (operand->flags & ARC_OPERAND_LIMM) 3947 1.1.1.3 christos insn->limm = t->X_add_number; 3948 1.1.1.3 christos break; 3949 1.1.1.3 christos 3950 1.1.1.3 christos case O_bracket: 3951 1.1.1.6 christos case O_colon: 3952 1.1.1.6 christos case O_addrtype: 3953 1.1.1.6 christos /* Ignore brackets, colons, and address types. */ 3954 1.1.1.3 christos break; 3955 1.1.1.3 christos 3956 1.1.1.3 christos case O_absent: 3957 1.1.1.3 christos gas_assert (operand->flags & ARC_OPERAND_IGNORE); 3958 1.1.1.3 christos break; 3959 1.1.1.3 christos 3960 1.1.1.3 christos case O_subtract: 3961 1.1.1.3 christos /* Maybe register range. */ 3962 1.1.1.3 christos if ((t->X_add_number == 0) 3963 1.1.1.3 christos && contains_register (t->X_add_symbol) 3964 1.1.1.3 christos && contains_register (t->X_op_symbol)) 3965 1.1.1.3 christos { 3966 1.1.1.3 christos int regs; 3967 1.1.1.3 christos 3968 1.1.1.3 christos regs = get_register (t->X_add_symbol); 3969 1.1.1.3 christos regs <<= 16; 3970 1.1.1.3 christos regs |= get_register (t->X_op_symbol); 3971 1.1.1.3 christos image = insert_operand (image, operand, regs, NULL, 0); 3972 1.1.1.3 christos break; 3973 1.1.1.3 christos } 3974 1.1.1.6 christos /* Fall through. */ 3975 1.1.1.3 christos 3976 1.1.1.3 christos default: 3977 1.1.1.3 christos /* This operand needs a relocation. */ 3978 1.1.1.8 christos needGOTSymbol = false; 3979 1.1.1.3 christos 3980 1.1.1.3 christos switch (t->X_md) 3981 1.1.1.3 christos { 3982 1.1.1.3 christos case O_plt: 3983 1.1.1.5 christos if (opcode->insn_class == JUMP) 3984 1.1.1.6 christos as_bad (_("Unable to use @plt relocation for insn %s"), 3985 1.1.1.6 christos opcode->name); 3986 1.1.1.8 christos needGOTSymbol = true; 3987 1.1.1.3 christos reloc = find_reloc ("plt", opcode->name, 3988 1.1.1.3 christos pflags, nflg, 3989 1.1.1.3 christos operand->default_reloc); 3990 1.1.1.3 christos break; 3991 1.1.1.3 christos 3992 1.1.1.3 christos case O_gotoff: 3993 1.1.1.3 christos case O_gotpc: 3994 1.1.1.8 christos needGOTSymbol = true; 3995 1.1.1.3 christos reloc = ARC_RELOC_TABLE (t->X_md)->reloc; 3996 1.1.1.3 christos break; 3997 1.1.1.3 christos case O_pcl: 3998 1.1.1.6 christos if (operand->flags & ARC_OPERAND_LIMM) 3999 1.1.1.6 christos { 4000 1.1.1.6 christos reloc = ARC_RELOC_TABLE (t->X_md)->reloc; 4001 1.1.1.6 christos if (arc_opcode_len (opcode) == 2 4002 1.1.1.6 christos || opcode->insn_class == JUMP) 4003 1.1.1.6 christos as_bad (_("Unable to use @pcl relocation for insn %s"), 4004 1.1.1.6 christos opcode->name); 4005 1.1.1.6 christos } 4006 1.1.1.6 christos else 4007 1.1.1.6 christos { 4008 1.1.1.6 christos /* This is a relaxed operand which initially was 4009 1.1.1.6 christos limm, choose whatever we have defined in the 4010 1.1.1.6 christos opcode as reloc. */ 4011 1.1.1.6 christos reloc = operand->default_reloc; 4012 1.1.1.6 christos } 4013 1.1.1.3 christos break; 4014 1.1.1.3 christos case O_sda: 4015 1.1.1.3 christos reloc = find_reloc ("sda", opcode->name, 4016 1.1.1.3 christos pflags, nflg, 4017 1.1.1.3 christos operand->default_reloc); 4018 1.1.1.3 christos break; 4019 1.1.1.3 christos case O_tlsgd: 4020 1.1.1.3 christos case O_tlsie: 4021 1.1.1.8 christos needGOTSymbol = true; 4022 1.1.1.3 christos /* Fall-through. */ 4023 1.1.1.3 christos 4024 1.1.1.3 christos case O_tpoff: 4025 1.1.1.3 christos case O_dtpoff: 4026 1.1.1.3 christos reloc = ARC_RELOC_TABLE (t->X_md)->reloc; 4027 1.1.1.3 christos break; 4028 1.1.1.3 christos 4029 1.1.1.3 christos case O_tpoff9: /*FIXME! Check for the conditionality of 4030 1.1.1.3 christos the insn. */ 4031 1.1.1.3 christos case O_dtpoff9: /*FIXME! Check for the conditionality of 4032 1.1.1.3 christos the insn. */ 4033 1.1.1.3 christos as_bad (_("TLS_*_S9 relocs are not supported yet")); 4034 1.1.1.3 christos break; 4035 1.1.1.3 christos 4036 1.1.1.3 christos default: 4037 1.1.1.3 christos /* Just consider the default relocation. */ 4038 1.1.1.3 christos reloc = operand->default_reloc; 4039 1.1.1.3 christos break; 4040 1.1.1.3 christos } 4041 1.1.1.3 christos 4042 1.1.1.3 christos if (needGOTSymbol && (GOT_symbol == NULL)) 4043 1.1.1.3 christos GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME); 4044 1.1.1.3 christos 4045 1.1.1.3 christos reloc_exp = t; 4046 1.1.1.3 christos 4047 1.1.1.3 christos #if 0 4048 1.1.1.3 christos if (reloc > 0) 4049 1.1.1.3 christos { 4050 1.1.1.3 christos /* sanity checks. */ 4051 1.1.1.3 christos reloc_howto_type *reloc_howto 4052 1.1.1.10 christos = bfd_reloc_type_lookup (stdoutput, reloc); 4053 1.1.1.3 christos unsigned reloc_bitsize = reloc_howto->bitsize; 4054 1.1.1.3 christos if (reloc_howto->rightshift) 4055 1.1.1.3 christos reloc_bitsize -= reloc_howto->rightshift; 4056 1.1.1.3 christos if (reloc_bitsize != operand->bits) 4057 1.1.1.3 christos { 4058 1.1.1.3 christos as_bad (_("invalid relocation %s for field"), 4059 1.1.1.3 christos bfd_get_reloc_code_name (reloc)); 4060 1.1.1.3 christos return; 4061 1.1.1.3 christos } 4062 1.1.1.3 christos } 4063 1.1.1.3 christos #endif 4064 1.1.1.3 christos if (insn->nfixups >= MAX_INSN_FIXUPS) 4065 1.1.1.3 christos as_fatal (_("too many fixups")); 4066 1.1.1.3 christos 4067 1.1.1.3 christos struct arc_fixup *fixup; 4068 1.1.1.3 christos fixup = &insn->fixups[insn->nfixups++]; 4069 1.1.1.3 christos fixup->exp = *t; 4070 1.1.1.3 christos fixup->reloc = reloc; 4071 1.1.1.6 christos if ((int) reloc < 0) 4072 1.1.1.6 christos pcrel = (operand->flags & ARC_OPERAND_PCREL) ? 1 : 0; 4073 1.1.1.6 christos else 4074 1.1.1.6 christos { 4075 1.1.1.6 christos reloc_howto_type *reloc_howto = 4076 1.1.1.10 christos bfd_reloc_type_lookup (stdoutput, fixup->reloc); 4077 1.1.1.6 christos pcrel = reloc_howto->pc_relative; 4078 1.1.1.6 christos } 4079 1.1.1.3 christos fixup->pcrel = pcrel; 4080 1.1.1.8 christos fixup->islong = (operand->flags & ARC_OPERAND_LIMM) != 0; 4081 1.1.1.3 christos break; 4082 1.1.1.3 christos } 4083 1.1.1.3 christos } 4084 1.1.1.3 christos 4085 1.1.1.3 christos /* Handle flags. */ 4086 1.1.1.3 christos for (i = 0; i < nflg; i++) 4087 1.1.1.3 christos { 4088 1.1.1.5 christos const struct arc_flag_operand *flg_operand = pflags[i].flgp; 4089 1.1.1.3 christos 4090 1.1.1.3 christos /* Check if the instruction has a delay slot. */ 4091 1.1.1.3 christos if (!strcmp (flg_operand->name, "d")) 4092 1.1.1.8 christos has_delay_slot = true; 4093 1.1.1.3 christos 4094 1.1.1.6 christos /* There is an exceptional case when we cannot insert a flag just as 4095 1.1.1.6 christos it is. On ARCv2 the '.t' and '.nt' flags must be handled in 4096 1.1.1.6 christos relation with the relative address. Unfortunately, some of the 4097 1.1.1.6 christos ARC700 extensions (NPS400) also have a '.nt' flag that should be 4098 1.1.1.6 christos handled in the normal way. 4099 1.1.1.6 christos 4100 1.1.1.6 christos Flag operands don't have an architecture field, so we can't 4101 1.1.1.6 christos directly validate that FLAG_OPERAND is valid for the current 4102 1.1.1.6 christos architecture, what we do instead is just validate that we're 4103 1.1.1.6 christos assembling for an ARCv2 architecture. */ 4104 1.1.1.6 christos if ((selected_cpu.flags & ARC_OPCODE_ARCV2) 4105 1.1.1.6 christos && (!strcmp (flg_operand->name, "t") 4106 1.1.1.6 christos || !strcmp (flg_operand->name, "nt"))) 4107 1.1.1.3 christos { 4108 1.1.1.3 christos unsigned bitYoperand = 0; 4109 1.1.1.3 christos /* FIXME! move selection bbit/brcc in arc-opc.c. */ 4110 1.1.1.3 christos if (!strcmp (flg_operand->name, "t")) 4111 1.1.1.3 christos if (!strcmp (opcode->name, "bbit0") 4112 1.1.1.3 christos || !strcmp (opcode->name, "bbit1")) 4113 1.1.1.3 christos bitYoperand = arc_NToperand; 4114 1.1.1.3 christos else 4115 1.1.1.3 christos bitYoperand = arc_Toperand; 4116 1.1.1.3 christos else 4117 1.1.1.3 christos if (!strcmp (opcode->name, "bbit0") 4118 1.1.1.3 christos || !strcmp (opcode->name, "bbit1")) 4119 1.1.1.3 christos bitYoperand = arc_Toperand; 4120 1.1.1.3 christos else 4121 1.1.1.3 christos bitYoperand = arc_NToperand; 4122 1.1.1.3 christos 4123 1.1.1.3 christos gas_assert (reloc_exp != NULL); 4124 1.1.1.3 christos if (reloc_exp->X_op == O_constant) 4125 1.1.1.3 christos { 4126 1.1.1.3 christos /* Check if we have a constant and solved it 4127 1.1.1.3 christos immediately. */ 4128 1.1.1.3 christos offsetT val = reloc_exp->X_add_number; 4129 1.1.1.3 christos image |= insert_operand (image, &arc_operands[bitYoperand], 4130 1.1.1.3 christos val, NULL, 0); 4131 1.1.1.3 christos } 4132 1.1.1.3 christos else 4133 1.1.1.3 christos { 4134 1.1.1.3 christos struct arc_fixup *fixup; 4135 1.1.1.3 christos 4136 1.1.1.3 christos if (insn->nfixups >= MAX_INSN_FIXUPS) 4137 1.1.1.3 christos as_fatal (_("too many fixups")); 4138 1.1.1.3 christos 4139 1.1.1.3 christos fixup = &insn->fixups[insn->nfixups++]; 4140 1.1.1.3 christos fixup->exp = *reloc_exp; 4141 1.1.1.3 christos fixup->reloc = -bitYoperand; 4142 1.1.1.3 christos fixup->pcrel = pcrel; 4143 1.1.1.8 christos fixup->islong = false; 4144 1.1.1.3 christos } 4145 1.1.1.3 christos } 4146 1.1.1.3 christos else 4147 1.1.1.3 christos image |= (flg_operand->code & ((1 << flg_operand->bits) - 1)) 4148 1.1.1.3 christos << flg_operand->shift; 4149 1.1.1.3 christos } 4150 1.1.1.3 christos 4151 1.1.1.5 christos insn->relax = relax_insn_p (opcode, tok, ntok, pflags, nflg); 4152 1.1.1.5 christos 4153 1.1.1.6 christos /* Instruction length. */ 4154 1.1.1.6 christos insn->len = arc_opcode_len (opcode); 4155 1.1.1.5 christos 4156 1.1.1.5 christos insn->insn = image; 4157 1.1.1.5 christos 4158 1.1.1.5 christos /* Update last insn status. */ 4159 1.1.1.5 christos arc_last_insns[1] = arc_last_insns[0]; 4160 1.1.1.5 christos arc_last_insns[0].opcode = opcode; 4161 1.1.1.5 christos arc_last_insns[0].has_limm = insn->has_limm; 4162 1.1.1.5 christos arc_last_insns[0].has_delay_slot = has_delay_slot; 4163 1.1.1.5 christos 4164 1.1.1.5 christos /* Check if the current instruction is legally used. */ 4165 1.1.1.5 christos if (arc_last_insns[1].has_delay_slot 4166 1.1.1.5 christos && is_br_jmp_insn_p (arc_last_insns[0].opcode)) 4167 1.1.1.6 christos as_bad (_("Insn %s has a jump/branch instruction %s in its delay slot."), 4168 1.1.1.6 christos arc_last_insns[1].opcode->name, 4169 1.1.1.6 christos arc_last_insns[0].opcode->name); 4170 1.1.1.6 christos if (arc_last_insns[1].has_delay_slot 4171 1.1.1.6 christos && arc_last_insns[0].has_limm) 4172 1.1.1.6 christos as_bad (_("Insn %s has an instruction %s with limm in its delay slot."), 4173 1.1.1.6 christos arc_last_insns[1].opcode->name, 4174 1.1.1.6 christos arc_last_insns[0].opcode->name); 4175 1.1.1.3 christos } 4176 1.1.1.3 christos 4177 1.1.1.3 christos void 4178 1.1.1.3 christos arc_handle_align (fragS* fragP) 4179 1.1.1.3 christos { 4180 1.1.1.3 christos if ((fragP)->fr_type == rs_align_code) 4181 1.1.1.3 christos { 4182 1.1.1.3 christos char *dest = (fragP)->fr_literal + (fragP)->fr_fix; 4183 1.1.1.3 christos valueT count = ((fragP)->fr_next->fr_address 4184 1.1.1.3 christos - (fragP)->fr_address - (fragP)->fr_fix); 4185 1.1.1.3 christos 4186 1.1.1.3 christos (fragP)->fr_var = 2; 4187 1.1.1.3 christos 4188 1.1.1.3 christos if (count & 1)/* Padding in the gap till the next 2-byte 4189 1.1.1.3 christos boundary with 0s. */ 4190 1.1.1.3 christos { 4191 1.1.1.3 christos (fragP)->fr_fix++; 4192 1.1.1.3 christos *dest++ = 0; 4193 1.1.1.3 christos } 4194 1.1.1.3 christos /* Writing nop_s. */ 4195 1.1.1.3 christos md_number_to_chars (dest, NOP_OPCODE_S, 2); 4196 1.1.1.3 christos } 4197 1.1.1.3 christos } 4198 1.1.1.3 christos 4199 1.1.1.3 christos /* Here we decide which fixups can be adjusted to make them relative 4200 1.1.1.3 christos to the beginning of the section instead of the symbol. Basically 4201 1.1.1.3 christos we need to make sure that the dynamic relocations are done 4202 1.1.1.3 christos correctly, so in some cases we force the original symbol to be 4203 1.1.1.3 christos used. */ 4204 1.1.1.3 christos 4205 1.1.1.3 christos int 4206 1.1.1.3 christos tc_arc_fix_adjustable (fixS *fixP) 4207 1.1.1.3 christos { 4208 1.1.1.3 christos 4209 1.1.1.3 christos /* Prevent all adjustments to global symbols. */ 4210 1.1.1.3 christos if (S_IS_EXTERNAL (fixP->fx_addsy)) 4211 1.1.1.3 christos return 0; 4212 1.1.1.3 christos if (S_IS_WEAK (fixP->fx_addsy)) 4213 1.1.1.3 christos return 0; 4214 1.1.1.3 christos 4215 1.1.1.3 christos /* Adjust_reloc_syms doesn't know about the GOT. */ 4216 1.1.1.3 christos switch (fixP->fx_r_type) 4217 1.1.1.3 christos { 4218 1.1.1.3 christos case BFD_RELOC_ARC_GOTPC32: 4219 1.1.1.11 christos case BFD_RELOC_32_PLT_PCREL: 4220 1.1.1.3 christos case BFD_RELOC_ARC_S25H_PCREL_PLT: 4221 1.1.1.3 christos case BFD_RELOC_ARC_S21H_PCREL_PLT: 4222 1.1.1.3 christos case BFD_RELOC_ARC_S25W_PCREL_PLT: 4223 1.1.1.3 christos case BFD_RELOC_ARC_S21W_PCREL_PLT: 4224 1.1.1.3 christos return 0; 4225 1.1.1.3 christos 4226 1.1.1.3 christos default: 4227 1.1.1.3 christos break; 4228 1.1.1.3 christos } 4229 1.1.1.3 christos 4230 1.1.1.5 christos return 1; 4231 1.1.1.3 christos } 4232 1.1.1.3 christos 4233 1.1.1.3 christos /* Compute the reloc type of an expression EXP. */ 4234 1.1.1.3 christos 4235 1.1.1.3 christos static void 4236 1.1.1.3 christos arc_check_reloc (expressionS *exp, 4237 1.1.1.3 christos bfd_reloc_code_real_type *r_type_p) 4238 1.1.1.3 christos { 4239 1.1.1.3 christos if (*r_type_p == BFD_RELOC_32 4240 1.1.1.3 christos && exp->X_op == O_subtract 4241 1.1.1.3 christos && exp->X_op_symbol != NULL 4242 1.1.1.7 christos && S_GET_SEGMENT (exp->X_op_symbol) == now_seg) 4243 1.1.1.3 christos *r_type_p = BFD_RELOC_ARC_32_PCREL; 4244 1.1.1.3 christos } 4245 1.1.1.3 christos 4246 1.1.1.3 christos 4247 1.1.1.3 christos /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG. */ 4248 1.1.1.3 christos 4249 1.1.1.3 christos void 4250 1.1.1.3 christos arc_cons_fix_new (fragS *frag, 4251 1.1.1.3 christos int off, 4252 1.1.1.3 christos int size, 4253 1.1.1.3 christos expressionS *exp, 4254 1.1.1.3 christos bfd_reloc_code_real_type r_type) 4255 1.1.1.3 christos { 4256 1.1.1.3 christos r_type = BFD_RELOC_UNUSED; 4257 1.1.1.3 christos 4258 1.1.1.3 christos switch (size) 4259 1.1.1.3 christos { 4260 1.1.1.3 christos case 1: 4261 1.1.1.3 christos r_type = BFD_RELOC_8; 4262 1.1.1.3 christos break; 4263 1.1.1.3 christos 4264 1.1.1.3 christos case 2: 4265 1.1.1.3 christos r_type = BFD_RELOC_16; 4266 1.1.1.3 christos break; 4267 1.1.1.3 christos 4268 1.1.1.3 christos case 3: 4269 1.1.1.3 christos r_type = BFD_RELOC_24; 4270 1.1.1.3 christos break; 4271 1.1.1.3 christos 4272 1.1.1.3 christos case 4: 4273 1.1.1.3 christos r_type = BFD_RELOC_32; 4274 1.1.1.3 christos arc_check_reloc (exp, &r_type); 4275 1.1.1.3 christos break; 4276 1.1.1.3 christos 4277 1.1.1.3 christos case 8: 4278 1.1.1.3 christos r_type = BFD_RELOC_64; 4279 1.1.1.3 christos break; 4280 1.1.1.3 christos 4281 1.1.1.3 christos default: 4282 1.1.1.3 christos as_bad (_("unsupported BFD relocation size %u"), size); 4283 1.1.1.3 christos r_type = BFD_RELOC_UNUSED; 4284 1.1.1.3 christos } 4285 1.1.1.3 christos 4286 1.1.1.3 christos fix_new_exp (frag, off, size, exp, 0, r_type); 4287 1.1.1.3 christos } 4288 1.1.1.3 christos 4289 1.1.1.3 christos /* The actual routine that checks the ZOL conditions. */ 4290 1.1.1.3 christos 4291 1.1.1.3 christos static void 4292 1.1.1.3 christos check_zol (symbolS *s) 4293 1.1.1.3 christos { 4294 1.1.1.6 christos switch (selected_cpu.mach) 4295 1.1.1.3 christos { 4296 1.1.1.3 christos case bfd_mach_arc_arcv2: 4297 1.1.1.6 christos if (selected_cpu.flags & ARC_OPCODE_ARCv2EM) 4298 1.1.1.3 christos return; 4299 1.1.1.3 christos 4300 1.1.1.3 christos if (is_br_jmp_insn_p (arc_last_insns[0].opcode) 4301 1.1.1.3 christos || arc_last_insns[1].has_delay_slot) 4302 1.1.1.3 christos as_bad (_("Jump/Branch instruction detected at the end of the ZOL label @%s"), 4303 1.1.1.3 christos S_GET_NAME (s)); 4304 1.1.1.3 christos 4305 1.1.1.3 christos break; 4306 1.1.1.3 christos case bfd_mach_arc_arc600: 4307 1.1.1.3 christos 4308 1.1.1.3 christos if (is_kernel_insn_p (arc_last_insns[0].opcode)) 4309 1.1.1.3 christos as_bad (_("Kernel instruction detected at the end of the ZOL label @%s"), 4310 1.1.1.3 christos S_GET_NAME (s)); 4311 1.1.1.3 christos 4312 1.1.1.3 christos if (arc_last_insns[0].has_limm 4313 1.1.1.3 christos && is_br_jmp_insn_p (arc_last_insns[0].opcode)) 4314 1.1.1.3 christos as_bad (_("A jump instruction with long immediate detected at the \ 4315 1.1.1.3 christos end of the ZOL label @%s"), S_GET_NAME (s)); 4316 1.1.1.3 christos 4317 1.1.1.3 christos /* Fall through. */ 4318 1.1.1.3 christos case bfd_mach_arc_arc700: 4319 1.1.1.3 christos if (arc_last_insns[0].has_delay_slot) 4320 1.1.1.3 christos as_bad (_("An illegal use of delay slot detected at the end of the ZOL label @%s"), 4321 1.1.1.3 christos S_GET_NAME (s)); 4322 1.1.1.3 christos 4323 1.1.1.3 christos break; 4324 1.1.1.3 christos default: 4325 1.1.1.3 christos break; 4326 1.1.1.3 christos } 4327 1.1.1.3 christos } 4328 1.1.1.3 christos 4329 1.1.1.3 christos /* If ZOL end check the last two instruction for illegals. */ 4330 1.1.1.3 christos void 4331 1.1.1.3 christos arc_frob_label (symbolS * sym) 4332 1.1.1.3 christos { 4333 1.1.1.3 christos if (ARC_GET_FLAG (sym) & ARC_FLAG_ZOL) 4334 1.1.1.3 christos check_zol (sym); 4335 1.1.1.3 christos 4336 1.1.1.3 christos dwarf2_emit_label (sym); 4337 1.1 skrll } 4338 1.1.1.5 christos 4339 1.1.1.5 christos /* Used because generic relaxation assumes a pc-rel value whilst we 4340 1.1.1.5 christos also relax instructions that use an absolute value resolved out of 4341 1.1.1.5 christos relative values (if that makes any sense). An example: 'add r1, 4342 1.1.1.5 christos r2, @.L2 - .' The symbols . and @.L2 are relative to the section 4343 1.1.1.5 christos but if they're in the same section we can subtract the section 4344 1.1.1.5 christos offset relocation which ends up in a resolved value. So if @.L2 is 4345 1.1.1.5 christos .text + 0x50 and . is .text + 0x10, we can say that .text + 0x50 - 4346 1.1.1.5 christos .text + 0x40 = 0x10. */ 4347 1.1.1.5 christos int 4348 1.1.1.5 christos arc_pcrel_adjust (fragS *fragP) 4349 1.1.1.5 christos { 4350 1.1.1.6 christos pr_debug ("arc_pcrel_adjust: address=%ld, fix=%ld, PCrel %s\n", 4351 1.1.1.6 christos fragP->fr_address, fragP->fr_fix, 4352 1.1.1.6 christos fragP->tc_frag_data.pcrel ? "Y" : "N"); 4353 1.1.1.6 christos 4354 1.1.1.5 christos if (!fragP->tc_frag_data.pcrel) 4355 1.1.1.5 christos return fragP->fr_address + fragP->fr_fix; 4356 1.1.1.5 christos 4357 1.1.1.6 christos /* Take into account the PCL rounding. */ 4358 1.1.1.6 christos return (fragP->fr_address + fragP->fr_fix) & 0x03; 4359 1.1.1.5 christos } 4360 1.1.1.5 christos 4361 1.1.1.5 christos /* Initialize the DWARF-2 unwind information for this procedure. */ 4362 1.1.1.5 christos 4363 1.1.1.5 christos void 4364 1.1.1.5 christos tc_arc_frame_initial_instructions (void) 4365 1.1.1.5 christos { 4366 1.1.1.5 christos /* Stack pointer is register 28. */ 4367 1.1.1.5 christos cfi_add_CFA_def_cfa (28, 0); 4368 1.1.1.5 christos } 4369 1.1.1.5 christos 4370 1.1.1.5 christos int 4371 1.1.1.5 christos tc_arc_regname_to_dw2regnum (char *regname) 4372 1.1.1.5 christos { 4373 1.1.1.5 christos struct symbol *sym; 4374 1.1.1.5 christos 4375 1.1.1.8 christos sym = str_hash_find (arc_reg_hash, regname); 4376 1.1.1.5 christos if (sym) 4377 1.1.1.5 christos return S_GET_VALUE (sym); 4378 1.1.1.5 christos 4379 1.1.1.5 christos return -1; 4380 1.1.1.5 christos } 4381 1.1.1.5 christos 4382 1.1.1.5 christos /* Adjust the symbol table. Delete found AUX register symbols. */ 4383 1.1.1.5 christos 4384 1.1.1.5 christos void 4385 1.1.1.5 christos arc_adjust_symtab (void) 4386 1.1.1.5 christos { 4387 1.1.1.5 christos symbolS * sym; 4388 1.1.1.5 christos 4389 1.1.1.5 christos for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym)) 4390 1.1.1.5 christos { 4391 1.1.1.5 christos /* I've created a symbol during parsing process. Now, remove 4392 1.1.1.5 christos the symbol as it is found to be an AUX register. */ 4393 1.1.1.5 christos if (ARC_GET_FLAG (sym) & ARC_FLAG_AUX) 4394 1.1.1.5 christos symbol_remove (sym, &symbol_rootP, &symbol_lastP); 4395 1.1.1.5 christos } 4396 1.1.1.5 christos 4397 1.1.1.5 christos /* Now do generic ELF adjustments. */ 4398 1.1.1.5 christos elf_adjust_symtab (); 4399 1.1.1.5 christos } 4400 1.1.1.5 christos 4401 1.1.1.5 christos static void 4402 1.1.1.5 christos tokenize_extinsn (extInstruction_t *einsn) 4403 1.1.1.5 christos { 4404 1.1.1.5 christos char *p, c; 4405 1.1.1.5 christos char *insn_name; 4406 1.1.1.5 christos unsigned char major_opcode; 4407 1.1.1.5 christos unsigned char sub_opcode; 4408 1.1.1.5 christos unsigned char syntax_class = 0; 4409 1.1.1.5 christos unsigned char syntax_class_modifiers = 0; 4410 1.1.1.5 christos unsigned char suffix_class = 0; 4411 1.1.1.5 christos unsigned int i; 4412 1.1.1.5 christos 4413 1.1.1.5 christos SKIP_WHITESPACE (); 4414 1.1.1.5 christos 4415 1.1.1.5 christos /* 1st: get instruction name. */ 4416 1.1.1.5 christos p = input_line_pointer; 4417 1.1.1.5 christos c = get_symbol_name (&p); 4418 1.1.1.5 christos 4419 1.1.1.5 christos insn_name = xstrdup (p); 4420 1.1.1.5 christos restore_line_pointer (c); 4421 1.1.1.5 christos 4422 1.1.1.7 christos /* Convert to lower case. */ 4423 1.1.1.7 christos for (p = insn_name; *p; ++p) 4424 1.1.1.7 christos *p = TOLOWER (*p); 4425 1.1.1.7 christos 4426 1.1.1.5 christos /* 2nd: get major opcode. */ 4427 1.1.1.5 christos if (*input_line_pointer != ',') 4428 1.1.1.5 christos { 4429 1.1.1.5 christos as_bad (_("expected comma after instruction name")); 4430 1.1.1.5 christos ignore_rest_of_line (); 4431 1.1.1.5 christos return; 4432 1.1.1.5 christos } 4433 1.1.1.5 christos input_line_pointer++; 4434 1.1.1.5 christos major_opcode = get_absolute_expression (); 4435 1.1.1.5 christos 4436 1.1.1.5 christos /* 3rd: get sub-opcode. */ 4437 1.1.1.5 christos SKIP_WHITESPACE (); 4438 1.1.1.5 christos 4439 1.1.1.5 christos if (*input_line_pointer != ',') 4440 1.1.1.5 christos { 4441 1.1.1.5 christos as_bad (_("expected comma after major opcode")); 4442 1.1.1.5 christos ignore_rest_of_line (); 4443 1.1.1.5 christos return; 4444 1.1.1.5 christos } 4445 1.1.1.5 christos input_line_pointer++; 4446 1.1.1.5 christos sub_opcode = get_absolute_expression (); 4447 1.1.1.5 christos 4448 1.1.1.5 christos /* 4th: get suffix class. */ 4449 1.1.1.5 christos SKIP_WHITESPACE (); 4450 1.1.1.5 christos 4451 1.1.1.5 christos if (*input_line_pointer != ',') 4452 1.1.1.5 christos { 4453 1.1.1.5 christos as_bad ("expected comma after sub opcode"); 4454 1.1.1.5 christos ignore_rest_of_line (); 4455 1.1.1.5 christos return; 4456 1.1.1.5 christos } 4457 1.1.1.5 christos input_line_pointer++; 4458 1.1.1.5 christos 4459 1.1.1.5 christos while (1) 4460 1.1.1.5 christos { 4461 1.1.1.5 christos SKIP_WHITESPACE (); 4462 1.1.1.5 christos 4463 1.1.1.5 christos for (i = 0; i < ARRAY_SIZE (suffixclass); i++) 4464 1.1.1.5 christos { 4465 1.1.1.5 christos if (!strncmp (suffixclass[i].name, input_line_pointer, 4466 1.1.1.5 christos suffixclass[i].len)) 4467 1.1.1.5 christos { 4468 1.1.1.5 christos suffix_class |= suffixclass[i].attr_class; 4469 1.1.1.5 christos input_line_pointer += suffixclass[i].len; 4470 1.1.1.5 christos break; 4471 1.1.1.5 christos } 4472 1.1.1.5 christos } 4473 1.1.1.5 christos 4474 1.1.1.5 christos if (i == ARRAY_SIZE (suffixclass)) 4475 1.1.1.5 christos { 4476 1.1.1.5 christos as_bad ("invalid suffix class"); 4477 1.1.1.5 christos ignore_rest_of_line (); 4478 1.1.1.5 christos return; 4479 1.1.1.5 christos } 4480 1.1.1.5 christos 4481 1.1.1.5 christos SKIP_WHITESPACE (); 4482 1.1.1.5 christos 4483 1.1.1.5 christos if (*input_line_pointer == '|') 4484 1.1.1.5 christos input_line_pointer++; 4485 1.1.1.5 christos else 4486 1.1.1.5 christos break; 4487 1.1.1.5 christos } 4488 1.1.1.5 christos 4489 1.1.1.5 christos /* 5th: get syntax class and syntax class modifiers. */ 4490 1.1.1.5 christos if (*input_line_pointer != ',') 4491 1.1.1.5 christos { 4492 1.1.1.5 christos as_bad ("expected comma after suffix class"); 4493 1.1.1.5 christos ignore_rest_of_line (); 4494 1.1.1.5 christos return; 4495 1.1.1.5 christos } 4496 1.1.1.5 christos input_line_pointer++; 4497 1.1.1.5 christos 4498 1.1.1.5 christos while (1) 4499 1.1.1.5 christos { 4500 1.1.1.5 christos SKIP_WHITESPACE (); 4501 1.1.1.5 christos 4502 1.1.1.5 christos for (i = 0; i < ARRAY_SIZE (syntaxclassmod); i++) 4503 1.1.1.5 christos { 4504 1.1.1.5 christos if (!strncmp (syntaxclassmod[i].name, 4505 1.1.1.5 christos input_line_pointer, 4506 1.1.1.5 christos syntaxclassmod[i].len)) 4507 1.1.1.5 christos { 4508 1.1.1.5 christos syntax_class_modifiers |= syntaxclassmod[i].attr_class; 4509 1.1.1.5 christos input_line_pointer += syntaxclassmod[i].len; 4510 1.1.1.5 christos break; 4511 1.1.1.5 christos } 4512 1.1.1.5 christos } 4513 1.1.1.5 christos 4514 1.1.1.5 christos if (i == ARRAY_SIZE (syntaxclassmod)) 4515 1.1.1.5 christos { 4516 1.1.1.5 christos for (i = 0; i < ARRAY_SIZE (syntaxclass); i++) 4517 1.1.1.5 christos { 4518 1.1.1.5 christos if (!strncmp (syntaxclass[i].name, 4519 1.1.1.5 christos input_line_pointer, 4520 1.1.1.5 christos syntaxclass[i].len)) 4521 1.1.1.5 christos { 4522 1.1.1.5 christos syntax_class |= syntaxclass[i].attr_class; 4523 1.1.1.5 christos input_line_pointer += syntaxclass[i].len; 4524 1.1.1.5 christos break; 4525 1.1.1.5 christos } 4526 1.1.1.5 christos } 4527 1.1.1.5 christos 4528 1.1.1.5 christos if (i == ARRAY_SIZE (syntaxclass)) 4529 1.1.1.5 christos { 4530 1.1.1.5 christos as_bad ("missing syntax class"); 4531 1.1.1.5 christos ignore_rest_of_line (); 4532 1.1.1.5 christos return; 4533 1.1.1.5 christos } 4534 1.1.1.5 christos } 4535 1.1.1.5 christos 4536 1.1.1.5 christos SKIP_WHITESPACE (); 4537 1.1.1.5 christos 4538 1.1.1.5 christos if (*input_line_pointer == '|') 4539 1.1.1.5 christos input_line_pointer++; 4540 1.1.1.5 christos else 4541 1.1.1.5 christos break; 4542 1.1.1.5 christos } 4543 1.1.1.5 christos 4544 1.1.1.5 christos demand_empty_rest_of_line (); 4545 1.1.1.5 christos 4546 1.1.1.5 christos einsn->name = insn_name; 4547 1.1.1.5 christos einsn->major = major_opcode; 4548 1.1.1.5 christos einsn->minor = sub_opcode; 4549 1.1.1.5 christos einsn->syntax = syntax_class; 4550 1.1.1.5 christos einsn->modsyn = syntax_class_modifiers; 4551 1.1.1.5 christos einsn->suffix = suffix_class; 4552 1.1.1.5 christos einsn->flags = syntax_class 4553 1.1.1.5 christos | (syntax_class_modifiers & ARC_OP1_IMM_IMPLIED ? 0x10 : 0); 4554 1.1.1.5 christos } 4555 1.1.1.5 christos 4556 1.1.1.5 christos /* Generate an extension section. */ 4557 1.1.1.5 christos 4558 1.1.1.5 christos static int 4559 1.1.1.5 christos arc_set_ext_seg (void) 4560 1.1.1.5 christos { 4561 1.1.1.5 christos if (!arcext_section) 4562 1.1.1.5 christos { 4563 1.1.1.5 christos arcext_section = subseg_new (".arcextmap", 0); 4564 1.1.1.7 christos bfd_set_section_flags (arcext_section, SEC_READONLY | SEC_HAS_CONTENTS); 4565 1.1.1.5 christos } 4566 1.1.1.5 christos else 4567 1.1.1.5 christos subseg_set (arcext_section, 0); 4568 1.1.1.5 christos return 1; 4569 1.1.1.5 christos } 4570 1.1.1.5 christos 4571 1.1.1.5 christos /* Create an extension instruction description in the arc extension 4572 1.1.1.5 christos section of the output file. 4573 1.1.1.5 christos The structure for an instruction is like this: 4574 1.1.1.5 christos [0]: Length of the record. 4575 1.1.1.5 christos [1]: Type of the record. 4576 1.1.1.5 christos 4577 1.1.1.5 christos [2]: Major opcode. 4578 1.1.1.5 christos [3]: Sub-opcode. 4579 1.1.1.5 christos [4]: Syntax (flags). 4580 1.1.1.5 christos [5]+ Name instruction. 4581 1.1.1.5 christos 4582 1.1.1.5 christos The sequence is terminated by an empty entry. */ 4583 1.1.1.5 christos 4584 1.1.1.5 christos static void 4585 1.1.1.5 christos create_extinst_section (extInstruction_t *einsn) 4586 1.1.1.5 christos { 4587 1.1.1.5 christos 4588 1.1.1.5 christos segT old_sec = now_seg; 4589 1.1.1.5 christos int old_subsec = now_subseg; 4590 1.1.1.5 christos char *p; 4591 1.1.1.5 christos int name_len = strlen (einsn->name); 4592 1.1.1.5 christos 4593 1.1.1.5 christos arc_set_ext_seg (); 4594 1.1.1.5 christos 4595 1.1.1.5 christos p = frag_more (1); 4596 1.1.1.5 christos *p = 5 + name_len + 1; 4597 1.1.1.5 christos p = frag_more (1); 4598 1.1.1.5 christos *p = EXT_INSTRUCTION; 4599 1.1.1.5 christos p = frag_more (1); 4600 1.1.1.5 christos *p = einsn->major; 4601 1.1.1.5 christos p = frag_more (1); 4602 1.1.1.5 christos *p = einsn->minor; 4603 1.1.1.5 christos p = frag_more (1); 4604 1.1.1.5 christos *p = einsn->flags; 4605 1.1.1.5 christos p = frag_more (name_len + 1); 4606 1.1.1.5 christos strcpy (p, einsn->name); 4607 1.1.1.5 christos 4608 1.1.1.5 christos subseg_set (old_sec, old_subsec); 4609 1.1.1.5 christos } 4610 1.1.1.5 christos 4611 1.1.1.5 christos /* Handler .extinstruction pseudo-op. */ 4612 1.1.1.5 christos 4613 1.1.1.5 christos static void 4614 1.1.1.5 christos arc_extinsn (int ignore ATTRIBUTE_UNUSED) 4615 1.1.1.5 christos { 4616 1.1.1.5 christos extInstruction_t einsn; 4617 1.1.1.5 christos struct arc_opcode *arc_ext_opcodes; 4618 1.1.1.5 christos const char *errmsg = NULL; 4619 1.1.1.5 christos unsigned char moplow, mophigh; 4620 1.1.1.5 christos 4621 1.1.1.5 christos memset (&einsn, 0, sizeof (einsn)); 4622 1.1.1.5 christos tokenize_extinsn (&einsn); 4623 1.1.1.5 christos 4624 1.1.1.5 christos /* Check if the name is already used. */ 4625 1.1.1.5 christos if (arc_find_opcode (einsn.name)) 4626 1.1.1.5 christos as_warn (_("Pseudocode already used %s"), einsn.name); 4627 1.1.1.5 christos 4628 1.1.1.5 christos /* Check the opcode ranges. */ 4629 1.1.1.5 christos moplow = 0x05; 4630 1.1.1.6 christos mophigh = (selected_cpu.flags & (ARC_OPCODE_ARCv2EM 4631 1.1.1.6 christos | ARC_OPCODE_ARCv2HS)) ? 0x07 : 0x0a; 4632 1.1.1.5 christos 4633 1.1.1.5 christos if ((einsn.major > mophigh) || (einsn.major < moplow)) 4634 1.1.1.5 christos as_fatal (_("major opcode not in range [0x%02x - 0x%02x]"), moplow, mophigh); 4635 1.1.1.5 christos 4636 1.1.1.5 christos if ((einsn.minor > 0x3f) && (einsn.major != 0x0a) 4637 1.1.1.5 christos && (einsn.major != 5) && (einsn.major != 9)) 4638 1.1.1.5 christos as_fatal (_("minor opcode not in range [0x00 - 0x3f]")); 4639 1.1.1.5 christos 4640 1.1.1.5 christos switch (einsn.syntax & ARC_SYNTAX_MASK) 4641 1.1.1.5 christos { 4642 1.1.1.5 christos case ARC_SYNTAX_3OP: 4643 1.1.1.5 christos if (einsn.modsyn & ARC_OP1_IMM_IMPLIED) 4644 1.1.1.5 christos as_fatal (_("Improper use of OP1_IMM_IMPLIED")); 4645 1.1.1.5 christos break; 4646 1.1.1.5 christos case ARC_SYNTAX_2OP: 4647 1.1.1.5 christos case ARC_SYNTAX_1OP: 4648 1.1.1.5 christos case ARC_SYNTAX_NOP: 4649 1.1.1.5 christos if (einsn.modsyn & ARC_OP1_MUST_BE_IMM) 4650 1.1.1.5 christos as_fatal (_("Improper use of OP1_MUST_BE_IMM")); 4651 1.1.1.5 christos break; 4652 1.1.1.5 christos default: 4653 1.1.1.5 christos break; 4654 1.1.1.5 christos } 4655 1.1.1.5 christos 4656 1.1.1.6 christos arc_ext_opcodes = arcExtMap_genOpcode (&einsn, selected_cpu.flags, &errmsg); 4657 1.1.1.5 christos if (arc_ext_opcodes == NULL) 4658 1.1.1.5 christos { 4659 1.1.1.5 christos if (errmsg) 4660 1.1.1.5 christos as_fatal ("%s", errmsg); 4661 1.1.1.5 christos else 4662 1.1.1.5 christos as_fatal (_("Couldn't generate extension instruction opcodes")); 4663 1.1.1.5 christos } 4664 1.1.1.5 christos else if (errmsg) 4665 1.1.1.5 christos as_warn ("%s", errmsg); 4666 1.1.1.5 christos 4667 1.1.1.5 christos /* Insert the extension instruction. */ 4668 1.1.1.10 christos arc_insert_opcode (arc_ext_opcodes); 4669 1.1.1.5 christos 4670 1.1.1.5 christos create_extinst_section (&einsn); 4671 1.1.1.5 christos } 4672 1.1.1.5 christos 4673 1.1.1.8 christos static bool 4674 1.1.1.5 christos tokenize_extregister (extRegister_t *ereg, int opertype) 4675 1.1.1.5 christos { 4676 1.1.1.5 christos char *name; 4677 1.1.1.5 christos char *mode; 4678 1.1.1.5 christos char c; 4679 1.1.1.5 christos char *p; 4680 1.1.1.5 christos int number, imode = 0; 4681 1.1.1.8 christos bool isCore_p = opertype == EXT_CORE_REGISTER; 4682 1.1.1.8 christos bool isReg_p = opertype == EXT_CORE_REGISTER || opertype == EXT_AUX_REGISTER; 4683 1.1.1.5 christos 4684 1.1.1.5 christos /* 1st: get register name. */ 4685 1.1.1.5 christos SKIP_WHITESPACE (); 4686 1.1.1.5 christos p = input_line_pointer; 4687 1.1.1.5 christos c = get_symbol_name (&p); 4688 1.1.1.5 christos 4689 1.1.1.5 christos name = xstrdup (p); 4690 1.1.1.5 christos restore_line_pointer (c); 4691 1.1.1.5 christos 4692 1.1.1.5 christos /* 2nd: get register number. */ 4693 1.1.1.5 christos SKIP_WHITESPACE (); 4694 1.1.1.5 christos 4695 1.1.1.5 christos if (*input_line_pointer != ',') 4696 1.1.1.5 christos { 4697 1.1.1.6 christos as_bad (_("expected comma after name")); 4698 1.1.1.5 christos ignore_rest_of_line (); 4699 1.1.1.5 christos free (name); 4700 1.1.1.8 christos return false; 4701 1.1.1.5 christos } 4702 1.1.1.5 christos input_line_pointer++; 4703 1.1.1.5 christos number = get_absolute_expression (); 4704 1.1.1.5 christos 4705 1.1.1.6 christos if ((number < 0) 4706 1.1.1.6 christos && (opertype != EXT_AUX_REGISTER)) 4707 1.1.1.5 christos { 4708 1.1.1.6 christos as_bad (_("%s second argument cannot be a negative number %d"), 4709 1.1.1.6 christos isCore_p ? "extCoreRegister's" : "extCondCode's", 4710 1.1.1.6 christos number); 4711 1.1.1.5 christos ignore_rest_of_line (); 4712 1.1.1.5 christos free (name); 4713 1.1.1.8 christos return false; 4714 1.1.1.5 christos } 4715 1.1.1.5 christos 4716 1.1.1.5 christos if (isReg_p) 4717 1.1.1.5 christos { 4718 1.1.1.5 christos /* 3rd: get register mode. */ 4719 1.1.1.5 christos SKIP_WHITESPACE (); 4720 1.1.1.5 christos 4721 1.1.1.5 christos if (*input_line_pointer != ',') 4722 1.1.1.5 christos { 4723 1.1.1.5 christos as_bad (_("expected comma after register number")); 4724 1.1.1.5 christos ignore_rest_of_line (); 4725 1.1.1.5 christos free (name); 4726 1.1.1.8 christos return false; 4727 1.1.1.5 christos } 4728 1.1.1.5 christos 4729 1.1.1.5 christos input_line_pointer++; 4730 1.1.1.5 christos mode = input_line_pointer; 4731 1.1.1.5 christos 4732 1.1.1.8 christos if (startswith (mode, "r|w")) 4733 1.1.1.5 christos { 4734 1.1.1.5 christos imode = 0; 4735 1.1.1.5 christos input_line_pointer += 3; 4736 1.1.1.5 christos } 4737 1.1.1.8 christos else if (startswith (mode, "r")) 4738 1.1.1.5 christos { 4739 1.1.1.5 christos imode = ARC_REGISTER_READONLY; 4740 1.1.1.5 christos input_line_pointer += 1; 4741 1.1.1.5 christos } 4742 1.1.1.8 christos else if (!startswith (mode, "w")) 4743 1.1.1.5 christos { 4744 1.1.1.5 christos as_bad (_("invalid mode")); 4745 1.1.1.5 christos ignore_rest_of_line (); 4746 1.1.1.5 christos free (name); 4747 1.1.1.8 christos return false; 4748 1.1.1.5 christos } 4749 1.1.1.5 christos else 4750 1.1.1.5 christos { 4751 1.1.1.5 christos imode = ARC_REGISTER_WRITEONLY; 4752 1.1.1.5 christos input_line_pointer += 1; 4753 1.1.1.5 christos } 4754 1.1.1.5 christos } 4755 1.1.1.5 christos 4756 1.1.1.5 christos if (isCore_p) 4757 1.1.1.5 christos { 4758 1.1.1.5 christos /* 4th: get core register shortcut. */ 4759 1.1.1.5 christos SKIP_WHITESPACE (); 4760 1.1.1.5 christos if (*input_line_pointer != ',') 4761 1.1.1.5 christos { 4762 1.1.1.5 christos as_bad (_("expected comma after register mode")); 4763 1.1.1.5 christos ignore_rest_of_line (); 4764 1.1.1.5 christos free (name); 4765 1.1.1.8 christos return false; 4766 1.1.1.5 christos } 4767 1.1.1.5 christos 4768 1.1.1.5 christos input_line_pointer++; 4769 1.1.1.5 christos 4770 1.1.1.8 christos if (startswith (input_line_pointer, "cannot_shortcut")) 4771 1.1.1.5 christos { 4772 1.1.1.5 christos imode |= ARC_REGISTER_NOSHORT_CUT; 4773 1.1.1.5 christos input_line_pointer += 15; 4774 1.1.1.5 christos } 4775 1.1.1.8 christos else if (!startswith (input_line_pointer, "can_shortcut")) 4776 1.1.1.5 christos { 4777 1.1.1.5 christos as_bad (_("shortcut designator invalid")); 4778 1.1.1.5 christos ignore_rest_of_line (); 4779 1.1.1.5 christos free (name); 4780 1.1.1.8 christos return false; 4781 1.1.1.5 christos } 4782 1.1.1.5 christos else 4783 1.1.1.5 christos { 4784 1.1.1.5 christos input_line_pointer += 12; 4785 1.1.1.5 christos } 4786 1.1.1.5 christos } 4787 1.1.1.5 christos demand_empty_rest_of_line (); 4788 1.1.1.5 christos 4789 1.1.1.5 christos ereg->name = name; 4790 1.1.1.5 christos ereg->number = number; 4791 1.1.1.5 christos ereg->imode = imode; 4792 1.1.1.8 christos return true; 4793 1.1.1.5 christos } 4794 1.1.1.5 christos 4795 1.1.1.5 christos /* Create an extension register/condition description in the arc 4796 1.1.1.5 christos extension section of the output file. 4797 1.1.1.5 christos 4798 1.1.1.5 christos The structure for an instruction is like this: 4799 1.1.1.5 christos [0]: Length of the record. 4800 1.1.1.5 christos [1]: Type of the record. 4801 1.1.1.5 christos 4802 1.1.1.5 christos For core regs and condition codes: 4803 1.1.1.5 christos [2]: Value. 4804 1.1.1.5 christos [3]+ Name. 4805 1.1.1.5 christos 4806 1.1.1.6 christos For auxiliary registers: 4807 1.1.1.5 christos [2..5]: Value. 4808 1.1.1.5 christos [6]+ Name 4809 1.1.1.5 christos 4810 1.1.1.5 christos The sequence is terminated by an empty entry. */ 4811 1.1.1.5 christos 4812 1.1.1.5 christos static void 4813 1.1.1.5 christos create_extcore_section (extRegister_t *ereg, int opertype) 4814 1.1.1.5 christos { 4815 1.1.1.5 christos segT old_sec = now_seg; 4816 1.1.1.5 christos int old_subsec = now_subseg; 4817 1.1.1.5 christos char *p; 4818 1.1.1.5 christos int name_len = strlen (ereg->name); 4819 1.1.1.5 christos 4820 1.1.1.5 christos arc_set_ext_seg (); 4821 1.1.1.5 christos 4822 1.1.1.5 christos switch (opertype) 4823 1.1.1.5 christos { 4824 1.1.1.5 christos case EXT_COND_CODE: 4825 1.1.1.5 christos case EXT_CORE_REGISTER: 4826 1.1.1.5 christos p = frag_more (1); 4827 1.1.1.5 christos *p = 3 + name_len + 1; 4828 1.1.1.5 christos p = frag_more (1); 4829 1.1.1.5 christos *p = opertype; 4830 1.1.1.5 christos p = frag_more (1); 4831 1.1.1.5 christos *p = ereg->number; 4832 1.1.1.5 christos break; 4833 1.1.1.5 christos case EXT_AUX_REGISTER: 4834 1.1.1.5 christos p = frag_more (1); 4835 1.1.1.5 christos *p = 6 + name_len + 1; 4836 1.1.1.5 christos p = frag_more (1); 4837 1.1.1.5 christos *p = EXT_AUX_REGISTER; 4838 1.1.1.5 christos p = frag_more (1); 4839 1.1.1.5 christos *p = (ereg->number >> 24) & 0xff; 4840 1.1.1.5 christos p = frag_more (1); 4841 1.1.1.5 christos *p = (ereg->number >> 16) & 0xff; 4842 1.1.1.5 christos p = frag_more (1); 4843 1.1.1.5 christos *p = (ereg->number >> 8) & 0xff; 4844 1.1.1.5 christos p = frag_more (1); 4845 1.1.1.5 christos *p = (ereg->number) & 0xff; 4846 1.1.1.5 christos break; 4847 1.1.1.5 christos default: 4848 1.1.1.5 christos break; 4849 1.1.1.5 christos } 4850 1.1.1.5 christos 4851 1.1.1.5 christos p = frag_more (name_len + 1); 4852 1.1.1.5 christos strcpy (p, ereg->name); 4853 1.1.1.5 christos 4854 1.1.1.5 christos subseg_set (old_sec, old_subsec); 4855 1.1.1.5 christos } 4856 1.1.1.5 christos 4857 1.1.1.5 christos /* Handler .extCoreRegister pseudo-op. */ 4858 1.1.1.5 christos 4859 1.1.1.5 christos static void 4860 1.1.1.5 christos arc_extcorereg (int opertype) 4861 1.1.1.5 christos { 4862 1.1.1.5 christos extRegister_t ereg; 4863 1.1.1.5 christos struct arc_aux_reg *auxr; 4864 1.1.1.5 christos struct arc_flag_operand *ccode; 4865 1.1.1.5 christos 4866 1.1.1.5 christos memset (&ereg, 0, sizeof (ereg)); 4867 1.1.1.6 christos if (!tokenize_extregister (&ereg, opertype)) 4868 1.1.1.6 christos return; 4869 1.1.1.5 christos 4870 1.1.1.5 christos switch (opertype) 4871 1.1.1.5 christos { 4872 1.1.1.5 christos case EXT_CORE_REGISTER: 4873 1.1.1.5 christos /* Core register. */ 4874 1.1.1.5 christos if (ereg.number > 60) 4875 1.1.1.5 christos as_bad (_("core register %s value (%d) too large"), ereg.name, 4876 1.1.1.5 christos ereg.number); 4877 1.1.1.5 christos declare_register (ereg.name, ereg.number); 4878 1.1.1.5 christos break; 4879 1.1.1.5 christos case EXT_AUX_REGISTER: 4880 1.1.1.5 christos /* Auxiliary register. */ 4881 1.1.1.5 christos auxr = XNEW (struct arc_aux_reg); 4882 1.1.1.5 christos auxr->name = ereg.name; 4883 1.1.1.6 christos auxr->cpu = selected_cpu.flags; 4884 1.1.1.5 christos auxr->subclass = NONE; 4885 1.1.1.5 christos auxr->address = ereg.number; 4886 1.1.1.8 christos if (str_hash_insert (arc_aux_hash, auxr->name, auxr, 0) != NULL) 4887 1.1.1.8 christos as_bad (_("duplicate aux register %s"), auxr->name); 4888 1.1.1.5 christos break; 4889 1.1.1.5 christos case EXT_COND_CODE: 4890 1.1.1.5 christos /* Condition code. */ 4891 1.1.1.5 christos if (ereg.number > 31) 4892 1.1.1.5 christos as_bad (_("condition code %s value (%d) too large"), ereg.name, 4893 1.1.1.5 christos ereg.number); 4894 1.1.1.5 christos ext_condcode.size ++; 4895 1.1.1.5 christos ext_condcode.arc_ext_condcode = 4896 1.1.1.5 christos XRESIZEVEC (struct arc_flag_operand, ext_condcode.arc_ext_condcode, 4897 1.1.1.5 christos ext_condcode.size + 1); 4898 1.1.1.5 christos 4899 1.1.1.5 christos ccode = ext_condcode.arc_ext_condcode + ext_condcode.size - 1; 4900 1.1.1.5 christos ccode->name = ereg.name; 4901 1.1.1.5 christos ccode->code = ereg.number; 4902 1.1.1.5 christos ccode->bits = 5; 4903 1.1.1.5 christos ccode->shift = 0; 4904 1.1.1.5 christos ccode->favail = 0; /* not used. */ 4905 1.1.1.5 christos ccode++; 4906 1.1.1.5 christos memset (ccode, 0, sizeof (struct arc_flag_operand)); 4907 1.1.1.5 christos break; 4908 1.1.1.5 christos default: 4909 1.1.1.5 christos as_bad (_("Unknown extension")); 4910 1.1.1.5 christos break; 4911 1.1.1.5 christos } 4912 1.1.1.5 christos create_extcore_section (&ereg, opertype); 4913 1.1.1.5 christos } 4914 1.1.1.5 christos 4915 1.1.1.6 christos /* Parse a .arc_attribute directive. */ 4916 1.1.1.6 christos 4917 1.1.1.6 christos static void 4918 1.1.1.6 christos arc_attribute (int ignored ATTRIBUTE_UNUSED) 4919 1.1.1.6 christos { 4920 1.1.1.11 christos obj_attr_tag_t tag = obj_attr_process_attribute (OBJ_ATTR_PROC); 4921 1.1.1.6 christos 4922 1.1.1.6 christos if (tag < NUM_KNOWN_OBJ_ATTRIBUTES) 4923 1.1.1.8 christos attributes_set_explicitly[tag] = true; 4924 1.1.1.6 christos } 4925 1.1.1.6 christos 4926 1.1.1.6 christos /* Set an attribute if it has not already been set by the user. */ 4927 1.1.1.6 christos 4928 1.1.1.6 christos static void 4929 1.1.1.11 christos arc_set_attribute_int (obj_attr_tag_t tag, int value) 4930 1.1.1.6 christos { 4931 1.1.1.6 christos if (tag < 1 4932 1.1.1.6 christos || tag >= NUM_KNOWN_OBJ_ATTRIBUTES 4933 1.1.1.6 christos || !attributes_set_explicitly[tag]) 4934 1.1.1.9 christos if (!bfd_elf_add_proc_attr_int (stdoutput, tag, value)) 4935 1.1.1.9 christos as_fatal (_("error adding attribute: %s"), 4936 1.1.1.9 christos bfd_errmsg (bfd_get_error ())); 4937 1.1.1.6 christos } 4938 1.1.1.6 christos 4939 1.1.1.6 christos static void 4940 1.1.1.11 christos arc_set_attribute_string (obj_attr_tag_t tag, const char *value) 4941 1.1.1.6 christos { 4942 1.1.1.6 christos if (tag < 1 4943 1.1.1.6 christos || tag >= NUM_KNOWN_OBJ_ATTRIBUTES 4944 1.1.1.6 christos || !attributes_set_explicitly[tag]) 4945 1.1.1.9 christos if (!bfd_elf_add_proc_attr_string (stdoutput, tag, value)) 4946 1.1.1.9 christos as_fatal (_("error adding attribute: %s"), 4947 1.1.1.9 christos bfd_errmsg (bfd_get_error ())); 4948 1.1.1.6 christos } 4949 1.1.1.6 christos 4950 1.1.1.6 christos /* Allocate and concatenate two strings. s1 can be NULL but not 4951 1.1.1.6 christos s2. s1 pointer is freed at end of this procedure. */ 4952 1.1.1.6 christos 4953 1.1.1.6 christos static char * 4954 1.1.1.6 christos arc_stralloc (char * s1, const char * s2) 4955 1.1.1.6 christos { 4956 1.1.1.6 christos char * p; 4957 1.1.1.6 christos int len = 0; 4958 1.1.1.6 christos 4959 1.1.1.6 christos if (s1) 4960 1.1.1.6 christos len = strlen (s1) + 1; 4961 1.1.1.6 christos 4962 1.1.1.6 christos /* Only s1 can be null. */ 4963 1.1.1.6 christos gas_assert (s2); 4964 1.1.1.6 christos len += strlen (s2) + 1; 4965 1.1.1.6 christos 4966 1.1.1.10 christos p = xmalloc (len); 4967 1.1.1.6 christos 4968 1.1.1.6 christos if (s1) 4969 1.1.1.6 christos { 4970 1.1.1.6 christos strcpy (p, s1); 4971 1.1.1.6 christos strcat (p, ","); 4972 1.1.1.6 christos strcat (p, s2); 4973 1.1.1.6 christos free (s1); 4974 1.1.1.6 christos } 4975 1.1.1.6 christos else 4976 1.1.1.6 christos strcpy (p, s2); 4977 1.1.1.6 christos 4978 1.1.1.6 christos return p; 4979 1.1.1.6 christos } 4980 1.1.1.6 christos 4981 1.1.1.6 christos /* Set the public ARC object attributes. */ 4982 1.1.1.6 christos 4983 1.1.1.6 christos static void 4984 1.1.1.6 christos arc_set_public_attributes (void) 4985 1.1.1.6 christos { 4986 1.1.1.6 christos int base = 0; 4987 1.1.1.6 christos char *s = NULL; 4988 1.1.1.6 christos unsigned int i; 4989 1.1.1.6 christos 4990 1.1.1.6 christos /* Tag_ARC_CPU_name. */ 4991 1.1.1.6 christos arc_set_attribute_string (Tag_ARC_CPU_name, selected_cpu.name); 4992 1.1.1.6 christos 4993 1.1.1.6 christos /* Tag_ARC_CPU_base. */ 4994 1.1.1.6 christos switch (selected_cpu.eflags & EF_ARC_MACH_MSK) 4995 1.1.1.6 christos { 4996 1.1.1.6 christos case E_ARC_MACH_ARC600: 4997 1.1.1.6 christos case E_ARC_MACH_ARC601: 4998 1.1.1.6 christos base = TAG_CPU_ARC6xx; 4999 1.1.1.6 christos break; 5000 1.1.1.6 christos case E_ARC_MACH_ARC700: 5001 1.1.1.6 christos base = TAG_CPU_ARC7xx; 5002 1.1.1.6 christos break; 5003 1.1.1.6 christos case EF_ARC_CPU_ARCV2EM: 5004 1.1.1.6 christos base = TAG_CPU_ARCEM; 5005 1.1.1.6 christos break; 5006 1.1.1.6 christos case EF_ARC_CPU_ARCV2HS: 5007 1.1.1.6 christos base = TAG_CPU_ARCHS; 5008 1.1.1.6 christos break; 5009 1.1.1.6 christos default: 5010 1.1.1.6 christos base = 0; 5011 1.1.1.6 christos break; 5012 1.1.1.6 christos } 5013 1.1.1.6 christos if (attributes_set_explicitly[Tag_ARC_CPU_base] 5014 1.1.1.6 christos && (base != bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_PROC, 5015 1.1.1.6 christos Tag_ARC_CPU_base))) 5016 1.1.1.6 christos as_warn (_("Overwrite explicitly set Tag_ARC_CPU_base")); 5017 1.1.1.9 christos if (!bfd_elf_add_proc_attr_int (stdoutput, Tag_ARC_CPU_base, base)) 5018 1.1.1.9 christos as_fatal (_("error adding attribute: %s"), 5019 1.1.1.9 christos bfd_errmsg (bfd_get_error ())); 5020 1.1.1.6 christos 5021 1.1.1.6 christos /* Tag_ARC_ABI_osver. */ 5022 1.1.1.6 christos if (attributes_set_explicitly[Tag_ARC_ABI_osver]) 5023 1.1.1.6 christos { 5024 1.1.1.6 christos int val = bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_PROC, 5025 1.1.1.6 christos Tag_ARC_ABI_osver); 5026 1.1.1.6 christos 5027 1.1.1.6 christos selected_cpu.eflags = ((selected_cpu.eflags & ~EF_ARC_OSABI_MSK) 5028 1.1.1.6 christos | (val & 0x0f << 8)); 5029 1.1.1.6 christos } 5030 1.1.1.6 christos else 5031 1.1.1.6 christos { 5032 1.1.1.6 christos arc_set_attribute_int (Tag_ARC_ABI_osver, E_ARC_OSABI_CURRENT >> 8); 5033 1.1.1.6 christos } 5034 1.1.1.6 christos 5035 1.1.1.6 christos /* Tag_ARC_ISA_config. */ 5036 1.1.1.6 christos arc_check_feature(); 5037 1.1.1.6 christos 5038 1.1.1.6 christos for (i = 0; i < ARRAY_SIZE (feature_list); i++) 5039 1.1.1.6 christos if (selected_cpu.features & feature_list[i].feature) 5040 1.1.1.6 christos s = arc_stralloc (s, feature_list[i].attr); 5041 1.1.1.6 christos 5042 1.1.1.6 christos if (s) 5043 1.1.1.6 christos arc_set_attribute_string (Tag_ARC_ISA_config, s); 5044 1.1.1.6 christos 5045 1.1.1.6 christos /* Tag_ARC_ISA_mpy_option. */ 5046 1.1.1.6 christos arc_set_attribute_int (Tag_ARC_ISA_mpy_option, mpy_option); 5047 1.1.1.6 christos 5048 1.1.1.6 christos /* Tag_ARC_ABI_pic. */ 5049 1.1.1.6 christos arc_set_attribute_int (Tag_ARC_ABI_pic, pic_option); 5050 1.1.1.6 christos 5051 1.1.1.6 christos /* Tag_ARC_ABI_sda. */ 5052 1.1.1.6 christos arc_set_attribute_int (Tag_ARC_ABI_sda, sda_option); 5053 1.1.1.6 christos 5054 1.1.1.6 christos /* Tag_ARC_ABI_tls. */ 5055 1.1.1.6 christos arc_set_attribute_int (Tag_ARC_ABI_tls, tls_option); 5056 1.1.1.7 christos 5057 1.1.1.7 christos /* Tag_ARC_ATR_version. */ 5058 1.1.1.7 christos arc_set_attribute_int (Tag_ARC_ATR_version, 1); 5059 1.1.1.7 christos 5060 1.1.1.7 christos /* Tag_ARC_ABI_rf16. */ 5061 1.1.1.7 christos if (attributes_set_explicitly[Tag_ARC_ABI_rf16] 5062 1.1.1.7 christos && bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_PROC, 5063 1.1.1.7 christos Tag_ARC_ABI_rf16) 5064 1.1.1.7 christos && !rf16_only) 5065 1.1.1.7 christos { 5066 1.1.1.7 christos as_warn (_("Overwrite explicitly set Tag_ARC_ABI_rf16 to full " 5067 1.1.1.7 christos "register file")); 5068 1.1.1.9 christos if (!bfd_elf_add_proc_attr_int (stdoutput, Tag_ARC_ABI_rf16, 0)) 5069 1.1.1.9 christos as_fatal (_("error adding attribute: %s"), 5070 1.1.1.9 christos bfd_errmsg (bfd_get_error ())); 5071 1.1.1.7 christos } 5072 1.1.1.6 christos } 5073 1.1.1.6 christos 5074 1.1.1.6 christos /* Add the default contents for the .ARC.attributes section. */ 5075 1.1.1.6 christos 5076 1.1.1.6 christos void 5077 1.1.1.9 christos arc_md_finish (void) 5078 1.1.1.6 christos { 5079 1.1.1.6 christos arc_set_public_attributes (); 5080 1.1.1.6 christos 5081 1.1.1.6 christos if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, selected_cpu.mach)) 5082 1.1.1.6 christos as_fatal (_("could not set architecture and machine")); 5083 1.1.1.6 christos 5084 1.1.1.6 christos bfd_set_private_flags (stdoutput, selected_cpu.eflags); 5085 1.1.1.6 christos } 5086 1.1.1.6 christos 5087 1.1.1.6 christos void arc_copy_symbol_attributes (symbolS *dest, symbolS *src) 5088 1.1.1.6 christos { 5089 1.1.1.6 christos ARC_GET_FLAG (dest) = ARC_GET_FLAG (src); 5090 1.1.1.6 christos } 5091 1.1.1.6 christos 5092 1.1.1.6 christos int arc_convert_symbolic_attribute (const char *name) 5093 1.1.1.6 christos { 5094 1.1.1.6 christos static const struct 5095 1.1.1.6 christos { 5096 1.1.1.6 christos const char * name; 5097 1.1.1.6 christos const int tag; 5098 1.1.1.6 christos } 5099 1.1.1.6 christos attribute_table[] = 5100 1.1.1.6 christos { 5101 1.1.1.6 christos #define T(tag) {#tag, tag} 5102 1.1.1.6 christos T (Tag_ARC_PCS_config), 5103 1.1.1.6 christos T (Tag_ARC_CPU_base), 5104 1.1.1.6 christos T (Tag_ARC_CPU_variation), 5105 1.1.1.6 christos T (Tag_ARC_CPU_name), 5106 1.1.1.6 christos T (Tag_ARC_ABI_rf16), 5107 1.1.1.6 christos T (Tag_ARC_ABI_osver), 5108 1.1.1.6 christos T (Tag_ARC_ABI_sda), 5109 1.1.1.6 christos T (Tag_ARC_ABI_pic), 5110 1.1.1.6 christos T (Tag_ARC_ABI_tls), 5111 1.1.1.6 christos T (Tag_ARC_ABI_enumsize), 5112 1.1.1.6 christos T (Tag_ARC_ABI_exceptions), 5113 1.1.1.6 christos T (Tag_ARC_ABI_double_size), 5114 1.1.1.6 christos T (Tag_ARC_ISA_config), 5115 1.1.1.6 christos T (Tag_ARC_ISA_apex), 5116 1.1.1.7 christos T (Tag_ARC_ISA_mpy_option), 5117 1.1.1.7 christos T (Tag_ARC_ATR_version) 5118 1.1.1.6 christos #undef T 5119 1.1.1.6 christos }; 5120 1.1.1.6 christos unsigned int i; 5121 1.1.1.6 christos 5122 1.1.1.6 christos if (name == NULL) 5123 1.1.1.6 christos return -1; 5124 1.1.1.6 christos 5125 1.1.1.6 christos for (i = 0; i < ARRAY_SIZE (attribute_table); i++) 5126 1.1.1.6 christos if (streq (name, attribute_table[i].name)) 5127 1.1.1.6 christos return attribute_table[i].tag; 5128 1.1.1.6 christos 5129 1.1.1.6 christos return -1; 5130 1.1.1.6 christos } 5131 1.1.1.6 christos 5132 1.1.1.5 christos /* Local variables: 5133 1.1.1.5 christos eval: (c-set-style "gnu") 5134 1.1.1.5 christos indent-tabs-mode: t 5135 1.1.1.5 christos End: */ 5136