1 1.1 christos /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU. 2 1.10 christos Copyright (C) 1989-2025 Free Software Foundation, Inc. 3 1.1 christos Contributed by Carnegie Mellon University, 1993. 4 1.1 christos Written by Alessandro Forin, based on earlier gas-1.38 target CPU files. 5 1.1 christos Modified by Ken Raeburn for gas-2.x and ECOFF support. 6 1.1 christos Modified by Richard Henderson for ELF support. 7 1.1 christos Modified by Klaus K"ampf for EVAX (OpenVMS/Alpha) support. 8 1.1 christos 9 1.1 christos This file is part of GAS, the GNU Assembler. 10 1.1 christos 11 1.1 christos GAS is free software; you can redistribute it and/or modify 12 1.1 christos it under the terms of the GNU General Public License as published by 13 1.1 christos the Free Software Foundation; either version 3, or (at your option) 14 1.1 christos any later version. 15 1.1 christos 16 1.1 christos GAS is distributed in the hope that it will be useful, 17 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 18 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 1.1 christos GNU General Public License for more details. 20 1.1 christos 21 1.1 christos You should have received a copy of the GNU General Public License 22 1.1 christos along with GAS; see the file COPYING. If not, write to the Free 23 1.1 christos Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 24 1.1 christos 02110-1301, USA. */ 25 1.1 christos 26 1.1 christos /* Mach Operating System 27 1.1 christos Copyright (c) 1993 Carnegie Mellon University 28 1.1 christos All Rights Reserved. 29 1.1 christos 30 1.1 christos Permission to use, copy, modify and distribute this software and its 31 1.1 christos documentation is hereby granted, provided that both the copyright 32 1.1 christos notice and this permission notice appear in all copies of the 33 1.1 christos software, derivative works or modified versions, and any portions 34 1.1 christos thereof, and that both notices appear in supporting documentation. 35 1.1 christos 36 1.1 christos CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 37 1.1 christos CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 38 1.1 christos ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 39 1.1 christos 40 1.1 christos Carnegie Mellon requests users of this software to return to 41 1.1 christos 42 1.1 christos Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU 43 1.1 christos School of Computer Science 44 1.1 christos Carnegie Mellon University 45 1.1 christos Pittsburgh PA 15213-3890 46 1.1 christos 47 1.1 christos any improvements or extensions that they make and grant Carnegie the 48 1.1 christos rights to redistribute these changes. */ 49 1.1 christos 50 1.1 christos #include "as.h" 51 1.1 christos #include "subsegs.h" 52 1.1 christos #include "ecoff.h" 53 1.1 christos 54 1.1 christos #include "opcode/alpha.h" 55 1.1 christos 56 1.1 christos #ifdef OBJ_ELF 57 1.1 christos #include "elf/alpha.h" 58 1.1 christos #endif 59 1.1 christos 60 1.1 christos #ifdef OBJ_EVAX 61 1.1 christos #include "vms.h" 62 1.1 christos #include "vms/egps.h" 63 1.1 christos #endif 64 1.1 christos 65 1.1 christos #include "dwarf2dbg.h" 66 1.1 christos #include "dw2gencfi.h" 67 1.1 christos #include "safe-ctype.h" 68 1.1 christos 69 1.1 christos /* Local types. */ 71 1.1 christos 72 1.1 christos #define TOKENIZE_ERROR -1 73 1.1 christos #define TOKENIZE_ERROR_REPORT -2 74 1.1 christos #define MAX_INSN_FIXUPS 2 75 1.1 christos #define MAX_INSN_ARGS 5 76 1.1 christos 77 1.1 christos /* Used since new relocation types are introduced in this 78 1.1 christos file (DUMMY_RELOC_LITUSE_*) */ 79 1.1 christos typedef int extended_bfd_reloc_code_real_type; 80 1.1 christos 81 1.1 christos struct alpha_fixup 82 1.1 christos { 83 1.1 christos expressionS exp; 84 1.1 christos /* bfd_reloc_code_real_type reloc; */ 85 1.1 christos extended_bfd_reloc_code_real_type reloc; 86 1.1 christos #ifdef OBJ_EVAX 87 1.1 christos /* The symbol of the item in the linkage section. */ 88 1.1 christos symbolS *xtrasym; 89 1.1 christos 90 1.1 christos /* The symbol of the procedure descriptor. */ 91 1.1 christos symbolS *procsym; 92 1.1 christos #endif 93 1.1 christos }; 94 1.1 christos 95 1.1 christos struct alpha_insn 96 1.1 christos { 97 1.1 christos unsigned insn; 98 1.1 christos int nfixups; 99 1.1 christos struct alpha_fixup fixups[MAX_INSN_FIXUPS]; 100 1.1 christos long sequence; 101 1.1 christos }; 102 1.10 christos 103 1.1 christos typedef enum 104 1.1 christos { 105 1.1 christos MACRO_EOA = 1, 106 1.1 christos MACRO_IR, 107 1.1 christos MACRO_PIR, 108 1.1 christos MACRO_OPIR, 109 1.1 christos MACRO_CPIR, 110 1.1 christos MACRO_FPR, 111 1.10 christos MACRO_EXP 112 1.10 christos } alpha_macro_argset; 113 1.10 christos 114 1.10 christos typedef union 115 1.10 christos { 116 1.10 christos const void *p; 117 1.10 christos uintptr_t i; 118 1.1 christos } alpha_macro_arg; 119 1.1 christos 120 1.1 christos struct alpha_macro 121 1.1 christos { 122 1.10 christos const char *name; 123 1.10 christos void (*emit) (const expressionS *, int, alpha_macro_arg); 124 1.10 christos alpha_macro_arg arg; 125 1.1 christos alpha_macro_argset argsets[16]; 126 1.1 christos }; 127 1.1 christos 128 1.1 christos /* Extra expression types. */ 129 1.1 christos 130 1.1 christos #define O_pregister O_md1 /* O_register, in parentheses. */ 131 1.1 christos #define O_cpregister O_md2 /* + a leading comma. */ 132 1.1 christos 133 1.1 christos /* The alpha_reloc_op table below depends on the ordering of these. */ 134 1.1 christos #define O_literal O_md3 /* !literal relocation. */ 135 1.1 christos #define O_lituse_addr O_md4 /* !lituse_addr relocation. */ 136 1.1 christos #define O_lituse_base O_md5 /* !lituse_base relocation. */ 137 1.1 christos #define O_lituse_bytoff O_md6 /* !lituse_bytoff relocation. */ 138 1.1 christos #define O_lituse_jsr O_md7 /* !lituse_jsr relocation. */ 139 1.1 christos #define O_lituse_tlsgd O_md8 /* !lituse_tlsgd relocation. */ 140 1.1 christos #define O_lituse_tlsldm O_md9 /* !lituse_tlsldm relocation. */ 141 1.1 christos #define O_lituse_jsrdirect O_md10 /* !lituse_jsrdirect relocation. */ 142 1.1 christos #define O_gpdisp O_md11 /* !gpdisp relocation. */ 143 1.1 christos #define O_gprelhigh O_md12 /* !gprelhigh relocation. */ 144 1.1 christos #define O_gprellow O_md13 /* !gprellow relocation. */ 145 1.1 christos #define O_gprel O_md14 /* !gprel relocation. */ 146 1.1 christos #define O_samegp O_md15 /* !samegp relocation. */ 147 1.1 christos #define O_tlsgd O_md16 /* !tlsgd relocation. */ 148 1.1 christos #define O_tlsldm O_md17 /* !tlsldm relocation. */ 149 1.1 christos #define O_gotdtprel O_md18 /* !gotdtprel relocation. */ 150 1.1 christos #define O_dtprelhi O_md19 /* !dtprelhi relocation. */ 151 1.1 christos #define O_dtprello O_md20 /* !dtprello relocation. */ 152 1.1 christos #define O_dtprel O_md21 /* !dtprel relocation. */ 153 1.1 christos #define O_gottprel O_md22 /* !gottprel relocation. */ 154 1.1 christos #define O_tprelhi O_md23 /* !tprelhi relocation. */ 155 1.1 christos #define O_tprello O_md24 /* !tprello relocation. */ 156 1.1 christos #define O_tprel O_md25 /* !tprel relocation. */ 157 1.1 christos 158 1.1 christos #define DUMMY_RELOC_LITUSE_ADDR (BFD_RELOC_UNUSED + 1) 159 1.1 christos #define DUMMY_RELOC_LITUSE_BASE (BFD_RELOC_UNUSED + 2) 160 1.1 christos #define DUMMY_RELOC_LITUSE_BYTOFF (BFD_RELOC_UNUSED + 3) 161 1.1 christos #define DUMMY_RELOC_LITUSE_JSR (BFD_RELOC_UNUSED + 4) 162 1.1 christos #define DUMMY_RELOC_LITUSE_TLSGD (BFD_RELOC_UNUSED + 5) 163 1.1 christos #define DUMMY_RELOC_LITUSE_TLSLDM (BFD_RELOC_UNUSED + 6) 164 1.1 christos #define DUMMY_RELOC_LITUSE_JSRDIRECT (BFD_RELOC_UNUSED + 7) 165 1.1 christos 166 1.1 christos #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_tprel) 167 1.1 christos 168 1.1 christos /* Macros for extracting the type and number of encoded register tokens. */ 169 1.1 christos 170 1.1 christos #define is_ir_num(x) (((x) & 32) == 0) 171 1.1 christos #define is_fpr_num(x) (((x) & 32) != 0) 172 1.1 christos #define regno(x) ((x) & 31) 173 1.1 christos 174 1.1 christos /* Something odd inherited from the old assembler. */ 175 1.1 christos 176 1.1 christos #define note_gpreg(R) (alpha_gprmask |= (1 << (R))) 177 1.1 christos #define note_fpreg(R) (alpha_fprmask |= (1 << (R))) 178 1.1 christos 179 1.10 christos /* Predicates for 16- and 32-bit ranges */ 180 1.10 christos #define range_signed_16(x) ((valueT) (x) + 0x8000 <= 0xFFFF) 181 1.1 christos #define range_signed_32(x) ((valueT) (x) + 0x80000000 <= 0xFFFFFFFF) 182 1.1 christos 183 1.10 christos /* Macros for sign extending from 16- and 32-bits. */ 184 1.10 christos #define sign_extend_16(x) ((((valueT) (x) & 0xFFFF) ^ 0x8000) - 0x8000) 185 1.10 christos #define sign_extend_32(x) ((((valueT) (x) & 0xFFFFFFFF) ^ 0x80000000) \ 186 1.1 christos - 0x80000000) 187 1.1 christos 188 1.1 christos /* Macros to build tokens. */ 189 1.1 christos 190 1.1 christos #define set_tok_reg(t, r) (memset (&(t), 0, sizeof (t)), \ 191 1.1 christos (t).X_op = O_register, \ 192 1.1 christos (t).X_add_number = (r)) 193 1.1 christos #define set_tok_preg(t, r) (memset (&(t), 0, sizeof (t)), \ 194 1.1 christos (t).X_op = O_pregister, \ 195 1.1 christos (t).X_add_number = (r)) 196 1.1 christos #define set_tok_cpreg(t, r) (memset (&(t), 0, sizeof (t)), \ 197 1.1 christos (t).X_op = O_cpregister, \ 198 1.1 christos (t).X_add_number = (r)) 199 1.1 christos #define set_tok_freg(t, r) (memset (&(t), 0, sizeof (t)), \ 200 1.1 christos (t).X_op = O_register, \ 201 1.1 christos (t).X_add_number = (r) + 32) 202 1.1 christos #define set_tok_sym(t, s, a) (memset (&(t), 0, sizeof (t)), \ 203 1.1 christos (t).X_op = O_symbol, \ 204 1.1 christos (t).X_add_symbol = (s), \ 205 1.1 christos (t).X_add_number = (a)) 206 1.1 christos #define set_tok_const(t, n) (memset (&(t), 0, sizeof (t)), \ 207 1.1 christos (t).X_op = O_constant, \ 208 1.1 christos (t).X_add_number = (n)) 209 1.1 christos 210 1.1 christos /* Generic assembler global variables which must be defined by all 212 1.1 christos targets. */ 213 1.1 christos 214 1.1 christos /* Characters which always start a comment. */ 215 1.1 christos const char comment_chars[] = "#"; 216 1.1 christos 217 1.1 christos /* Characters which start a comment at the beginning of a line. */ 218 1.1 christos const char line_comment_chars[] = "#"; 219 1.1 christos 220 1.1 christos /* Characters which may be used to separate multiple commands on a 221 1.1 christos single line. */ 222 1.1 christos const char line_separator_chars[] = ";"; 223 1.1 christos 224 1.1 christos /* Characters which are used to indicate an exponent in a floating 225 1.1 christos point number. */ 226 1.1 christos const char EXP_CHARS[] = "eE"; 227 1.1 christos 228 1.1 christos /* Characters which mean that a number is a floating point constant, 229 1.5 christos as in 0d1.0. */ 230 1.1 christos /* XXX: Do all of these really get used on the alpha?? */ 231 1.1 christos const char FLT_CHARS[] = "rRsSfFdDxXpP"; 232 1.10 christos 233 1.1 christos #ifdef OBJ_EVAX 234 1.10 christos const char md_shortopts[] = "Fm:g+1h:HG:"; 235 1.1 christos #else 236 1.1 christos const char md_shortopts[] = "Fm:gG:"; 237 1.10 christos #endif 238 1.1 christos 239 1.1 christos const struct option md_longopts[] = 240 1.1 christos { 241 1.1 christos #define OPTION_32ADDR (OPTION_MD_BASE) 242 1.1 christos { "32addr", no_argument, NULL, OPTION_32ADDR }, 243 1.1 christos #define OPTION_RELAX (OPTION_32ADDR + 1) 244 1.1 christos { "relax", no_argument, NULL, OPTION_RELAX }, 245 1.1 christos #ifdef OBJ_ELF 246 1.1 christos #define OPTION_MDEBUG (OPTION_RELAX + 1) 247 1.1 christos #define OPTION_NO_MDEBUG (OPTION_MDEBUG + 1) 248 1.1 christos { "mdebug", no_argument, NULL, OPTION_MDEBUG }, 249 1.1 christos { "no-mdebug", no_argument, NULL, OPTION_NO_MDEBUG }, 250 1.1 christos #endif 251 1.1 christos #ifdef OBJ_EVAX 252 1.1 christos #define OPTION_REPLACE (OPTION_RELAX + 1) 253 1.3 christos #define OPTION_NOREPLACE (OPTION_REPLACE+1) 254 1.1 christos { "replace", no_argument, NULL, OPTION_REPLACE }, 255 1.1 christos { "noreplace", no_argument, NULL, OPTION_NOREPLACE }, 256 1.1 christos #endif 257 1.1 christos { NULL, no_argument, NULL, 0 } 258 1.10 christos }; 259 1.1 christos 260 1.1 christos const size_t md_longopts_size = sizeof (md_longopts); 261 1.1 christos 262 1.1 christos #ifdef OBJ_EVAX 264 1.1 christos #define AXP_REG_R0 0 265 1.1 christos #define AXP_REG_R16 16 266 1.1 christos #define AXP_REG_R17 17 267 1.1 christos #undef AXP_REG_T9 268 1.1 christos #define AXP_REG_T9 22 269 1.1 christos #undef AXP_REG_T10 270 1.1 christos #define AXP_REG_T10 23 271 1.1 christos #undef AXP_REG_T11 272 1.1 christos #define AXP_REG_T11 24 273 1.1 christos #undef AXP_REG_T12 274 1.1 christos #define AXP_REG_T12 25 275 1.1 christos #define AXP_REG_AI 25 276 1.1 christos #undef AXP_REG_FP 277 1.1 christos #define AXP_REG_FP 29 278 1.1 christos 279 1.1 christos #undef AXP_REG_GP 280 1.1 christos #define AXP_REG_GP AXP_REG_PV 281 1.1 christos 282 1.1 christos #endif /* OBJ_EVAX */ 283 1.1 christos 284 1.1 christos /* The cpu for which we are generating code. */ 285 1.1 christos static unsigned alpha_target = AXP_OPCODE_BASE; 286 1.8 christos static const char *alpha_target_name = "<all>"; 287 1.1 christos 288 1.1 christos /* The hash table of instruction opcodes. */ 289 1.8 christos static htab_t alpha_opcode_hash; 290 1.1 christos 291 1.1 christos /* The hash table of macro opcodes. */ 292 1.1 christos static htab_t alpha_macro_hash; 293 1.1 christos 294 1.1 christos #ifdef OBJ_ECOFF 295 1.1 christos /* The $gp relocation symbol. */ 296 1.1 christos static symbolS *alpha_gp_symbol; 297 1.1 christos 298 1.1 christos /* XXX: what is this, and why is it exported? */ 299 1.1 christos valueT alpha_gp_value; 300 1.1 christos #endif 301 1.1 christos 302 1.1 christos /* The current $gp register. */ 303 1.1 christos static int alpha_gp_register = AXP_REG_GP; 304 1.1 christos 305 1.1 christos /* A table of the register symbols. */ 306 1.1 christos static symbolS *alpha_register_table[64]; 307 1.1 christos 308 1.1 christos /* Constant sections, or sections of constants. */ 309 1.1 christos #ifdef OBJ_ECOFF 310 1.1 christos static segT alpha_lita_section; 311 1.1 christos #endif 312 1.1 christos #ifdef OBJ_EVAX 313 1.1 christos segT alpha_link_section; 314 1.1 christos #endif 315 1.1 christos #ifndef OBJ_EVAX 316 1.1 christos static segT alpha_lit8_section; 317 1.1 christos #endif 318 1.1 christos 319 1.1 christos /* Symbols referring to said sections. */ 320 1.1 christos #ifdef OBJ_ECOFF 321 1.1 christos static symbolS *alpha_lita_symbol; 322 1.1 christos #endif 323 1.1 christos #ifdef OBJ_EVAX 324 1.1 christos static symbolS *alpha_link_symbol; 325 1.1 christos #endif 326 1.1 christos #ifndef OBJ_EVAX 327 1.1 christos static symbolS *alpha_lit8_symbol; 328 1.1 christos #endif 329 1.1 christos 330 1.1 christos /* Literal for .litX+0x8000 within .lita. */ 331 1.1 christos #ifdef OBJ_ECOFF 332 1.1 christos static offsetT alpha_lit8_literal; 333 1.1 christos #endif 334 1.1 christos 335 1.1 christos /* Is the assembler not allowed to use $at? */ 336 1.1 christos static int alpha_noat_on = 0; 337 1.1 christos 338 1.1 christos /* Are macros enabled? */ 339 1.1 christos static int alpha_macros_on = 1; 340 1.1 christos 341 1.1 christos /* Are floats disabled? */ 342 1.1 christos static int alpha_nofloats_on = 0; 343 1.1 christos 344 1.1 christos /* Are addresses 32 bit? */ 345 1.1 christos static int alpha_addr32_on = 0; 346 1.1 christos 347 1.1 christos /* Symbol labelling the current insn. When the Alpha gas sees 348 1.1 christos foo: 349 1.1 christos .quad 0 350 1.1 christos and the section happens to not be on an eight byte boundary, it 351 1.1 christos will align both the symbol and the .quad to an eight byte boundary. */ 352 1.1 christos static symbolS *alpha_insn_label; 353 1.1 christos #if defined(OBJ_ELF) || defined (OBJ_EVAX) 354 1.1 christos static symbolS *alpha_prologue_label; 355 1.1 christos #endif 356 1.1 christos 357 1.1 christos #ifdef OBJ_EVAX 358 1.1 christos /* Symbol associate with the current jsr instruction. */ 359 1.1 christos static symbolS *alpha_linkage_symbol; 360 1.1 christos #endif 361 1.1 christos 362 1.1 christos /* Whether we should automatically align data generation pseudo-ops. 363 1.1 christos .align 0 will turn this off. */ 364 1.1 christos static int alpha_auto_align_on = 1; 365 1.1 christos 366 1.1 christos /* The known current alignment of the current section. */ 367 1.1 christos static int alpha_current_align; 368 1.1 christos 369 1.1 christos /* These are exported to ECOFF code. */ 370 1.1 christos unsigned long alpha_gprmask, alpha_fprmask; 371 1.1 christos 372 1.1 christos /* Whether the debugging option was seen. */ 373 1.1 christos static int alpha_debug; 374 1.1 christos 375 1.1 christos #ifdef OBJ_ELF 376 1.1 christos /* Whether we are emitting an mdebug section. */ 377 1.1 christos int alpha_flag_mdebug = -1; 378 1.1 christos #endif 379 1.1 christos 380 1.1 christos #ifdef OBJ_EVAX 381 1.1 christos /* Whether to perform the VMS procedure call optimization. */ 382 1.1 christos int alpha_flag_replace = 1; 383 1.1 christos #endif 384 1.1 christos 385 1.1 christos /* Don't fully resolve relocations, allowing code movement in the linker. */ 386 1.1 christos static int alpha_flag_relax; 387 1.1 christos 388 1.1 christos /* What value to give to bfd_set_gp_size. */ 389 1.1 christos static int g_switch_value = 8; 390 1.1 christos 391 1.1 christos #ifdef OBJ_EVAX 392 1.1 christos /* Collect information about current procedure here. */ 393 1.1 christos struct alpha_evax_procs 394 1.1 christos { 395 1.1 christos symbolS *symbol; /* Proc pdesc symbol. */ 396 1.1 christos int pdsckind; 397 1.1 christos int framereg; /* Register for frame pointer. */ 398 1.1 christos int framesize; /* Size of frame. */ 399 1.1 christos int rsa_offset; 400 1.1 christos int ra_save; 401 1.1 christos int fp_save; 402 1.1 christos long imask; 403 1.1 christos long fmask; 404 1.1 christos int type; 405 1.1 christos int prologue; 406 1.1 christos symbolS *handler; 407 1.1 christos int handler_data; 408 1.1 christos }; 409 1.1 christos 410 1.1 christos /* Linked list of .linkage fixups. */ 411 1.1 christos struct alpha_linkage_fixups *alpha_linkage_fixup_root; 412 1.1 christos static struct alpha_linkage_fixups *alpha_linkage_fixup_tail; 413 1.1 christos 414 1.1 christos /* Current procedure descriptor. */ 415 1.1 christos static struct alpha_evax_procs *alpha_evax_proc; 416 1.1 christos static struct alpha_evax_procs alpha_evax_proc_data; 417 1.1 christos 418 1.1 christos static int alpha_flag_hash_long_names = 0; /* -+ */ 419 1.1 christos static int alpha_flag_show_after_trunc = 0; /* -H */ 420 1.1 christos 421 1.1 christos /* If the -+ switch is given, then a hash is appended to any name that is 422 1.1 christos longer than 64 characters, else longer symbol names are truncated. */ 423 1.1 christos 424 1.1 christos #endif 425 1.1 christos 426 1.1 christos #ifdef RELOC_OP_P 428 1.1 christos /* A table to map the spelling of a relocation operand into an appropriate 429 1.1 christos bfd_reloc_code_real_type type. The table is assumed to be ordered such 430 1.1 christos that op-O_literal indexes into it. */ 431 1.10 christos 432 1.1 christos #define ALPHA_RELOC_TABLE(op) \ 433 1.1 christos (&alpha_reloc_op[ ((!USER_RELOC_P (op)) \ 434 1.1 christos ? (abort (), 0) \ 435 1.1 christos : (op) - O_literal) ]) 436 1.1 christos 437 1.1 christos #define DEF(NAME, RELOC, REQ, ALLOW) \ 438 1.1 christos { #NAME, sizeof(#NAME)-1, O_##NAME, RELOC, REQ, ALLOW} 439 1.1 christos 440 1.1 christos static const struct alpha_reloc_op_tag 441 1.1 christos { 442 1.1 christos const char *name; /* String to lookup. */ 443 1.1 christos size_t length; /* Size of the string. */ 444 1.1 christos operatorT op; /* Which operator to use. */ 445 1.1 christos extended_bfd_reloc_code_real_type reloc; 446 1.1 christos unsigned int require_seq : 1; /* Require a sequence number. */ 447 1.1 christos unsigned int allow_seq : 1; /* Allow a sequence number. */ 448 1.1 christos } 449 1.1 christos alpha_reloc_op[] = 450 1.1 christos { 451 1.1 christos DEF (literal, BFD_RELOC_ALPHA_ELF_LITERAL, 0, 1), 452 1.1 christos DEF (lituse_addr, DUMMY_RELOC_LITUSE_ADDR, 1, 1), 453 1.1 christos DEF (lituse_base, DUMMY_RELOC_LITUSE_BASE, 1, 1), 454 1.1 christos DEF (lituse_bytoff, DUMMY_RELOC_LITUSE_BYTOFF, 1, 1), 455 1.1 christos DEF (lituse_jsr, DUMMY_RELOC_LITUSE_JSR, 1, 1), 456 1.1 christos DEF (lituse_tlsgd, DUMMY_RELOC_LITUSE_TLSGD, 1, 1), 457 1.1 christos DEF (lituse_tlsldm, DUMMY_RELOC_LITUSE_TLSLDM, 1, 1), 458 1.1 christos DEF (lituse_jsrdirect, DUMMY_RELOC_LITUSE_JSRDIRECT, 1, 1), 459 1.1 christos DEF (gpdisp, BFD_RELOC_ALPHA_GPDISP, 1, 1), 460 1.1 christos DEF (gprelhigh, BFD_RELOC_ALPHA_GPREL_HI16, 0, 0), 461 1.1 christos DEF (gprellow, BFD_RELOC_ALPHA_GPREL_LO16, 0, 0), 462 1.1 christos DEF (gprel, BFD_RELOC_GPREL16, 0, 0), 463 1.1 christos DEF (samegp, BFD_RELOC_ALPHA_BRSGP, 0, 0), 464 1.1 christos DEF (tlsgd, BFD_RELOC_ALPHA_TLSGD, 0, 1), 465 1.1 christos DEF (tlsldm, BFD_RELOC_ALPHA_TLSLDM, 0, 1), 466 1.1 christos DEF (gotdtprel, BFD_RELOC_ALPHA_GOTDTPREL16, 0, 0), 467 1.1 christos DEF (dtprelhi, BFD_RELOC_ALPHA_DTPREL_HI16, 0, 0), 468 1.1 christos DEF (dtprello, BFD_RELOC_ALPHA_DTPREL_LO16, 0, 0), 469 1.1 christos DEF (dtprel, BFD_RELOC_ALPHA_DTPREL16, 0, 0), 470 1.1 christos DEF (gottprel, BFD_RELOC_ALPHA_GOTTPREL16, 0, 0), 471 1.1 christos DEF (tprelhi, BFD_RELOC_ALPHA_TPREL_HI16, 0, 0), 472 1.1 christos DEF (tprello, BFD_RELOC_ALPHA_TPREL_LO16, 0, 0), 473 1.1 christos DEF (tprel, BFD_RELOC_ALPHA_TPREL16, 0, 0), 474 1.1 christos }; 475 1.1 christos 476 1.1 christos #undef DEF 477 1.1 christos 478 1.1 christos static const int alpha_num_reloc_op 479 1.1 christos = sizeof (alpha_reloc_op) / sizeof (*alpha_reloc_op); 480 1.1 christos #endif /* RELOC_OP_P */ 481 1.1 christos 482 1.1 christos /* Maximum # digits needed to hold the largest sequence #. */ 483 1.1 christos #define ALPHA_RELOC_DIGITS 25 484 1.1 christos 485 1.1 christos /* Structure to hold explicit sequence information. */ 486 1.1 christos struct alpha_reloc_tag 487 1.1 christos { 488 1.1 christos fixS *master; /* The literal reloc. */ 489 1.1 christos #ifdef OBJ_EVAX 490 1.1 christos struct symbol *sym; /* Linkage section item symbol. */ 491 1.1 christos struct symbol *psym; /* Pdesc symbol. */ 492 1.1 christos #endif 493 1.1 christos fixS *slaves; /* Head of linked list of lituses. */ 494 1.1 christos segT segment; /* Segment relocs are in or undefined_section. */ 495 1.1 christos long sequence; /* Sequence #. */ 496 1.1 christos unsigned n_master; /* # of literals. */ 497 1.1 christos unsigned n_slaves; /* # of lituses. */ 498 1.1 christos unsigned saw_tlsgd : 1; /* True if ... */ 499 1.1 christos unsigned saw_tlsldm : 1; 500 1.1 christos unsigned saw_lu_tlsgd : 1; 501 1.1 christos unsigned saw_lu_tlsldm : 1; 502 1.1 christos unsigned multi_section_p : 1; /* True if more than one section was used. */ 503 1.8 christos char string[1]; /* Printable form of sequence to hash with. */ 504 1.1 christos }; 505 1.1 christos 506 1.1 christos /* Hash table to link up literals with the appropriate lituse. */ 507 1.1 christos static htab_t alpha_literal_hash; 508 1.1 christos 509 1.1 christos /* Sequence numbers for internal use by macros. */ 510 1.1 christos static long next_sequence_num = -1; 511 1.1 christos 512 1.1 christos /* A table of CPU names and opcode sets. */ 514 1.1 christos 515 1.1 christos static const struct cpu_type 516 1.1 christos { 517 1.1 christos const char *name; 518 1.1 christos unsigned flags; 519 1.1 christos } 520 1.1 christos cpu_types[] = 521 1.1 christos { 522 1.1 christos /* Ad hoc convention: cpu number gets palcode, process code doesn't. 523 1.1 christos This supports usage under DU 4.0b that does ".arch ev4", and 524 1.1 christos usage in MILO that does -m21064. Probably something more 525 1.1 christos specific like -m21064-pal should be used, but oh well. */ 526 1.1 christos 527 1.1 christos { "21064", AXP_OPCODE_BASE|AXP_OPCODE_EV4 }, 528 1.1 christos { "21064a", AXP_OPCODE_BASE|AXP_OPCODE_EV4 }, 529 1.1 christos { "21066", AXP_OPCODE_BASE|AXP_OPCODE_EV4 }, 530 1.1 christos { "21068", AXP_OPCODE_BASE|AXP_OPCODE_EV4 }, 531 1.1 christos { "21164", AXP_OPCODE_BASE|AXP_OPCODE_EV5 }, 532 1.1 christos { "21164a", AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX }, 533 1.1 christos { "21164pc", (AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX 534 1.1 christos |AXP_OPCODE_MAX) }, 535 1.1 christos { "21264", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX 536 1.1 christos |AXP_OPCODE_MAX|AXP_OPCODE_CIX) }, 537 1.1 christos { "21264a", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX 538 1.1 christos |AXP_OPCODE_MAX|AXP_OPCODE_CIX) }, 539 1.1 christos { "21264b", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX 540 1.1 christos |AXP_OPCODE_MAX|AXP_OPCODE_CIX) }, 541 1.1 christos 542 1.1 christos { "ev4", AXP_OPCODE_BASE }, 543 1.1 christos { "ev45", AXP_OPCODE_BASE }, 544 1.1 christos { "lca45", AXP_OPCODE_BASE }, 545 1.1 christos { "ev5", AXP_OPCODE_BASE }, 546 1.1 christos { "ev56", AXP_OPCODE_BASE|AXP_OPCODE_BWX }, 547 1.1 christos { "pca56", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX }, 548 1.1 christos { "ev6", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX }, 549 1.1 christos { "ev67", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX }, 550 1.1 christos { "ev68", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX }, 551 1.1 christos 552 1.1 christos { "all", AXP_OPCODE_BASE }, 553 1.1 christos { 0, 0 } 554 1.1 christos }; 555 1.1 christos 556 1.1 christos /* Some instruction sets indexed by lg(size). */ 557 1.1 christos static const char * const sextX_op[] = { "sextb", "sextw", "sextl", NULL }; 558 1.1 christos static const char * const insXl_op[] = { "insbl", "inswl", "insll", "insql" }; 559 1.1 christos static const char * const insXh_op[] = { NULL, "inswh", "inslh", "insqh" }; 560 1.1 christos static const char * const extXl_op[] = { "extbl", "extwl", "extll", "extql" }; 561 1.1 christos static const char * const extXh_op[] = { NULL, "extwh", "extlh", "extqh" }; 562 1.1 christos static const char * const mskXl_op[] = { "mskbl", "mskwl", "mskll", "mskql" }; 563 1.1 christos static const char * const mskXh_op[] = { NULL, "mskwh", "msklh", "mskqh" }; 564 1.1 christos static const char * const stX_op[] = { "stb", "stw", "stl", "stq" }; 565 1.1 christos static const char * const ldXu_op[] = { "ldbu", "ldwu", NULL, NULL }; 566 1.5 christos 567 1.1 christos static void assemble_insn (const struct alpha_opcode *, const expressionS *, int, struct alpha_insn *, extended_bfd_reloc_code_real_type); 568 1.1 christos static void emit_insn (struct alpha_insn *); 569 1.1 christos static void assemble_tokens (const char *, const expressionS *, int, int); 570 1.1 christos #ifdef OBJ_EVAX 571 1.1 christos static const char *s_alpha_section_name (void); 572 1.1 christos static symbolS *add_to_link_pool (symbolS *, offsetT); 573 1.1 christos #endif 574 1.1 christos 575 1.1 christos static struct alpha_reloc_tag * 577 1.1 christos get_alpha_reloc_tag (long sequence) 578 1.10 christos { 579 1.1 christos char buffer[ALPHA_RELOC_DIGITS]; 580 1.1 christos struct alpha_reloc_tag *info; 581 1.1 christos 582 1.1 christos sprintf (buffer, "!%ld", sequence); 583 1.9 christos 584 1.1 christos info = str_hash_find (alpha_literal_hash, buffer); 585 1.1 christos if (! info) 586 1.1 christos { 587 1.1 christos size_t len = strlen (buffer); 588 1.8 christos 589 1.1 christos info = notes_calloc (sizeof (struct alpha_reloc_tag) + len, 1); 590 1.1 christos 591 1.1 christos info->segment = now_seg; 592 1.1 christos info->sequence = sequence; 593 1.1 christos strcpy (info->string, buffer); 594 1.1 christos str_hash_insert (alpha_literal_hash, info->string, info, 0); 595 1.1 christos #ifdef OBJ_EVAX 596 1.1 christos info->sym = 0; 597 1.1 christos info->psym = 0; 598 1.1 christos #endif 599 1.1 christos } 600 1.1 christos 601 1.1 christos return info; 602 1.1 christos } 603 1.1 christos 604 1.1 christos #ifndef OBJ_EVAX 605 1.1 christos 606 1.1 christos static void 607 1.1 christos alpha_adjust_relocs (bfd *abfd ATTRIBUTE_UNUSED, 608 1.1 christos asection *sec, 609 1.1 christos void * ptr ATTRIBUTE_UNUSED) 610 1.1 christos { 611 1.1 christos segment_info_type *seginfo = seg_info (sec); 612 1.1 christos fixS **prevP; 613 1.1 christos fixS *fixp; 614 1.1 christos fixS *next; 615 1.1 christos fixS *slave; 616 1.1 christos 617 1.1 christos /* If seginfo is NULL, we did not create this section; don't do 618 1.1 christos anything with it. By using a pointer to a pointer, we can update 619 1.1 christos the links in place. */ 620 1.1 christos if (seginfo == NULL) 621 1.1 christos return; 622 1.1 christos 623 1.1 christos /* If there are no relocations, skip the section. */ 624 1.1 christos if (! seginfo->fix_root) 625 1.1 christos return; 626 1.1 christos 627 1.10 christos /* First rebuild the fixup chain without the explicit lituse and 628 1.1 christos gpdisp_lo16 relocs. */ 629 1.1 christos prevP = &seginfo->fix_root; 630 1.1 christos for (fixp = seginfo->fix_root; fixp; fixp = next) 631 1.1 christos { 632 1.1 christos next = fixp->fx_next; 633 1.1 christos fixp->fx_next = NULL; 634 1.1 christos 635 1.1 christos switch (fixp->fx_r_type) 636 1.1 christos { 637 1.1 christos case BFD_RELOC_ALPHA_LITUSE: 638 1.1 christos if (fixp->tc_fix_data.info->n_master == 0) 639 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line, 640 1.1 christos _("No !literal!%ld was found"), 641 1.1 christos fixp->tc_fix_data.info->sequence); 642 1.1 christos #ifdef RELOC_OP_P 643 1.1 christos if (fixp->fx_offset == LITUSE_ALPHA_TLSGD) 644 1.1 christos { 645 1.1 christos if (! fixp->tc_fix_data.info->saw_tlsgd) 646 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line, 647 1.1 christos _("No !tlsgd!%ld was found"), 648 1.1 christos fixp->tc_fix_data.info->sequence); 649 1.1 christos } 650 1.1 christos else if (fixp->fx_offset == LITUSE_ALPHA_TLSLDM) 651 1.1 christos { 652 1.1 christos if (! fixp->tc_fix_data.info->saw_tlsldm) 653 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line, 654 1.1 christos _("No !tlsldm!%ld was found"), 655 1.1 christos fixp->tc_fix_data.info->sequence); 656 1.1 christos } 657 1.1 christos #endif 658 1.1 christos break; 659 1.1 christos 660 1.1 christos case BFD_RELOC_ALPHA_GPDISP_LO16: 661 1.1 christos if (fixp->tc_fix_data.info->n_master == 0) 662 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line, 663 1.1 christos _("No ldah !gpdisp!%ld was found"), 664 1.1 christos fixp->tc_fix_data.info->sequence); 665 1.1 christos break; 666 1.1 christos 667 1.1 christos case BFD_RELOC_ALPHA_ELF_LITERAL: 668 1.1 christos if (fixp->tc_fix_data.info 669 1.1 christos && (fixp->tc_fix_data.info->saw_tlsgd 670 1.1 christos || fixp->tc_fix_data.info->saw_tlsldm)) 671 1.1 christos break; 672 1.1 christos /* FALLTHRU */ 673 1.1 christos 674 1.1 christos default: 675 1.1 christos *prevP = fixp; 676 1.1 christos prevP = &fixp->fx_next; 677 1.1 christos break; 678 1.1 christos } 679 1.1 christos } 680 1.1 christos 681 1.1 christos /* Go back and re-chain dependent relocations. They are currently 682 1.1 christos linked through the next_reloc field in reverse order, so as we 683 1.1 christos go through the next_reloc chain, we effectively reverse the chain 684 1.1 christos once again. 685 1.1 christos 686 1.1 christos Except if there is more than one !literal for a given sequence 687 1.1 christos number. In that case, the programmer and/or compiler is not sure 688 1.1 christos how control flows from literal to lituse, and we can't be sure to 689 1.1 christos get the relaxation correct. 690 1.6 christos 691 1.1 christos ??? Well, actually we could, if there are enough lituses such that 692 1.1 christos we can make each literal have at least one of each lituse type 693 1.1 christos present. Not implemented. 694 1.1 christos 695 1.1 christos Also suppress the optimization if the !literals/!lituses are spread 696 1.1 christos in different segments. This can happen with "interesting" uses of 697 1.1 christos inline assembly; examples are present in the Linux kernel semaphores. */ 698 1.1 christos 699 1.1 christos for (fixp = seginfo->fix_root; fixp; fixp = next) 700 1.1 christos { 701 1.1 christos next = fixp->fx_next; 702 1.1 christos switch (fixp->fx_r_type) 703 1.1 christos { 704 1.1 christos case BFD_RELOC_ALPHA_TLSGD: 705 1.1 christos case BFD_RELOC_ALPHA_TLSLDM: 706 1.1 christos if (!fixp->tc_fix_data.info) 707 1.1 christos break; 708 1.1 christos if (fixp->tc_fix_data.info->n_master == 0) 709 1.1 christos break; 710 1.1 christos else if (fixp->tc_fix_data.info->n_master > 1) 711 1.1 christos { 712 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line, 713 1.1 christos _("too many !literal!%ld for %s"), 714 1.1 christos fixp->tc_fix_data.info->sequence, 715 1.1 christos (fixp->fx_r_type == BFD_RELOC_ALPHA_TLSGD 716 1.1 christos ? "!tlsgd" : "!tlsldm")); 717 1.1 christos break; 718 1.1 christos } 719 1.1 christos 720 1.1 christos fixp->tc_fix_data.info->master->fx_next = fixp->fx_next; 721 1.1 christos fixp->fx_next = fixp->tc_fix_data.info->master; 722 1.1 christos fixp = fixp->fx_next; 723 1.1 christos /* Fall through. */ 724 1.1 christos 725 1.10 christos case BFD_RELOC_ALPHA_ELF_LITERAL: 726 1.1 christos if (fixp->tc_fix_data.info 727 1.1 christos && fixp->tc_fix_data.info->n_master == 1 728 1.1 christos && ! fixp->tc_fix_data.info->multi_section_p) 729 1.1 christos { 730 1.1 christos for (slave = fixp->tc_fix_data.info->slaves; 731 1.1 christos slave != NULL; 732 1.1 christos slave = slave->tc_fix_data.next_reloc) 733 1.1 christos { 734 1.1 christos slave->fx_next = fixp->fx_next; 735 1.1 christos fixp->fx_next = slave; 736 1.1 christos } 737 1.1 christos } 738 1.1 christos break; 739 1.1 christos 740 1.1 christos case BFD_RELOC_ALPHA_GPDISP_HI16: 741 1.1 christos if (fixp->tc_fix_data.info->n_slaves == 0) 742 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line, 743 1.1 christos _("No lda !gpdisp!%ld was found"), 744 1.1 christos fixp->tc_fix_data.info->sequence); 745 1.1 christos else 746 1.1 christos { 747 1.1 christos slave = fixp->tc_fix_data.info->slaves; 748 1.1 christos slave->fx_next = next; 749 1.1 christos fixp->fx_next = slave; 750 1.1 christos } 751 1.1 christos break; 752 1.1 christos 753 1.1 christos default: 754 1.1 christos break; 755 1.1 christos } 756 1.1 christos } 757 1.1 christos } 758 1.1 christos 759 1.1 christos /* Before the relocations are written, reorder them, so that user 760 1.1 christos supplied !lituse relocations follow the appropriate !literal 761 1.1 christos relocations, and similarly for !gpdisp relocations. */ 762 1.1 christos 763 1.1 christos void 764 1.1 christos alpha_before_fix (void) 765 1.1 christos { 766 1.1 christos if (alpha_literal_hash) 767 1.1 christos bfd_map_over_sections (stdoutput, alpha_adjust_relocs, NULL); 768 1.1 christos } 769 1.1 christos 770 1.1 christos #endif 771 1.1 christos 772 1.1 christos #ifdef DEBUG_ALPHA 774 1.1 christos static void 775 1.1 christos debug_exp (expressionS tok[], int ntok) 776 1.1 christos { 777 1.1 christos int i; 778 1.1 christos 779 1.1 christos fprintf (stderr, "debug_exp: %d tokens", ntok); 780 1.1 christos for (i = 0; i < ntok; i++) 781 1.1 christos { 782 1.1 christos expressionS *t = &tok[i]; 783 1.1 christos const char *name; 784 1.1 christos 785 1.1 christos switch (t->X_op) 786 1.1 christos { 787 1.1 christos default: name = "unknown"; break; 788 1.1 christos case O_illegal: name = "O_illegal"; break; 789 1.1 christos case O_absent: name = "O_absent"; break; 790 1.1 christos case O_constant: name = "O_constant"; break; 791 1.1 christos case O_symbol: name = "O_symbol"; break; 792 1.1 christos case O_symbol_rva: name = "O_symbol_rva"; break; 793 1.1 christos case O_register: name = "O_register"; break; 794 1.1 christos case O_big: name = "O_big"; break; 795 1.1 christos case O_uminus: name = "O_uminus"; break; 796 1.1 christos case O_bit_not: name = "O_bit_not"; break; 797 1.1 christos case O_logical_not: name = "O_logical_not"; break; 798 1.1 christos case O_multiply: name = "O_multiply"; break; 799 1.1 christos case O_divide: name = "O_divide"; break; 800 1.1 christos case O_modulus: name = "O_modulus"; break; 801 1.1 christos case O_left_shift: name = "O_left_shift"; break; 802 1.1 christos case O_right_shift: name = "O_right_shift"; break; 803 1.1 christos case O_bit_inclusive_or: name = "O_bit_inclusive_or"; break; 804 1.1 christos case O_bit_or_not: name = "O_bit_or_not"; break; 805 1.1 christos case O_bit_exclusive_or: name = "O_bit_exclusive_or"; break; 806 1.1 christos case O_bit_and: name = "O_bit_and"; break; 807 1.1 christos case O_add: name = "O_add"; break; 808 1.1 christos case O_subtract: name = "O_subtract"; break; 809 1.1 christos case O_eq: name = "O_eq"; break; 810 1.1 christos case O_ne: name = "O_ne"; break; 811 1.1 christos case O_lt: name = "O_lt"; break; 812 1.1 christos case O_le: name = "O_le"; break; 813 1.1 christos case O_ge: name = "O_ge"; break; 814 1.1 christos case O_gt: name = "O_gt"; break; 815 1.1 christos case O_logical_and: name = "O_logical_and"; break; 816 1.1 christos case O_logical_or: name = "O_logical_or"; break; 817 1.1 christos case O_index: name = "O_index"; break; 818 1.1 christos case O_pregister: name = "O_pregister"; break; 819 1.1 christos case O_cpregister: name = "O_cpregister"; break; 820 1.1 christos case O_literal: name = "O_literal"; break; 821 1.1 christos case O_lituse_addr: name = "O_lituse_addr"; break; 822 1.1 christos case O_lituse_base: name = "O_lituse_base"; break; 823 1.1 christos case O_lituse_bytoff: name = "O_lituse_bytoff"; break; 824 1.1 christos case O_lituse_jsr: name = "O_lituse_jsr"; break; 825 1.1 christos case O_lituse_tlsgd: name = "O_lituse_tlsgd"; break; 826 1.1 christos case O_lituse_tlsldm: name = "O_lituse_tlsldm"; break; 827 1.1 christos case O_lituse_jsrdirect: name = "O_lituse_jsrdirect"; break; 828 1.1 christos case O_gpdisp: name = "O_gpdisp"; break; 829 1.1 christos case O_gprelhigh: name = "O_gprelhigh"; break; 830 1.1 christos case O_gprellow: name = "O_gprellow"; break; 831 1.1 christos case O_gprel: name = "O_gprel"; break; 832 1.1 christos case O_samegp: name = "O_samegp"; break; 833 1.1 christos case O_tlsgd: name = "O_tlsgd"; break; 834 1.1 christos case O_tlsldm: name = "O_tlsldm"; break; 835 1.1 christos case O_gotdtprel: name = "O_gotdtprel"; break; 836 1.1 christos case O_dtprelhi: name = "O_dtprelhi"; break; 837 1.1 christos case O_dtprello: name = "O_dtprello"; break; 838 1.1 christos case O_dtprel: name = "O_dtprel"; break; 839 1.1 christos case O_gottprel: name = "O_gottprel"; break; 840 1.1 christos case O_tprelhi: name = "O_tprelhi"; break; 841 1.1 christos case O_tprello: name = "O_tprello"; break; 842 1.1 christos case O_tprel: name = "O_tprel"; break; 843 1.1 christos } 844 1.1 christos 845 1.1 christos fprintf (stderr, ", %s(%s, %s, %d)", name, 846 1.1 christos (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--", 847 1.1 christos (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--", 848 1.1 christos (int) t->X_add_number); 849 1.1 christos } 850 1.1 christos fprintf (stderr, "\n"); 851 1.1 christos fflush (stderr); 852 1.1 christos } 853 1.1 christos #endif 854 1.1 christos 855 1.1 christos /* Parse the arguments to an opcode. */ 856 1.1 christos 857 1.1 christos static int 858 1.1 christos tokenize_arguments (char *str, 859 1.1 christos expressionS tok[], 860 1.1 christos int ntok) 861 1.1 christos { 862 1.1 christos expressionS *end_tok = tok + ntok; 863 1.1 christos char *old_input_line_pointer; 864 1.1 christos int saw_comma = 0, saw_arg = 0; 865 1.1 christos #ifdef DEBUG_ALPHA 866 1.1 christos expressionS *orig_tok = tok; 867 1.1 christos #endif 868 1.1 christos #ifdef RELOC_OP_P 869 1.1 christos char *p; 870 1.1 christos const struct alpha_reloc_op_tag *r; 871 1.1 christos int c, i; 872 1.1 christos size_t len; 873 1.1 christos int reloc_found_p = 0; 874 1.1 christos #endif 875 1.1 christos 876 1.1 christos memset (tok, 0, sizeof (*tok) * ntok); 877 1.10 christos 878 1.1 christos /* Save and restore input_line_pointer around this function. */ 879 1.1 christos old_input_line_pointer = input_line_pointer; 880 1.1 christos input_line_pointer = str; 881 1.1 christos 882 1.1 christos #ifdef RELOC_OP_P 883 1.1 christos /* ??? Wrest control of ! away from the regular expression parser. */ 884 1.1 christos lex_type[(unsigned char) '!'] |= LEX_EOS; 885 1.1 christos #endif 886 1.1 christos 887 1.1 christos while (tok < end_tok && *input_line_pointer) 888 1.1 christos { 889 1.1 christos SKIP_WHITESPACE (); 890 1.1 christos switch (*input_line_pointer) 891 1.1 christos { 892 1.1 christos case '\0': 893 1.1 christos goto fini; 894 1.1 christos 895 1.1 christos #ifdef RELOC_OP_P 896 1.1 christos case '!': 897 1.1 christos /* A relocation operand can be placed after the normal operand on an 898 1.1 christos assembly language statement, and has the following form: 899 1.1 christos !relocation_type!sequence_number. */ 900 1.1 christos if (reloc_found_p) 901 1.1 christos { 902 1.1 christos /* Only support one relocation op per insn. */ 903 1.1 christos as_bad (_("More than one relocation op per insn")); 904 1.1 christos goto err_report; 905 1.3 christos } 906 1.1 christos 907 1.1 christos if (!saw_arg) 908 1.1 christos goto err; 909 1.1 christos 910 1.1 christos ++input_line_pointer; 911 1.1 christos SKIP_WHITESPACE (); 912 1.1 christos c = get_symbol_name (&p); 913 1.1 christos 914 1.1 christos /* Parse !relocation_type. */ 915 1.1 christos len = input_line_pointer - p; 916 1.1 christos if (len == 0) 917 1.1 christos { 918 1.1 christos as_bad (_("No relocation operand")); 919 1.1 christos goto err_report; 920 1.1 christos } 921 1.1 christos 922 1.1 christos r = &alpha_reloc_op[0]; 923 1.1 christos for (i = alpha_num_reloc_op - 1; i >= 0; i--, r++) 924 1.1 christos if (len == r->length && memcmp (p, r->name, len) == 0) 925 1.10 christos break; 926 1.10 christos if (i < 0) 927 1.1 christos { 928 1.1 christos as_bad (_("Unknown relocation operand: !%s"), p); 929 1.1 christos goto err_report; 930 1.1 christos } 931 1.1 christos 932 1.1 christos restore_line_pointer (c); 933 1.1 christos SKIP_WHITESPACE (); 934 1.1 christos if (*input_line_pointer != '!') 935 1.1 christos { 936 1.1 christos if (r->require_seq) 937 1.1 christos { 938 1.1 christos as_bad (_("no sequence number after !%s"), p); 939 1.1 christos goto err_report; 940 1.1 christos } 941 1.1 christos 942 1.1 christos tok->X_add_number = 0; 943 1.1 christos } 944 1.1 christos else 945 1.1 christos { 946 1.1 christos if (! r->allow_seq) 947 1.1 christos { 948 1.1 christos as_bad (_("!%s does not use a sequence number"), p); 949 1.1 christos goto err_report; 950 1.1 christos } 951 1.1 christos 952 1.1 christos input_line_pointer++; 953 1.1 christos 954 1.1 christos /* Parse !sequence_number. */ 955 1.1 christos expression (tok); 956 1.1 christos if (tok->X_op != O_constant || tok->X_add_number <= 0) 957 1.1 christos { 958 1.1 christos as_bad (_("Bad sequence number: !%s!%s"), 959 1.1 christos r->name, input_line_pointer); 960 1.1 christos goto err_report; 961 1.1 christos } 962 1.1 christos } 963 1.1 christos 964 1.1 christos tok->X_op = r->op; 965 1.1 christos reloc_found_p = 1; 966 1.1 christos ++tok; 967 1.1 christos break; 968 1.1 christos #endif /* RELOC_OP_P */ 969 1.1 christos 970 1.1 christos case ',': 971 1.1 christos ++input_line_pointer; 972 1.1 christos if (saw_comma || !saw_arg) 973 1.1 christos goto err; 974 1.1 christos saw_comma = 1; 975 1.1 christos break; 976 1.9 christos 977 1.1 christos case '(': 978 1.1 christos { 979 1.1 christos char *hold = input_line_pointer++; 980 1.1 christos 981 1.1 christos /* First try for parenthesized register ... */ 982 1.1 christos expression (tok); 983 1.1 christos resolve_register (tok); 984 1.1 christos if (*input_line_pointer == ')' && tok->X_op == O_register) 985 1.1 christos { 986 1.1 christos tok->X_op = (saw_comma ? O_cpregister : O_pregister); 987 1.1 christos saw_comma = 0; 988 1.1 christos saw_arg = 1; 989 1.1 christos ++input_line_pointer; 990 1.6 christos ++tok; 991 1.1 christos break; 992 1.1 christos } 993 1.1 christos 994 1.1 christos /* ... then fall through to plain expression. */ 995 1.1 christos input_line_pointer = hold; 996 1.1 christos } 997 1.1 christos /* Fall through. */ 998 1.1 christos 999 1.1 christos default: 1000 1.9 christos if (saw_arg && !saw_comma) 1001 1.9 christos goto err; 1002 1.1 christos 1003 1.1 christos expression (tok); 1004 1.1 christos if (tok->X_op == O_illegal || tok->X_op == O_absent) 1005 1.1 christos goto err; 1006 1.1 christos 1007 1.1 christos resolve_register (tok); 1008 1.1 christos 1009 1.8 christos saw_comma = 0; 1010 1.1 christos saw_arg = 1; 1011 1.1 christos ++tok; 1012 1.1 christos break; 1013 1.1 christos } 1014 1.1 christos } 1015 1.1 christos 1016 1.1 christos fini: 1017 1.1 christos if (saw_comma) 1018 1.10 christos goto err; 1019 1.1 christos input_line_pointer = old_input_line_pointer; 1020 1.1 christos 1021 1.1 christos #ifdef DEBUG_ALPHA 1022 1.1 christos debug_exp (orig_tok, ntok - (end_tok - tok)); 1023 1.8 christos #endif 1024 1.1 christos #ifdef RELOC_OP_P 1025 1.10 christos lex_type[(unsigned char) '!'] &= ~LEX_EOS; 1026 1.1 christos #endif 1027 1.1 christos 1028 1.1 christos return ntok - (end_tok - tok); 1029 1.1 christos 1030 1.1 christos err: 1031 1.8 christos #ifdef RELOC_OP_P 1032 1.10 christos lex_type[(unsigned char) '!'] &= ~LEX_EOS; 1033 1.1 christos #endif 1034 1.1 christos input_line_pointer = old_input_line_pointer; 1035 1.1 christos return TOKENIZE_ERROR; 1036 1.1 christos 1037 1.1 christos #ifdef RELOC_OP_P 1038 1.1 christos err_report: 1039 1.1 christos lex_type[(unsigned char) '!'] &= ~LEX_EOS; 1040 1.1 christos #endif 1041 1.1 christos input_line_pointer = old_input_line_pointer; 1042 1.1 christos return TOKENIZE_ERROR_REPORT; 1043 1.1 christos } 1044 1.1 christos 1045 1.1 christos /* Search forward through all variants of an opcode looking for a 1046 1.1 christos syntax match. */ 1047 1.1 christos 1048 1.1 christos static const struct alpha_opcode * 1049 1.1 christos find_opcode_match (const struct alpha_opcode *first_opcode, 1050 1.1 christos const expressionS *tok, 1051 1.1 christos int *pntok, 1052 1.1 christos int *pcpumatch) 1053 1.1 christos { 1054 1.1 christos const struct alpha_opcode *opcode = first_opcode; 1055 1.1 christos int ntok = *pntok; 1056 1.1 christos int got_cpu_match = 0; 1057 1.1 christos 1058 1.1 christos do 1059 1.1 christos { 1060 1.1 christos const unsigned char *opidx; 1061 1.1 christos int tokidx = 0; 1062 1.1 christos 1063 1.1 christos /* Don't match opcodes that don't exist on this architecture. */ 1064 1.1 christos if (!(opcode->flags & alpha_target)) 1065 1.1 christos goto match_failed; 1066 1.1 christos 1067 1.1 christos got_cpu_match = 1; 1068 1.1 christos 1069 1.1 christos for (opidx = opcode->operands; *opidx; ++opidx) 1070 1.1 christos { 1071 1.1 christos const struct alpha_operand *operand = &alpha_operands[*opidx]; 1072 1.1 christos 1073 1.1 christos /* Only take input from real operands. */ 1074 1.1 christos if (operand->flags & AXP_OPERAND_FAKE) 1075 1.1 christos continue; 1076 1.1 christos 1077 1.1 christos /* When we expect input, make sure we have it. */ 1078 1.1 christos if (tokidx >= ntok) 1079 1.1 christos { 1080 1.1 christos if ((operand->flags & AXP_OPERAND_OPTIONAL_MASK) == 0) 1081 1.1 christos goto match_failed; 1082 1.1 christos continue; 1083 1.1 christos } 1084 1.1 christos 1085 1.1 christos /* Match operand type with expression type. */ 1086 1.1 christos switch (operand->flags & AXP_OPERAND_TYPECHECK_MASK) 1087 1.1 christos { 1088 1.1 christos case AXP_OPERAND_IR: 1089 1.1 christos if (tok[tokidx].X_op != O_register 1090 1.1 christos || !is_ir_num (tok[tokidx].X_add_number)) 1091 1.1 christos goto match_failed; 1092 1.1 christos break; 1093 1.1 christos case AXP_OPERAND_FPR: 1094 1.1 christos if (tok[tokidx].X_op != O_register 1095 1.1 christos || !is_fpr_num (tok[tokidx].X_add_number)) 1096 1.1 christos goto match_failed; 1097 1.1 christos break; 1098 1.1 christos case AXP_OPERAND_IR | AXP_OPERAND_PARENS: 1099 1.1 christos if (tok[tokidx].X_op != O_pregister 1100 1.1 christos || !is_ir_num (tok[tokidx].X_add_number)) 1101 1.1 christos goto match_failed; 1102 1.1 christos break; 1103 1.1 christos case AXP_OPERAND_IR | AXP_OPERAND_PARENS | AXP_OPERAND_COMMA: 1104 1.1 christos if (tok[tokidx].X_op != O_cpregister 1105 1.1 christos || !is_ir_num (tok[tokidx].X_add_number)) 1106 1.1 christos goto match_failed; 1107 1.1 christos break; 1108 1.1 christos 1109 1.1 christos case AXP_OPERAND_RELATIVE: 1110 1.1 christos case AXP_OPERAND_SIGNED: 1111 1.1 christos case AXP_OPERAND_UNSIGNED: 1112 1.1 christos switch (tok[tokidx].X_op) 1113 1.1 christos { 1114 1.1 christos case O_illegal: 1115 1.1 christos case O_absent: 1116 1.1 christos case O_register: 1117 1.1 christos case O_pregister: 1118 1.1 christos case O_cpregister: 1119 1.1 christos goto match_failed; 1120 1.1 christos 1121 1.1 christos default: 1122 1.1 christos break; 1123 1.1 christos } 1124 1.1 christos break; 1125 1.1 christos 1126 1.1 christos default: 1127 1.1 christos /* Everything else should have been fake. */ 1128 1.1 christos abort (); 1129 1.1 christos } 1130 1.1 christos ++tokidx; 1131 1.1 christos } 1132 1.1 christos 1133 1.1 christos /* Possible match -- did we use all of our input? */ 1134 1.1 christos if (tokidx == ntok) 1135 1.1 christos { 1136 1.1 christos *pntok = ntok; 1137 1.1 christos return opcode; 1138 1.1 christos } 1139 1.1 christos 1140 1.1 christos match_failed:; 1141 1.1 christos } 1142 1.1 christos while (++opcode - alpha_opcodes < (int) alpha_num_opcodes 1143 1.1 christos && !strcmp (opcode->name, first_opcode->name)); 1144 1.1 christos 1145 1.1 christos if (*pcpumatch) 1146 1.1 christos *pcpumatch = got_cpu_match; 1147 1.1 christos 1148 1.1 christos return NULL; 1149 1.1 christos } 1150 1.1 christos 1151 1.1 christos /* Given an opcode name and a pre-tokenized set of arguments, assemble 1152 1.1 christos the insn, but do not emit it. 1153 1.1 christos 1154 1.1 christos Note that this implies no macros allowed, since we can't store more 1155 1.1 christos than one insn in an insn structure. */ 1156 1.1 christos 1157 1.1 christos static void 1158 1.1 christos assemble_tokens_to_insn (const char *opname, 1159 1.10 christos const expressionS *tok, 1160 1.1 christos int ntok, 1161 1.1 christos struct alpha_insn *insn) 1162 1.1 christos { 1163 1.1 christos const struct alpha_opcode *opcode; 1164 1.1 christos 1165 1.1 christos /* Search opcodes. */ 1166 1.1 christos opcode = str_hash_find (alpha_opcode_hash, opname); 1167 1.1 christos if (opcode) 1168 1.1 christos { 1169 1.1 christos int cpumatch; 1170 1.1 christos opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch); 1171 1.1 christos if (opcode) 1172 1.1 christos { 1173 1.1 christos assemble_insn (opcode, tok, ntok, insn, BFD_RELOC_UNUSED); 1174 1.1 christos return; 1175 1.1 christos } 1176 1.1 christos else if (cpumatch) 1177 1.1 christos as_bad (_("inappropriate arguments for opcode `%s'"), opname); 1178 1.1 christos else 1179 1.1 christos as_bad (_("opcode `%s' not supported for target %s"), opname, 1180 1.1 christos alpha_target_name); 1181 1.1 christos } 1182 1.1 christos else 1183 1.1 christos as_bad (_("unknown opcode `%s'"), opname); 1184 1.1 christos } 1185 1.1 christos 1186 1.1 christos /* Build a BFD section with its flags set appropriately for the .lita, 1187 1.1 christos .lit8, or .lit4 sections. */ 1188 1.1 christos 1189 1.1 christos static void 1190 1.1 christos create_literal_section (const char *name, 1191 1.1 christos segT *secp, 1192 1.1 christos symbolS **symp) 1193 1.7 christos { 1194 1.7 christos segT current_section = now_seg; 1195 1.7 christos int current_subsec = now_subseg; 1196 1.1 christos segT new_sec; 1197 1.1 christos 1198 1.1 christos *secp = new_sec = subseg_new (name, 0); 1199 1.1 christos subseg_set (current_section, current_subsec); 1200 1.1 christos bfd_set_section_alignment (new_sec, 4); 1201 1.1 christos bfd_set_section_flags (new_sec, (SEC_RELOC | SEC_ALLOC | SEC_LOAD 1202 1.1 christos | SEC_READONLY | SEC_DATA)); 1203 1.1 christos 1204 1.1 christos S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec)); 1205 1.1 christos } 1206 1.1 christos 1207 1.1 christos /* Load a (partial) expression into a target register. 1208 1.1 christos 1209 1.1 christos If poffset is not null, after the call it will either contain 1210 1.1 christos O_constant 0, or a 16-bit offset appropriate for any MEM format 1211 1.1 christos instruction. In addition, pbasereg will be modified to point to 1212 1.1 christos the base register to use in that MEM format instruction. 1213 1.1 christos 1214 1.1 christos In any case, *pbasereg should contain a base register to add to the 1215 1.1 christos expression. This will normally be either AXP_REG_ZERO or 1216 1.1 christos alpha_gp_register. Symbol addresses will always be loaded via $gp, 1217 1.1 christos so "foo($0)" is interpreted as adding the address of foo to $0; 1218 1.1 christos i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps, 1219 1.1 christos but this is what OSF/1 does. 1220 1.1 christos 1221 1.1 christos If explicit relocations of the form !literal!<number> are allowed, 1222 1.1 christos and used, then explicit_reloc with be an expression pointer. 1223 1.1 christos 1224 1.1 christos Finally, the return value is nonzero if the calling macro may emit 1225 1.1 christos a LITUSE reloc if otherwise appropriate; the return value is the 1226 1.1 christos sequence number to use. */ 1227 1.1 christos 1228 1.1 christos static long 1229 1.1 christos load_expression (int targreg, 1230 1.1 christos const expressionS *exp, 1231 1.1 christos int *pbasereg, 1232 1.1 christos expressionS *poffset, 1233 1.1 christos const char *opname) 1234 1.1 christos { 1235 1.1 christos long emit_lituse = 0; 1236 1.1 christos offsetT addend = exp->X_add_number; 1237 1.1 christos int basereg = *pbasereg; 1238 1.1 christos struct alpha_insn insn; 1239 1.1 christos expressionS newtok[3]; 1240 1.1 christos 1241 1.1 christos switch (exp->X_op) 1242 1.1 christos { 1243 1.1 christos case O_symbol: 1244 1.1 christos { 1245 1.1 christos #ifdef OBJ_ECOFF 1246 1.1 christos offsetT lit; 1247 1.1 christos 1248 1.1 christos /* Attempt to reduce .lit load by splitting the offset from 1249 1.1 christos its symbol when possible, but don't create a situation in 1250 1.1 christos which we'd fail. */ 1251 1.1 christos if (!range_signed_32 (addend) && 1252 1.1 christos (alpha_noat_on || targreg == AXP_REG_AT)) 1253 1.1 christos { 1254 1.1 christos lit = add_to_literal_pool (exp->X_add_symbol, addend, 1255 1.1 christos alpha_lita_section, 8); 1256 1.1 christos addend = 0; 1257 1.1 christos } 1258 1.1 christos else 1259 1.1 christos lit = add_to_literal_pool (exp->X_add_symbol, 0, 1260 1.1 christos alpha_lita_section, 8); 1261 1.1 christos 1262 1.1 christos if (lit >= 0x8000) 1263 1.1 christos as_fatal (_("overflow in literal (.lita) table")); 1264 1.1 christos 1265 1.1 christos /* Emit "ldq r, lit(gp)". */ 1266 1.1 christos 1267 1.1 christos if (basereg != alpha_gp_register && targreg == basereg) 1268 1.1 christos { 1269 1.1 christos if (alpha_noat_on) 1270 1.1 christos as_bad (_("macro requires $at register while noat in effect")); 1271 1.1 christos if (targreg == AXP_REG_AT) 1272 1.1 christos as_bad (_("macro requires $at while $at in use")); 1273 1.1 christos 1274 1.1 christos set_tok_reg (newtok[0], AXP_REG_AT); 1275 1.1 christos } 1276 1.1 christos else 1277 1.1 christos set_tok_reg (newtok[0], targreg); 1278 1.1 christos 1279 1.1 christos set_tok_sym (newtok[1], alpha_lita_symbol, lit); 1280 1.1 christos set_tok_preg (newtok[2], alpha_gp_register); 1281 1.1 christos 1282 1.1 christos assemble_tokens_to_insn ("ldq", newtok, 3, &insn); 1283 1.1 christos 1284 1.1 christos gas_assert (insn.nfixups == 1); 1285 1.1 christos insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL; 1286 1.1 christos insn.sequence = emit_lituse = next_sequence_num--; 1287 1.1 christos #endif /* OBJ_ECOFF */ 1288 1.1 christos #ifdef OBJ_ELF 1289 1.1 christos /* Emit "ldq r, gotoff(gp)". */ 1290 1.1 christos 1291 1.1 christos if (basereg != alpha_gp_register && targreg == basereg) 1292 1.1 christos { 1293 1.1 christos if (alpha_noat_on) 1294 1.1 christos as_bad (_("macro requires $at register while noat in effect")); 1295 1.1 christos if (targreg == AXP_REG_AT) 1296 1.1 christos as_bad (_("macro requires $at while $at in use")); 1297 1.1 christos 1298 1.1 christos set_tok_reg (newtok[0], AXP_REG_AT); 1299 1.1 christos } 1300 1.1 christos else 1301 1.1 christos set_tok_reg (newtok[0], targreg); 1302 1.1 christos 1303 1.1 christos /* XXX: Disable this .got minimizing optimization so that we can get 1304 1.1 christos better instruction offset knowledge in the compiler. This happens 1305 1.1 christos very infrequently anyway. */ 1306 1.1 christos if (1 1307 1.1 christos || (!range_signed_32 (addend) 1308 1.1 christos && (alpha_noat_on || targreg == AXP_REG_AT))) 1309 1.1 christos { 1310 1.1 christos newtok[1] = *exp; 1311 1.1 christos addend = 0; 1312 1.1 christos } 1313 1.1 christos else 1314 1.1 christos set_tok_sym (newtok[1], exp->X_add_symbol, 0); 1315 1.1 christos 1316 1.1 christos set_tok_preg (newtok[2], alpha_gp_register); 1317 1.1 christos 1318 1.1 christos assemble_tokens_to_insn ("ldq", newtok, 3, &insn); 1319 1.1 christos 1320 1.1 christos gas_assert (insn.nfixups == 1); 1321 1.1 christos insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL; 1322 1.1 christos insn.sequence = emit_lituse = next_sequence_num--; 1323 1.1 christos #endif /* OBJ_ELF */ 1324 1.1 christos #ifdef OBJ_EVAX 1325 1.1 christos /* Find symbol or symbol pointer in link section. */ 1326 1.1 christos 1327 1.1 christos if (exp->X_add_symbol == alpha_evax_proc->symbol) 1328 1.1 christos { 1329 1.1 christos /* Linkage-relative expression. */ 1330 1.1 christos set_tok_reg (newtok[0], targreg); 1331 1.1 christos 1332 1.1 christos if (range_signed_16 (addend)) 1333 1.1 christos { 1334 1.1 christos set_tok_const (newtok[1], addend); 1335 1.1 christos addend = 0; 1336 1.1 christos } 1337 1.1 christos else 1338 1.1 christos { 1339 1.1 christos set_tok_const (newtok[1], 0); 1340 1.1 christos } 1341 1.1 christos set_tok_preg (newtok[2], basereg); 1342 1.1 christos assemble_tokens_to_insn ("lda", newtok, 3, &insn); 1343 1.1 christos } 1344 1.1 christos else 1345 1.1 christos { 1346 1.1 christos const char *symname = S_GET_NAME (exp->X_add_symbol); 1347 1.1 christos const char *ptr1, *ptr2; 1348 1.1 christos int symlen = strlen (symname); 1349 1.1 christos 1350 1.1 christos if ((symlen > 4 && 1351 1.1 christos strcmp (ptr2 = &symname [symlen - 4], "..lk") == 0)) 1352 1.1 christos { 1353 1.1 christos /* Access to an item whose address is stored in the linkage 1354 1.1 christos section. Just read the address. */ 1355 1.1 christos set_tok_reg (newtok[0], targreg); 1356 1.1 christos 1357 1.1 christos newtok[1] = *exp; 1358 1.1 christos newtok[1].X_op = O_subtract; 1359 1.1 christos newtok[1].X_op_symbol = alpha_evax_proc->symbol; 1360 1.1 christos 1361 1.1 christos set_tok_preg (newtok[2], basereg); 1362 1.1 christos assemble_tokens_to_insn ("ldq", newtok, 3, &insn); 1363 1.1 christos alpha_linkage_symbol = exp->X_add_symbol; 1364 1.1 christos 1365 1.1 christos if (poffset) 1366 1.1 christos set_tok_const (*poffset, 0); 1367 1.1 christos 1368 1.1 christos if (alpha_flag_replace && targreg == 26) 1369 1.1 christos { 1370 1.1 christos /* Add a NOP fixup for 'ldX $26,YYY..NAME..lk'. */ 1371 1.5 christos char *ensymname; 1372 1.1 christos symbolS *ensym; 1373 1.1 christos 1374 1.1 christos /* Build the entry name as 'NAME..en'. */ 1375 1.1 christos ptr1 = strstr (symname, "..") + 2; 1376 1.1 christos if (ptr1 > ptr2) 1377 1.1 christos ptr1 = symname; 1378 1.5 christos ensymname = XNEWVEC (char, ptr2 - ptr1 + 5); 1379 1.1 christos memcpy (ensymname, ptr1, ptr2 - ptr1); 1380 1.1 christos memcpy (ensymname + (ptr2 - ptr1), "..en", 5); 1381 1.1 christos 1382 1.1 christos gas_assert (insn.nfixups + 1 <= MAX_INSN_FIXUPS); 1383 1.1 christos insn.fixups[insn.nfixups].reloc = BFD_RELOC_ALPHA_NOP; 1384 1.1 christos ensym = symbol_find_or_make (ensymname); 1385 1.1 christos free (ensymname); 1386 1.1 christos symbol_mark_used (ensym); 1387 1.1 christos /* The fixup must be the same as the BFD_RELOC_ALPHA_BOH 1388 1.1 christos case in emit_jsrjmp. See B.4.5.2 of the OpenVMS Linker 1389 1.1 christos Utility Manual. */ 1390 1.1 christos insn.fixups[insn.nfixups].exp.X_op = O_symbol; 1391 1.1 christos insn.fixups[insn.nfixups].exp.X_add_symbol = ensym; 1392 1.1 christos insn.fixups[insn.nfixups].exp.X_add_number = 0; 1393 1.1 christos insn.fixups[insn.nfixups].xtrasym = alpha_linkage_symbol; 1394 1.1 christos insn.fixups[insn.nfixups].procsym = alpha_evax_proc->symbol; 1395 1.1 christos insn.nfixups++; 1396 1.1 christos 1397 1.1 christos /* ??? Force bsym to be instantiated now, as it will be 1398 1.1 christos too late to do so in tc_gen_reloc. */ 1399 1.1 christos symbol_get_bfdsym (exp->X_add_symbol); 1400 1.1 christos } 1401 1.1 christos else if (alpha_flag_replace && targreg == 27) 1402 1.1 christos { 1403 1.1 christos /* Add a lda fixup for 'ldX $27,YYY.NAME..lk+8'. */ 1404 1.5 christos char *psymname; 1405 1.1 christos symbolS *psym; 1406 1.1 christos 1407 1.1 christos /* Extract NAME. */ 1408 1.1 christos ptr1 = strstr (symname, "..") + 2; 1409 1.5 christos if (ptr1 > ptr2) 1410 1.1 christos ptr1 = symname; 1411 1.1 christos psymname = xmemdup0 (ptr1, ptr2 - ptr1); 1412 1.1 christos 1413 1.1 christos gas_assert (insn.nfixups + 1 <= MAX_INSN_FIXUPS); 1414 1.1 christos insn.fixups[insn.nfixups].reloc = BFD_RELOC_ALPHA_LDA; 1415 1.1 christos psym = symbol_find_or_make (psymname); 1416 1.1 christos free (psymname); 1417 1.1 christos symbol_mark_used (psym); 1418 1.1 christos insn.fixups[insn.nfixups].exp.X_op = O_subtract; 1419 1.1 christos insn.fixups[insn.nfixups].exp.X_add_symbol = psym; 1420 1.1 christos insn.fixups[insn.nfixups].exp.X_op_symbol = alpha_evax_proc->symbol; 1421 1.1 christos insn.fixups[insn.nfixups].exp.X_add_number = 0; 1422 1.1 christos insn.fixups[insn.nfixups].xtrasym = alpha_linkage_symbol; 1423 1.1 christos insn.fixups[insn.nfixups].procsym = alpha_evax_proc->symbol; 1424 1.1 christos insn.nfixups++; 1425 1.1 christos } 1426 1.1 christos 1427 1.1 christos emit_insn (&insn); 1428 1.1 christos return 0; 1429 1.1 christos } 1430 1.1 christos else 1431 1.1 christos { 1432 1.1 christos /* Not in the linkage section. Put the value into the linkage 1433 1.1 christos section. */ 1434 1.1 christos symbolS *linkexp; 1435 1.1 christos 1436 1.1 christos if (!range_signed_32 (addend)) 1437 1.1 christos addend = sign_extend_32 (addend); 1438 1.1 christos linkexp = add_to_link_pool (exp->X_add_symbol, 0); 1439 1.1 christos set_tok_reg (newtok[0], targreg); 1440 1.1 christos set_tok_sym (newtok[1], linkexp, 0); 1441 1.1 christos set_tok_preg (newtok[2], basereg); 1442 1.1 christos assemble_tokens_to_insn ("ldq", newtok, 3, &insn); 1443 1.1 christos } 1444 1.1 christos } 1445 1.1 christos #endif /* OBJ_EVAX */ 1446 1.1 christos 1447 1.1 christos emit_insn (&insn); 1448 1.1 christos 1449 1.1 christos #ifndef OBJ_EVAX 1450 1.1 christos if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO) 1451 1.1 christos { 1452 1.1 christos /* Emit "addq r, base, r". */ 1453 1.1 christos 1454 1.1 christos set_tok_reg (newtok[1], basereg); 1455 1.1 christos set_tok_reg (newtok[2], targreg); 1456 1.1 christos assemble_tokens ("addq", newtok, 3, 0); 1457 1.1 christos } 1458 1.1 christos #endif 1459 1.1 christos basereg = targreg; 1460 1.1 christos } 1461 1.1 christos break; 1462 1.1 christos 1463 1.1 christos case O_constant: 1464 1.1 christos break; 1465 1.1 christos 1466 1.1 christos case O_subtract: 1467 1.1 christos /* Assume that this difference expression will be resolved to an 1468 1.1 christos absolute value and that that value will fit in 16 bits. */ 1469 1.1 christos 1470 1.1 christos set_tok_reg (newtok[0], targreg); 1471 1.1 christos newtok[1] = *exp; 1472 1.1 christos set_tok_preg (newtok[2], basereg); 1473 1.1 christos assemble_tokens (opname, newtok, 3, 0); 1474 1.1 christos 1475 1.1 christos if (poffset) 1476 1.1 christos set_tok_const (*poffset, 0); 1477 1.1 christos return 0; 1478 1.1 christos 1479 1.1 christos case O_big: 1480 1.1 christos if (exp->X_add_number > 0) 1481 1.1 christos as_bad (_("bignum invalid; zero assumed")); 1482 1.1 christos else 1483 1.1 christos as_bad (_("floating point number invalid; zero assumed")); 1484 1.1 christos addend = 0; 1485 1.1 christos break; 1486 1.1 christos 1487 1.1 christos default: 1488 1.1 christos as_bad (_("can't handle expression")); 1489 1.1 christos addend = 0; 1490 1.1 christos break; 1491 1.1 christos } 1492 1.1 christos 1493 1.1 christos if (!range_signed_32 (addend)) 1494 1.1 christos { 1495 1.1 christos #ifdef OBJ_EVAX 1496 1.1 christos symbolS *litexp; 1497 1.1 christos #else 1498 1.1 christos offsetT lit; 1499 1.1 christos long seq_num = next_sequence_num--; 1500 1.1 christos #endif 1501 1.1 christos 1502 1.1 christos /* For 64-bit addends, just put it in the literal pool. */ 1503 1.1 christos #ifdef OBJ_EVAX 1504 1.1 christos /* Emit "ldq targreg, lit(basereg)". */ 1505 1.1 christos litexp = add_to_link_pool (section_symbol (absolute_section), addend); 1506 1.1 christos set_tok_reg (newtok[0], targreg); 1507 1.1 christos set_tok_sym (newtok[1], litexp, 0); 1508 1.1 christos set_tok_preg (newtok[2], alpha_gp_register); 1509 1.1 christos assemble_tokens ("ldq", newtok, 3, 0); 1510 1.1 christos #else 1511 1.1 christos 1512 1.1 christos if (alpha_lit8_section == NULL) 1513 1.1 christos { 1514 1.1 christos create_literal_section (".lit8", 1515 1.1 christos &alpha_lit8_section, 1516 1.1 christos &alpha_lit8_symbol); 1517 1.1 christos 1518 1.1 christos #ifdef OBJ_ECOFF 1519 1.1 christos alpha_lit8_literal = add_to_literal_pool (alpha_lit8_symbol, 0x8000, 1520 1.1 christos alpha_lita_section, 8); 1521 1.1 christos if (alpha_lit8_literal >= 0x8000) 1522 1.1 christos as_fatal (_("overflow in literal (.lita) table")); 1523 1.1 christos #endif 1524 1.1 christos } 1525 1.1 christos 1526 1.1 christos lit = add_to_literal_pool (NULL, addend, alpha_lit8_section, 8) - 0x8000; 1527 1.1 christos if (lit >= 0x8000) 1528 1.1 christos as_fatal (_("overflow in literal (.lit8) table")); 1529 1.1 christos 1530 1.1 christos /* Emit "lda litreg, .lit8+0x8000". */ 1531 1.1 christos 1532 1.1 christos if (targreg == basereg) 1533 1.1 christos { 1534 1.1 christos if (alpha_noat_on) 1535 1.1 christos as_bad (_("macro requires $at register while noat in effect")); 1536 1.1 christos if (targreg == AXP_REG_AT) 1537 1.1 christos as_bad (_("macro requires $at while $at in use")); 1538 1.1 christos 1539 1.1 christos set_tok_reg (newtok[0], AXP_REG_AT); 1540 1.1 christos } 1541 1.1 christos else 1542 1.1 christos set_tok_reg (newtok[0], targreg); 1543 1.1 christos #ifdef OBJ_ECOFF 1544 1.1 christos set_tok_sym (newtok[1], alpha_lita_symbol, alpha_lit8_literal); 1545 1.1 christos #endif 1546 1.1 christos #ifdef OBJ_ELF 1547 1.1 christos set_tok_sym (newtok[1], alpha_lit8_symbol, 0x8000); 1548 1.1 christos #endif 1549 1.1 christos set_tok_preg (newtok[2], alpha_gp_register); 1550 1.1 christos 1551 1.1 christos assemble_tokens_to_insn ("ldq", newtok, 3, &insn); 1552 1.1 christos 1553 1.1 christos gas_assert (insn.nfixups == 1); 1554 1.1 christos #ifdef OBJ_ECOFF 1555 1.1 christos insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL; 1556 1.1 christos #endif 1557 1.1 christos #ifdef OBJ_ELF 1558 1.1 christos insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL; 1559 1.1 christos #endif 1560 1.1 christos insn.sequence = seq_num; 1561 1.1 christos 1562 1.1 christos emit_insn (&insn); 1563 1.1 christos 1564 1.1 christos /* Emit "ldq litreg, lit(litreg)". */ 1565 1.1 christos 1566 1.1 christos set_tok_const (newtok[1], lit); 1567 1.1 christos set_tok_preg (newtok[2], newtok[0].X_add_number); 1568 1.1 christos 1569 1.1 christos assemble_tokens_to_insn ("ldq", newtok, 3, &insn); 1570 1.1 christos 1571 1.1 christos gas_assert (insn.nfixups < MAX_INSN_FIXUPS); 1572 1.1 christos insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE; 1573 1.1 christos insn.fixups[insn.nfixups].exp.X_op = O_absent; 1574 1.1 christos insn.nfixups++; 1575 1.1 christos insn.sequence = seq_num; 1576 1.1 christos emit_lituse = 0; 1577 1.1 christos 1578 1.1 christos emit_insn (&insn); 1579 1.1 christos 1580 1.1 christos /* Emit "addq litreg, base, target". */ 1581 1.1 christos 1582 1.1 christos if (basereg != AXP_REG_ZERO) 1583 1.1 christos { 1584 1.1 christos set_tok_reg (newtok[1], basereg); 1585 1.1 christos set_tok_reg (newtok[2], targreg); 1586 1.1 christos assemble_tokens ("addq", newtok, 3, 0); 1587 1.1 christos } 1588 1.1 christos #endif /* !OBJ_EVAX */ 1589 1.1 christos 1590 1.1 christos if (poffset) 1591 1.1 christos set_tok_const (*poffset, 0); 1592 1.1 christos *pbasereg = targreg; 1593 1.1 christos } 1594 1.1 christos else 1595 1.1 christos { 1596 1.1 christos offsetT low, high, extra, tmp; 1597 1.1 christos 1598 1.1 christos /* For 32-bit operands, break up the addend. */ 1599 1.1 christos 1600 1.1 christos low = sign_extend_16 (addend); 1601 1.1 christos tmp = addend - low; 1602 1.1 christos high = sign_extend_16 (tmp >> 16); 1603 1.1 christos 1604 1.1 christos if (tmp - (high << 16)) 1605 1.1 christos { 1606 1.1 christos extra = 0x4000; 1607 1.1 christos tmp -= 0x40000000; 1608 1.1 christos high = sign_extend_16 (tmp >> 16); 1609 1.1 christos } 1610 1.1 christos else 1611 1.1 christos extra = 0; 1612 1.1 christos 1613 1.1 christos set_tok_reg (newtok[0], targreg); 1614 1.1 christos set_tok_preg (newtok[2], basereg); 1615 1.1 christos 1616 1.1 christos if (extra) 1617 1.1 christos { 1618 1.1 christos /* Emit "ldah r, extra(r). */ 1619 1.1 christos set_tok_const (newtok[1], extra); 1620 1.1 christos assemble_tokens ("ldah", newtok, 3, 0); 1621 1.1 christos set_tok_preg (newtok[2], basereg = targreg); 1622 1.1 christos } 1623 1.1 christos 1624 1.1 christos if (high) 1625 1.1 christos { 1626 1.1 christos /* Emit "ldah r, high(r). */ 1627 1.1 christos set_tok_const (newtok[1], high); 1628 1.1 christos assemble_tokens ("ldah", newtok, 3, 0); 1629 1.1 christos basereg = targreg; 1630 1.1 christos set_tok_preg (newtok[2], basereg); 1631 1.1 christos } 1632 1.1 christos 1633 1.1 christos if ((low && !poffset) || (!poffset && basereg != targreg)) 1634 1.1 christos { 1635 1.1 christos /* Emit "lda r, low(base)". */ 1636 1.1 christos set_tok_const (newtok[1], low); 1637 1.1 christos assemble_tokens ("lda", newtok, 3, 0); 1638 1.1 christos basereg = targreg; 1639 1.1 christos low = 0; 1640 1.1 christos } 1641 1.1 christos 1642 1.1 christos if (poffset) 1643 1.1 christos set_tok_const (*poffset, low); 1644 1.1 christos *pbasereg = basereg; 1645 1.1 christos } 1646 1.1 christos 1647 1.1 christos return emit_lituse; 1648 1.1 christos } 1649 1.1 christos 1650 1.10 christos /* The lda macro differs from the lda instruction in that it handles 1651 1.1 christos most simple expressions, particularly symbol address loads and 1652 1.1 christos large constants. */ 1653 1.1 christos 1654 1.1 christos static void 1655 1.1 christos emit_lda (const expressionS *tok, 1656 1.1 christos int ntok, 1657 1.1 christos alpha_macro_arg unused ATTRIBUTE_UNUSED) 1658 1.1 christos { 1659 1.1 christos int basereg; 1660 1.1 christos 1661 1.1 christos if (ntok == 2) 1662 1.1 christos basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register); 1663 1.1 christos else 1664 1.1 christos basereg = tok[2].X_add_number; 1665 1.1 christos 1666 1.1 christos (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL, "lda"); 1667 1.1 christos } 1668 1.10 christos 1669 1.1 christos /* The ldah macro differs from the ldah instruction in that it has $31 1670 1.1 christos as an implied base register. */ 1671 1.1 christos 1672 1.1 christos static void 1673 1.1 christos emit_ldah (const expressionS *tok, 1674 1.1 christos int ntok ATTRIBUTE_UNUSED, 1675 1.1 christos alpha_macro_arg unused ATTRIBUTE_UNUSED) 1676 1.1 christos { 1677 1.1 christos expressionS newtok[3]; 1678 1.1 christos 1679 1.1 christos newtok[0] = tok[0]; 1680 1.1 christos newtok[1] = tok[1]; 1681 1.1 christos set_tok_preg (newtok[2], AXP_REG_ZERO); 1682 1.1 christos 1683 1.1 christos assemble_tokens ("ldah", newtok, 3, 0); 1684 1.1 christos } 1685 1.1 christos 1686 1.1 christos /* Called internally to handle all alignment needs. This takes care 1687 1.1 christos of eliding calls to frag_align if'n the cached current alignment 1688 1.1 christos says we've already got it, as well as taking care of the auto-align 1689 1.1 christos feature wrt labels. */ 1690 1.1 christos 1691 1.1 christos static void 1692 1.1 christos alpha_align (int n, 1693 1.1 christos char *pfill, 1694 1.1 christos symbolS *label, 1695 1.1 christos int force ATTRIBUTE_UNUSED) 1696 1.1 christos { 1697 1.1 christos if (alpha_current_align >= n) 1698 1.1 christos return; 1699 1.1 christos 1700 1.1 christos if (pfill == NULL) 1701 1.1 christos { 1702 1.1 christos if (subseg_text_p (now_seg)) 1703 1.1 christos frag_align_code (n, 0); 1704 1.1 christos else 1705 1.1 christos frag_align (n, 0, 0); 1706 1.1 christos } 1707 1.1 christos else 1708 1.10 christos frag_align (n, *pfill, 0); 1709 1.1 christos 1710 1.1 christos alpha_current_align = n; 1711 1.1 christos 1712 1.1 christos if (label != NULL && S_GET_SEGMENT (label) == now_seg) 1713 1.1 christos { 1714 1.1 christos symbol_set_frag (label, frag_now); 1715 1.1 christos S_SET_VALUE (label, frag_now_fix ()); 1716 1.1 christos } 1717 1.1 christos 1718 1.1 christos record_alignment (now_seg, n); 1719 1.1 christos 1720 1.1 christos /* ??? If alpha_flag_relax && force && elf, record the requested alignment 1721 1.1 christos in a reloc for the linker to see. */ 1722 1.1 christos } 1723 1.1 christos 1724 1.1 christos /* Actually output an instruction with its fixup. */ 1725 1.1 christos 1726 1.1 christos static void 1727 1.10 christos emit_insn (struct alpha_insn *insn) 1728 1.1 christos { 1729 1.1 christos char *f; 1730 1.1 christos int i; 1731 1.1 christos 1732 1.1 christos /* Take care of alignment duties. */ 1733 1.1 christos if (alpha_auto_align_on && alpha_current_align < 2) 1734 1.1 christos alpha_align (2, NULL, alpha_insn_label, 0); 1735 1.1 christos if (alpha_current_align > 2) 1736 1.1 christos alpha_current_align = 2; 1737 1.1 christos alpha_insn_label = NULL; 1738 1.1 christos 1739 1.1 christos /* Write out the instruction. */ 1740 1.1 christos f = frag_more (4); 1741 1.1 christos md_number_to_chars (f, insn->insn, 4); 1742 1.1 christos 1743 1.10 christos #ifdef OBJ_ELF 1744 1.1 christos dwarf2_emit_insn (4); 1745 1.1 christos #endif 1746 1.1 christos 1747 1.1 christos /* Apply the fixups in order. */ 1748 1.1 christos for (i = 0; i < insn->nfixups; ++i) 1749 1.1 christos { 1750 1.1 christos const struct alpha_operand *operand = NULL; 1751 1.1 christos struct alpha_fixup *fixup = &insn->fixups[i]; 1752 1.1 christos struct alpha_reloc_tag *info = NULL; 1753 1.1 christos int size, pcrel; 1754 1.1 christos fixS *fixP; 1755 1.1 christos 1756 1.1 christos /* Some fixups are only used internally and so have no howto. */ 1757 1.1 christos if ((int) fixup->reloc < 0) 1758 1.1 christos { 1759 1.1 christos operand = &alpha_operands[-(int) fixup->reloc]; 1760 1.1 christos size = 4; 1761 1.1 christos pcrel = ((operand->flags & AXP_OPERAND_RELATIVE) != 0); 1762 1.1 christos } 1763 1.1 christos else if (fixup->reloc > BFD_RELOC_UNUSED 1764 1.1 christos || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16 1765 1.1 christos || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16) 1766 1.10 christos { 1767 1.1 christos size = 2; 1768 1.1 christos pcrel = 0; 1769 1.1 christos } 1770 1.1 christos else 1771 1.1 christos { 1772 1.1 christos reloc_howto_type *reloc_howto = 1773 1.1 christos bfd_reloc_type_lookup (stdoutput, fixup->reloc); 1774 1.1 christos gas_assert (reloc_howto); 1775 1.1 christos 1776 1.1 christos size = bfd_get_reloc_size (reloc_howto); 1777 1.1 christos 1778 1.1 christos switch (fixup->reloc) 1779 1.1 christos { 1780 1.1 christos #ifdef OBJ_EVAX 1781 1.1 christos case BFD_RELOC_ALPHA_NOP: 1782 1.1 christos case BFD_RELOC_ALPHA_BSR: 1783 1.3 christos case BFD_RELOC_ALPHA_LDA: 1784 1.1 christos case BFD_RELOC_ALPHA_BOH: 1785 1.1 christos break; 1786 1.1 christos #endif 1787 1.1 christos default: 1788 1.10 christos gas_assert (size >= 1 && size <= 4); 1789 1.1 christos } 1790 1.1 christos 1791 1.1 christos pcrel = reloc_howto->pc_relative; 1792 1.1 christos } 1793 1.1 christos 1794 1.1 christos fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size, 1795 1.1 christos &fixup->exp, pcrel, fixup->reloc); 1796 1.1 christos 1797 1.1 christos /* Turn off complaints that the addend is too large for some fixups, 1798 1.1 christos and copy in the sequence number for the explicit relocations. */ 1799 1.1 christos switch (fixup->reloc) 1800 1.1 christos { 1801 1.1 christos case BFD_RELOC_ALPHA_HINT: 1802 1.1 christos case BFD_RELOC_GPREL32: 1803 1.1 christos case BFD_RELOC_GPREL16: 1804 1.1 christos case BFD_RELOC_ALPHA_GPREL_HI16: 1805 1.1 christos case BFD_RELOC_ALPHA_GPREL_LO16: 1806 1.1 christos case BFD_RELOC_ALPHA_GOTDTPREL16: 1807 1.1 christos case BFD_RELOC_ALPHA_DTPREL_HI16: 1808 1.1 christos case BFD_RELOC_ALPHA_DTPREL_LO16: 1809 1.1 christos case BFD_RELOC_ALPHA_DTPREL16: 1810 1.1 christos case BFD_RELOC_ALPHA_GOTTPREL16: 1811 1.1 christos case BFD_RELOC_ALPHA_TPREL_HI16: 1812 1.1 christos case BFD_RELOC_ALPHA_TPREL_LO16: 1813 1.1 christos case BFD_RELOC_ALPHA_TPREL16: 1814 1.1 christos fixP->fx_no_overflow = 1; 1815 1.1 christos break; 1816 1.1 christos 1817 1.1 christos case BFD_RELOC_ALPHA_GPDISP_HI16: 1818 1.1 christos fixP->fx_no_overflow = 1; 1819 1.1 christos fixP->fx_addsy = section_symbol (now_seg); 1820 1.1 christos fixP->fx_offset = 0; 1821 1.1 christos 1822 1.1 christos info = get_alpha_reloc_tag (insn->sequence); 1823 1.1 christos if (++info->n_master > 1) 1824 1.1 christos as_bad (_("too many ldah insns for !gpdisp!%ld"), insn->sequence); 1825 1.1 christos if (info->segment != now_seg) 1826 1.1 christos as_bad (_("both insns for !gpdisp!%ld must be in the same section"), 1827 1.1 christos insn->sequence); 1828 1.1 christos fixP->tc_fix_data.info = info; 1829 1.1 christos break; 1830 1.1 christos 1831 1.1 christos case BFD_RELOC_ALPHA_GPDISP_LO16: 1832 1.1 christos fixP->fx_no_overflow = 1; 1833 1.1 christos 1834 1.1 christos info = get_alpha_reloc_tag (insn->sequence); 1835 1.1 christos if (++info->n_slaves > 1) 1836 1.1 christos as_bad (_("too many lda insns for !gpdisp!%ld"), insn->sequence); 1837 1.1 christos if (info->segment != now_seg) 1838 1.1 christos as_bad (_("both insns for !gpdisp!%ld must be in the same section"), 1839 1.1 christos insn->sequence); 1840 1.1 christos fixP->tc_fix_data.info = info; 1841 1.1 christos info->slaves = fixP; 1842 1.1 christos break; 1843 1.1 christos 1844 1.1 christos case BFD_RELOC_ALPHA_LITERAL: 1845 1.1 christos case BFD_RELOC_ALPHA_ELF_LITERAL: 1846 1.1 christos fixP->fx_no_overflow = 1; 1847 1.1 christos 1848 1.1 christos if (insn->sequence == 0) 1849 1.1 christos break; 1850 1.1 christos info = get_alpha_reloc_tag (insn->sequence); 1851 1.1 christos info->master = fixP; 1852 1.1 christos info->n_master++; 1853 1.1 christos if (info->segment != now_seg) 1854 1.1 christos info->multi_section_p = 1; 1855 1.1 christos fixP->tc_fix_data.info = info; 1856 1.1 christos break; 1857 1.1 christos 1858 1.1 christos #ifdef RELOC_OP_P 1859 1.1 christos case DUMMY_RELOC_LITUSE_ADDR: 1860 1.1 christos fixP->fx_offset = LITUSE_ALPHA_ADDR; 1861 1.1 christos goto do_lituse; 1862 1.1 christos case DUMMY_RELOC_LITUSE_BASE: 1863 1.1 christos fixP->fx_offset = LITUSE_ALPHA_BASE; 1864 1.1 christos goto do_lituse; 1865 1.1 christos case DUMMY_RELOC_LITUSE_BYTOFF: 1866 1.1 christos fixP->fx_offset = LITUSE_ALPHA_BYTOFF; 1867 1.1 christos goto do_lituse; 1868 1.1 christos case DUMMY_RELOC_LITUSE_JSR: 1869 1.1 christos fixP->fx_offset = LITUSE_ALPHA_JSR; 1870 1.1 christos goto do_lituse; 1871 1.1 christos case DUMMY_RELOC_LITUSE_TLSGD: 1872 1.1 christos fixP->fx_offset = LITUSE_ALPHA_TLSGD; 1873 1.1 christos goto do_lituse; 1874 1.1 christos case DUMMY_RELOC_LITUSE_TLSLDM: 1875 1.1 christos fixP->fx_offset = LITUSE_ALPHA_TLSLDM; 1876 1.1 christos goto do_lituse; 1877 1.1 christos case DUMMY_RELOC_LITUSE_JSRDIRECT: 1878 1.1 christos fixP->fx_offset = LITUSE_ALPHA_JSRDIRECT; 1879 1.1 christos goto do_lituse; 1880 1.1 christos do_lituse: 1881 1.1 christos fixP->fx_addsy = section_symbol (now_seg); 1882 1.1 christos fixP->fx_r_type = BFD_RELOC_ALPHA_LITUSE; 1883 1.1 christos 1884 1.1 christos info = get_alpha_reloc_tag (insn->sequence); 1885 1.1 christos if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSGD) 1886 1.1 christos info->saw_lu_tlsgd = 1; 1887 1.1 christos else if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSLDM) 1888 1.1 christos info->saw_lu_tlsldm = 1; 1889 1.1 christos if (++info->n_slaves > 1) 1890 1.1 christos { 1891 1.1 christos if (info->saw_lu_tlsgd) 1892 1.1 christos as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"), 1893 1.1 christos insn->sequence); 1894 1.1 christos else if (info->saw_lu_tlsldm) 1895 1.1 christos as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"), 1896 1.1 christos insn->sequence); 1897 1.1 christos } 1898 1.1 christos fixP->tc_fix_data.info = info; 1899 1.1 christos fixP->tc_fix_data.next_reloc = info->slaves; 1900 1.1 christos info->slaves = fixP; 1901 1.1 christos if (info->segment != now_seg) 1902 1.1 christos info->multi_section_p = 1; 1903 1.1 christos break; 1904 1.1 christos 1905 1.1 christos case BFD_RELOC_ALPHA_TLSGD: 1906 1.1 christos fixP->fx_no_overflow = 1; 1907 1.1 christos 1908 1.1 christos if (insn->sequence == 0) 1909 1.1 christos break; 1910 1.1 christos info = get_alpha_reloc_tag (insn->sequence); 1911 1.1 christos if (info->saw_tlsgd) 1912 1.1 christos as_bad (_("duplicate !tlsgd!%ld"), insn->sequence); 1913 1.1 christos else if (info->saw_tlsldm) 1914 1.1 christos as_bad (_("sequence number in use for !tlsldm!%ld"), 1915 1.1 christos insn->sequence); 1916 1.1 christos else 1917 1.1 christos info->saw_tlsgd = 1; 1918 1.1 christos fixP->tc_fix_data.info = info; 1919 1.1 christos break; 1920 1.1 christos 1921 1.1 christos case BFD_RELOC_ALPHA_TLSLDM: 1922 1.1 christos fixP->fx_no_overflow = 1; 1923 1.1 christos 1924 1.1 christos if (insn->sequence == 0) 1925 1.1 christos break; 1926 1.1 christos info = get_alpha_reloc_tag (insn->sequence); 1927 1.1 christos if (info->saw_tlsldm) 1928 1.1 christos as_bad (_("duplicate !tlsldm!%ld"), insn->sequence); 1929 1.1 christos else if (info->saw_tlsgd) 1930 1.1 christos as_bad (_("sequence number in use for !tlsgd!%ld"), 1931 1.1 christos insn->sequence); 1932 1.1 christos else 1933 1.1 christos info->saw_tlsldm = 1; 1934 1.1 christos fixP->tc_fix_data.info = info; 1935 1.1 christos break; 1936 1.1 christos #endif 1937 1.1 christos #ifdef OBJ_EVAX 1938 1.1 christos case BFD_RELOC_ALPHA_NOP: 1939 1.1 christos case BFD_RELOC_ALPHA_LDA: 1940 1.1 christos case BFD_RELOC_ALPHA_BSR: 1941 1.1 christos case BFD_RELOC_ALPHA_BOH: 1942 1.1 christos info = get_alpha_reloc_tag (next_sequence_num--); 1943 1.1 christos fixP->tc_fix_data.info = info; 1944 1.1 christos fixP->tc_fix_data.info->sym = fixup->xtrasym; 1945 1.1 christos fixP->tc_fix_data.info->psym = fixup->procsym; 1946 1.1 christos break; 1947 1.1 christos #endif 1948 1.1 christos 1949 1.1 christos default: 1950 1.1 christos if ((int) fixup->reloc < 0) 1951 1.1 christos { 1952 1.1 christos if (operand->flags & AXP_OPERAND_NOOVERFLOW) 1953 1.1 christos fixP->fx_no_overflow = 1; 1954 1.1 christos } 1955 1.1 christos break; 1956 1.1 christos } 1957 1.1 christos } 1958 1.1 christos } 1959 1.5 christos 1960 1.1 christos /* Insert an operand value into an instruction. */ 1961 1.1 christos 1962 1.8 christos static unsigned 1963 1.1 christos insert_operand (unsigned insn, 1964 1.1 christos const struct alpha_operand *operand, 1965 1.1 christos offsetT val, 1966 1.1 christos const char *file, 1967 1.1 christos unsigned line) 1968 1.1 christos { 1969 1.1 christos if (!(operand->flags & AXP_OPERAND_NOOVERFLOW)) 1970 1.1 christos { 1971 1.1 christos offsetT min, max; 1972 1.1 christos 1973 1.1 christos if (operand->flags & AXP_OPERAND_SIGNED) 1974 1.1 christos { 1975 1.1 christos max = (1 << (operand->bits - 1)) - 1; 1976 1.1 christos min = -(1 << (operand->bits - 1)); 1977 1.1 christos } 1978 1.1 christos else 1979 1.1 christos { 1980 1.1 christos max = (1 << operand->bits) - 1; 1981 1.1 christos min = 0; 1982 1.1 christos } 1983 1.1 christos 1984 1.1 christos if (val < min || val > max) 1985 1.1 christos as_bad_value_out_of_range (_("operand"), val, min, max, file, line); 1986 1.1 christos } 1987 1.1 christos 1988 1.1 christos if (operand->insert) 1989 1.1 christos { 1990 1.1 christos const char *errmsg = NULL; 1991 1.1 christos 1992 1.1 christos insn = (*operand->insert) (insn, val, &errmsg); 1993 1.1 christos if (errmsg) 1994 1.1 christos as_warn ("%s", errmsg); 1995 1.1 christos } 1996 1.1 christos else 1997 1.1 christos insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift); 1998 1.1 christos 1999 1.1 christos return insn; 2000 1.1 christos } 2001 1.1 christos 2002 1.1 christos /* Turn an opcode description and a set of arguments into 2003 1.1 christos an instruction and a fixup. */ 2004 1.1 christos 2005 1.1 christos static void 2006 1.1 christos assemble_insn (const struct alpha_opcode *opcode, 2007 1.1 christos const expressionS *tok, 2008 1.1 christos int ntok, 2009 1.1 christos struct alpha_insn *insn, 2010 1.1 christos extended_bfd_reloc_code_real_type reloc) 2011 1.1 christos { 2012 1.1 christos const struct alpha_operand *reloc_operand = NULL; 2013 1.1 christos const expressionS *reloc_exp = NULL; 2014 1.1 christos const unsigned char *argidx; 2015 1.1 christos unsigned image; 2016 1.1 christos int tokidx = 0; 2017 1.10 christos 2018 1.1 christos memset (insn, 0, sizeof (*insn)); 2019 1.1 christos image = opcode->opcode; 2020 1.1 christos 2021 1.1 christos for (argidx = opcode->operands; *argidx; ++argidx) 2022 1.1 christos { 2023 1.1 christos const struct alpha_operand *operand = &alpha_operands[*argidx]; 2024 1.1 christos const expressionS *t = NULL; 2025 1.1 christos 2026 1.1 christos if (operand->flags & AXP_OPERAND_FAKE) 2027 1.1 christos { 2028 1.1 christos /* Fake operands take no value and generate no fixup. */ 2029 1.1 christos image = insert_operand (image, operand, 0, NULL, 0); 2030 1.1 christos continue; 2031 1.1 christos } 2032 1.1 christos 2033 1.1 christos if (tokidx >= ntok) 2034 1.1 christos { 2035 1.1 christos switch (operand->flags & AXP_OPERAND_OPTIONAL_MASK) 2036 1.1 christos { 2037 1.1 christos case AXP_OPERAND_DEFAULT_FIRST: 2038 1.1 christos t = &tok[0]; 2039 1.1 christos break; 2040 1.1 christos case AXP_OPERAND_DEFAULT_SECOND: 2041 1.1 christos t = &tok[1]; 2042 1.1 christos break; 2043 1.1 christos case AXP_OPERAND_DEFAULT_ZERO: 2044 1.1 christos { 2045 1.1 christos static expressionS zero_exp; 2046 1.1 christos t = &zero_exp; 2047 1.1 christos zero_exp.X_op = O_constant; 2048 1.1 christos zero_exp.X_unsigned = 1; 2049 1.1 christos } 2050 1.1 christos break; 2051 1.1 christos default: 2052 1.1 christos abort (); 2053 1.1 christos } 2054 1.1 christos } 2055 1.1 christos else 2056 1.1 christos t = &tok[tokidx++]; 2057 1.1 christos 2058 1.1 christos switch (t->X_op) 2059 1.1 christos { 2060 1.1 christos case O_register: 2061 1.1 christos case O_pregister: 2062 1.1 christos case O_cpregister: 2063 1.1 christos image = insert_operand (image, operand, regno (t->X_add_number), 2064 1.1 christos NULL, 0); 2065 1.1 christos break; 2066 1.1 christos 2067 1.1 christos case O_constant: 2068 1.1 christos image = insert_operand (image, operand, t->X_add_number, NULL, 0); 2069 1.1 christos gas_assert (reloc_operand == NULL); 2070 1.1 christos reloc_operand = operand; 2071 1.1 christos reloc_exp = t; 2072 1.1 christos break; 2073 1.1 christos 2074 1.1 christos default: 2075 1.1 christos /* This is only 0 for fields that should contain registers, 2076 1.1 christos which means this pattern shouldn't have matched. */ 2077 1.1 christos if (operand->default_reloc == 0) 2078 1.1 christos abort (); 2079 1.1 christos 2080 1.1 christos /* There is one special case for which an insn receives two 2081 1.1 christos relocations, and thus the user-supplied reloc does not 2082 1.1 christos override the operand reloc. */ 2083 1.1 christos if (operand->default_reloc == BFD_RELOC_ALPHA_HINT) 2084 1.1 christos { 2085 1.1 christos struct alpha_fixup *fixup; 2086 1.1 christos 2087 1.1 christos if (insn->nfixups >= MAX_INSN_FIXUPS) 2088 1.1 christos as_fatal (_("too many fixups")); 2089 1.1 christos 2090 1.1 christos fixup = &insn->fixups[insn->nfixups++]; 2091 1.1 christos fixup->exp = *t; 2092 1.1 christos fixup->reloc = BFD_RELOC_ALPHA_HINT; 2093 1.1 christos } 2094 1.1 christos else 2095 1.1 christos { 2096 1.1 christos if (reloc == BFD_RELOC_UNUSED) 2097 1.1 christos reloc = operand->default_reloc; 2098 1.1 christos 2099 1.1 christos gas_assert (reloc_operand == NULL); 2100 1.1 christos reloc_operand = operand; 2101 1.1 christos reloc_exp = t; 2102 1.1 christos } 2103 1.1 christos break; 2104 1.1 christos } 2105 1.1 christos } 2106 1.1 christos 2107 1.1 christos if (reloc != BFD_RELOC_UNUSED) 2108 1.1 christos { 2109 1.1 christos struct alpha_fixup *fixup; 2110 1.1 christos 2111 1.1 christos if (insn->nfixups >= MAX_INSN_FIXUPS) 2112 1.1 christos as_fatal (_("too many fixups")); 2113 1.1 christos 2114 1.1 christos /* ??? My but this is hacky. But the OSF/1 assembler uses the same 2115 1.1 christos relocation tag for both ldah and lda with gpdisp. Choose the 2116 1.1 christos correct internal relocation based on the opcode. */ 2117 1.1 christos if (reloc == BFD_RELOC_ALPHA_GPDISP) 2118 1.1 christos { 2119 1.1 christos if (strcmp (opcode->name, "ldah") == 0) 2120 1.1 christos reloc = BFD_RELOC_ALPHA_GPDISP_HI16; 2121 1.1 christos else if (strcmp (opcode->name, "lda") == 0) 2122 1.3 christos reloc = BFD_RELOC_ALPHA_GPDISP_LO16; 2123 1.1 christos else 2124 1.1 christos as_bad (_("invalid relocation for instruction")); 2125 1.1 christos } 2126 1.10 christos 2127 1.1 christos /* If this is a real relocation (as opposed to a lituse hint), then 2128 1.1 christos the relocation width should match the operand width. 2129 1.1 christos Take care of -MDISP in operand table. */ 2130 1.1 christos else if (reloc < BFD_RELOC_UNUSED && reloc > 0) 2131 1.1 christos { 2132 1.1 christos reloc_howto_type *reloc_howto 2133 1.1 christos = bfd_reloc_type_lookup (stdoutput, reloc); 2134 1.1 christos if (reloc_operand == NULL 2135 1.1 christos || reloc_howto->bitsize != reloc_operand->bits) 2136 1.1 christos { 2137 1.1 christos as_bad (_("invalid relocation for field")); 2138 1.1 christos return; 2139 1.1 christos } 2140 1.1 christos } 2141 1.1 christos 2142 1.1 christos fixup = &insn->fixups[insn->nfixups++]; 2143 1.1 christos if (reloc_exp) 2144 1.1 christos fixup->exp = *reloc_exp; 2145 1.1 christos else 2146 1.1 christos fixup->exp.X_op = O_absent; 2147 1.1 christos fixup->reloc = reloc; 2148 1.1 christos } 2149 1.1 christos 2150 1.1 christos insn->insn = image; 2151 1.1 christos } 2152 1.1 christos 2153 1.10 christos /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u, 2154 1.1 christos etc. They differ from the real instructions in that they do simple 2155 1.1 christos expressions like the lda macro. */ 2156 1.1 christos 2157 1.1 christos static void 2158 1.1 christos emit_ir_load (const expressionS *tok, 2159 1.1 christos int ntok, 2160 1.1 christos alpha_macro_arg opname) 2161 1.1 christos { 2162 1.1 christos int basereg; 2163 1.1 christos long lituse; 2164 1.1 christos expressionS newtok[3]; 2165 1.1 christos struct alpha_insn insn; 2166 1.1 christos const char *symname 2167 1.1 christos = tok[1].X_add_symbol ? S_GET_NAME (tok[1].X_add_symbol): ""; 2168 1.1 christos int symlen = strlen (symname); 2169 1.10 christos 2170 1.1 christos if (ntok == 2) 2171 1.1 christos basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register); 2172 1.1 christos else 2173 1.1 christos basereg = tok[2].X_add_number; 2174 1.3 christos 2175 1.1 christos lituse = load_expression (tok[0].X_add_number, &tok[1], 2176 1.1 christos &basereg, &newtok[1], opname.p); 2177 1.1 christos 2178 1.10 christos if (basereg == alpha_gp_register && 2179 1.1 christos (symlen > 4 && strcmp (&symname [symlen - 4], "..lk") == 0)) 2180 1.1 christos return; 2181 1.1 christos 2182 1.1 christos newtok[0] = tok[0]; 2183 1.1 christos set_tok_preg (newtok[2], basereg); 2184 1.1 christos 2185 1.1 christos assemble_tokens_to_insn (opname.p, newtok, 3, &insn); 2186 1.1 christos 2187 1.1 christos if (lituse) 2188 1.1 christos { 2189 1.1 christos gas_assert (insn.nfixups < MAX_INSN_FIXUPS); 2190 1.1 christos insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE; 2191 1.1 christos insn.fixups[insn.nfixups].exp.X_op = O_absent; 2192 1.1 christos insn.nfixups++; 2193 1.1 christos insn.sequence = lituse; 2194 1.1 christos } 2195 1.1 christos 2196 1.1 christos emit_insn (&insn); 2197 1.1 christos } 2198 1.10 christos 2199 1.1 christos /* Handle fp register loads, and both integer and fp register stores. 2200 1.1 christos Again, we handle simple expressions. */ 2201 1.1 christos 2202 1.1 christos static void 2203 1.1 christos emit_loadstore (const expressionS *tok, 2204 1.1 christos int ntok, 2205 1.1 christos alpha_macro_arg opname) 2206 1.1 christos { 2207 1.1 christos int basereg; 2208 1.1 christos long lituse; 2209 1.1 christos expressionS newtok[3]; 2210 1.1 christos struct alpha_insn insn; 2211 1.1 christos 2212 1.1 christos if (ntok == 2) 2213 1.1 christos basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register); 2214 1.1 christos else 2215 1.3 christos basereg = tok[2].X_add_number; 2216 1.10 christos 2217 1.1 christos if (tok[1].X_op != O_constant || !range_signed_16 (tok[1].X_add_number)) 2218 1.1 christos { 2219 1.1 christos if (alpha_noat_on) 2220 1.1 christos as_bad (_("macro requires $at register while noat in effect")); 2221 1.1 christos 2222 1.1 christos lituse = load_expression (AXP_REG_AT, &tok[1], 2223 1.1 christos &basereg, &newtok[1], opname.p); 2224 1.1 christos } 2225 1.1 christos else 2226 1.1 christos { 2227 1.10 christos newtok[1] = tok[1]; 2228 1.1 christos lituse = 0; 2229 1.1 christos } 2230 1.1 christos 2231 1.1 christos newtok[0] = tok[0]; 2232 1.1 christos set_tok_preg (newtok[2], basereg); 2233 1.1 christos 2234 1.1 christos assemble_tokens_to_insn (opname.p, newtok, 3, &insn); 2235 1.1 christos 2236 1.1 christos if (lituse) 2237 1.1 christos { 2238 1.1 christos gas_assert (insn.nfixups < MAX_INSN_FIXUPS); 2239 1.1 christos insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE; 2240 1.1 christos insn.fixups[insn.nfixups].exp.X_op = O_absent; 2241 1.1 christos insn.nfixups++; 2242 1.1 christos insn.sequence = lituse; 2243 1.1 christos } 2244 1.1 christos 2245 1.1 christos emit_insn (&insn); 2246 1.10 christos } 2247 1.1 christos 2248 1.1 christos /* Load a half-word or byte as an unsigned value. */ 2249 1.10 christos 2250 1.1 christos static void 2251 1.1 christos emit_ldXu (const expressionS *tok, 2252 1.1 christos int ntok, 2253 1.1 christos alpha_macro_arg lgsize) 2254 1.1 christos { 2255 1.1 christos if (alpha_target & AXP_OPCODE_BWX) 2256 1.1 christos emit_ir_load (tok, ntok, (alpha_macro_arg) { ldXu_op[lgsize.i] }); 2257 1.1 christos else 2258 1.1 christos { 2259 1.1 christos expressionS newtok[3]; 2260 1.1 christos struct alpha_insn insn; 2261 1.1 christos int basereg; 2262 1.1 christos long lituse; 2263 1.1 christos 2264 1.1 christos if (alpha_noat_on) 2265 1.1 christos as_bad (_("macro requires $at register while noat in effect")); 2266 1.1 christos 2267 1.1 christos if (ntok == 2) 2268 1.1 christos basereg = (tok[1].X_op == O_constant 2269 1.1 christos ? AXP_REG_ZERO : alpha_gp_register); 2270 1.1 christos else 2271 1.1 christos basereg = tok[2].X_add_number; 2272 1.1 christos 2273 1.1 christos /* Emit "lda $at, exp". */ 2274 1.1 christos lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL, "lda"); 2275 1.1 christos 2276 1.1 christos /* Emit "ldq_u targ, 0($at)". */ 2277 1.1 christos newtok[0] = tok[0]; 2278 1.1 christos set_tok_const (newtok[1], 0); 2279 1.1 christos set_tok_preg (newtok[2], basereg); 2280 1.1 christos assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn); 2281 1.1 christos 2282 1.1 christos if (lituse) 2283 1.1 christos { 2284 1.1 christos gas_assert (insn.nfixups < MAX_INSN_FIXUPS); 2285 1.1 christos insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE; 2286 1.1 christos insn.fixups[insn.nfixups].exp.X_op = O_absent; 2287 1.1 christos insn.nfixups++; 2288 1.1 christos insn.sequence = lituse; 2289 1.10 christos } 2290 1.1 christos 2291 1.1 christos emit_insn (&insn); 2292 1.1 christos 2293 1.1 christos /* Emit "extXl targ, $at, targ". */ 2294 1.1 christos set_tok_reg (newtok[1], basereg); 2295 1.1 christos newtok[2] = newtok[0]; 2296 1.1 christos assemble_tokens_to_insn (extXl_op[lgsize.i], newtok, 3, &insn); 2297 1.1 christos 2298 1.1 christos if (lituse) 2299 1.1 christos { 2300 1.1 christos gas_assert (insn.nfixups < MAX_INSN_FIXUPS); 2301 1.1 christos insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF; 2302 1.1 christos insn.fixups[insn.nfixups].exp.X_op = O_absent; 2303 1.1 christos insn.nfixups++; 2304 1.1 christos insn.sequence = lituse; 2305 1.1 christos } 2306 1.1 christos 2307 1.1 christos emit_insn (&insn); 2308 1.1 christos } 2309 1.10 christos } 2310 1.1 christos 2311 1.10 christos /* Load a half-word or byte as a signed value. */ 2312 1.10 christos 2313 1.1 christos static void 2314 1.1 christos emit_ldX (const expressionS *tok, 2315 1.1 christos int ntok, 2316 1.1 christos alpha_macro_arg lgsize) 2317 1.1 christos { 2318 1.1 christos emit_ldXu (tok, ntok, lgsize); 2319 1.1 christos assemble_tokens (sextX_op[lgsize.i], tok, 1, 1); 2320 1.1 christos } 2321 1.10 christos 2322 1.1 christos /* Load an integral value from an unaligned address as an unsigned 2323 1.1 christos value. */ 2324 1.1 christos 2325 1.1 christos static void 2326 1.1 christos emit_uldXu (const expressionS *tok, 2327 1.1 christos int ntok, 2328 1.1 christos alpha_macro_arg lgsize) 2329 1.1 christos { 2330 1.1 christos expressionS newtok[3]; 2331 1.1 christos 2332 1.1 christos if (alpha_noat_on) 2333 1.1 christos as_bad (_("macro requires $at register while noat in effect")); 2334 1.1 christos 2335 1.1 christos /* Emit "lda $at, exp". */ 2336 1.1 christos memcpy (newtok, tok, sizeof (expressionS) * ntok); 2337 1.1 christos newtok[0].X_add_number = AXP_REG_AT; 2338 1.1 christos assemble_tokens ("lda", newtok, ntok, 1); 2339 1.1 christos 2340 1.1 christos /* Emit "ldq_u $t9, 0($at)". */ 2341 1.10 christos set_tok_reg (newtok[0], AXP_REG_T9); 2342 1.1 christos set_tok_const (newtok[1], 0); 2343 1.1 christos set_tok_preg (newtok[2], AXP_REG_AT); 2344 1.1 christos assemble_tokens ("ldq_u", newtok, 3, 1); 2345 1.1 christos 2346 1.1 christos /* Emit "ldq_u $t10, size-1($at)". */ 2347 1.1 christos set_tok_reg (newtok[0], AXP_REG_T10); 2348 1.10 christos set_tok_const (newtok[1], (1 << lgsize.i) - 1); 2349 1.1 christos assemble_tokens ("ldq_u", newtok, 3, 1); 2350 1.1 christos 2351 1.1 christos /* Emit "extXl $t9, $at, $t9". */ 2352 1.1 christos set_tok_reg (newtok[0], AXP_REG_T9); 2353 1.10 christos set_tok_reg (newtok[1], AXP_REG_AT); 2354 1.1 christos set_tok_reg (newtok[2], AXP_REG_T9); 2355 1.1 christos assemble_tokens (extXl_op[lgsize.i], newtok, 3, 1); 2356 1.1 christos 2357 1.1 christos /* Emit "extXh $t10, $at, $t10". */ 2358 1.1 christos set_tok_reg (newtok[0], AXP_REG_T10); 2359 1.1 christos set_tok_reg (newtok[2], AXP_REG_T10); 2360 1.1 christos assemble_tokens (extXh_op[lgsize.i], newtok, 3, 1); 2361 1.1 christos 2362 1.1 christos /* Emit "or $t9, $t10, targ". */ 2363 1.1 christos set_tok_reg (newtok[0], AXP_REG_T9); 2364 1.1 christos set_tok_reg (newtok[1], AXP_REG_T10); 2365 1.1 christos newtok[2] = tok[0]; 2366 1.1 christos assemble_tokens ("or", newtok, 3, 1); 2367 1.1 christos } 2368 1.1 christos 2369 1.10 christos /* Load an integral value from an unaligned address as a signed value. 2370 1.1 christos Note that quads should get funneled to the unsigned load since we 2371 1.10 christos don't have to do the sign extension. */ 2372 1.10 christos 2373 1.1 christos static void 2374 1.1 christos emit_uldX (const expressionS *tok, 2375 1.1 christos int ntok, 2376 1.1 christos alpha_macro_arg lgsize) 2377 1.1 christos { 2378 1.1 christos emit_uldXu (tok, ntok, lgsize); 2379 1.1 christos assemble_tokens (sextX_op[lgsize.i], tok, 1, 1); 2380 1.10 christos } 2381 1.1 christos 2382 1.1 christos /* Implement the ldil macro. */ 2383 1.1 christos 2384 1.1 christos static void 2385 1.1 christos emit_ldil (const expressionS *tok, 2386 1.1 christos int ntok, 2387 1.1 christos alpha_macro_arg unused ATTRIBUTE_UNUSED) 2388 1.1 christos { 2389 1.1 christos expressionS newtok[2]; 2390 1.1 christos 2391 1.1 christos memcpy (newtok, tok, sizeof (newtok)); 2392 1.1 christos newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number); 2393 1.1 christos 2394 1.1 christos assemble_tokens ("lda", newtok, ntok, 1); 2395 1.10 christos } 2396 1.1 christos 2397 1.1 christos /* Store a half-word or byte. */ 2398 1.10 christos 2399 1.1 christos static void 2400 1.1 christos emit_stX (const expressionS *tok, 2401 1.1 christos int ntok, 2402 1.1 christos alpha_macro_arg lgsize) 2403 1.1 christos { 2404 1.1 christos if (alpha_target & AXP_OPCODE_BWX) 2405 1.1 christos emit_loadstore (tok, ntok, (alpha_macro_arg) { stX_op[lgsize.i] }); 2406 1.1 christos else 2407 1.1 christos { 2408 1.1 christos expressionS newtok[3]; 2409 1.1 christos struct alpha_insn insn; 2410 1.1 christos int basereg; 2411 1.1 christos long lituse; 2412 1.1 christos 2413 1.1 christos if (alpha_noat_on) 2414 1.1 christos as_bad (_("macro requires $at register while noat in effect")); 2415 1.1 christos 2416 1.1 christos if (ntok == 2) 2417 1.1 christos basereg = (tok[1].X_op == O_constant 2418 1.1 christos ? AXP_REG_ZERO : alpha_gp_register); 2419 1.1 christos else 2420 1.1 christos basereg = tok[2].X_add_number; 2421 1.1 christos 2422 1.1 christos /* Emit "lda $at, exp". */ 2423 1.1 christos lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL, "lda"); 2424 1.1 christos 2425 1.1 christos /* Emit "ldq_u $t9, 0($at)". */ 2426 1.1 christos set_tok_reg (newtok[0], AXP_REG_T9); 2427 1.1 christos set_tok_const (newtok[1], 0); 2428 1.1 christos set_tok_preg (newtok[2], basereg); 2429 1.1 christos assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn); 2430 1.1 christos 2431 1.1 christos if (lituse) 2432 1.1 christos { 2433 1.1 christos gas_assert (insn.nfixups < MAX_INSN_FIXUPS); 2434 1.1 christos insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE; 2435 1.1 christos insn.fixups[insn.nfixups].exp.X_op = O_absent; 2436 1.1 christos insn.nfixups++; 2437 1.1 christos insn.sequence = lituse; 2438 1.1 christos } 2439 1.10 christos 2440 1.1 christos emit_insn (&insn); 2441 1.1 christos 2442 1.1 christos /* Emit "insXl src, $at, $t10". */ 2443 1.1 christos newtok[0] = tok[0]; 2444 1.1 christos set_tok_reg (newtok[1], basereg); 2445 1.1 christos set_tok_reg (newtok[2], AXP_REG_T10); 2446 1.1 christos assemble_tokens_to_insn (insXl_op[lgsize.i], newtok, 3, &insn); 2447 1.1 christos 2448 1.1 christos if (lituse) 2449 1.1 christos { 2450 1.1 christos gas_assert (insn.nfixups < MAX_INSN_FIXUPS); 2451 1.1 christos insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF; 2452 1.1 christos insn.fixups[insn.nfixups].exp.X_op = O_absent; 2453 1.1 christos insn.nfixups++; 2454 1.1 christos insn.sequence = lituse; 2455 1.10 christos } 2456 1.1 christos 2457 1.1 christos emit_insn (&insn); 2458 1.1 christos 2459 1.1 christos /* Emit "mskXl $t9, $at, $t9". */ 2460 1.1 christos set_tok_reg (newtok[0], AXP_REG_T9); 2461 1.1 christos newtok[2] = newtok[0]; 2462 1.1 christos assemble_tokens_to_insn (mskXl_op[lgsize.i], newtok, 3, &insn); 2463 1.1 christos 2464 1.1 christos if (lituse) 2465 1.1 christos { 2466 1.1 christos gas_assert (insn.nfixups < MAX_INSN_FIXUPS); 2467 1.1 christos insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF; 2468 1.1 christos insn.fixups[insn.nfixups].exp.X_op = O_absent; 2469 1.1 christos insn.nfixups++; 2470 1.1 christos insn.sequence = lituse; 2471 1.1 christos } 2472 1.1 christos 2473 1.1 christos emit_insn (&insn); 2474 1.1 christos 2475 1.1 christos /* Emit "or $t9, $t10, $t9". */ 2476 1.1 christos set_tok_reg (newtok[1], AXP_REG_T10); 2477 1.1 christos assemble_tokens ("or", newtok, 3, 1); 2478 1.1 christos 2479 1.1 christos /* Emit "stq_u $t9, 0($at). */ 2480 1.1 christos set_tok_const(newtok[1], 0); 2481 1.1 christos set_tok_preg (newtok[2], AXP_REG_AT); 2482 1.1 christos assemble_tokens_to_insn ("stq_u", newtok, 3, &insn); 2483 1.1 christos 2484 1.1 christos if (lituse) 2485 1.1 christos { 2486 1.1 christos gas_assert (insn.nfixups < MAX_INSN_FIXUPS); 2487 1.1 christos insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE; 2488 1.1 christos insn.fixups[insn.nfixups].exp.X_op = O_absent; 2489 1.1 christos insn.nfixups++; 2490 1.1 christos insn.sequence = lituse; 2491 1.1 christos } 2492 1.1 christos 2493 1.1 christos emit_insn (&insn); 2494 1.1 christos } 2495 1.10 christos } 2496 1.1 christos 2497 1.1 christos /* Store an integer to an unaligned address. */ 2498 1.1 christos 2499 1.1 christos static void 2500 1.1 christos emit_ustX (const expressionS *tok, 2501 1.1 christos int ntok, 2502 1.1 christos alpha_macro_arg lgsize) 2503 1.1 christos { 2504 1.1 christos expressionS newtok[3]; 2505 1.1 christos 2506 1.1 christos /* Emit "lda $at, exp". */ 2507 1.1 christos memcpy (newtok, tok, sizeof (expressionS) * ntok); 2508 1.1 christos newtok[0].X_add_number = AXP_REG_AT; 2509 1.1 christos assemble_tokens ("lda", newtok, ntok, 1); 2510 1.1 christos 2511 1.1 christos /* Emit "ldq_u $9, 0($at)". */ 2512 1.10 christos set_tok_reg (newtok[0], AXP_REG_T9); 2513 1.1 christos set_tok_const (newtok[1], 0); 2514 1.1 christos set_tok_preg (newtok[2], AXP_REG_AT); 2515 1.1 christos assemble_tokens ("ldq_u", newtok, 3, 1); 2516 1.1 christos 2517 1.1 christos /* Emit "ldq_u $10, size-1($at)". */ 2518 1.1 christos set_tok_reg (newtok[0], AXP_REG_T10); 2519 1.10 christos set_tok_const (newtok[1], (1 << lgsize.i) - 1); 2520 1.1 christos assemble_tokens ("ldq_u", newtok, 3, 1); 2521 1.1 christos 2522 1.1 christos /* Emit "insXl src, $at, $t11". */ 2523 1.10 christos newtok[0] = tok[0]; 2524 1.1 christos set_tok_reg (newtok[1], AXP_REG_AT); 2525 1.1 christos set_tok_reg (newtok[2], AXP_REG_T11); 2526 1.1 christos assemble_tokens (insXl_op[lgsize.i], newtok, 3, 1); 2527 1.1 christos 2528 1.10 christos /* Emit "insXh src, $at, $t12". */ 2529 1.1 christos set_tok_reg (newtok[2], AXP_REG_T12); 2530 1.1 christos assemble_tokens (insXh_op[lgsize.i], newtok, 3, 1); 2531 1.1 christos 2532 1.1 christos /* Emit "mskXl $t9, $at, $t9". */ 2533 1.10 christos set_tok_reg (newtok[0], AXP_REG_T9); 2534 1.1 christos newtok[2] = newtok[0]; 2535 1.1 christos assemble_tokens (mskXl_op[lgsize.i], newtok, 3, 1); 2536 1.1 christos 2537 1.1 christos /* Emit "mskXh $t10, $at, $t10". */ 2538 1.1 christos set_tok_reg (newtok[0], AXP_REG_T10); 2539 1.1 christos newtok[2] = newtok[0]; 2540 1.1 christos assemble_tokens (mskXh_op[lgsize.i], newtok, 3, 1); 2541 1.1 christos 2542 1.1 christos /* Emit "or $t9, $t11, $t9". */ 2543 1.1 christos set_tok_reg (newtok[0], AXP_REG_T9); 2544 1.1 christos set_tok_reg (newtok[1], AXP_REG_T11); 2545 1.1 christos newtok[2] = newtok[0]; 2546 1.1 christos assemble_tokens ("or", newtok, 3, 1); 2547 1.1 christos 2548 1.1 christos /* Emit "or $t10, $t12, $t10". */ 2549 1.10 christos set_tok_reg (newtok[0], AXP_REG_T10); 2550 1.1 christos set_tok_reg (newtok[1], AXP_REG_T12); 2551 1.1 christos newtok[2] = newtok[0]; 2552 1.1 christos assemble_tokens ("or", newtok, 3, 1); 2553 1.1 christos 2554 1.1 christos /* Emit "stq_u $t10, size-1($at)". */ 2555 1.1 christos set_tok_reg (newtok[0], AXP_REG_T10); 2556 1.1 christos set_tok_const (newtok[1], (1 << lgsize.i) - 1); 2557 1.1 christos set_tok_preg (newtok[2], AXP_REG_AT); 2558 1.1 christos assemble_tokens ("stq_u", newtok, 3, 1); 2559 1.1 christos 2560 1.1 christos /* Emit "stq_u $t9, 0($at)". */ 2561 1.1 christos set_tok_reg (newtok[0], AXP_REG_T9); 2562 1.1 christos set_tok_const (newtok[1], 0); 2563 1.1 christos assemble_tokens ("stq_u", newtok, 3, 1); 2564 1.1 christos } 2565 1.10 christos 2566 1.1 christos /* Sign extend a half-word or byte. The 32-bit sign extend is 2567 1.1 christos implemented as "addl $31, $r, $t" in the opcode table. */ 2568 1.10 christos 2569 1.1 christos static void 2570 1.1 christos emit_sextX (const expressionS *tok, 2571 1.10 christos int ntok, 2572 1.1 christos alpha_macro_arg lgsize) 2573 1.1 christos { 2574 1.1 christos if (alpha_target & AXP_OPCODE_BWX) 2575 1.1 christos assemble_tokens (sextX_op[lgsize.i], tok, ntok, 0); 2576 1.1 christos else 2577 1.1 christos { 2578 1.1 christos int bitshift = 64 - 8 * (1 << lgsize.i); 2579 1.1 christos expressionS newtok[3]; 2580 1.1 christos 2581 1.1 christos /* Emit "sll src,bits,dst". */ 2582 1.1 christos newtok[0] = tok[0]; 2583 1.1 christos set_tok_const (newtok[1], bitshift); 2584 1.1 christos newtok[2] = tok[ntok - 1]; 2585 1.1 christos assemble_tokens ("sll", newtok, 3, 1); 2586 1.1 christos 2587 1.1 christos /* Emit "sra dst,bits,dst". */ 2588 1.1 christos newtok[0] = newtok[2]; 2589 1.1 christos assemble_tokens ("sra", newtok, 3, 1); 2590 1.1 christos } 2591 1.1 christos } 2592 1.1 christos 2593 1.1 christos /* Implement the division and modulus macros. */ 2594 1.1 christos 2595 1.1 christos #ifdef OBJ_EVAX 2596 1.10 christos 2597 1.1 christos /* Make register usage like in normal procedure call. 2598 1.1 christos Don't clobber PV and RA. */ 2599 1.1 christos 2600 1.1 christos static void 2601 1.1 christos emit_division (const expressionS *tok, 2602 1.1 christos int ntok, 2603 1.1 christos alpha_macro_arg symname) 2604 1.1 christos { 2605 1.1 christos /* DIVISION and MODULUS. Yech. 2606 1.1 christos 2607 1.1 christos Convert 2608 1.1 christos OP x,y,result 2609 1.1 christos to 2610 1.1 christos mov x,R16 # if x != R16 2611 1.1 christos mov y,R17 # if y != R17 2612 1.1 christos lda AT,__OP 2613 1.1 christos jsr AT,(AT),0 2614 1.1 christos mov R0,result 2615 1.1 christos 2616 1.1 christos with appropriate optimizations if R0,R16,R17 are the registers 2617 1.1 christos specified by the compiler. */ 2618 1.1 christos 2619 1.1 christos int xr, yr, rr; 2620 1.1 christos symbolS *sym; 2621 1.1 christos expressionS newtok[3]; 2622 1.1 christos 2623 1.1 christos xr = regno (tok[0].X_add_number); 2624 1.1 christos yr = regno (tok[1].X_add_number); 2625 1.1 christos 2626 1.1 christos if (ntok < 3) 2627 1.1 christos rr = xr; 2628 1.1 christos else 2629 1.1 christos rr = regno (tok[2].X_add_number); 2630 1.1 christos 2631 1.1 christos /* Move the operands into the right place. */ 2632 1.1 christos if (yr == AXP_REG_R16 && xr == AXP_REG_R17) 2633 1.1 christos { 2634 1.1 christos /* They are in exactly the wrong order -- swap through AT. */ 2635 1.1 christos if (alpha_noat_on) 2636 1.1 christos as_bad (_("macro requires $at register while noat in effect")); 2637 1.1 christos 2638 1.1 christos set_tok_reg (newtok[0], AXP_REG_R16); 2639 1.1 christos set_tok_reg (newtok[1], AXP_REG_AT); 2640 1.1 christos assemble_tokens ("mov", newtok, 2, 1); 2641 1.1 christos 2642 1.1 christos set_tok_reg (newtok[0], AXP_REG_R17); 2643 1.1 christos set_tok_reg (newtok[1], AXP_REG_R16); 2644 1.1 christos assemble_tokens ("mov", newtok, 2, 1); 2645 1.1 christos 2646 1.1 christos set_tok_reg (newtok[0], AXP_REG_AT); 2647 1.1 christos set_tok_reg (newtok[1], AXP_REG_R17); 2648 1.1 christos assemble_tokens ("mov", newtok, 2, 1); 2649 1.1 christos } 2650 1.1 christos else 2651 1.1 christos { 2652 1.1 christos if (yr == AXP_REG_R16) 2653 1.1 christos { 2654 1.1 christos set_tok_reg (newtok[0], AXP_REG_R16); 2655 1.1 christos set_tok_reg (newtok[1], AXP_REG_R17); 2656 1.1 christos assemble_tokens ("mov", newtok, 2, 1); 2657 1.1 christos } 2658 1.1 christos 2659 1.1 christos if (xr != AXP_REG_R16) 2660 1.1 christos { 2661 1.1 christos set_tok_reg (newtok[0], xr); 2662 1.1 christos set_tok_reg (newtok[1], AXP_REG_R16); 2663 1.1 christos assemble_tokens ("mov", newtok, 2, 1); 2664 1.1 christos } 2665 1.1 christos 2666 1.1 christos if (yr != AXP_REG_R16 && yr != AXP_REG_R17) 2667 1.10 christos { 2668 1.1 christos set_tok_reg (newtok[0], yr); 2669 1.1 christos set_tok_reg (newtok[1], AXP_REG_R17); 2670 1.1 christos assemble_tokens ("mov", newtok, 2, 1); 2671 1.1 christos } 2672 1.1 christos } 2673 1.1 christos 2674 1.1 christos sym = symbol_find_or_make (symname.p); 2675 1.1 christos 2676 1.1 christos set_tok_reg (newtok[0], AXP_REG_AT); 2677 1.1 christos set_tok_sym (newtok[1], sym, 0); 2678 1.1 christos assemble_tokens ("lda", newtok, 2, 1); 2679 1.1 christos 2680 1.1 christos /* Call the division routine. */ 2681 1.1 christos set_tok_reg (newtok[0], AXP_REG_AT); 2682 1.1 christos set_tok_cpreg (newtok[1], AXP_REG_AT); 2683 1.1 christos set_tok_const (newtok[2], 0); 2684 1.1 christos assemble_tokens ("jsr", newtok, 3, 1); 2685 1.1 christos 2686 1.1 christos /* Move the result to the right place. */ 2687 1.1 christos if (rr != AXP_REG_R0) 2688 1.1 christos { 2689 1.1 christos set_tok_reg (newtok[0], AXP_REG_R0); 2690 1.1 christos set_tok_reg (newtok[1], rr); 2691 1.1 christos assemble_tokens ("mov", newtok, 2, 1); 2692 1.1 christos } 2693 1.10 christos } 2694 1.1 christos 2695 1.1 christos #else /* !OBJ_EVAX */ 2696 1.1 christos 2697 1.1 christos static void 2698 1.1 christos emit_division (const expressionS *tok, 2699 1.1 christos int ntok, 2700 1.1 christos alpha_macro_arg symname) 2701 1.1 christos { 2702 1.1 christos /* DIVISION and MODULUS. Yech. 2703 1.1 christos Convert 2704 1.1 christos OP x,y,result 2705 1.1 christos to 2706 1.1 christos lda pv,__OP 2707 1.1 christos mov x,t10 2708 1.1 christos mov y,t11 2709 1.1 christos jsr t9,(pv),__OP 2710 1.1 christos mov t12,result 2711 1.1 christos 2712 1.1 christos with appropriate optimizations if t10,t11,t12 are the registers 2713 1.1 christos specified by the compiler. */ 2714 1.1 christos 2715 1.1 christos int xr, yr, rr; 2716 1.1 christos symbolS *sym; 2717 1.1 christos expressionS newtok[3]; 2718 1.1 christos 2719 1.1 christos xr = regno (tok[0].X_add_number); 2720 1.10 christos yr = regno (tok[1].X_add_number); 2721 1.1 christos 2722 1.1 christos if (ntok < 3) 2723 1.1 christos rr = xr; 2724 1.1 christos else 2725 1.1 christos rr = regno (tok[2].X_add_number); 2726 1.1 christos 2727 1.1 christos sym = symbol_find_or_make (symname.p); 2728 1.1 christos 2729 1.1 christos /* Move the operands into the right place. */ 2730 1.1 christos if (yr == AXP_REG_T10 && xr == AXP_REG_T11) 2731 1.1 christos { 2732 1.1 christos /* They are in exactly the wrong order -- swap through AT. */ 2733 1.1 christos if (alpha_noat_on) 2734 1.1 christos as_bad (_("macro requires $at register while noat in effect")); 2735 1.1 christos 2736 1.1 christos set_tok_reg (newtok[0], AXP_REG_T10); 2737 1.1 christos set_tok_reg (newtok[1], AXP_REG_AT); 2738 1.1 christos assemble_tokens ("mov", newtok, 2, 1); 2739 1.1 christos 2740 1.1 christos set_tok_reg (newtok[0], AXP_REG_T11); 2741 1.1 christos set_tok_reg (newtok[1], AXP_REG_T10); 2742 1.1 christos assemble_tokens ("mov", newtok, 2, 1); 2743 1.1 christos 2744 1.1 christos set_tok_reg (newtok[0], AXP_REG_AT); 2745 1.1 christos set_tok_reg (newtok[1], AXP_REG_T11); 2746 1.1 christos assemble_tokens ("mov", newtok, 2, 1); 2747 1.1 christos } 2748 1.1 christos else 2749 1.1 christos { 2750 1.1 christos if (yr == AXP_REG_T10) 2751 1.1 christos { 2752 1.1 christos set_tok_reg (newtok[0], AXP_REG_T10); 2753 1.1 christos set_tok_reg (newtok[1], AXP_REG_T11); 2754 1.1 christos assemble_tokens ("mov", newtok, 2, 1); 2755 1.1 christos } 2756 1.1 christos 2757 1.1 christos if (xr != AXP_REG_T10) 2758 1.1 christos { 2759 1.1 christos set_tok_reg (newtok[0], xr); 2760 1.1 christos set_tok_reg (newtok[1], AXP_REG_T10); 2761 1.1 christos assemble_tokens ("mov", newtok, 2, 1); 2762 1.1 christos } 2763 1.1 christos 2764 1.1 christos if (yr != AXP_REG_T10 && yr != AXP_REG_T11) 2765 1.1 christos { 2766 1.1 christos set_tok_reg (newtok[0], yr); 2767 1.1 christos set_tok_reg (newtok[1], AXP_REG_T11); 2768 1.1 christos assemble_tokens ("mov", newtok, 2, 1); 2769 1.1 christos } 2770 1.1 christos } 2771 1.1 christos 2772 1.1 christos /* Call the division routine. */ 2773 1.1 christos set_tok_reg (newtok[0], AXP_REG_T9); 2774 1.1 christos set_tok_sym (newtok[1], sym, 0); 2775 1.1 christos assemble_tokens ("jsr", newtok, 2, 1); 2776 1.1 christos 2777 1.1 christos /* Reload the GP register. */ 2778 1.1 christos #ifdef OBJ_AOUT 2779 1.1 christos FIXME 2780 1.1 christos #endif 2781 1.1 christos #if defined(OBJ_ECOFF) || defined(OBJ_ELF) 2782 1.1 christos set_tok_reg (newtok[0], alpha_gp_register); 2783 1.1 christos set_tok_const (newtok[1], 0); 2784 1.1 christos set_tok_preg (newtok[2], AXP_REG_T9); 2785 1.1 christos assemble_tokens ("ldgp", newtok, 3, 1); 2786 1.1 christos #endif 2787 1.1 christos 2788 1.1 christos /* Move the result to the right place. */ 2789 1.1 christos if (rr != AXP_REG_T12) 2790 1.1 christos { 2791 1.1 christos set_tok_reg (newtok[0], AXP_REG_T12); 2792 1.1 christos set_tok_reg (newtok[1], rr); 2793 1.1 christos assemble_tokens ("mov", newtok, 2, 1); 2794 1.1 christos } 2795 1.1 christos } 2796 1.1 christos 2797 1.1 christos #endif /* !OBJ_EVAX */ 2798 1.1 christos 2799 1.10 christos /* The jsr and jmp macros differ from their instruction counterparts 2800 1.1 christos in that they can load the target address and default most 2801 1.1 christos everything. */ 2802 1.1 christos 2803 1.1 christos static void 2804 1.1 christos emit_jsrjmp (const expressionS *tok, 2805 1.1 christos int ntok, 2806 1.1 christos alpha_macro_arg opname) 2807 1.1 christos { 2808 1.1 christos struct alpha_insn insn; 2809 1.10 christos expressionS newtok[3]; 2810 1.1 christos int r, tokidx = 0; 2811 1.1 christos long lituse = 0; 2812 1.1 christos 2813 1.1 christos if (tokidx < ntok && tok[tokidx].X_op == O_register) 2814 1.1 christos r = regno (tok[tokidx++].X_add_number); 2815 1.1 christos else 2816 1.1 christos r = strcmp (opname.p, "jmp") == 0 ? AXP_REG_ZERO : AXP_REG_RA; 2817 1.1 christos 2818 1.1 christos set_tok_reg (newtok[0], r); 2819 1.1 christos 2820 1.1 christos if (tokidx < ntok && 2821 1.1 christos (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister)) 2822 1.1 christos r = regno (tok[tokidx++].X_add_number); 2823 1.10 christos #ifdef OBJ_EVAX 2824 1.1 christos /* Keep register if jsr $n.<sym>. */ 2825 1.1 christos #else 2826 1.1 christos else 2827 1.1 christos { 2828 1.1 christos int basereg = alpha_gp_register; 2829 1.1 christos lituse = load_expression (r = AXP_REG_PV, &tok[tokidx], 2830 1.1 christos &basereg, NULL, opname.p); 2831 1.1 christos } 2832 1.1 christos #endif 2833 1.1 christos 2834 1.1 christos set_tok_cpreg (newtok[1], r); 2835 1.1 christos 2836 1.10 christos #ifndef OBJ_EVAX 2837 1.1 christos if (tokidx < ntok) 2838 1.1 christos newtok[2] = tok[tokidx]; 2839 1.1 christos else 2840 1.1 christos #endif 2841 1.1 christos set_tok_const (newtok[2], 0); 2842 1.1 christos 2843 1.1 christos assemble_tokens_to_insn (opname.p, newtok, 3, &insn); 2844 1.1 christos 2845 1.1 christos if (lituse) 2846 1.1 christos { 2847 1.1 christos gas_assert (insn.nfixups < MAX_INSN_FIXUPS); 2848 1.1 christos insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_JSR; 2849 1.1 christos insn.fixups[insn.nfixups].exp.X_op = O_absent; 2850 1.1 christos insn.nfixups++; 2851 1.1 christos insn.sequence = lituse; 2852 1.1 christos } 2853 1.1 christos 2854 1.1 christos #ifdef OBJ_EVAX 2855 1.1 christos if (alpha_flag_replace 2856 1.1 christos && r == AXP_REG_RA 2857 1.1 christos && tok[tokidx].X_add_symbol 2858 1.1 christos && alpha_linkage_symbol) 2859 1.5 christos { 2860 1.1 christos /* Create a BOH reloc for 'jsr $27,NAME'. */ 2861 1.1 christos const char *symname = S_GET_NAME (tok[tokidx].X_add_symbol); 2862 1.1 christos int symlen = strlen (symname); 2863 1.1 christos char *ensymname; 2864 1.1 christos 2865 1.1 christos /* Build the entry name as 'NAME..en'. */ 2866 1.1 christos ensymname = XNEWVEC (char, symlen + 5); 2867 1.1 christos memcpy (ensymname, symname, symlen); 2868 1.1 christos memcpy (ensymname + symlen, "..en", 5); 2869 1.1 christos 2870 1.1 christos gas_assert (insn.nfixups < MAX_INSN_FIXUPS); 2871 1.1 christos if (insn.nfixups > 0) 2872 1.1 christos { 2873 1.1 christos memmove (&insn.fixups[1], &insn.fixups[0], 2874 1.1 christos sizeof(struct alpha_fixup) * insn.nfixups); 2875 1.1 christos } 2876 1.1 christos 2877 1.1 christos /* The fixup must be the same as the BFD_RELOC_ALPHA_NOP 2878 1.1 christos case in load_expression. See B.4.5.2 of the OpenVMS 2879 1.1 christos Linker Utility Manual. */ 2880 1.1 christos insn.fixups[0].reloc = BFD_RELOC_ALPHA_BOH; 2881 1.5 christos insn.fixups[0].exp.X_op = O_symbol; 2882 1.1 christos insn.fixups[0].exp.X_add_symbol = symbol_find_or_make (ensymname); 2883 1.1 christos insn.fixups[0].exp.X_add_number = 0; 2884 1.1 christos insn.fixups[0].xtrasym = alpha_linkage_symbol; 2885 1.1 christos insn.fixups[0].procsym = alpha_evax_proc->symbol; 2886 1.1 christos insn.nfixups++; 2887 1.1 christos alpha_linkage_symbol = 0; 2888 1.1 christos free (ensymname); 2889 1.1 christos } 2890 1.1 christos #endif 2891 1.1 christos 2892 1.1 christos emit_insn (&insn); 2893 1.1 christos } 2894 1.10 christos 2895 1.1 christos /* The ret and jcr instructions differ from their instruction 2896 1.1 christos counterparts in that everything can be defaulted. */ 2897 1.1 christos 2898 1.1 christos static void 2899 1.1 christos emit_retjcr (const expressionS *tok, 2900 1.1 christos int ntok, 2901 1.1 christos alpha_macro_arg opname) 2902 1.1 christos { 2903 1.1 christos expressionS newtok[3]; 2904 1.1 christos int r, tokidx = 0; 2905 1.1 christos 2906 1.1 christos if (tokidx < ntok && tok[tokidx].X_op == O_register) 2907 1.1 christos r = regno (tok[tokidx++].X_add_number); 2908 1.1 christos else 2909 1.1 christos r = AXP_REG_ZERO; 2910 1.1 christos 2911 1.1 christos set_tok_reg (newtok[0], r); 2912 1.1 christos 2913 1.1 christos if (tokidx < ntok && 2914 1.1 christos (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister)) 2915 1.1 christos r = regno (tok[tokidx++].X_add_number); 2916 1.1 christos else 2917 1.10 christos r = AXP_REG_RA; 2918 1.1 christos 2919 1.10 christos set_tok_cpreg (newtok[1], r); 2920 1.1 christos 2921 1.1 christos if (tokidx < ntok) 2922 1.1 christos newtok[2] = tok[tokidx]; 2923 1.1 christos else 2924 1.1 christos set_tok_const (newtok[2], strcmp (opname.p, "ret") == 0); 2925 1.1 christos 2926 1.1 christos assemble_tokens (opname.p, newtok, 3, 0); 2927 1.10 christos } 2928 1.1 christos 2929 1.1 christos /* Implement the ldgp macro. */ 2930 1.1 christos 2931 1.1 christos static void 2932 1.1 christos emit_ldgp (const expressionS *tok ATTRIBUTE_UNUSED, 2933 1.1 christos int ntok ATTRIBUTE_UNUSED, 2934 1.1 christos alpha_macro_arg unused ATTRIBUTE_UNUSED) 2935 1.1 christos { 2936 1.1 christos #ifdef OBJ_AOUT 2937 1.1 christos FIXME 2938 1.1 christos #endif 2939 1.1 christos #if defined(OBJ_ECOFF) || defined(OBJ_ELF) 2940 1.1 christos /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)" 2941 1.1 christos with appropriate constants and relocations. */ 2942 1.1 christos struct alpha_insn insn; 2943 1.1 christos expressionS newtok[3]; 2944 1.1 christos expressionS addend; 2945 1.1 christos 2946 1.1 christos #ifdef OBJ_ECOFF 2947 1.1 christos if (regno (tok[2].X_add_number) == AXP_REG_PV) 2948 1.1 christos ecoff_set_gp_prolog_size (0); 2949 1.1 christos #endif 2950 1.1 christos 2951 1.1 christos newtok[0] = tok[0]; 2952 1.1 christos set_tok_const (newtok[1], 0); 2953 1.1 christos newtok[2] = tok[2]; 2954 1.1 christos 2955 1.1 christos assemble_tokens_to_insn ("ldah", newtok, 3, &insn); 2956 1.1 christos 2957 1.1 christos addend = tok[1]; 2958 1.1 christos 2959 1.1 christos #ifdef OBJ_ECOFF 2960 1.1 christos if (addend.X_op != O_constant) 2961 1.1 christos as_bad (_("can not resolve expression")); 2962 1.1 christos addend.X_op = O_symbol; 2963 1.1 christos addend.X_add_symbol = alpha_gp_symbol; 2964 1.1 christos #endif 2965 1.1 christos 2966 1.1 christos insn.nfixups = 1; 2967 1.1 christos insn.fixups[0].exp = addend; 2968 1.1 christos insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_HI16; 2969 1.1 christos insn.sequence = next_sequence_num; 2970 1.1 christos 2971 1.1 christos emit_insn (&insn); 2972 1.1 christos 2973 1.1 christos set_tok_preg (newtok[2], tok[0].X_add_number); 2974 1.1 christos 2975 1.1 christos assemble_tokens_to_insn ("lda", newtok, 3, &insn); 2976 1.1 christos 2977 1.1 christos #ifdef OBJ_ECOFF 2978 1.1 christos addend.X_add_number += 4; 2979 1.1 christos #endif 2980 1.1 christos 2981 1.1 christos insn.nfixups = 1; 2982 1.1 christos insn.fixups[0].exp = addend; 2983 1.1 christos insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_LO16; 2984 1.1 christos insn.sequence = next_sequence_num--; 2985 1.1 christos 2986 1.1 christos emit_insn (&insn); 2987 1.1 christos #endif /* OBJ_ECOFF || OBJ_ELF */ 2988 1.10 christos } 2989 1.1 christos 2990 1.10 christos /* The macro table. */ 2991 1.1 christos 2992 1.1 christos static const struct alpha_macro alpha_macros[] = 2993 1.10 christos { 2994 1.1 christos /* Load/Store macros. */ 2995 1.10 christos { "lda", emit_lda, { NULL }, 2996 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 2997 1.10 christos { "ldah", emit_ldah, { NULL }, 2998 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_EOA } }, 2999 1.10 christos 3000 1.1 christos { "ldl", emit_ir_load, { "ldl" }, 3001 1.10 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3002 1.1 christos { "ldl_l", emit_ir_load, { "ldl_l" }, 3003 1.10 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3004 1.1 christos { "ldq", emit_ir_load, { "ldq" }, 3005 1.10 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3006 1.1 christos { "ldq_l", emit_ir_load, { "ldq_l" }, 3007 1.10 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3008 1.1 christos { "ldq_u", emit_ir_load, { "ldq_u" }, 3009 1.10 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3010 1.1 christos { "ldf", emit_loadstore, { "ldf" }, 3011 1.1 christos { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3012 1.10 christos { "ldg", emit_loadstore, { "ldg" }, 3013 1.1 christos { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3014 1.10 christos { "lds", emit_loadstore, { "lds" }, 3015 1.1 christos { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3016 1.10 christos { "ldt", emit_loadstore, { "ldt" }, 3017 1.1 christos { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3018 1.10 christos 3019 1.1 christos { "ldb", emit_ldX, { .i = 0 }, 3020 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3021 1.10 christos { "ldbu", emit_ldXu, { .i = 0 }, 3022 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3023 1.10 christos { "ldw", emit_ldX, { .i = 1 }, 3024 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3025 1.10 christos { "ldwu", emit_ldXu, { .i = 1 }, 3026 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3027 1.10 christos 3028 1.1 christos { "uldw", emit_uldX, { .i = 1 }, 3029 1.10 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3030 1.1 christos { "uldwu", emit_uldXu, { .i = 1 }, 3031 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3032 1.10 christos { "uldl", emit_uldX, { .i = 2 }, 3033 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3034 1.1 christos { "uldlu", emit_uldXu, { .i = 2 }, 3035 1.10 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3036 1.1 christos { "uldq", emit_uldXu, { .i = 3 }, 3037 1.10 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3038 1.1 christos 3039 1.10 christos { "ldgp", emit_ldgp, { NULL }, 3040 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA } }, 3041 1.1 christos 3042 1.10 christos { "ldi", emit_lda, { NULL }, 3043 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_EOA } }, 3044 1.10 christos { "ldil", emit_ldil, { NULL }, 3045 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_EOA } }, 3046 1.10 christos { "ldiq", emit_lda, { NULL }, 3047 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_EOA } }, 3048 1.10 christos 3049 1.1 christos { "stl", emit_loadstore, { "stl" }, 3050 1.10 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3051 1.1 christos { "stl_c", emit_loadstore, { "stl_c" }, 3052 1.10 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3053 1.1 christos { "stq", emit_loadstore, { "stq" }, 3054 1.10 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3055 1.1 christos { "stq_c", emit_loadstore, { "stq_c" }, 3056 1.10 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3057 1.1 christos { "stq_u", emit_loadstore, { "stq_u" }, 3058 1.10 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3059 1.1 christos { "stf", emit_loadstore, { "stf" }, 3060 1.1 christos { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3061 1.10 christos { "stg", emit_loadstore, { "stg" }, 3062 1.1 christos { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3063 1.10 christos { "sts", emit_loadstore, { "sts" }, 3064 1.1 christos { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3065 1.10 christos { "stt", emit_loadstore, { "stt" }, 3066 1.1 christos { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3067 1.10 christos 3068 1.1 christos { "stb", emit_stX, { .i = 0 }, 3069 1.10 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3070 1.1 christos { "stw", emit_stX, { .i = 1 }, 3071 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3072 1.1 christos { "ustw", emit_ustX, { .i = 1 }, 3073 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3074 1.10 christos { "ustl", emit_ustX, { .i = 2 }, 3075 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3076 1.1 christos { "ustq", emit_ustX, { .i = 3 }, 3077 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } }, 3078 1.10 christos 3079 1.1 christos /* Arithmetic macros. */ 3080 1.1 christos 3081 1.1 christos { "sextb", emit_sextX, { .i = 0 }, 3082 1.1 christos { MACRO_IR, MACRO_IR, MACRO_EOA, 3083 1.10 christos MACRO_IR, MACRO_EOA, 3084 1.1 christos /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } }, 3085 1.1 christos { "sextw", emit_sextX, { .i = 1 }, 3086 1.1 christos { MACRO_IR, MACRO_IR, MACRO_EOA, 3087 1.1 christos MACRO_IR, MACRO_EOA, 3088 1.10 christos /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } }, 3089 1.1 christos 3090 1.1 christos { "divl", emit_division, { "__divl" }, 3091 1.1 christos { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA, 3092 1.1 christos MACRO_IR, MACRO_IR, MACRO_EOA, 3093 1.10 christos /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA, 3094 1.1 christos MACRO_IR, MACRO_EXP, MACRO_EOA */ } }, 3095 1.1 christos { "divlu", emit_division, { "__divlu" }, 3096 1.1 christos { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA, 3097 1.1 christos MACRO_IR, MACRO_IR, MACRO_EOA, 3098 1.10 christos /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA, 3099 1.1 christos MACRO_IR, MACRO_EXP, MACRO_EOA */ } }, 3100 1.1 christos { "divq", emit_division, { "__divq" }, 3101 1.1 christos { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA, 3102 1.1 christos MACRO_IR, MACRO_IR, MACRO_EOA, 3103 1.10 christos /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA, 3104 1.1 christos MACRO_IR, MACRO_EXP, MACRO_EOA */ } }, 3105 1.1 christos { "divqu", emit_division, { "__divqu" }, 3106 1.1 christos { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA, 3107 1.1 christos MACRO_IR, MACRO_IR, MACRO_EOA, 3108 1.10 christos /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA, 3109 1.1 christos MACRO_IR, MACRO_EXP, MACRO_EOA */ } }, 3110 1.1 christos { "reml", emit_division, { "__reml" }, 3111 1.1 christos { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA, 3112 1.1 christos MACRO_IR, MACRO_IR, MACRO_EOA, 3113 1.10 christos /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA, 3114 1.1 christos MACRO_IR, MACRO_EXP, MACRO_EOA */ } }, 3115 1.1 christos { "remlu", emit_division, { "__remlu" }, 3116 1.1 christos { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA, 3117 1.1 christos MACRO_IR, MACRO_IR, MACRO_EOA, 3118 1.10 christos /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA, 3119 1.1 christos MACRO_IR, MACRO_EXP, MACRO_EOA */ } }, 3120 1.1 christos { "remq", emit_division, { "__remq" }, 3121 1.1 christos { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA, 3122 1.1 christos MACRO_IR, MACRO_IR, MACRO_EOA, 3123 1.1 christos /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA, 3124 1.10 christos MACRO_IR, MACRO_EXP, MACRO_EOA */ } }, 3125 1.1 christos { "remqu", emit_division, { "__remqu" }, 3126 1.1 christos { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA, 3127 1.1 christos MACRO_IR, MACRO_IR, MACRO_EOA, 3128 1.1 christos /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA, 3129 1.10 christos MACRO_IR, MACRO_EXP, MACRO_EOA */ } }, 3130 1.1 christos 3131 1.1 christos { "jsr", emit_jsrjmp, { "jsr" }, 3132 1.1 christos { MACRO_PIR, MACRO_EXP, MACRO_EOA, 3133 1.1 christos MACRO_PIR, MACRO_EOA, 3134 1.10 christos MACRO_IR, MACRO_EXP, MACRO_EOA, 3135 1.1 christos MACRO_EXP, MACRO_EOA } }, 3136 1.1 christos { "jmp", emit_jsrjmp, { "jmp" }, 3137 1.1 christos { MACRO_PIR, MACRO_EXP, MACRO_EOA, 3138 1.1 christos MACRO_PIR, MACRO_EOA, 3139 1.1 christos MACRO_IR, MACRO_EXP, MACRO_EOA, 3140 1.1 christos MACRO_EXP, MACRO_EOA } }, 3141 1.10 christos { "ret", emit_retjcr, { "ret" }, 3142 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_EOA, 3143 1.1 christos MACRO_IR, MACRO_EOA, 3144 1.1 christos MACRO_PIR, MACRO_EXP, MACRO_EOA, 3145 1.1 christos MACRO_PIR, MACRO_EOA, 3146 1.1 christos MACRO_EXP, MACRO_EOA, 3147 1.1 christos MACRO_EOA } }, 3148 1.10 christos { "jcr", emit_retjcr, { "jcr" }, 3149 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_EOA, 3150 1.1 christos MACRO_IR, MACRO_EOA, 3151 1.1 christos MACRO_PIR, MACRO_EXP, MACRO_EOA, 3152 1.1 christos MACRO_PIR, MACRO_EOA, 3153 1.1 christos MACRO_EXP, MACRO_EOA, 3154 1.1 christos MACRO_EOA } }, 3155 1.1 christos { "jsr_coroutine", emit_retjcr, { "jcr" }, 3156 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_EOA, 3157 1.1 christos MACRO_IR, MACRO_EOA, 3158 1.1 christos MACRO_PIR, MACRO_EXP, MACRO_EOA, 3159 1.1 christos MACRO_PIR, MACRO_EOA, 3160 1.1 christos MACRO_EXP, MACRO_EOA, 3161 1.1 christos MACRO_EOA } }, 3162 1.1 christos }; 3163 1.1 christos 3164 1.1 christos static const unsigned int alpha_num_macros 3165 1.1 christos = sizeof (alpha_macros) / sizeof (*alpha_macros); 3166 1.1 christos 3167 1.1 christos /* Search forward through all variants of a macro looking for a syntax 3168 1.1 christos match. */ 3169 1.1 christos 3170 1.1 christos static const struct alpha_macro * 3171 1.1 christos find_macro_match (const struct alpha_macro *first_macro, 3172 1.1 christos const expressionS *tok, 3173 1.1 christos int *pntok) 3174 1.10 christos 3175 1.1 christos { 3176 1.1 christos const struct alpha_macro *macro = first_macro; 3177 1.1 christos int ntok = *pntok; 3178 1.1 christos 3179 1.1 christos do 3180 1.1 christos { 3181 1.1 christos const alpha_macro_argset *arg = macro->argsets; 3182 1.1 christos int tokidx = 0; 3183 1.1 christos 3184 1.1 christos while (*arg) 3185 1.1 christos { 3186 1.1 christos switch (*arg) 3187 1.1 christos { 3188 1.1 christos case MACRO_EOA: 3189 1.1 christos if (tokidx == ntok) 3190 1.1 christos return macro; 3191 1.1 christos else 3192 1.1 christos tokidx = 0; 3193 1.1 christos break; 3194 1.1 christos 3195 1.1 christos /* Index register. */ 3196 1.1 christos case MACRO_IR: 3197 1.1 christos if (tokidx >= ntok || tok[tokidx].X_op != O_register 3198 1.1 christos || !is_ir_num (tok[tokidx].X_add_number)) 3199 1.1 christos goto match_failed; 3200 1.1 christos ++tokidx; 3201 1.1 christos break; 3202 1.1 christos 3203 1.1 christos /* Parenthesized index register. */ 3204 1.1 christos case MACRO_PIR: 3205 1.1 christos if (tokidx >= ntok || tok[tokidx].X_op != O_pregister 3206 1.1 christos || !is_ir_num (tok[tokidx].X_add_number)) 3207 1.1 christos goto match_failed; 3208 1.1 christos ++tokidx; 3209 1.1 christos break; 3210 1.1 christos 3211 1.1 christos /* Optional parenthesized index register. */ 3212 1.1 christos case MACRO_OPIR: 3213 1.1 christos if (tokidx < ntok && tok[tokidx].X_op == O_pregister 3214 1.1 christos && is_ir_num (tok[tokidx].X_add_number)) 3215 1.1 christos ++tokidx; 3216 1.1 christos break; 3217 1.1 christos 3218 1.1 christos /* Leading comma with a parenthesized index register. */ 3219 1.1 christos case MACRO_CPIR: 3220 1.1 christos if (tokidx >= ntok || tok[tokidx].X_op != O_cpregister 3221 1.1 christos || !is_ir_num (tok[tokidx].X_add_number)) 3222 1.1 christos goto match_failed; 3223 1.1 christos ++tokidx; 3224 1.1 christos break; 3225 1.1 christos 3226 1.1 christos /* Floating point register. */ 3227 1.1 christos case MACRO_FPR: 3228 1.1 christos if (tokidx >= ntok || tok[tokidx].X_op != O_register 3229 1.1 christos || !is_fpr_num (tok[tokidx].X_add_number)) 3230 1.1 christos goto match_failed; 3231 1.1 christos ++tokidx; 3232 1.1 christos break; 3233 1.1 christos 3234 1.1 christos /* Normal expression. */ 3235 1.1 christos case MACRO_EXP: 3236 1.1 christos if (tokidx >= ntok) 3237 1.1 christos goto match_failed; 3238 1.1 christos switch (tok[tokidx].X_op) 3239 1.1 christos { 3240 1.1 christos case O_illegal: 3241 1.1 christos case O_absent: 3242 1.1 christos case O_register: 3243 1.1 christos case O_pregister: 3244 1.1 christos case O_cpregister: 3245 1.1 christos case O_literal: 3246 1.1 christos case O_lituse_base: 3247 1.1 christos case O_lituse_bytoff: 3248 1.1 christos case O_lituse_jsr: 3249 1.1 christos case O_gpdisp: 3250 1.1 christos case O_gprelhigh: 3251 1.1 christos case O_gprellow: 3252 1.1 christos case O_gprel: 3253 1.1 christos case O_samegp: 3254 1.1 christos goto match_failed; 3255 1.1 christos 3256 1.1 christos default: 3257 1.1 christos break; 3258 1.1 christos } 3259 1.1 christos ++tokidx; 3260 1.1 christos break; 3261 1.1 christos 3262 1.1 christos match_failed: 3263 1.1 christos while (*arg != MACRO_EOA) 3264 1.1 christos ++arg; 3265 1.1 christos tokidx = 0; 3266 1.1 christos break; 3267 1.1 christos } 3268 1.1 christos ++arg; 3269 1.1 christos } 3270 1.1 christos } 3271 1.1 christos while (++macro - alpha_macros < (int) alpha_num_macros 3272 1.1 christos && !strcmp (macro->name, first_macro->name)); 3273 1.1 christos 3274 1.1 christos return NULL; 3275 1.1 christos } 3276 1.1 christos 3277 1.1 christos /* Given an opcode name and a pre-tokenized set of arguments, take the 3278 1.1 christos opcode all the way through emission. */ 3279 1.1 christos 3280 1.1 christos static void 3281 1.1 christos assemble_tokens (const char *opname, 3282 1.1 christos const expressionS *tok, 3283 1.1 christos int ntok, 3284 1.1 christos int local_macros_on) 3285 1.1 christos { 3286 1.1 christos int found_something = 0; 3287 1.1 christos const struct alpha_opcode *opcode; 3288 1.1 christos const struct alpha_macro *macro; 3289 1.1 christos int cpumatch = 1; 3290 1.1 christos extended_bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED; 3291 1.1 christos 3292 1.1 christos #ifdef RELOC_OP_P 3293 1.1 christos /* If a user-specified relocation is present, this is not a macro. */ 3294 1.1 christos if (ntok && USER_RELOC_P (tok[ntok - 1].X_op)) 3295 1.1 christos { 3296 1.10 christos reloc = ALPHA_RELOC_TABLE (tok[ntok - 1].X_op)->reloc; 3297 1.1 christos ntok--; 3298 1.1 christos } 3299 1.1 christos else 3300 1.1 christos #endif 3301 1.1 christos if (local_macros_on) 3302 1.1 christos { 3303 1.1 christos macro = str_hash_find (alpha_macro_hash, opname); 3304 1.1 christos if (macro) 3305 1.1 christos { 3306 1.1 christos found_something = 1; 3307 1.1 christos macro = find_macro_match (macro, tok, &ntok); 3308 1.1 christos if (macro) 3309 1.1 christos { 3310 1.10 christos (*macro->emit) (tok, ntok, macro->arg); 3311 1.1 christos return; 3312 1.1 christos } 3313 1.1 christos } 3314 1.1 christos } 3315 1.1 christos 3316 1.1 christos /* Search opcodes. */ 3317 1.1 christos opcode = str_hash_find (alpha_opcode_hash, opname); 3318 1.1 christos if (opcode) 3319 1.1 christos { 3320 1.1 christos found_something = 1; 3321 1.1 christos opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch); 3322 1.1 christos if (opcode) 3323 1.1 christos { 3324 1.1 christos struct alpha_insn insn; 3325 1.1 christos assemble_insn (opcode, tok, ntok, &insn, reloc); 3326 1.1 christos 3327 1.1 christos /* Copy the sequence number for the reloc from the reloc token. */ 3328 1.1 christos if (reloc != BFD_RELOC_UNUSED) 3329 1.1 christos insn.sequence = tok[ntok].X_add_number; 3330 1.1 christos 3331 1.1 christos emit_insn (&insn); 3332 1.1 christos return; 3333 1.1 christos } 3334 1.1 christos } 3335 1.1 christos 3336 1.1 christos if (found_something) 3337 1.1 christos { 3338 1.1 christos if (cpumatch) 3339 1.1 christos as_bad (_("inappropriate arguments for opcode `%s'"), opname); 3340 1.1 christos else 3341 1.1 christos as_bad (_("opcode `%s' not supported for target %s"), opname, 3342 1.1 christos alpha_target_name); 3343 1.1 christos } 3344 1.6 christos else 3345 1.1 christos as_bad (_("unknown opcode `%s'"), opname); 3346 1.1 christos } 3347 1.1 christos 3348 1.1 christos #ifdef OBJ_EVAX 3350 1.1 christos 3351 1.1 christos /* Add sym+addend to link pool. 3352 1.1 christos Return offset from current procedure value (pv) to entry in link pool. 3353 1.1 christos 3354 1.1 christos Add new fixup only if offset isn't 16bit. */ 3355 1.1 christos 3356 1.1 christos static symbolS * 3357 1.1 christos add_to_link_pool (symbolS *sym, offsetT addend) 3358 1.1 christos { 3359 1.3 christos symbolS *basesym; 3360 1.1 christos segT current_section = now_seg; 3361 1.1 christos int current_subsec = now_subseg; 3362 1.1 christos char *p; 3363 1.1 christos segment_info_type *seginfo = seg_info (alpha_link_section); 3364 1.1 christos fixS *fixp; 3365 1.1 christos symbolS *linksym, *expsym; 3366 1.1 christos expressionS e; 3367 1.1 christos 3368 1.10 christos basesym = alpha_evax_proc->symbol; 3369 1.1 christos 3370 1.1 christos /* @@ This assumes all entries in a given section will be of the same 3371 1.1 christos size... Probably correct, but unwise to rely on. */ 3372 1.10 christos /* This must always be called with the same subsegment. */ 3373 1.1 christos 3374 1.1 christos if (seginfo->frchainP) 3375 1.7 christos for (fixp = seginfo->frchainP->fix_root; 3376 1.7 christos fixp != NULL; 3377 1.7 christos fixp = fixp->fx_next) 3378 1.1 christos { 3379 1.1 christos if (fixp->fx_addsy == sym 3380 1.1 christos && fixp->fx_offset == (valueT) addend 3381 1.1 christos && fixp->tc_fix_data.info 3382 1.1 christos && fixp->tc_fix_data.info->sym 3383 1.8 christos && symbol_symbolS (fixp->tc_fix_data.info->sym) 3384 1.1 christos && (symbol_get_value_expression (fixp->tc_fix_data.info->sym) 3385 1.1 christos ->X_op_symbol == basesym)) 3386 1.1 christos return fixp->tc_fix_data.info->sym; 3387 1.1 christos } 3388 1.1 christos 3389 1.1 christos /* Not found, add a new entry. */ 3390 1.1 christos subseg_set (alpha_link_section, 0); 3391 1.1 christos linksym = symbol_new (FAKE_LABEL_NAME, now_seg, frag_now, frag_now_fix ()); 3392 1.1 christos p = frag_more (8); 3393 1.1 christos memset (p, 0, 8); 3394 1.1 christos 3395 1.10 christos /* Create a symbol for 'basesym - linksym' (offset of the added entry). */ 3396 1.10 christos e.X_op = O_subtract; 3397 1.1 christos e.X_add_symbol = linksym; 3398 1.1 christos e.X_op_symbol = basesym; 3399 1.1 christos e.X_add_number = 0; 3400 1.1 christos expsym = make_expr_symbol (&e); 3401 1.1 christos 3402 1.1 christos /* Create a fixup for the entry. */ 3403 1.1 christos fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 3404 1.1 christos sym, addend, 0, BFD_RELOC_64); 3405 1.1 christos fixp->tc_fix_data.info = get_alpha_reloc_tag (next_sequence_num--); 3406 1.1 christos fixp->tc_fix_data.info->sym = expsym; 3407 1.1 christos 3408 1.1 christos subseg_set (current_section, current_subsec); 3409 1.1 christos 3410 1.1 christos /* Return the symbol. */ 3411 1.1 christos return expsym; 3412 1.1 christos } 3413 1.1 christos #endif /* OBJ_EVAX */ 3414 1.1 christos 3415 1.1 christos /* Assembler directives. */ 3417 1.1 christos 3418 1.1 christos /* Handle the .text pseudo-op. This is like the usual one, but it 3419 1.1 christos clears alpha_insn_label and restores auto alignment. */ 3420 1.1 christos 3421 1.1 christos static void 3422 1.1 christos s_alpha_text (int i) 3423 1.1 christos { 3424 1.1 christos #ifdef OBJ_ELF 3425 1.1 christos obj_elf_text (i); 3426 1.1 christos #else 3427 1.1 christos s_text (i); 3428 1.1 christos #endif 3429 1.1 christos #ifdef OBJ_EVAX 3430 1.1 christos { 3431 1.1 christos symbolS * symbolP; 3432 1.1 christos 3433 1.1 christos symbolP = symbol_find (".text"); 3434 1.1 christos if (symbolP == NULL) 3435 1.1 christos { 3436 1.1 christos symbolP = symbol_make (".text"); 3437 1.1 christos S_SET_SEGMENT (symbolP, text_section); 3438 1.1 christos symbol_table_insert (symbolP); 3439 1.1 christos } 3440 1.1 christos } 3441 1.1 christos #endif 3442 1.1 christos alpha_insn_label = NULL; 3443 1.1 christos alpha_auto_align_on = 1; 3444 1.1 christos alpha_current_align = 0; 3445 1.1 christos } 3446 1.1 christos 3447 1.1 christos /* Handle the .data pseudo-op. This is like the usual one, but it 3448 1.1 christos clears alpha_insn_label and restores auto alignment. */ 3449 1.1 christos 3450 1.1 christos static void 3451 1.1 christos s_alpha_data (int i) 3452 1.1 christos { 3453 1.1 christos #ifdef OBJ_ELF 3454 1.1 christos obj_elf_data (i); 3455 1.1 christos #else 3456 1.1 christos s_data (i); 3457 1.1 christos #endif 3458 1.1 christos alpha_insn_label = NULL; 3459 1.1 christos alpha_auto_align_on = 1; 3460 1.1 christos alpha_current_align = 0; 3461 1.1 christos } 3462 1.1 christos 3463 1.1 christos #if defined (OBJ_ECOFF) || defined (OBJ_EVAX) 3464 1.1 christos 3465 1.1 christos /* Handle the OSF/1 and openVMS .comm pseudo quirks. */ 3466 1.1 christos 3467 1.1 christos static void 3468 1.1 christos s_alpha_comm (int ignore ATTRIBUTE_UNUSED) 3469 1.1 christos { 3470 1.1 christos char *name; 3471 1.3 christos char c; 3472 1.1 christos char *p; 3473 1.1 christos offsetT size; 3474 1.1 christos symbolS *symbolP; 3475 1.10 christos #ifdef OBJ_EVAX 3476 1.1 christos offsetT temp; 3477 1.10 christos int log_align = 0; 3478 1.1 christos #endif 3479 1.1 christos 3480 1.1 christos c = get_symbol_name (&name); 3481 1.1 christos 3482 1.1 christos /* Just after name is now '\0'. */ 3483 1.1 christos p = input_line_pointer; 3484 1.1 christos restore_line_pointer (c); 3485 1.1 christos 3486 1.1 christos SKIP_WHITESPACE (); 3487 1.1 christos 3488 1.1 christos /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */ 3489 1.1 christos if (*input_line_pointer == ',') 3490 1.1 christos { 3491 1.1 christos input_line_pointer++; 3492 1.1 christos SKIP_WHITESPACE (); 3493 1.1 christos } 3494 1.1 christos if ((size = get_absolute_expression ()) < 0) 3495 1.1 christos { 3496 1.1 christos as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size); 3497 1.1 christos ignore_rest_of_line (); 3498 1.1 christos return; 3499 1.1 christos } 3500 1.1 christos 3501 1.1 christos *p = 0; 3502 1.1 christos symbolP = symbol_find_or_make (name); 3503 1.1 christos *p = c; 3504 1.1 christos 3505 1.1 christos if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP)) 3506 1.1 christos { 3507 1.1 christos as_bad (_("Ignoring attempt to re-define symbol")); 3508 1.1 christos ignore_rest_of_line (); 3509 1.1 christos return; 3510 1.1 christos } 3511 1.1 christos 3512 1.1 christos #ifdef OBJ_EVAX 3513 1.1 christos if (*input_line_pointer != ',') 3514 1.1 christos temp = 8; /* Default alignment. */ 3515 1.1 christos else 3516 1.1 christos { 3517 1.1 christos input_line_pointer++; 3518 1.1 christos SKIP_WHITESPACE (); 3519 1.1 christos temp = get_absolute_expression (); 3520 1.1 christos } 3521 1.1 christos 3522 1.1 christos /* ??? Unlike on OSF/1, the alignment factor is not in log units. */ 3523 1.1 christos while ((temp >>= 1) != 0) 3524 1.1 christos ++log_align; 3525 1.1 christos 3526 1.1 christos if (*input_line_pointer == ',') 3527 1.5 christos { 3528 1.1 christos /* Extended form of the directive 3529 1.1 christos 3530 1.1 christos .comm symbol, size, alignment, section 3531 1.10 christos 3532 1.3 christos where the "common" semantics is transferred to the section. 3533 1.1 christos The symbol is effectively an alias for the section name. */ 3534 1.1 christos 3535 1.1 christos segT sec; 3536 1.1 christos const char *sec_name; 3537 1.1 christos symbolS *sec_symbol; 3538 1.1 christos segT current_seg = now_seg; 3539 1.1 christos subsegT current_subseg = now_subseg; 3540 1.1 christos offsetT cur_size; 3541 1.1 christos 3542 1.1 christos input_line_pointer++; 3543 1.1 christos SKIP_WHITESPACE (); 3544 1.1 christos sec_name = s_alpha_section_name (); 3545 1.1 christos sec_symbol = symbol_find_or_make (sec_name); 3546 1.10 christos sec = subseg_new (sec_name, 0); 3547 1.1 christos S_SET_SEGMENT (sec_symbol, sec); 3548 1.10 christos symbol_get_bfdsym (sec_symbol)->flags |= BSF_SECTION_SYM; 3549 1.10 christos bfd_vms_set_section_flags (stdoutput, sec, 0, 3550 1.1 christos EGPS__V_OVR | EGPS__V_GBL | EGPS__V_NOMOD); 3551 1.10 christos record_alignment (sec, log_align); 3552 1.1 christos 3553 1.1 christos /* Reuse stab_string_size to store the size of the section. */ 3554 1.1 christos cur_size = seg_info (sec)->stabu.stab_string_size; 3555 1.1 christos if (size > cur_size) 3556 1.1 christos { 3557 1.1 christos char *pfrag = frag_var (rs_fill, 1, 1, 0, NULL, 3558 1.1 christos size - cur_size, NULL); 3559 1.1 christos *pfrag = 0; 3560 1.1 christos seg_info (sec)->stabu.stab_string_size = size; 3561 1.1 christos } 3562 1.1 christos 3563 1.1 christos S_SET_SEGMENT (symbolP, sec); 3564 1.1 christos 3565 1.1 christos subseg_set (current_seg, current_subseg); 3566 1.1 christos } 3567 1.1 christos else 3568 1.1 christos { 3569 1.1 christos /* Regular form of the directive 3570 1.1 christos 3571 1.1 christos .comm symbol, size, alignment 3572 1.1 christos 3573 1.1 christos where the "common" semantics in on the symbol. 3574 1.1 christos These symbols are assembled in the .bss section. */ 3575 1.1 christos 3576 1.10 christos char *pfrag; 3577 1.1 christos segT current_seg = now_seg; 3578 1.1 christos subsegT current_subseg = now_subseg; 3579 1.1 christos 3580 1.1 christos subseg_set (bss_section, 1); 3581 1.1 christos frag_align (log_align, 0, 0); 3582 1.1 christos record_alignment (bss_section, log_align); 3583 1.1 christos 3584 1.3 christos symbol_set_frag (symbolP, frag_now); 3585 1.1 christos pfrag = frag_var (rs_org, 1, 1, 0, symbolP, size, NULL); 3586 1.1 christos *pfrag = 0; 3587 1.1 christos 3588 1.1 christos S_SET_SEGMENT (symbolP, bss_section); 3589 1.1 christos 3590 1.1 christos subseg_set (current_seg, current_subseg); 3591 1.1 christos } 3592 1.1 christos #endif 3593 1.1 christos 3594 1.1 christos if (S_GET_VALUE (symbolP)) 3595 1.1 christos { 3596 1.1 christos if (S_GET_VALUE (symbolP) != (valueT) size) 3597 1.1 christos as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."), 3598 1.1 christos S_GET_NAME (symbolP), 3599 1.1 christos (long) S_GET_VALUE (symbolP), 3600 1.3 christos (long) size); 3601 1.1 christos } 3602 1.7 christos else 3603 1.1 christos { 3604 1.1 christos #ifndef OBJ_EVAX 3605 1.1 christos S_SET_VALUE (symbolP, (valueT) size); 3606 1.1 christos #endif 3607 1.1 christos S_SET_EXTERNAL (symbolP); 3608 1.1 christos } 3609 1.1 christos 3610 1.1 christos #ifndef OBJ_EVAX 3611 1.1 christos know (symbol_get_frag (symbolP) == &zero_address_frag); 3612 1.1 christos #endif 3613 1.1 christos demand_empty_rest_of_line (); 3614 1.1 christos } 3615 1.1 christos 3616 1.1 christos #endif /* ! OBJ_ELF */ 3617 1.1 christos 3618 1.1 christos #ifdef OBJ_ECOFF 3619 1.1 christos 3620 1.1 christos /* Handle the .rdata pseudo-op. This is like the usual one, but it 3621 1.1 christos clears alpha_insn_label and restores auto alignment. */ 3622 1.1 christos 3623 1.1 christos static void 3624 1.1 christos s_alpha_rdata (int ignore ATTRIBUTE_UNUSED) 3625 1.1 christos { 3626 1.1 christos get_absolute_expression (); 3627 1.1 christos subseg_new (".rdata", 0); 3628 1.1 christos demand_empty_rest_of_line (); 3629 1.1 christos alpha_insn_label = NULL; 3630 1.1 christos alpha_auto_align_on = 1; 3631 1.1 christos alpha_current_align = 0; 3632 1.1 christos } 3633 1.1 christos 3634 1.1 christos #endif 3635 1.1 christos 3636 1.1 christos #ifdef OBJ_ECOFF 3637 1.1 christos 3638 1.1 christos /* Handle the .sdata pseudo-op. This is like the usual one, but it 3639 1.1 christos clears alpha_insn_label and restores auto alignment. */ 3640 1.1 christos 3641 1.1 christos static void 3642 1.1 christos s_alpha_sdata (int ignore ATTRIBUTE_UNUSED) 3643 1.1 christos { 3644 1.1 christos get_absolute_expression (); 3645 1.1 christos subseg_new (".sdata", 0); 3646 1.1 christos demand_empty_rest_of_line (); 3647 1.1 christos alpha_insn_label = NULL; 3648 1.1 christos alpha_auto_align_on = 1; 3649 1.1 christos alpha_current_align = 0; 3650 1.1 christos } 3651 1.1 christos #endif 3652 1.1 christos 3653 1.1 christos #ifdef OBJ_ELF 3654 1.1 christos struct alpha_elf_frame_data 3655 1.1 christos { 3656 1.1 christos symbolS *func_sym; 3657 1.1 christos symbolS *func_end_sym; 3658 1.1 christos symbolS *prologue_sym; 3659 1.1 christos unsigned int mask; 3660 1.1 christos unsigned int fmask; 3661 1.1 christos int fp_regno; 3662 1.1 christos int ra_regno; 3663 1.1 christos offsetT frame_size; 3664 1.1 christos offsetT mask_offset; 3665 1.3 christos offsetT fmask_offset; 3666 1.3 christos 3667 1.1 christos struct alpha_elf_frame_data *next; 3668 1.1 christos }; 3669 1.1 christos 3670 1.1 christos static struct alpha_elf_frame_data *all_frame_data; 3671 1.1 christos static struct alpha_elf_frame_data **plast_frame_data = &all_frame_data; 3672 1.1 christos static struct alpha_elf_frame_data *cur_frame_data; 3673 1.1 christos 3674 1.1 christos extern int all_cfi_sections; 3675 1.1 christos 3676 1.1 christos /* Handle the .section pseudo-op. This is like the usual one, but it 3677 1.1 christos clears alpha_insn_label and restores auto alignment. */ 3678 1.1 christos 3679 1.1 christos static void 3680 1.1 christos s_alpha_section (int ignore ATTRIBUTE_UNUSED) 3681 1.1 christos { 3682 1.1 christos obj_elf_section (ignore); 3683 1.1 christos 3684 1.1 christos alpha_insn_label = NULL; 3685 1.1 christos alpha_auto_align_on = 1; 3686 1.1 christos alpha_current_align = 0; 3687 1.1 christos } 3688 1.3 christos 3689 1.3 christos static void 3690 1.3 christos s_alpha_ent (int dummy ATTRIBUTE_UNUSED) 3691 1.3 christos { 3692 1.1 christos if (ECOFF_DEBUGGING) 3693 1.1 christos ecoff_directive_ent (0); 3694 1.1 christos else 3695 1.1 christos { 3696 1.3 christos char *name, name_end; 3697 1.1 christos 3698 1.1 christos name_end = get_symbol_name (&name); 3699 1.1 christos /* CFI_EMIT_eh_frame is the default. */ 3700 1.1 christos all_cfi_sections = CFI_EMIT_eh_frame; 3701 1.1 christos 3702 1.1 christos if (! is_name_beginner (*name)) 3703 1.1 christos { 3704 1.1 christos as_warn (_(".ent directive has no name")); 3705 1.1 christos (void) restore_line_pointer (name_end); 3706 1.1 christos } 3707 1.1 christos else 3708 1.5 christos { 3709 1.1 christos symbolS *sym; 3710 1.1 christos 3711 1.1 christos if (cur_frame_data) 3712 1.1 christos as_warn (_("nested .ent directives")); 3713 1.1 christos 3714 1.1 christos sym = symbol_find_or_make (name); 3715 1.1 christos symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION; 3716 1.1 christos 3717 1.1 christos cur_frame_data = XCNEW (struct alpha_elf_frame_data); 3718 1.1 christos cur_frame_data->func_sym = sym; 3719 1.1 christos 3720 1.10 christos /* Provide sensible defaults. */ 3721 1.10 christos cur_frame_data->fp_regno = 30; /* sp */ 3722 1.1 christos cur_frame_data->ra_regno = 26; /* ra */ 3723 1.1 christos 3724 1.1 christos *plast_frame_data = cur_frame_data; 3725 1.1 christos plast_frame_data = &cur_frame_data->next; 3726 1.1 christos 3727 1.1 christos /* The .ent directive is sometimes followed by a number. Not sure 3728 1.1 christos what it really means, but ignore it. */ 3729 1.1 christos restore_line_pointer (name_end); 3730 1.1 christos SKIP_WHITESPACE (); 3731 1.1 christos if (*input_line_pointer == ',') 3732 1.1 christos { 3733 1.1 christos input_line_pointer++; 3734 1.1 christos SKIP_WHITESPACE (); 3735 1.1 christos } 3736 1.1 christos if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-') 3737 1.1 christos (void) get_absolute_expression (); 3738 1.1 christos } 3739 1.1 christos demand_empty_rest_of_line (); 3740 1.1 christos } 3741 1.1 christos } 3742 1.3 christos 3743 1.3 christos static void 3744 1.1 christos s_alpha_end (int dummy ATTRIBUTE_UNUSED) 3745 1.1 christos { 3746 1.1 christos if (ECOFF_DEBUGGING) 3747 1.1 christos ecoff_directive_end (0); 3748 1.1 christos else 3749 1.1 christos { 3750 1.1 christos char *name, name_end; 3751 1.1 christos 3752 1.1 christos name_end = get_symbol_name (&name); 3753 1.1 christos 3754 1.1 christos if (! is_name_beginner (*name)) 3755 1.1 christos { 3756 1.1 christos as_warn (_(".end directive has no name")); 3757 1.1 christos } 3758 1.1 christos else 3759 1.1 christos { 3760 1.1 christos symbolS *sym; 3761 1.1 christos 3762 1.1 christos sym = symbol_find (name); 3763 1.10 christos if (!cur_frame_data) 3764 1.1 christos as_warn (_(".end directive without matching .ent")); 3765 1.1 christos else if (sym != cur_frame_data->func_sym) 3766 1.1 christos as_warn (_(".end directive names different symbol than .ent")); 3767 1.1 christos 3768 1.1 christos /* Create an expression to calculate the size of the function. */ 3769 1.1 christos if (sym && cur_frame_data) 3770 1.1 christos { 3771 1.1 christos OBJ_SYMFIELD_TYPE *obj = symbol_get_obj (sym); 3772 1.1 christos expressionS *exp = notes_alloc (sizeof (*exp)); 3773 1.1 christos 3774 1.1 christos obj->size = exp; 3775 1.3 christos exp->X_op = O_subtract; 3776 1.1 christos exp->X_add_symbol = symbol_temp_new_now (); 3777 1.3 christos exp->X_op_symbol = sym; 3778 1.1 christos exp->X_add_number = 0; 3779 1.1 christos 3780 1.1 christos cur_frame_data->func_end_sym = exp->X_add_symbol; 3781 1.1 christos } 3782 1.1 christos 3783 1.1 christos cur_frame_data = NULL; 3784 1.1 christos } 3785 1.1 christos 3786 1.1 christos (void) restore_line_pointer (name_end); 3787 1.1 christos demand_empty_rest_of_line (); 3788 1.1 christos } 3789 1.1 christos } 3790 1.1 christos 3791 1.1 christos static void 3792 1.1 christos s_alpha_mask (int fp) 3793 1.1 christos { 3794 1.1 christos if (ECOFF_DEBUGGING) 3795 1.1 christos { 3796 1.1 christos if (fp) 3797 1.1 christos ecoff_directive_fmask (0); 3798 1.1 christos else 3799 1.1 christos ecoff_directive_mask (0); 3800 1.1 christos } 3801 1.1 christos else 3802 1.1 christos { 3803 1.1 christos long val; 3804 1.1 christos offsetT offset; 3805 1.1 christos 3806 1.1 christos if (!cur_frame_data) 3807 1.1 christos { 3808 1.1 christos if (fp) 3809 1.1 christos as_warn (_(".fmask outside of .ent")); 3810 1.1 christos else 3811 1.1 christos as_warn (_(".mask outside of .ent")); 3812 1.1 christos discard_rest_of_line (); 3813 1.1 christos return; 3814 1.1 christos } 3815 1.1 christos 3816 1.1 christos if (get_absolute_expression_and_terminator (&val) != ',') 3817 1.1 christos { 3818 1.1 christos if (fp) 3819 1.1 christos as_warn (_("bad .fmask directive")); 3820 1.1 christos else 3821 1.1 christos as_warn (_("bad .mask directive")); 3822 1.1 christos --input_line_pointer; 3823 1.1 christos discard_rest_of_line (); 3824 1.1 christos return; 3825 1.1 christos } 3826 1.1 christos 3827 1.1 christos offset = get_absolute_expression (); 3828 1.1 christos demand_empty_rest_of_line (); 3829 1.1 christos 3830 1.1 christos if (fp) 3831 1.1 christos { 3832 1.1 christos cur_frame_data->fmask = val; 3833 1.1 christos cur_frame_data->fmask_offset = offset; 3834 1.1 christos } 3835 1.1 christos else 3836 1.1 christos { 3837 1.1 christos cur_frame_data->mask = val; 3838 1.1 christos cur_frame_data->mask_offset = offset; 3839 1.1 christos } 3840 1.1 christos } 3841 1.1 christos } 3842 1.1 christos 3843 1.1 christos static void 3844 1.1 christos s_alpha_frame (int dummy ATTRIBUTE_UNUSED) 3845 1.1 christos { 3846 1.1 christos if (ECOFF_DEBUGGING) 3847 1.1 christos ecoff_directive_frame (0); 3848 1.1 christos else 3849 1.1 christos { 3850 1.1 christos long val; 3851 1.1 christos 3852 1.1 christos if (!cur_frame_data) 3853 1.1 christos { 3854 1.1 christos as_warn (_(".frame outside of .ent")); 3855 1.1 christos discard_rest_of_line (); 3856 1.1 christos return; 3857 1.1 christos } 3858 1.1 christos 3859 1.1 christos cur_frame_data->fp_regno = tc_get_register (1); 3860 1.1 christos 3861 1.1 christos SKIP_WHITESPACE (); 3862 1.1 christos if (*input_line_pointer++ != ',' 3863 1.1 christos || get_absolute_expression_and_terminator (&val) != ',') 3864 1.1 christos { 3865 1.1 christos as_warn (_("bad .frame directive")); 3866 1.1 christos --input_line_pointer; 3867 1.1 christos discard_rest_of_line (); 3868 1.1 christos return; 3869 1.1 christos } 3870 1.1 christos cur_frame_data->frame_size = val; 3871 1.1 christos 3872 1.1 christos cur_frame_data->ra_regno = tc_get_register (0); 3873 1.1 christos 3874 1.1 christos /* Next comes the "offset of saved $a0 from $sp". In gcc terms 3875 1.1 christos this is current_function_pretend_args_size. There's no place 3876 1.1 christos to put this value, so ignore it. */ 3877 1.1 christos s_ignore (42); 3878 1.1 christos } 3879 1.1 christos } 3880 1.8 christos 3881 1.8 christos static void 3882 1.1 christos s_alpha_prologue (int ignore ATTRIBUTE_UNUSED) 3883 1.1 christos { 3884 1.1 christos symbolS *sym; 3885 1.1 christos int arg; 3886 1.1 christos 3887 1.1 christos arg = get_absolute_expression (); 3888 1.1 christos demand_empty_rest_of_line (); 3889 1.1 christos alpha_prologue_label = symbol_new (FAKE_LABEL_NAME, now_seg, frag_now, 3890 1.1 christos frag_now_fix ()); 3891 1.1 christos 3892 1.1 christos if (ECOFF_DEBUGGING) 3893 1.1 christos sym = ecoff_get_cur_proc_sym (); 3894 1.1 christos else 3895 1.1 christos sym = cur_frame_data ? cur_frame_data->func_sym : NULL; 3896 1.1 christos 3897 1.1 christos if (sym == NULL) 3898 1.1 christos { 3899 1.1 christos as_bad (_(".prologue directive without a preceding .ent directive")); 3900 1.1 christos return; 3901 1.1 christos } 3902 1.1 christos 3903 1.1 christos switch (arg) 3904 1.1 christos { 3905 1.1 christos case 0: /* No PV required. */ 3906 1.1 christos S_SET_OTHER (sym, STO_ALPHA_NOPV 3907 1.1 christos | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD)); 3908 1.1 christos break; 3909 1.1 christos case 1: /* Std GP load. */ 3910 1.1 christos S_SET_OTHER (sym, STO_ALPHA_STD_GPLOAD 3911 1.1 christos | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD)); 3912 1.1 christos break; 3913 1.1 christos case 2: /* Non-std use of PV. */ 3914 1.1 christos break; 3915 1.1 christos 3916 1.1 christos default: 3917 1.1 christos as_bad (_("Invalid argument %d to .prologue."), arg); 3918 1.1 christos break; 3919 1.1 christos } 3920 1.1 christos 3921 1.1 christos if (cur_frame_data) 3922 1.1 christos cur_frame_data->prologue_sym = symbol_temp_new_now (); 3923 1.1 christos } 3924 1.1 christos 3925 1.1 christos static char *first_file_directive; 3926 1.1 christos 3927 1.1 christos static void 3928 1.1 christos s_alpha_file (int ignore ATTRIBUTE_UNUSED) 3929 1.1 christos { 3930 1.1 christos /* Save the first .file directive we see, so that we can change our 3931 1.5 christos minds about whether ecoff debugging should or shouldn't be enabled. */ 3932 1.1 christos if (alpha_flag_mdebug < 0 && ! first_file_directive) 3933 1.1 christos { 3934 1.1 christos char *start = input_line_pointer; 3935 1.1 christos size_t len; 3936 1.1 christos 3937 1.1 christos discard_rest_of_line (); 3938 1.1 christos 3939 1.1 christos len = input_line_pointer - start; 3940 1.1 christos first_file_directive = xmemdup0 (start, len); 3941 1.1 christos 3942 1.1 christos input_line_pointer = start; 3943 1.1 christos } 3944 1.1 christos 3945 1.1 christos if (ECOFF_DEBUGGING) 3946 1.1 christos ecoff_directive_file (0); 3947 1.1 christos else 3948 1.1 christos dwarf2_directive_file (0); 3949 1.1 christos } 3950 1.1 christos 3951 1.1 christos static void 3952 1.1 christos s_alpha_loc (int ignore ATTRIBUTE_UNUSED) 3953 1.1 christos { 3954 1.1 christos if (ECOFF_DEBUGGING) 3955 1.1 christos ecoff_directive_loc (0); 3956 1.1 christos else 3957 1.1 christos dwarf2_directive_loc (0); 3958 1.7 christos } 3959 1.7 christos 3960 1.1 christos static void 3961 1.1 christos s_alpha_stab (int n) 3962 1.1 christos { 3963 1.1 christos /* If we've been undecided about mdebug, make up our minds in favour. */ 3964 1.1 christos if (alpha_flag_mdebug < 0) 3965 1.1 christos { 3966 1.1 christos segT sec = subseg_new (".mdebug", 0); 3967 1.1 christos bfd_set_section_flags (sec, SEC_HAS_CONTENTS | SEC_READONLY); 3968 1.1 christos bfd_set_section_alignment (sec, 3); 3969 1.1 christos 3970 1.1 christos ecoff_read_begin_hook (); 3971 1.1 christos 3972 1.1 christos if (first_file_directive) 3973 1.1 christos { 3974 1.1 christos char *save_ilp = input_line_pointer; 3975 1.1 christos input_line_pointer = first_file_directive; 3976 1.1 christos ecoff_directive_file (0); 3977 1.1 christos input_line_pointer = save_ilp; 3978 1.1 christos free (first_file_directive); 3979 1.1 christos } 3980 1.1 christos 3981 1.1 christos alpha_flag_mdebug = 1; 3982 1.1 christos } 3983 1.1 christos s_stab (n); 3984 1.1 christos } 3985 1.1 christos 3986 1.1 christos static void 3987 1.1 christos s_alpha_coff_wrapper (int which) 3988 1.1 christos { 3989 1.1 christos static void (* const fns[]) (int) = { 3990 1.1 christos ecoff_directive_begin, 3991 1.1 christos ecoff_directive_bend, 3992 1.1 christos ecoff_directive_def, 3993 1.1 christos ecoff_directive_dim, 3994 1.1 christos ecoff_directive_endef, 3995 1.1 christos ecoff_directive_scl, 3996 1.1 christos ecoff_directive_tag, 3997 1.1 christos ecoff_directive_val, 3998 1.1 christos }; 3999 1.1 christos 4000 1.1 christos gas_assert (which >= 0 && which < (int) (sizeof (fns)/sizeof (*fns))); 4001 1.1 christos 4002 1.1 christos if (ECOFF_DEBUGGING) 4003 1.1 christos (*fns[which]) (0); 4004 1.1 christos else 4005 1.1 christos { 4006 1.9 christos as_bad (_("ECOFF debugging is disabled.")); 4007 1.1 christos ignore_rest_of_line (); 4008 1.1 christos } 4009 1.1 christos } 4010 1.1 christos 4011 1.1 christos /* Called at the end of assembly. Here we emit unwind info for frames 4012 1.1 christos unless the compiler has done it for us. */ 4013 1.1 christos 4014 1.1 christos void 4015 1.1 christos alpha_elf_md_finish (void) 4016 1.1 christos { 4017 1.1 christos struct alpha_elf_frame_data *p; 4018 1.1 christos 4019 1.1 christos if (cur_frame_data) 4020 1.1 christos as_warn (_(".ent directive without matching .end")); 4021 1.1 christos 4022 1.1 christos /* If someone has generated the unwind info themselves, great. */ 4023 1.1 christos if (bfd_get_section_by_name (stdoutput, ".eh_frame") != NULL) 4024 1.1 christos return; 4025 1.1 christos 4026 1.1 christos /* ??? In theory we could look for functions for which we have 4027 1.1 christos generated unwind info via CFI directives, and those we have not. 4028 1.1 christos Those we have not could still get their unwind info from here. 4029 1.1 christos For now, do nothing if we've seen any CFI directives. Note that 4030 1.1 christos the above test will not trigger, as we've not emitted data yet. */ 4031 1.1 christos if (all_fde_data != NULL) 4032 1.8 christos return; 4033 1.10 christos 4034 1.10 christos /* Generate .eh_frame data for the unwind directives specified. */ 4035 1.1 christos for (p = all_frame_data; p ; p = p->next) 4036 1.3 christos if (p->prologue_sym) 4037 1.1 christos { 4038 1.1 christos /* Create a temporary symbol at the same location as our 4039 1.1 christos function symbol. This prevents problems with globals. */ 4040 1.1 christos cfi_new_fde (symbol_temp_new (S_GET_SEGMENT (p->func_sym), 4041 1.1 christos symbol_get_frag (p->func_sym), 4042 1.1 christos S_GET_VALUE (p->func_sym)), 4043 1.1 christos false); 4044 1.1 christos 4045 1.1 christos cfi_set_sections (); 4046 1.1 christos cfi_set_return_column (p->ra_regno); 4047 1.1 christos cfi_add_CFA_def_cfa_register (30); 4048 1.1 christos if (p->fp_regno != 30 || p->mask || p->fmask || p->frame_size) 4049 1.1 christos { 4050 1.1 christos unsigned int mask; 4051 1.1 christos offsetT offset; 4052 1.1 christos 4053 1.1 christos cfi_add_advance_loc (p->prologue_sym); 4054 1.1 christos 4055 1.1 christos if (p->fp_regno != 30) 4056 1.1 christos if (p->frame_size != 0) 4057 1.1 christos cfi_add_CFA_def_cfa (p->fp_regno, p->frame_size); 4058 1.1 christos else 4059 1.1 christos cfi_add_CFA_def_cfa_register (p->fp_regno); 4060 1.1 christos else if (p->frame_size != 0) 4061 1.1 christos cfi_add_CFA_def_cfa_offset (p->frame_size); 4062 1.1 christos 4063 1.1 christos mask = p->mask; 4064 1.1 christos offset = p->mask_offset; 4065 1.1 christos 4066 1.1 christos /* Recall that $26 is special-cased and stored first. */ 4067 1.1 christos if ((mask >> 26) & 1) 4068 1.1 christos { 4069 1.1 christos cfi_add_CFA_offset (26, offset); 4070 1.1 christos offset += 8; 4071 1.1 christos mask &= ~(1 << 26); 4072 1.1 christos } 4073 1.1 christos while (mask) 4074 1.1 christos { 4075 1.1 christos unsigned int i; 4076 1.1 christos i = mask & -mask; 4077 1.1 christos mask ^= i; 4078 1.1 christos i = ffs (i) - 1; 4079 1.1 christos 4080 1.1 christos cfi_add_CFA_offset (i, offset); 4081 1.1 christos offset += 8; 4082 1.1 christos } 4083 1.1 christos 4084 1.1 christos mask = p->fmask; 4085 1.1 christos offset = p->fmask_offset; 4086 1.1 christos while (mask) 4087 1.1 christos { 4088 1.1 christos unsigned int i; 4089 1.1 christos i = mask & -mask; 4090 1.1 christos mask ^= i; 4091 1.1 christos i = ffs (i) - 1; 4092 1.1 christos 4093 1.1 christos cfi_add_CFA_offset (i + 32, offset); 4094 1.1 christos offset += 8; 4095 1.1 christos } 4096 1.1 christos } 4097 1.1 christos 4098 1.1 christos cfi_end_fde (p->func_end_sym); 4099 1.1 christos } 4100 1.1 christos } 4101 1.3 christos 4102 1.1 christos static void 4103 1.1 christos s_alpha_usepv (int unused ATTRIBUTE_UNUSED) 4104 1.1 christos { 4105 1.1 christos char *name, name_end; 4106 1.3 christos char *which, which_end; 4107 1.1 christos symbolS *sym; 4108 1.1 christos int other; 4109 1.1 christos 4110 1.1 christos name_end = get_symbol_name (&name); 4111 1.1 christos 4112 1.3 christos if (! is_name_beginner (*name)) 4113 1.10 christos { 4114 1.3 christos as_bad (_(".usepv directive has no name")); 4115 1.1 christos (void) restore_line_pointer (name_end); 4116 1.1 christos ignore_rest_of_line (); 4117 1.1 christos return; 4118 1.1 christos } 4119 1.1 christos 4120 1.1 christos sym = symbol_find_or_make (name); 4121 1.1 christos name_end = restore_line_pointer (name_end); 4122 1.1 christos if (! is_end_of_stmt (name_end)) 4123 1.1 christos input_line_pointer++; 4124 1.3 christos 4125 1.3 christos if (name_end != ',') 4126 1.1 christos { 4127 1.1 christos as_bad (_(".usepv directive has no type")); 4128 1.1 christos ignore_rest_of_line (); 4129 1.1 christos return; 4130 1.1 christos } 4131 1.1 christos 4132 1.1 christos SKIP_WHITESPACE (); 4133 1.1 christos 4134 1.1 christos which_end = get_symbol_name (&which); 4135 1.1 christos 4136 1.1 christos if (strcmp (which, "no") == 0) 4137 1.3 christos other = STO_ALPHA_NOPV; 4138 1.1 christos else if (strcmp (which, "std") == 0) 4139 1.1 christos other = STO_ALPHA_STD_GPLOAD; 4140 1.1 christos else 4141 1.1 christos { 4142 1.1 christos as_bad (_("unknown argument for .usepv")); 4143 1.1 christos other = 0; 4144 1.1 christos } 4145 1.1 christos 4146 1.1 christos (void) restore_line_pointer (which_end); 4147 1.1 christos demand_empty_rest_of_line (); 4148 1.1 christos 4149 1.1 christos S_SET_OTHER (sym, other | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD)); 4150 1.1 christos } 4151 1.1 christos #endif /* OBJ_ELF */ 4152 1.1 christos 4153 1.1 christos /* Standard calling conventions leaves the CFA at $30 on entry. */ 4154 1.1 christos 4155 1.5 christos void 4156 1.1 christos alpha_cfi_frame_initial_instructions (void) 4157 1.1 christos { 4158 1.1 christos cfi_add_CFA_def_cfa_register (30); 4159 1.1 christos } 4160 1.1 christos 4161 1.1 christos #ifdef OBJ_EVAX 4162 1.1 christos 4163 1.1 christos /* Get name of section. */ 4164 1.1 christos static const char * 4165 1.1 christos s_alpha_section_name (void) 4166 1.1 christos { 4167 1.1 christos char *name; 4168 1.1 christos 4169 1.1 christos SKIP_WHITESPACE (); 4170 1.1 christos if (*input_line_pointer == '"') 4171 1.1 christos { 4172 1.1 christos int dummy; 4173 1.1 christos 4174 1.1 christos name = demand_copy_C_string (&dummy); 4175 1.1 christos if (name == NULL) 4176 1.10 christos { 4177 1.1 christos ignore_rest_of_line (); 4178 1.1 christos return NULL; 4179 1.1 christos } 4180 1.1 christos } 4181 1.1 christos else 4182 1.1 christos { 4183 1.1 christos char *end = input_line_pointer; 4184 1.1 christos 4185 1.5 christos while (!is_whitespace (*end) && !is_end_of_stmt (*end) && *end != ',') 4186 1.1 christos end++; 4187 1.1 christos if (end == input_line_pointer) 4188 1.1 christos { 4189 1.1 christos as_warn (_("missing name")); 4190 1.1 christos ignore_rest_of_line (); 4191 1.1 christos return NULL; 4192 1.1 christos } 4193 1.1 christos 4194 1.1 christos name = xmemdup0 (input_line_pointer, end - input_line_pointer); 4195 1.1 christos input_line_pointer = end; 4196 1.1 christos } 4197 1.1 christos SKIP_WHITESPACE (); 4198 1.1 christos return name; 4199 1.1 christos } 4200 1.1 christos 4201 1.1 christos /* Put clear/set flags in one flagword. The LSBs are flags to be set, 4202 1.1 christos the MSBs are the flags to be cleared. */ 4203 1.1 christos 4204 1.1 christos #define EGPS__V_NO_SHIFT 16 4205 1.1 christos #define EGPS__V_MASK 0xffff 4206 1.8 christos 4207 1.1 christos /* Parse one VMS section flag. */ 4208 1.1 christos 4209 1.1 christos static flagword 4210 1.3 christos s_alpha_section_word (char *str, size_t len) 4211 1.1 christos { 4212 1.1 christos int no = 0; 4213 1.1 christos flagword flag = 0; 4214 1.1 christos 4215 1.8 christos if (len == 5 && startswith (str, "NO")) 4216 1.1 christos { 4217 1.8 christos no = 1; 4218 1.1 christos str += 2; 4219 1.8 christos len -= 2; 4220 1.1 christos } 4221 1.8 christos 4222 1.1 christos if (len == 3) 4223 1.8 christos { 4224 1.1 christos if (startswith (str, "PIC")) 4225 1.8 christos flag = EGPS__V_PIC; 4226 1.1 christos else if (startswith (str, "LIB")) 4227 1.8 christos flag = EGPS__V_LIB; 4228 1.1 christos else if (startswith (str, "OVR")) 4229 1.8 christos flag = EGPS__V_OVR; 4230 1.1 christos else if (startswith (str, "REL")) 4231 1.8 christos flag = EGPS__V_REL; 4232 1.1 christos else if (startswith (str, "GBL")) 4233 1.8 christos flag = EGPS__V_GBL; 4234 1.1 christos else if (startswith (str, "SHR")) 4235 1.1 christos flag = EGPS__V_SHR; 4236 1.1 christos else if (startswith (str, "EXE")) 4237 1.1 christos flag = EGPS__V_EXE; 4238 1.8 christos else if (startswith (str, "WRT")) 4239 1.1 christos flag = EGPS__V_WRT; 4240 1.1 christos else if (startswith (str, "VEC")) 4241 1.1 christos flag = EGPS__V_VEC; 4242 1.1 christos else if (startswith (str, "MOD")) 4243 1.1 christos { 4244 1.1 christos flag = no ? EGPS__V_NOMOD : EGPS__V_NOMOD << EGPS__V_NO_SHIFT; 4245 1.1 christos no = 0; 4246 1.1 christos } 4247 1.1 christos else if (startswith (str, "COM")) 4248 1.1 christos flag = EGPS__V_COM; 4249 1.1 christos } 4250 1.1 christos 4251 1.1 christos if (flag == 0) 4252 1.1 christos { 4253 1.1 christos char c = str[len]; 4254 1.1 christos str[len] = 0; 4255 1.1 christos as_warn (_("unknown section attribute %s"), str); 4256 1.1 christos str[len] = c; 4257 1.1 christos return 0; 4258 1.1 christos } 4259 1.1 christos 4260 1.1 christos if (no) 4261 1.5 christos return flag << EGPS__V_NO_SHIFT; 4262 1.1 christos else 4263 1.1 christos return flag; 4264 1.1 christos } 4265 1.1 christos 4266 1.1 christos /* Handle the section specific pseudo-op. */ 4267 1.5 christos 4268 1.5 christos #define EVAX_SECTION_COUNT 5 4269 1.1 christos 4270 1.1 christos static const char *section_name[EVAX_SECTION_COUNT + 1] = 4271 1.1 christos { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" }; 4272 1.1 christos 4273 1.1 christos static void 4274 1.1 christos s_alpha_section (int secid) 4275 1.1 christos { 4276 1.1 christos const char *name; 4277 1.1 christos char *beg; 4278 1.1 christos segT sec; 4279 1.1 christos flagword vms_flags = 0; 4280 1.1 christos symbolS *symbol; 4281 1.1 christos 4282 1.1 christos if (secid == 0) 4283 1.1 christos { 4284 1.1 christos name = s_alpha_section_name (); 4285 1.1 christos if (name == NULL) 4286 1.1 christos return; 4287 1.1 christos sec = subseg_new (name, 0); 4288 1.1 christos if (*input_line_pointer == ',') 4289 1.1 christos { 4290 1.3 christos /* Skip the comma. */ 4291 1.10 christos ++input_line_pointer; 4292 1.1 christos SKIP_WHITESPACE (); 4293 1.1 christos 4294 1.1 christos do 4295 1.10 christos { 4296 1.1 christos char c; 4297 1.1 christos 4298 1.3 christos SKIP_WHITESPACE (); 4299 1.1 christos c = get_symbol_name (&beg); 4300 1.1 christos restore_line_pointer (c); 4301 1.1 christos 4302 1.1 christos vms_flags |= s_alpha_section_word (beg, input_line_pointer - beg); 4303 1.1 christos 4304 1.1 christos SKIP_WHITESPACE (); 4305 1.1 christos } 4306 1.1 christos while (*input_line_pointer++ == ','); 4307 1.1 christos 4308 1.1 christos --input_line_pointer; 4309 1.1 christos } 4310 1.1 christos 4311 1.1 christos symbol = symbol_find_or_make (name); 4312 1.1 christos S_SET_SEGMENT (symbol, sec); 4313 1.1 christos symbol_get_bfdsym (symbol)->flags |= BSF_SECTION_SYM; 4314 1.1 christos bfd_vms_set_section_flags 4315 1.1 christos (stdoutput, sec, 4316 1.1 christos (vms_flags >> EGPS__V_NO_SHIFT) & EGPS__V_MASK, 4317 1.1 christos vms_flags & EGPS__V_MASK); 4318 1.1 christos } 4319 1.1 christos else 4320 1.1 christos { 4321 1.1 christos get_absolute_expression (); 4322 1.1 christos subseg_new (section_name[secid], 0); 4323 1.1 christos } 4324 1.1 christos 4325 1.1 christos demand_empty_rest_of_line (); 4326 1.1 christos alpha_insn_label = NULL; 4327 1.1 christos alpha_auto_align_on = 1; 4328 1.1 christos alpha_current_align = 0; 4329 1.1 christos } 4330 1.1 christos 4331 1.1 christos static void 4332 1.1 christos s_alpha_literals (int ignore ATTRIBUTE_UNUSED) 4333 1.1 christos { 4334 1.1 christos subseg_new (".literals", 0); 4335 1.1 christos demand_empty_rest_of_line (); 4336 1.1 christos alpha_insn_label = NULL; 4337 1.1 christos alpha_auto_align_on = 1; 4338 1.1 christos alpha_current_align = 0; 4339 1.1 christos } 4340 1.1 christos 4341 1.1 christos /* Parse .ent directives. */ 4342 1.1 christos 4343 1.1 christos static void 4344 1.1 christos s_alpha_ent (int ignore ATTRIBUTE_UNUSED) 4345 1.1 christos { 4346 1.1 christos symbolS *symbol; 4347 1.1 christos expressionS symexpr; 4348 1.1 christos 4349 1.1 christos if (alpha_evax_proc != NULL) 4350 1.1 christos as_bad (_("previous .ent not closed by a .end")); 4351 1.1 christos 4352 1.1 christos alpha_evax_proc = &alpha_evax_proc_data; 4353 1.1 christos 4354 1.1 christos alpha_evax_proc->pdsckind = 0; 4355 1.1 christos alpha_evax_proc->framereg = -1; 4356 1.1 christos alpha_evax_proc->framesize = 0; 4357 1.1 christos alpha_evax_proc->rsa_offset = 0; 4358 1.1 christos alpha_evax_proc->ra_save = AXP_REG_RA; 4359 1.1 christos alpha_evax_proc->fp_save = -1; 4360 1.1 christos alpha_evax_proc->imask = 0; 4361 1.1 christos alpha_evax_proc->fmask = 0; 4362 1.1 christos alpha_evax_proc->prologue = 0; 4363 1.1 christos alpha_evax_proc->type = 0; 4364 1.1 christos alpha_evax_proc->handler = 0; 4365 1.1 christos alpha_evax_proc->handler_data = 0; 4366 1.1 christos 4367 1.1 christos expression (&symexpr); 4368 1.1 christos 4369 1.1 christos if (symexpr.X_op != O_symbol) 4370 1.1 christos { 4371 1.1 christos as_fatal (_(".ent directive has no symbol")); 4372 1.1 christos demand_empty_rest_of_line (); 4373 1.1 christos return; 4374 1.1 christos } 4375 1.1 christos 4376 1.1 christos symbol = make_expr_symbol (&symexpr); 4377 1.1 christos symbol_get_bfdsym (symbol)->flags |= BSF_FUNCTION; 4378 1.1 christos alpha_evax_proc->symbol = symbol; 4379 1.1 christos 4380 1.1 christos demand_empty_rest_of_line (); 4381 1.1 christos } 4382 1.3 christos 4383 1.3 christos static void 4384 1.1 christos s_alpha_handler (int is_data) 4385 1.1 christos { 4386 1.1 christos if (is_data) 4387 1.1 christos alpha_evax_proc->handler_data = get_absolute_expression (); 4388 1.1 christos else 4389 1.1 christos { 4390 1.1 christos char *name, name_end; 4391 1.1 christos 4392 1.1 christos name_end = get_symbol_name (&name); 4393 1.1 christos 4394 1.1 christos if (! is_name_beginner (*name)) 4395 1.1 christos { 4396 1.1 christos as_warn (_(".handler directive has no name")); 4397 1.3 christos } 4398 1.3 christos else 4399 1.3 christos { 4400 1.3 christos symbolS *sym; 4401 1.1 christos 4402 1.1 christos sym = symbol_find_or_make (name); 4403 1.1 christos symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION; 4404 1.1 christos alpha_evax_proc->handler = sym; 4405 1.1 christos } 4406 1.1 christos 4407 1.1 christos (void) restore_line_pointer (name_end); 4408 1.1 christos } 4409 1.1 christos 4410 1.1 christos demand_empty_rest_of_line (); 4411 1.1 christos } 4412 1.1 christos 4413 1.1 christos /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */ 4414 1.1 christos 4415 1.1 christos static void 4416 1.1 christos s_alpha_frame (int ignore ATTRIBUTE_UNUSED) 4417 1.1 christos { 4418 1.1 christos long val; 4419 1.1 christos int ra; 4420 1.1 christos 4421 1.1 christos alpha_evax_proc->framereg = tc_get_register (1); 4422 1.1 christos 4423 1.1 christos SKIP_WHITESPACE (); 4424 1.1 christos if (*input_line_pointer++ != ',' 4425 1.1 christos || get_absolute_expression_and_terminator (&val) != ',') 4426 1.1 christos { 4427 1.1 christos as_warn (_("Bad .frame directive 1./2. param")); 4428 1.1 christos --input_line_pointer; 4429 1.1 christos demand_empty_rest_of_line (); 4430 1.1 christos return; 4431 1.1 christos } 4432 1.1 christos 4433 1.1 christos alpha_evax_proc->framesize = val; 4434 1.1 christos 4435 1.1 christos ra = tc_get_register (1); 4436 1.1 christos if (ra != AXP_REG_RA) 4437 1.1 christos as_warn (_("Bad RA (%d) register for .frame"), ra); 4438 1.1 christos 4439 1.1 christos SKIP_WHITESPACE (); 4440 1.1 christos if (*input_line_pointer++ != ',') 4441 1.1 christos { 4442 1.1 christos as_warn (_("Bad .frame directive 3./4. param")); 4443 1.1 christos --input_line_pointer; 4444 1.1 christos demand_empty_rest_of_line (); 4445 1.1 christos return; 4446 1.1 christos } 4447 1.8 christos alpha_evax_proc->rsa_offset = get_absolute_expression (); 4448 1.8 christos } 4449 1.1 christos 4450 1.1 christos /* Parse .prologue. */ 4451 1.1 christos 4452 1.1 christos static void 4453 1.1 christos s_alpha_prologue (int ignore ATTRIBUTE_UNUSED) 4454 1.1 christos { 4455 1.1 christos demand_empty_rest_of_line (); 4456 1.1 christos alpha_prologue_label = symbol_new (FAKE_LABEL_NAME, now_seg, frag_now, 4457 1.1 christos frag_now_fix ()); 4458 1.1 christos } 4459 1.3 christos 4460 1.1 christos /* Parse .pdesc <entry_name>,{null|stack|reg} 4461 1.1 christos Insert a procedure descriptor. */ 4462 1.1 christos 4463 1.1 christos static void 4464 1.1 christos s_alpha_pdesc (int ignore ATTRIBUTE_UNUSED) 4465 1.1 christos { 4466 1.1 christos char *name; 4467 1.1 christos char name_end; 4468 1.1 christos char *p; 4469 1.1 christos expressionS exp; 4470 1.1 christos symbolS *entry_sym; 4471 1.1 christos const char *entry_sym_name; 4472 1.1 christos const char *pdesc_sym_name; 4473 1.1 christos fixS *fixp; 4474 1.1 christos size_t len; 4475 1.1 christos 4476 1.1 christos if (now_seg != alpha_link_section) 4477 1.1 christos { 4478 1.1 christos as_bad (_(".pdesc directive not in link (.link) section")); 4479 1.3 christos return; 4480 1.1 christos } 4481 1.1 christos 4482 1.3 christos expression (&exp); 4483 1.1 christos if (exp.X_op != O_symbol) 4484 1.1 christos { 4485 1.1 christos as_bad (_(".pdesc directive has no entry symbol")); 4486 1.1 christos return; 4487 1.1 christos } 4488 1.1 christos 4489 1.1 christos entry_sym = make_expr_symbol (&exp); 4490 1.1 christos entry_sym_name = S_GET_NAME (entry_sym); 4491 1.1 christos 4492 1.1 christos /* Strip "..en". */ 4493 1.1 christos len = strlen (entry_sym_name); 4494 1.1 christos if (len < 4 || strcmp (entry_sym_name + len - 4, "..en") != 0) 4495 1.1 christos { 4496 1.1 christos as_bad (_(".pdesc has a bad entry symbol")); 4497 1.1 christos return; 4498 1.1 christos } 4499 1.1 christos len -= 4; 4500 1.1 christos pdesc_sym_name = S_GET_NAME (alpha_evax_proc->symbol); 4501 1.1 christos 4502 1.1 christos if (!alpha_evax_proc 4503 1.1 christos || !S_IS_DEFINED (alpha_evax_proc->symbol) 4504 1.3 christos || strlen (pdesc_sym_name) != len 4505 1.1 christos || memcmp (entry_sym_name, pdesc_sym_name, len) != 0) 4506 1.1 christos { 4507 1.1 christos as_fatal (_(".pdesc doesn't match with last .ent")); 4508 1.1 christos return; 4509 1.3 christos } 4510 1.1 christos 4511 1.1 christos /* Define pdesc symbol. */ 4512 1.1 christos symbol_set_value_now (alpha_evax_proc->symbol); 4513 1.1 christos 4514 1.1 christos /* Save bfd symbol of proc entry in function symbol. */ 4515 1.1 christos ((struct evax_private_udata_struct *) 4516 1.1 christos symbol_get_bfdsym (alpha_evax_proc->symbol)->udata.p)->enbsym 4517 1.1 christos = symbol_get_bfdsym (entry_sym); 4518 1.1 christos 4519 1.3 christos SKIP_WHITESPACE (); 4520 1.1 christos if (*input_line_pointer++ != ',') 4521 1.8 christos { 4522 1.1 christos as_warn (_("No comma after .pdesc <entryname>")); 4523 1.1 christos demand_empty_rest_of_line (); 4524 1.8 christos return; 4525 1.1 christos } 4526 1.1 christos 4527 1.8 christos SKIP_WHITESPACE (); 4528 1.1 christos name_end = get_symbol_name (&name); 4529 1.1 christos 4530 1.1 christos if (startswith (name, "stack")) 4531 1.1 christos alpha_evax_proc->pdsckind = PDSC_S_K_KIND_FP_STACK; 4532 1.3 christos 4533 1.1 christos else if (startswith (name, "reg")) 4534 1.1 christos alpha_evax_proc->pdsckind = PDSC_S_K_KIND_FP_REGISTER; 4535 1.1 christos 4536 1.1 christos else if (startswith (name, "null")) 4537 1.1 christos alpha_evax_proc->pdsckind = PDSC_S_K_KIND_NULL; 4538 1.3 christos 4539 1.1 christos else 4540 1.1 christos { 4541 1.1 christos (void) restore_line_pointer (name_end); 4542 1.1 christos as_fatal (_("unknown procedure kind")); 4543 1.1 christos demand_empty_rest_of_line (); 4544 1.1 christos return; 4545 1.1 christos } 4546 1.1 christos 4547 1.1 christos (void) restore_line_pointer (name_end); 4548 1.1 christos demand_empty_rest_of_line (); 4549 1.1 christos 4550 1.1 christos #ifdef md_flush_pending_output 4551 1.1 christos md_flush_pending_output (); 4552 1.1 christos #endif 4553 1.1 christos 4554 1.1 christos frag_align (3, 0, 0); 4555 1.1 christos p = frag_more (16); 4556 1.1 christos fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0); 4557 1.1 christos fixp->fx_done = 1; 4558 1.1 christos 4559 1.1 christos *p = alpha_evax_proc->pdsckind 4560 1.1 christos | ((alpha_evax_proc->framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0) 4561 1.1 christos | ((alpha_evax_proc->handler) ? PDSC_S_M_HANDLER_VALID : 0) 4562 1.1 christos | ((alpha_evax_proc->handler_data) ? PDSC_S_M_HANDLER_DATA_VALID : 0); 4563 1.1 christos *(p + 1) = PDSC_S_M_NATIVE | PDSC_S_M_NO_JACKET; 4564 1.1 christos 4565 1.1 christos switch (alpha_evax_proc->pdsckind) 4566 1.1 christos { 4567 1.10 christos case PDSC_S_K_KIND_NULL: 4568 1.1 christos *(p + 2) = 0; 4569 1.1 christos *(p + 3) = 0; 4570 1.1 christos break; 4571 1.1 christos case PDSC_S_K_KIND_FP_REGISTER: 4572 1.1 christos *(p + 2) = alpha_evax_proc->fp_save; 4573 1.1 christos *(p + 3) = alpha_evax_proc->ra_save; 4574 1.1 christos break; 4575 1.1 christos case PDSC_S_K_KIND_FP_STACK: 4576 1.1 christos md_number_to_chars (p + 2, alpha_evax_proc->rsa_offset, 2); 4577 1.10 christos break; 4578 1.1 christos default: /* impossible */ 4579 1.1 christos break; 4580 1.1 christos } 4581 1.1 christos 4582 1.1 christos *(p + 4) = 0; 4583 1.1 christos *(p + 5) = alpha_evax_proc->type & 0x0f; 4584 1.1 christos 4585 1.1 christos /* Signature offset. */ 4586 1.1 christos md_number_to_chars (p + 6, 0, 2); 4587 1.10 christos 4588 1.10 christos fix_new_exp (frag_now, p - frag_now->fr_literal + 8, 4589 1.1 christos 8, &exp, 0, BFD_RELOC_64); 4590 1.1 christos 4591 1.1 christos if (alpha_evax_proc->pdsckind == PDSC_S_K_KIND_NULL) 4592 1.1 christos return; 4593 1.1 christos 4594 1.1 christos /* pdesc+16: Size. */ 4595 1.1 christos p = frag_more (6); 4596 1.1 christos md_number_to_chars (p, alpha_evax_proc->framesize, 4); 4597 1.1 christos md_number_to_chars (p + 4, 0, 2); 4598 1.1 christos 4599 1.1 christos /* Entry length. */ 4600 1.1 christos exp.X_op = O_subtract; 4601 1.1 christos exp.X_add_symbol = alpha_prologue_label; 4602 1.1 christos exp.X_op_symbol = entry_sym; 4603 1.1 christos emit_expr (&exp, 2); 4604 1.1 christos 4605 1.1 christos if (alpha_evax_proc->pdsckind == PDSC_S_K_KIND_FP_REGISTER) 4606 1.1 christos return; 4607 1.1 christos 4608 1.1 christos /* pdesc+24: register masks. */ 4609 1.1 christos p = frag_more (8); 4610 1.1 christos md_number_to_chars (p, alpha_evax_proc->imask, 4); 4611 1.1 christos md_number_to_chars (p + 4, alpha_evax_proc->fmask, 4); 4612 1.1 christos 4613 1.1 christos if (alpha_evax_proc->handler) 4614 1.1 christos { 4615 1.1 christos p = frag_more (8); 4616 1.1 christos fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 4617 1.1 christos alpha_evax_proc->handler, 0, 0, BFD_RELOC_64); 4618 1.1 christos } 4619 1.1 christos 4620 1.1 christos if (alpha_evax_proc->handler_data) 4621 1.1 christos { 4622 1.1 christos p = frag_more (8); 4623 1.1 christos md_number_to_chars (p, alpha_evax_proc->handler_data, 8); 4624 1.1 christos } 4625 1.1 christos } 4626 1.1 christos 4627 1.1 christos /* Support for crash debug on vms. */ 4628 1.1 christos 4629 1.1 christos static void 4630 1.1 christos s_alpha_name (int ignore ATTRIBUTE_UNUSED) 4631 1.1 christos { 4632 1.1 christos char *p; 4633 1.1 christos expressionS exp; 4634 1.1 christos 4635 1.1 christos if (now_seg != alpha_link_section) 4636 1.1 christos { 4637 1.1 christos as_bad (_(".name directive not in link (.link) section")); 4638 1.1 christos demand_empty_rest_of_line (); 4639 1.1 christos return; 4640 1.1 christos } 4641 1.1 christos 4642 1.1 christos expression (&exp); 4643 1.1 christos if (exp.X_op != O_symbol) 4644 1.1 christos { 4645 1.1 christos as_warn (_(".name directive has no symbol")); 4646 1.1 christos demand_empty_rest_of_line (); 4647 1.1 christos return; 4648 1.1 christos } 4649 1.1 christos 4650 1.1 christos demand_empty_rest_of_line (); 4651 1.1 christos 4652 1.1 christos #ifdef md_flush_pending_output 4653 1.1 christos md_flush_pending_output (); 4654 1.1 christos #endif 4655 1.1 christos 4656 1.1 christos frag_align (3, 0, 0); 4657 1.1 christos p = frag_more (8); 4658 1.1 christos 4659 1.1 christos fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64); 4660 1.1 christos } 4661 1.1 christos 4662 1.1 christos /* Parse .linkage <symbol>. 4663 1.1 christos Create a linkage pair relocation. */ 4664 1.1 christos 4665 1.1 christos static void 4666 1.1 christos s_alpha_linkage (int ignore ATTRIBUTE_UNUSED) 4667 1.1 christos { 4668 1.1 christos expressionS exp; 4669 1.1 christos char *p; 4670 1.1 christos fixS *fixp; 4671 1.1 christos 4672 1.1 christos #ifdef md_flush_pending_output 4673 1.1 christos md_flush_pending_output (); 4674 1.1 christos #endif 4675 1.3 christos 4676 1.1 christos expression (&exp); 4677 1.1 christos if (exp.X_op != O_symbol) 4678 1.1 christos { 4679 1.1 christos as_fatal (_("No symbol after .linkage")); 4680 1.1 christos } 4681 1.1 christos else 4682 1.1 christos { 4683 1.8 christos struct alpha_linkage_fixups *linkage_fixup; 4684 1.8 christos 4685 1.1 christos p = frag_more (LKP_S_K_SIZE); 4686 1.1 christos memset (p, 0, LKP_S_K_SIZE); 4687 1.5 christos fixp = fix_new_exp 4688 1.1 christos (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0, 4689 1.1 christos BFD_RELOC_ALPHA_LINKAGE); 4690 1.1 christos 4691 1.1 christos if (alpha_insn_label == NULL) 4692 1.1 christos alpha_insn_label = symbol_new (FAKE_LABEL_NAME, now_seg, frag_now, 4693 1.1 christos frag_now_fix ()); 4694 1.1 christos 4695 1.1 christos /* Create a linkage element. */ 4696 1.1 christos linkage_fixup = XNEW (struct alpha_linkage_fixups); 4697 1.1 christos linkage_fixup->fixp = fixp; 4698 1.1 christos linkage_fixup->next = NULL; 4699 1.1 christos linkage_fixup->label = alpha_insn_label; 4700 1.1 christos 4701 1.1 christos /* Append it to the list. */ 4702 1.1 christos if (alpha_linkage_fixup_root == NULL) 4703 1.1 christos alpha_linkage_fixup_root = linkage_fixup; 4704 1.1 christos else 4705 1.1 christos alpha_linkage_fixup_tail->next = linkage_fixup; 4706 1.1 christos alpha_linkage_fixup_tail = linkage_fixup; 4707 1.1 christos } 4708 1.1 christos demand_empty_rest_of_line (); 4709 1.1 christos } 4710 1.1 christos 4711 1.1 christos /* Parse .code_address <symbol>. 4712 1.1 christos Create a code address relocation. */ 4713 1.1 christos 4714 1.1 christos static void 4715 1.1 christos s_alpha_code_address (int ignore ATTRIBUTE_UNUSED) 4716 1.1 christos { 4717 1.1 christos expressionS exp; 4718 1.1 christos char *p; 4719 1.1 christos 4720 1.1 christos #ifdef md_flush_pending_output 4721 1.1 christos md_flush_pending_output (); 4722 1.1 christos #endif 4723 1.1 christos 4724 1.1 christos expression (&exp); 4725 1.1 christos if (exp.X_op != O_symbol) 4726 1.1 christos as_fatal (_("No symbol after .code_address")); 4727 1.1 christos else 4728 1.1 christos { 4729 1.1 christos p = frag_more (8); 4730 1.1 christos memset (p, 0, 8); 4731 1.1 christos fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0,\ 4732 1.1 christos BFD_RELOC_ALPHA_CODEADDR); 4733 1.1 christos } 4734 1.1 christos demand_empty_rest_of_line (); 4735 1.1 christos } 4736 1.1 christos 4737 1.1 christos static void 4738 1.1 christos s_alpha_fp_save (int ignore ATTRIBUTE_UNUSED) 4739 1.1 christos { 4740 1.1 christos alpha_evax_proc->fp_save = tc_get_register (1); 4741 1.1 christos 4742 1.1 christos demand_empty_rest_of_line (); 4743 1.1 christos } 4744 1.1 christos 4745 1.1 christos static void 4746 1.1 christos s_alpha_mask (int ignore ATTRIBUTE_UNUSED) 4747 1.1 christos { 4748 1.1 christos long val; 4749 1.1 christos 4750 1.1 christos if (get_absolute_expression_and_terminator (&val) != ',') 4751 1.1 christos { 4752 1.1 christos as_warn (_("Bad .mask directive")); 4753 1.1 christos --input_line_pointer; 4754 1.1 christos } 4755 1.1 christos else 4756 1.1 christos { 4757 1.1 christos alpha_evax_proc->imask = val; 4758 1.1 christos (void) get_absolute_expression (); 4759 1.1 christos } 4760 1.1 christos demand_empty_rest_of_line (); 4761 1.1 christos } 4762 1.1 christos 4763 1.1 christos static void 4764 1.1 christos s_alpha_fmask (int ignore ATTRIBUTE_UNUSED) 4765 1.1 christos { 4766 1.1 christos long val; 4767 1.1 christos 4768 1.1 christos if (get_absolute_expression_and_terminator (&val) != ',') 4769 1.1 christos { 4770 1.1 christos as_warn (_("Bad .fmask directive")); 4771 1.1 christos --input_line_pointer; 4772 1.1 christos } 4773 1.1 christos else 4774 1.1 christos { 4775 1.3 christos alpha_evax_proc->fmask = val; 4776 1.1 christos (void) get_absolute_expression (); 4777 1.1 christos } 4778 1.3 christos demand_empty_rest_of_line (); 4779 1.3 christos } 4780 1.1 christos 4781 1.1 christos static void 4782 1.1 christos s_alpha_end (int ignore ATTRIBUTE_UNUSED) 4783 1.1 christos { 4784 1.1 christos char *name; 4785 1.1 christos char c; 4786 1.1 christos 4787 1.1 christos c = get_symbol_name (&name); 4788 1.1 christos (void) restore_line_pointer (c); 4789 1.1 christos demand_empty_rest_of_line (); 4790 1.1 christos alpha_evax_proc = NULL; 4791 1.1 christos } 4792 1.1 christos 4793 1.1 christos static void 4794 1.1 christos s_alpha_file (int ignore ATTRIBUTE_UNUSED) 4795 1.1 christos { 4796 1.1 christos symbolS *s; 4797 1.1 christos int length; 4798 1.1 christos static char case_hack[32]; 4799 1.1 christos 4800 1.1 christos sprintf (case_hack, "<CASE:%01d%01d>", 4801 1.1 christos alpha_flag_hash_long_names, alpha_flag_show_after_trunc); 4802 1.1 christos 4803 1.1 christos s = symbol_find_or_make (case_hack); 4804 1.1 christos symbol_get_bfdsym (s)->flags |= BSF_FILE; 4805 1.1 christos 4806 1.1 christos get_absolute_expression (); 4807 1.1 christos s = symbol_find_or_make (demand_copy_string (&length)); 4808 1.1 christos symbol_get_bfdsym (s)->flags |= BSF_FILE; 4809 1.1 christos demand_empty_rest_of_line (); 4810 1.1 christos } 4811 1.1 christos #endif /* OBJ_EVAX */ 4812 1.1 christos 4813 1.1 christos /* Handle the .gprel32 pseudo op. */ 4814 1.1 christos 4815 1.1 christos static void 4816 1.1 christos s_alpha_gprel32 (int ignore ATTRIBUTE_UNUSED) 4817 1.1 christos { 4818 1.1 christos expressionS e; 4819 1.1 christos char *p; 4820 1.1 christos 4821 1.1 christos SKIP_WHITESPACE (); 4822 1.1 christos expression (&e); 4823 1.1 christos 4824 1.1 christos #ifdef OBJ_ELF 4825 1.1 christos switch (e.X_op) 4826 1.1 christos { 4827 1.1 christos case O_constant: 4828 1.1 christos e.X_add_symbol = section_symbol (absolute_section); 4829 1.1 christos e.X_op = O_symbol; 4830 1.1 christos /* FALLTHRU */ 4831 1.1 christos case O_symbol: 4832 1.1 christos break; 4833 1.1 christos default: 4834 1.1 christos abort (); 4835 1.1 christos } 4836 1.1 christos #else 4837 1.1 christos #ifdef OBJ_ECOFF 4838 1.1 christos switch (e.X_op) 4839 1.1 christos { 4840 1.1 christos case O_constant: 4841 1.1 christos e.X_add_symbol = section_symbol (absolute_section); 4842 1.1 christos /* fall through */ 4843 1.1 christos case O_symbol: 4844 1.1 christos e.X_op = O_subtract; 4845 1.10 christos e.X_op_symbol = alpha_gp_symbol; 4846 1.1 christos break; 4847 1.1 christos default: 4848 1.1 christos abort (); 4849 1.1 christos } 4850 1.1 christos #endif 4851 1.1 christos #endif 4852 1.1 christos 4853 1.1 christos if (alpha_auto_align_on && alpha_current_align < 2) 4854 1.1 christos alpha_align (2, NULL, alpha_insn_label, 0); 4855 1.1 christos if (alpha_current_align > 2) 4856 1.1 christos alpha_current_align = 2; 4857 1.6 christos alpha_insn_label = NULL; 4858 1.1 christos 4859 1.1 christos p = frag_more (4); 4860 1.1 christos memset (p, 0, 4); 4861 1.1 christos fix_new_exp (frag_now, p - frag_now->fr_literal, 4, 4862 1.1 christos &e, 0, BFD_RELOC_GPREL32); 4863 1.1 christos } 4864 1.1 christos 4865 1.1 christos /* Handle floating point allocation pseudo-ops. This is like the 4866 1.1 christos generic version, but it makes sure the current label, if any, is 4867 1.1 christos correctly aligned. */ 4868 1.1 christos 4869 1.1 christos static void 4870 1.1 christos s_alpha_float_cons (int type) 4871 1.1 christos { 4872 1.1 christos int log_size; 4873 1.1 christos 4874 1.1 christos switch (type) 4875 1.1 christos { 4876 1.1 christos default: 4877 1.1 christos case 'f': 4878 1.1 christos case 'F': 4879 1.1 christos log_size = 2; 4880 1.1 christos break; 4881 1.1 christos 4882 1.1 christos case 'd': 4883 1.1 christos case 'D': 4884 1.1 christos case 'G': 4885 1.1 christos log_size = 3; 4886 1.1 christos break; 4887 1.1 christos 4888 1.10 christos case 'x': 4889 1.1 christos case 'X': 4890 1.1 christos case 'p': 4891 1.1 christos case 'P': 4892 1.1 christos log_size = 4; 4893 1.1 christos break; 4894 1.1 christos } 4895 1.1 christos 4896 1.1 christos if (alpha_auto_align_on && alpha_current_align < log_size) 4897 1.1 christos alpha_align (log_size, NULL, alpha_insn_label, 0); 4898 1.1 christos if (alpha_current_align > log_size) 4899 1.1 christos alpha_current_align = log_size; 4900 1.1 christos alpha_insn_label = NULL; 4901 1.1 christos 4902 1.1 christos float_cons (type); 4903 1.1 christos } 4904 1.1 christos 4905 1.1 christos /* Handle the .proc pseudo op. We don't really do much with it except 4906 1.1 christos parse it. */ 4907 1.1 christos 4908 1.1 christos static void 4909 1.1 christos s_alpha_proc (int is_static ATTRIBUTE_UNUSED) 4910 1.3 christos { 4911 1.1 christos char *name; 4912 1.1 christos char c; 4913 1.10 christos char *p; 4914 1.10 christos symbolS *symbolP; 4915 1.1 christos int temp; 4916 1.1 christos 4917 1.1 christos /* Takes ".proc name,nargs". */ 4918 1.1 christos SKIP_WHITESPACE (); 4919 1.1 christos c = get_symbol_name (&name); 4920 1.1 christos p = input_line_pointer; 4921 1.1 christos symbolP = symbol_find_or_make (name); 4922 1.1 christos restore_line_pointer (c); 4923 1.1 christos SKIP_WHITESPACE (); 4924 1.1 christos if (*input_line_pointer != ',') 4925 1.1 christos { 4926 1.1 christos *p = 0; 4927 1.1 christos as_warn (_("Expected comma after name \"%s\""), name); 4928 1.1 christos *p = c; 4929 1.1 christos temp = 0; 4930 1.1 christos ignore_rest_of_line (); 4931 1.1 christos } 4932 1.1 christos else 4933 1.1 christos { 4934 1.1 christos input_line_pointer++; 4935 1.1 christos temp = get_absolute_expression (); 4936 1.1 christos } 4937 1.1 christos /* *symbol_get_obj (symbolP) = (signed char) temp; */ 4938 1.1 christos (void) symbolP; 4939 1.1 christos as_warn (_("unhandled: .proc %s,%d"), name, temp); 4940 1.1 christos demand_empty_rest_of_line (); 4941 1.1 christos } 4942 1.1 christos 4943 1.1 christos /* Handle the .set pseudo op. This is used to turn on and off most of 4944 1.1 christos the assembler features. */ 4945 1.3 christos 4946 1.1 christos static void 4947 1.1 christos s_alpha_set (int x ATTRIBUTE_UNUSED) 4948 1.1 christos { 4949 1.1 christos char *name, ch, *s; 4950 1.1 christos int yesno = 1; 4951 1.1 christos 4952 1.1 christos SKIP_WHITESPACE (); 4953 1.1 christos 4954 1.1 christos ch = get_symbol_name (&name); 4955 1.1 christos s = name; 4956 1.1 christos if (s[0] == 'n' && s[1] == 'o') 4957 1.1 christos { 4958 1.1 christos yesno = 0; 4959 1.1 christos s += 2; 4960 1.1 christos } 4961 1.1 christos if (!strcmp ("reorder", s)) 4962 1.1 christos /* ignore */ ; 4963 1.1 christos else if (!strcmp ("at", s)) 4964 1.1 christos alpha_noat_on = !yesno; 4965 1.3 christos else if (!strcmp ("macro", s)) 4966 1.1 christos alpha_macros_on = yesno; 4967 1.1 christos else if (!strcmp ("move", s)) 4968 1.1 christos /* ignore */ ; 4969 1.1 christos else if (!strcmp ("volatile", s)) 4970 1.1 christos /* ignore */ ; 4971 1.1 christos else 4972 1.1 christos as_warn (_("Tried to .set unrecognized mode `%s'"), name); 4973 1.1 christos 4974 1.1 christos (void) restore_line_pointer (ch); 4975 1.1 christos demand_empty_rest_of_line (); 4976 1.1 christos } 4977 1.1 christos 4978 1.1 christos /* Handle the .base pseudo op. This changes the assembler's notion of 4979 1.1 christos the $gp register. */ 4980 1.1 christos 4981 1.1 christos static void 4982 1.1 christos s_alpha_base (int ignore ATTRIBUTE_UNUSED) 4983 1.1 christos { 4984 1.1 christos SKIP_WHITESPACE (); 4985 1.1 christos 4986 1.1 christos if (*input_line_pointer == '$') 4987 1.1 christos { 4988 1.1 christos /* $rNN form. */ 4989 1.1 christos input_line_pointer++; 4990 1.1 christos if (*input_line_pointer == 'r') 4991 1.1 christos input_line_pointer++; 4992 1.1 christos } 4993 1.1 christos 4994 1.1 christos alpha_gp_register = get_absolute_expression (); 4995 1.1 christos if (alpha_gp_register < 0 || alpha_gp_register > 31) 4996 1.1 christos { 4997 1.1 christos alpha_gp_register = AXP_REG_GP; 4998 1.1 christos as_warn (_("Bad base register, using $%d."), alpha_gp_register); 4999 1.1 christos } 5000 1.1 christos 5001 1.1 christos demand_empty_rest_of_line (); 5002 1.1 christos } 5003 1.1 christos 5004 1.1 christos /* Handle the .align pseudo-op. This aligns to a power of two. It 5005 1.1 christos also adjusts any current instruction label. We treat this the same 5006 1.1 christos way the MIPS port does: .align 0 turns off auto alignment. */ 5007 1.1 christos 5008 1.1 christos static void 5009 1.1 christos s_alpha_align (int ignore ATTRIBUTE_UNUSED) 5010 1.1 christos { 5011 1.1 christos int align; 5012 1.1 christos char fill, *pfill; 5013 1.1 christos long max_alignment = 16; 5014 1.1 christos 5015 1.1 christos align = get_absolute_expression (); 5016 1.1 christos if (align > max_alignment) 5017 1.1 christos { 5018 1.1 christos align = max_alignment; 5019 1.1 christos as_bad (_("Alignment too large: %d. assumed"), align); 5020 1.1 christos } 5021 1.1 christos else if (align < 0) 5022 1.1 christos { 5023 1.1 christos as_warn (_("Alignment negative: 0 assumed")); 5024 1.1 christos align = 0; 5025 1.1 christos } 5026 1.1 christos 5027 1.1 christos if (*input_line_pointer == ',') 5028 1.1 christos { 5029 1.1 christos input_line_pointer++; 5030 1.1 christos fill = get_absolute_expression (); 5031 1.1 christos pfill = &fill; 5032 1.1 christos } 5033 1.1 christos else 5034 1.1 christos pfill = NULL; 5035 1.1 christos 5036 1.1 christos if (align != 0) 5037 1.1 christos { 5038 1.1 christos alpha_auto_align_on = 1; 5039 1.1 christos alpha_align (align, pfill, NULL, 1); 5040 1.1 christos } 5041 1.1 christos else 5042 1.1 christos { 5043 1.1 christos alpha_auto_align_on = 0; 5044 1.1 christos } 5045 1.1 christos alpha_insn_label = NULL; 5046 1.1 christos 5047 1.1 christos demand_empty_rest_of_line (); 5048 1.1 christos } 5049 1.1 christos 5050 1.1 christos /* Hook the normal string processor to reset known alignment. */ 5051 1.1 christos 5052 1.1 christos static void 5053 1.1 christos s_alpha_stringer (int terminate) 5054 1.1 christos { 5055 1.1 christos alpha_current_align = 0; 5056 1.1 christos alpha_insn_label = NULL; 5057 1.1 christos stringer (8 + terminate); 5058 1.1 christos } 5059 1.1 christos 5060 1.1 christos /* Hook the normal space processing to reset known alignment. */ 5061 1.1 christos 5062 1.1 christos static void 5063 1.1 christos s_alpha_space (int ignore) 5064 1.1 christos { 5065 1.1 christos alpha_current_align = 0; 5066 1.1 christos alpha_insn_label = NULL; 5067 1.1 christos s_space (ignore); 5068 1.1 christos } 5069 1.1 christos 5070 1.1 christos /* Hook into cons for auto-alignment. */ 5071 1.1 christos 5072 1.1 christos void 5073 1.10 christos alpha_cons_align (int size) 5074 1.1 christos { 5075 1.1 christos int log_size; 5076 1.1 christos 5077 1.1 christos log_size = 0; 5078 1.1 christos while ((size >>= 1) != 0) 5079 1.1 christos ++log_size; 5080 1.1 christos 5081 1.1 christos if (alpha_auto_align_on && alpha_current_align < log_size) 5082 1.1 christos alpha_align (log_size, NULL, alpha_insn_label, 0); 5083 1.1 christos if (alpha_current_align > log_size) 5084 1.1 christos alpha_current_align = log_size; 5085 1.1 christos alpha_insn_label = NULL; 5086 1.1 christos } 5087 1.1 christos 5088 1.1 christos /* Here come the .uword, .ulong, and .uquad explicitly unaligned 5089 1.1 christos pseudos. We just turn off auto-alignment and call down to cons. */ 5090 1.1 christos 5091 1.1 christos static void 5092 1.1 christos s_alpha_ucons (int bytes) 5093 1.1 christos { 5094 1.1 christos int hold = alpha_auto_align_on; 5095 1.1 christos alpha_auto_align_on = 0; 5096 1.1 christos cons (bytes); 5097 1.1 christos alpha_auto_align_on = hold; 5098 1.1 christos } 5099 1.1 christos 5100 1.3 christos /* Switch the working cpu type. */ 5101 1.3 christos 5102 1.1 christos static void 5103 1.1 christos s_alpha_arch (int ignored ATTRIBUTE_UNUSED) 5104 1.1 christos { 5105 1.1 christos char *name, ch; 5106 1.1 christos const struct cpu_type *p; 5107 1.1 christos 5108 1.1 christos SKIP_WHITESPACE (); 5109 1.1 christos 5110 1.1 christos ch = get_symbol_name (&name); 5111 1.8 christos 5112 1.3 christos for (p = cpu_types; p->name; ++p) 5113 1.1 christos if (strcmp (name, p->name) == 0) 5114 1.1 christos { 5115 1.1 christos alpha_target_name = p->name, alpha_target = p->flags; 5116 1.1 christos goto found; 5117 1.1 christos } 5118 1.1 christos as_warn (_("Unknown CPU identifier `%s'"), name); 5119 1.1 christos 5120 1.1 christos found: 5121 1.1 christos (void) restore_line_pointer (ch); 5122 1.1 christos demand_empty_rest_of_line (); 5123 1.1 christos } 5124 1.1 christos 5125 1.1 christos #ifdef DEBUG1 5127 1.1 christos /* print token expression with alpha specific extension. */ 5128 1.1 christos 5129 1.1 christos static void 5130 1.1 christos alpha_print_token (FILE *f, const expressionS *exp) 5131 1.1 christos { 5132 1.1 christos switch (exp->X_op) 5133 1.1 christos { 5134 1.1 christos case O_cpregister: 5135 1.1 christos putc (',', f); 5136 1.1 christos /* FALLTHRU */ 5137 1.1 christos case O_pregister: 5138 1.1 christos putc ('(', f); 5139 1.1 christos { 5140 1.1 christos expressionS nexp = *exp; 5141 1.1 christos nexp.X_op = O_register; 5142 1.1 christos print_expr_1 (f, &nexp); 5143 1.1 christos } 5144 1.1 christos putc (')', f); 5145 1.1 christos break; 5146 1.1 christos default: 5147 1.1 christos print_expr_1 (f, exp); 5148 1.1 christos break; 5149 1.1 christos } 5150 1.1 christos } 5151 1.1 christos #endif 5152 1.1 christos 5153 1.1 christos /* The target specific pseudo-ops which we support. */ 5155 1.1 christos 5156 1.1 christos const pseudo_typeS md_pseudo_table[] = 5157 1.1 christos { 5158 1.1 christos #ifdef OBJ_ECOFF 5159 1.1 christos {"comm", s_alpha_comm, 0}, /* OSF1 compiler does this. */ 5160 1.1 christos {"rdata", s_alpha_rdata, 0}, 5161 1.1 christos #endif 5162 1.1 christos {"text", s_alpha_text, 0}, 5163 1.1 christos {"data", s_alpha_data, 0}, 5164 1.1 christos #ifdef OBJ_ECOFF 5165 1.1 christos {"sdata", s_alpha_sdata, 0}, 5166 1.1 christos #endif 5167 1.1 christos #ifdef OBJ_ELF 5168 1.1 christos {"section", s_alpha_section, 0}, 5169 1.1 christos {"section.s", s_alpha_section, 0}, 5170 1.1 christos {"sect", s_alpha_section, 0}, 5171 1.1 christos {"sect.s", s_alpha_section, 0}, 5172 1.1 christos #endif 5173 1.1 christos #ifdef OBJ_EVAX 5174 1.1 christos {"section", s_alpha_section, 0}, 5175 1.1 christos {"literals", s_alpha_literals, 0}, 5176 1.1 christos {"pdesc", s_alpha_pdesc, 0}, 5177 1.1 christos {"name", s_alpha_name, 0}, 5178 1.1 christos {"linkage", s_alpha_linkage, 0}, 5179 1.1 christos {"code_address", s_alpha_code_address, 0}, 5180 1.1 christos {"ent", s_alpha_ent, 0}, 5181 1.1 christos {"frame", s_alpha_frame, 0}, 5182 1.1 christos {"fp_save", s_alpha_fp_save, 0}, 5183 1.1 christos {"mask", s_alpha_mask, 0}, 5184 1.1 christos {"fmask", s_alpha_fmask, 0}, 5185 1.1 christos {"end", s_alpha_end, 0}, 5186 1.1 christos {"file", s_alpha_file, 0}, 5187 1.1 christos {"rdata", s_alpha_section, 1}, 5188 1.1 christos {"comm", s_alpha_comm, 0}, 5189 1.1 christos {"link", s_alpha_section, 3}, 5190 1.1 christos {"ctors", s_alpha_section, 4}, 5191 1.1 christos {"dtors", s_alpha_section, 5}, 5192 1.1 christos {"handler", s_alpha_handler, 0}, 5193 1.1 christos {"handler_data", s_alpha_handler, 1}, 5194 1.1 christos #endif 5195 1.1 christos #ifdef OBJ_ELF 5196 1.1 christos /* Frame related pseudos. */ 5197 1.1 christos {"ent", s_alpha_ent, 0}, 5198 1.1 christos {"end", s_alpha_end, 0}, 5199 1.1 christos {"mask", s_alpha_mask, 0}, 5200 1.1 christos {"fmask", s_alpha_mask, 1}, 5201 1.1 christos {"frame", s_alpha_frame, 0}, 5202 1.1 christos {"prologue", s_alpha_prologue, 0}, 5203 1.1 christos {"file", s_alpha_file, 5}, 5204 1.1 christos {"loc", s_alpha_loc, 9}, 5205 1.1 christos {"stabs", s_alpha_stab, 's'}, 5206 1.1 christos {"stabn", s_alpha_stab, 'n'}, 5207 1.1 christos {"usepv", s_alpha_usepv, 0}, 5208 1.1 christos /* COFF debugging related pseudos. */ 5209 1.1 christos {"begin", s_alpha_coff_wrapper, 0}, 5210 1.1 christos {"bend", s_alpha_coff_wrapper, 1}, 5211 1.1 christos {"def", s_alpha_coff_wrapper, 2}, 5212 1.1 christos {"dim", s_alpha_coff_wrapper, 3}, 5213 1.1 christos {"endef", s_alpha_coff_wrapper, 4}, 5214 1.1 christos {"scl", s_alpha_coff_wrapper, 5}, 5215 1.1 christos {"tag", s_alpha_coff_wrapper, 6}, 5216 1.1 christos {"val", s_alpha_coff_wrapper, 7}, 5217 1.1 christos #else 5218 1.1 christos #ifdef OBJ_EVAX 5219 1.1 christos {"prologue", s_alpha_prologue, 0}, 5220 1.1 christos #else 5221 1.1 christos {"prologue", s_ignore, 0}, 5222 1.1 christos #endif 5223 1.1 christos #endif 5224 1.1 christos {"gprel32", s_alpha_gprel32, 0}, 5225 1.1 christos {"t_floating", s_alpha_float_cons, 'd'}, 5226 1.1 christos {"s_floating", s_alpha_float_cons, 'f'}, 5227 1.1 christos {"f_floating", s_alpha_float_cons, 'F'}, 5228 1.1 christos {"g_floating", s_alpha_float_cons, 'G'}, 5229 1.1 christos {"d_floating", s_alpha_float_cons, 'D'}, 5230 1.1 christos 5231 1.1 christos {"proc", s_alpha_proc, 0}, 5232 1.1 christos {"aproc", s_alpha_proc, 1}, 5233 1.1 christos {"set", s_alpha_set, 0}, 5234 1.1 christos {"reguse", s_ignore, 0}, 5235 1.1 christos {"livereg", s_ignore, 0}, 5236 1.1 christos {"base", s_alpha_base, 0}, /*??*/ 5237 1.1 christos {"option", s_ignore, 0}, 5238 1.1 christos {"aent", s_ignore, 0}, 5239 1.1 christos {"ugen", s_ignore, 0}, 5240 1.1 christos {"eflag", s_ignore, 0}, 5241 1.1 christos 5242 1.1 christos {"align", s_alpha_align, 0}, 5243 1.1 christos {"double", s_alpha_float_cons, 'd'}, 5244 1.1 christos {"float", s_alpha_float_cons, 'f'}, 5245 1.1 christos {"single", s_alpha_float_cons, 'f'}, 5246 1.1 christos {"ascii", s_alpha_stringer, 0}, 5247 1.1 christos {"asciz", s_alpha_stringer, 1}, 5248 1.1 christos {"string", s_alpha_stringer, 1}, 5249 1.1 christos {"space", s_alpha_space, 0}, 5250 1.1 christos {"skip", s_alpha_space, 0}, 5251 1.1 christos {"zero", s_alpha_space, 0}, 5252 1.1 christos 5253 1.1 christos /* Unaligned data pseudos. */ 5254 1.1 christos {"uword", s_alpha_ucons, 2}, 5255 1.1 christos {"ulong", s_alpha_ucons, 4}, 5256 1.1 christos {"uquad", s_alpha_ucons, 8}, 5257 1.1 christos 5258 1.1 christos #ifdef OBJ_ELF 5259 1.1 christos /* Dwarf wants these versions of unaligned. */ 5260 1.1 christos {"2byte", s_alpha_ucons, 2}, 5261 1.1 christos {"4byte", s_alpha_ucons, 4}, 5262 1.1 christos {"8byte", s_alpha_ucons, 8}, 5263 1.1 christos #endif 5264 1.1 christos 5265 1.1 christos /* We don't do any optimizing, so we can safely ignore these. */ 5266 1.1 christos {"noalias", s_ignore, 0}, 5267 1.1 christos {"alias", s_ignore, 0}, 5268 1.1 christos 5269 1.1 christos {"arch", s_alpha_arch, 0}, 5270 1.1 christos 5271 1.1 christos {NULL, 0, 0}, 5272 1.1 christos }; 5273 1.1 christos 5274 1.1 christos #ifdef OBJ_ECOFF 5276 1.1 christos 5277 1.1 christos /* @@@ GP selection voodoo. All of this seems overly complicated and 5278 1.1 christos unnecessary; which is the primary reason it's for ECOFF only. */ 5279 1.1 christos 5280 1.1 christos static inline void 5281 1.1 christos maybe_set_gp (asection *sec) 5282 1.1 christos { 5283 1.1 christos bfd_vma vma; 5284 1.1 christos 5285 1.1 christos if (!sec) 5286 1.1 christos return; 5287 1.1 christos vma = bfd_section_vma (sec); 5288 1.1 christos if (vma && vma < alpha_gp_value) 5289 1.1 christos alpha_gp_value = vma; 5290 1.1 christos } 5291 1.1 christos 5292 1.1 christos static void 5293 1.1 christos select_gp_value (void) 5294 1.1 christos { 5295 1.1 christos gas_assert (alpha_gp_value == 0); 5296 1.1 christos 5297 1.1 christos /* Get minus-one in whatever width... */ 5298 1.1 christos alpha_gp_value = 0; 5299 1.1 christos alpha_gp_value--; 5300 1.1 christos 5301 1.1 christos /* Select the smallest VMA of these existing sections. */ 5302 1.1 christos maybe_set_gp (alpha_lita_section); 5303 1.1 christos 5304 1.1 christos /* @@ Will a simple 0x8000 work here? If not, why not? */ 5305 1.1 christos #define GP_ADJUSTMENT (0x8000 - 0x10) 5306 1.1 christos 5307 1.1 christos alpha_gp_value += GP_ADJUSTMENT; 5308 1.1 christos 5309 1.5 christos S_SET_VALUE (alpha_gp_symbol, alpha_gp_value); 5310 1.1 christos 5311 1.1 christos #ifdef DEBUG1 5312 1.1 christos printf (_("Chose GP value of %lx\n"), alpha_gp_value); 5313 1.1 christos #endif 5314 1.1 christos } 5315 1.1 christos #endif /* OBJ_ECOFF */ 5316 1.1 christos 5317 1.1 christos #ifdef OBJ_ELF 5318 1.1 christos /* Map 's' to SHF_ALPHA_GPREL. */ 5319 1.1 christos 5320 1.1 christos bfd_vma 5321 1.1 christos alpha_elf_section_letter (int letter, const char **ptr_msg) 5322 1.1 christos { 5323 1.1 christos if (letter == 's') 5324 1.1 christos return SHF_ALPHA_GPREL; 5325 1.1 christos 5326 1.1 christos *ptr_msg = _("bad .section directive: want a,s,w,x,M,S,G,T in string"); 5327 1.1 christos return -1; 5328 1.1 christos } 5329 1.1 christos 5330 1.1 christos /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */ 5331 1.1 christos 5332 1.1 christos flagword 5333 1.1 christos alpha_elf_section_flags (flagword flags, bfd_vma attr, int type ATTRIBUTE_UNUSED) 5334 1.1 christos { 5335 1.5 christos if (attr & SHF_ALPHA_GPREL) 5336 1.5 christos flags |= SEC_SMALL_DATA; 5337 1.1 christos return flags; 5338 1.1 christos } 5339 1.1 christos #endif /* OBJ_ELF */ 5340 1.1 christos 5341 1.1 christos /* This is called from HANDLE_ALIGN in write.c. Fill in the contents 5342 1.10 christos of an rs_align_code fragment. */ 5343 1.1 christos 5344 1.1 christos void 5345 1.1 christos alpha_handle_align (fragS *fragp) 5346 1.1 christos { 5347 1.1 christos static unsigned char const unop[4] = { 0x00, 0x00, 0xfe, 0x2f }; 5348 1.1 christos static unsigned char const nopunop[8] = 5349 1.1 christos { 5350 1.1 christos 0x1f, 0x04, 0xff, 0x47, 5351 1.10 christos 0x00, 0x00, 0xfe, 0x2f 5352 1.10 christos }; 5353 1.1 christos 5354 1.1 christos size_t bytes, fix; 5355 1.1 christos char *p; 5356 1.1 christos 5357 1.1 christos if (fragp->fr_type != rs_align_code) 5358 1.1 christos return; 5359 1.1 christos 5360 1.1 christos bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix; 5361 1.1 christos p = fragp->fr_literal + fragp->fr_fix; 5362 1.1 christos 5363 1.1 christos fix = bytes & 3; 5364 1.1 christos if (fix) 5365 1.10 christos { 5366 1.1 christos memset (p, 0, fix); 5367 1.10 christos p += fix; 5368 1.10 christos bytes -= fix; 5369 1.10 christos } 5370 1.10 christos if (bytes & 4) 5371 1.10 christos { 5372 1.1 christos memcpy (p, unop, 4); 5373 1.1 christos p += 4; 5374 1.1 christos bytes -= 4; 5375 1.1 christos fix += 4; 5376 1.1 christos } 5377 1.1 christos fragp->fr_fix += fix; 5378 1.1 christos 5379 1.1 christos if (bytes) 5380 1.1 christos { 5381 1.1 christos memcpy (p, nopunop, 8); 5382 1.1 christos fragp->fr_var = 8; 5383 1.1 christos } 5384 1.1 christos } 5385 1.1 christos 5386 1.1 christos /* Public interface functions. */ 5388 1.1 christos 5389 1.1 christos /* This function is called once, at assembler startup time. It sets 5390 1.1 christos up all the tables, etc. that the MD part of the assembler will 5391 1.1 christos need, that can be determined before arguments are parsed. */ 5392 1.1 christos 5393 1.1 christos void 5394 1.8 christos md_begin (void) 5395 1.1 christos { 5396 1.1 christos unsigned int i; 5397 1.1 christos 5398 1.8 christos /* Verify that X_op field is wide enough. */ 5399 1.1 christos { 5400 1.1 christos expressionS e; 5401 1.8 christos 5402 1.8 christos e.X_op = O_max; 5403 1.1 christos gas_assert (e.X_op == O_max); 5404 1.1 christos } 5405 1.1 christos 5406 1.1 christos /* Create the opcode hash table. */ 5407 1.1 christos alpha_opcode_hash = str_htab_create (); 5408 1.1 christos 5409 1.1 christos for (i = 0; i < alpha_num_opcodes;) 5410 1.1 christos { 5411 1.9 christos const char *name, *slash; 5412 1.9 christos 5413 1.9 christos name = alpha_opcodes[i].name; 5414 1.1 christos if (str_hash_insert (alpha_opcode_hash, name, &alpha_opcodes[i], 0)) 5415 1.9 christos as_fatal (_("duplicate %s"), name); 5416 1.9 christos 5417 1.1 christos /* Some opcodes include modifiers of various sorts with a "/mod" 5418 1.8 christos syntax, like the architecture manual suggests. However, for 5419 1.1 christos use with gcc at least, we also need access to those same opcodes 5420 1.1 christos without the "/". */ 5421 1.1 christos 5422 1.1 christos if ((slash = strchr (name, '/')) != NULL) 5423 1.1 christos { 5424 1.1 christos size_t len = strlen (name); 5425 1.1 christos char *p = notes_alloc (len); 5426 1.1 christos size_t len1 = slash - name; 5427 1.1 christos 5428 1.1 christos memcpy (p, name, len1); 5429 1.1 christos memcpy (p + len1, slash + 1, len - len1); 5430 1.8 christos 5431 1.1 christos (void) str_hash_insert (alpha_opcode_hash, p, &alpha_opcodes[i], 0); 5432 1.1 christos /* Ignore failures -- the opcode table does duplicate some 5433 1.1 christos variants in different forms, like "hw_stq" and "hw_st/q". */ 5434 1.8 christos } 5435 1.1 christos 5436 1.1 christos while (++i < alpha_num_opcodes 5437 1.8 christos && (alpha_opcodes[i].name == name 5438 1.8 christos || !strcmp (alpha_opcodes[i].name, name))) 5439 1.1 christos continue; 5440 1.1 christos } 5441 1.1 christos 5442 1.1 christos /* Create the macro hash table. */ 5443 1.1 christos alpha_macro_hash = str_htab_create (); 5444 1.1 christos 5445 1.1 christos for (i = 0; i < alpha_num_macros;) 5446 1.1 christos { 5447 1.1 christos const char *name; 5448 1.1 christos 5449 1.1 christos name = alpha_macros[i].name; 5450 1.1 christos if (str_hash_insert (alpha_macro_hash, name, &alpha_macros[i], 0)) 5451 1.1 christos as_fatal (_("duplicate %s"), name); 5452 1.8 christos 5453 1.8 christos while (++i < alpha_num_macros 5454 1.1 christos && (alpha_macros[i].name == name 5455 1.1 christos || !strcmp (alpha_macros[i].name, name))) 5456 1.1 christos continue; 5457 1.1 christos } 5458 1.1 christos 5459 1.1 christos /* Construct symbols for each of the registers. */ 5460 1.1 christos for (i = 0; i < 32; ++i) 5461 1.8 christos { 5462 1.8 christos char name[4]; 5463 1.1 christos 5464 1.1 christos sprintf (name, "$%d", i); 5465 1.1 christos alpha_register_table[i] = symbol_create (name, reg_section, 5466 1.1 christos &zero_address_frag, i); 5467 1.1 christos } 5468 1.1 christos 5469 1.1 christos for (; i < 64; ++i) 5470 1.1 christos { 5471 1.1 christos char name[5]; 5472 1.1 christos 5473 1.1 christos sprintf (name, "$f%d", i - 32); 5474 1.1 christos alpha_register_table[i] = symbol_create (name, reg_section, 5475 1.8 christos &zero_address_frag, i); 5476 1.8 christos } 5477 1.1 christos 5478 1.1 christos /* Create the special symbols and sections we'll be using. */ 5479 1.1 christos 5480 1.1 christos /* So .sbss will get used for tiny objects. */ 5481 1.1 christos bfd_set_gp_size (stdoutput, g_switch_value); 5482 1.1 christos 5483 1.1 christos #ifdef OBJ_ECOFF 5484 1.1 christos create_literal_section (".lita", &alpha_lita_section, &alpha_lita_symbol); 5485 1.1 christos 5486 1.10 christos /* For handling the GP, create a symbol that won't be output in the 5487 1.7 christos symbol table. We'll edit it out of relocs later. */ 5488 1.7 christos alpha_gp_symbol = symbol_create ("<GP value>", alpha_lita_section, 5489 1.1 christos &zero_address_frag, 0x8000); 5490 1.1 christos #endif 5491 1.1 christos 5492 1.1 christos #ifdef OBJ_EVAX 5493 1.8 christos create_literal_section (".link", &alpha_link_section, &alpha_link_symbol); 5494 1.1 christos #endif 5495 1.1 christos 5496 1.1 christos #ifdef OBJ_ELF 5497 1.1 christos if (ECOFF_DEBUGGING) 5498 1.1 christos { 5499 1.1 christos segT sec = subseg_new (".mdebug", 0); 5500 1.1 christos bfd_set_section_flags (sec, SEC_HAS_CONTENTS | SEC_READONLY); 5501 1.1 christos bfd_set_section_alignment (sec, 3); 5502 1.1 christos } 5503 1.1 christos #endif 5504 1.1 christos 5505 1.1 christos /* Create literal lookup hash table. */ 5506 1.1 christos alpha_literal_hash = str_htab_create (); 5507 1.1 christos 5508 1.1 christos subseg_set (text_section, 0); 5509 1.1 christos } 5510 1.1 christos 5511 1.1 christos /* The public interface to the instruction assembler. */ 5512 1.1 christos 5513 1.1 christos void 5514 1.1 christos md_assemble (char *str) 5515 1.1 christos { 5516 1.1 christos /* Current maximum is 13. */ 5517 1.1 christos char opname[32]; 5518 1.1 christos expressionS tok[MAX_INSN_ARGS]; 5519 1.1 christos int ntok, trunclen; 5520 1.1 christos size_t opnamelen; 5521 1.1 christos 5522 1.1 christos /* Split off the opcode. */ 5523 1.1 christos opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_/46819"); 5524 1.1 christos trunclen = (opnamelen < sizeof (opname) - 1 5525 1.1 christos ? opnamelen 5526 1.1 christos : sizeof (opname) - 1); 5527 1.1 christos memcpy (opname, str, trunclen); 5528 1.1 christos opname[trunclen] = '\0'; 5529 1.1 christos 5530 1.1 christos /* Tokenize the rest of the line. */ 5531 1.1 christos if ((ntok = tokenize_arguments (str + opnamelen, tok, MAX_INSN_ARGS)) < 0) 5532 1.1 christos { 5533 1.1 christos if (ntok != TOKENIZE_ERROR_REPORT) 5534 1.1 christos as_bad (_("syntax error")); 5535 1.7 christos 5536 1.1 christos return; 5537 1.1 christos } 5538 1.1 christos 5539 1.1 christos /* Finish it off. */ 5540 1.1 christos assemble_tokens (opname, tok, ntok, alpha_macros_on); 5541 1.1 christos } 5542 1.1 christos 5543 1.1 christos /* Round up a section's size to the appropriate boundary. */ 5544 1.1 christos 5545 1.1 christos valueT 5546 1.5 christos md_section_align (segT seg, valueT size) 5547 1.1 christos { 5548 1.1 christos int align = bfd_section_alignment (seg); 5549 1.5 christos valueT mask = ((valueT) 1 << align) - 1; 5550 1.1 christos 5551 1.1 christos return (size + mask) & ~mask; 5552 1.1 christos } 5553 1.1 christos 5554 1.1 christos /* Turn a string in input_line_pointer into a floating point constant 5555 1.1 christos of type TYPE, and store the appropriate bytes in *LITP. The number 5556 1.1 christos of LITTLENUMS emitted is stored in *SIZEP. An error message is 5557 1.6 christos returned, or NULL on OK. */ 5558 1.1 christos 5559 1.1 christos const char * 5560 1.1 christos md_atof (int type, char *litP, int *sizeP) 5561 1.1 christos { 5562 1.1 christos extern const char *vax_md_atof (int, char *, int *); 5563 1.8 christos 5564 1.1 christos switch (type) 5565 1.1 christos { 5566 1.1 christos /* VAX floats. */ 5567 1.1 christos case 'G': 5568 1.1 christos /* vax_md_atof() doesn't like "G" for some reason. */ 5569 1.1 christos type = 'g'; 5570 1.5 christos /* Fall through. */ 5571 1.1 christos case 'F': 5572 1.1 christos case 'D': 5573 1.1 christos return vax_md_atof (type, litP, sizeP); 5574 1.1 christos 5575 1.1 christos default: 5576 1.1 christos return ieee_md_atof (type, litP, sizeP, false); 5577 1.1 christos } 5578 1.1 christos } 5579 1.1 christos 5580 1.1 christos /* Take care of the target-specific command-line options. */ 5581 1.1 christos 5582 1.1 christos int 5583 1.1 christos md_parse_option (int c, const char *arg) 5584 1.1 christos { 5585 1.1 christos switch (c) 5586 1.1 christos { 5587 1.1 christos case 'F': 5588 1.1 christos alpha_nofloats_on = 1; 5589 1.1 christos break; 5590 1.1 christos 5591 1.1 christos case OPTION_32ADDR: 5592 1.1 christos alpha_addr32_on = 1; 5593 1.1 christos break; 5594 1.1 christos 5595 1.1 christos case 'g': 5596 1.1 christos alpha_debug = 1; 5597 1.1 christos break; 5598 1.1 christos 5599 1.1 christos case 'G': 5600 1.1 christos g_switch_value = atoi (arg); 5601 1.1 christos break; 5602 1.1 christos 5603 1.1 christos case 'm': 5604 1.1 christos { 5605 1.1 christos const struct cpu_type *p; 5606 1.1 christos 5607 1.1 christos for (p = cpu_types; p->name; ++p) 5608 1.1 christos if (strcmp (arg, p->name) == 0) 5609 1.1 christos { 5610 1.1 christos alpha_target_name = p->name, alpha_target = p->flags; 5611 1.1 christos goto found; 5612 1.1 christos } 5613 1.1 christos as_warn (_("Unknown CPU identifier `%s'"), arg); 5614 1.1 christos found:; 5615 1.1 christos } 5616 1.1 christos break; 5617 1.1 christos 5618 1.1 christos #ifdef OBJ_EVAX 5619 1.1 christos case '+': /* For g++. Hash any name > 63 chars long. */ 5620 1.1 christos alpha_flag_hash_long_names = 1; 5621 1.1 christos break; 5622 1.1 christos 5623 1.1 christos case 'H': /* Show new symbol after hash truncation. */ 5624 1.1 christos alpha_flag_show_after_trunc = 1; 5625 1.1 christos break; 5626 1.1 christos 5627 1.1 christos case 'h': /* For gnu-c/vax compatibility. */ 5628 1.1 christos break; 5629 1.1 christos 5630 1.1 christos case OPTION_REPLACE: 5631 1.1 christos alpha_flag_replace = 1; 5632 1.1 christos break; 5633 1.1 christos 5634 1.1 christos case OPTION_NOREPLACE: 5635 1.1 christos alpha_flag_replace = 0; 5636 1.1 christos break; 5637 1.1 christos #endif 5638 1.1 christos 5639 1.1 christos case OPTION_RELAX: 5640 1.1 christos alpha_flag_relax = 1; 5641 1.1 christos break; 5642 1.1 christos 5643 1.1 christos #ifdef OBJ_ELF 5644 1.1 christos case OPTION_MDEBUG: 5645 1.1 christos alpha_flag_mdebug = 1; 5646 1.1 christos break; 5647 1.1 christos case OPTION_NO_MDEBUG: 5648 1.1 christos alpha_flag_mdebug = 0; 5649 1.1 christos break; 5650 1.1 christos #endif 5651 1.1 christos 5652 1.1 christos default: 5653 1.1 christos return 0; 5654 1.1 christos } 5655 1.1 christos 5656 1.1 christos return 1; 5657 1.1 christos } 5658 1.1 christos 5659 1.1 christos /* Print a description of the command-line options that we accept. */ 5660 1.1 christos 5661 1.1 christos void 5662 1.1 christos md_show_usage (FILE *stream) 5663 1.1 christos { 5664 1.1 christos fputs (_("\ 5665 1.1 christos Alpha options:\n\ 5666 1.1 christos -32addr treat addresses as 32-bit values\n\ 5667 1.1 christos -F lack floating point instructions support\n\ 5668 1.1 christos -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mev67 | -mev68 | -mall\n\ 5669 1.1 christos specify variant of Alpha architecture\n\ 5670 1.1 christos -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264 | -m21264a | -m21264b\n\ 5671 1.1 christos these variants include PALcode opcodes\n"), 5672 1.1 christos stream); 5673 1.1 christos #ifdef OBJ_EVAX 5674 1.1 christos fputs (_("\ 5675 1.1 christos VMS options:\n\ 5676 1.1 christos -+ encode (don't truncate) names longer than 64 characters\n\ 5677 1.1 christos -H show new symbol after hash truncation\n\ 5678 1.1 christos -replace/-noreplace enable or disable the optimization of procedure calls\n"), 5679 1.1 christos stream); 5680 1.1 christos #endif 5681 1.1 christos } 5682 1.1 christos 5683 1.1 christos /* Decide from what point a pc-relative relocation is relative to, 5684 1.1 christos relative to the pc-relative fixup. Er, relatively speaking. */ 5685 1.1 christos 5686 1.1 christos long 5687 1.1 christos md_pcrel_from (fixS *fixP) 5688 1.1 christos { 5689 1.1 christos valueT addr = fixP->fx_where + fixP->fx_frag->fr_address; 5690 1.1 christos 5691 1.1 christos switch (fixP->fx_r_type) 5692 1.1 christos { 5693 1.1 christos case BFD_RELOC_23_PCREL_S2: 5694 1.1 christos case BFD_RELOC_ALPHA_HINT: 5695 1.1 christos case BFD_RELOC_ALPHA_BRSGP: 5696 1.1 christos return addr + 4; 5697 1.1 christos default: 5698 1.1 christos return addr; 5699 1.1 christos } 5700 1.1 christos } 5701 1.1 christos 5702 1.1 christos /* Attempt to simplify or even eliminate a fixup. The return value is 5703 1.1 christos ignored; perhaps it was once meaningful, but now it is historical. 5704 1.1 christos To indicate that a fixup has been eliminated, set fixP->fx_done. 5705 1.1 christos 5706 1.1 christos For ELF, here it is that we transform the GPDISP_HI16 reloc we used 5707 1.1 christos internally into the GPDISP reloc used externally. We had to do 5708 1.1 christos this so that we'd have the GPDISP_LO16 reloc as a tag to compute 5709 1.1 christos the distance to the "lda" instruction for setting the addend to 5710 1.1 christos GPDISP. */ 5711 1.1 christos 5712 1.1 christos void 5713 1.1 christos md_apply_fix (fixS *fixP, valueT * valP, segT seg) 5714 1.1 christos { 5715 1.1 christos char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where; 5716 1.1 christos valueT value = * valP; 5717 1.1 christos unsigned image, size; 5718 1.1 christos 5719 1.1 christos switch (fixP->fx_r_type) 5720 1.1 christos { 5721 1.1 christos /* The GPDISP relocations are processed internally with a symbol 5722 1.1 christos referring to the current function's section; we need to drop 5723 1.1 christos in a value which, when added to the address of the start of 5724 1.1 christos the function, gives the desired GP. */ 5725 1.1 christos case BFD_RELOC_ALPHA_GPDISP_HI16: 5726 1.1 christos { 5727 1.1 christos fixS *next = fixP->fx_next; 5728 1.1 christos 5729 1.1 christos /* With user-specified !gpdisp relocations, we can be missing 5730 1.1 christos the matching LO16 reloc. We will have already issued an 5731 1.1 christos error message. */ 5732 1.1 christos if (next) 5733 1.1 christos fixP->fx_offset = (next->fx_frag->fr_address + next->fx_where 5734 1.1 christos - fixP->fx_frag->fr_address - fixP->fx_where); 5735 1.1 christos 5736 1.1 christos value = (value - sign_extend_16 (value)) >> 16; 5737 1.1 christos } 5738 1.1 christos #ifdef OBJ_ELF 5739 1.1 christos fixP->fx_r_type = BFD_RELOC_ALPHA_GPDISP; 5740 1.1 christos #endif 5741 1.1 christos goto do_reloc_gp; 5742 1.7 christos 5743 1.7 christos case BFD_RELOC_ALPHA_GPDISP_LO16: 5744 1.7 christos value = sign_extend_16 (value); 5745 1.7 christos fixP->fx_offset = 0; 5746 1.7 christos #ifdef OBJ_ELF 5747 1.7 christos fixP->fx_done = 1; 5748 1.1 christos #endif 5749 1.1 christos 5750 1.1 christos do_reloc_gp: 5751 1.1 christos fixP->fx_addsy = section_symbol (seg); 5752 1.1 christos md_number_to_chars (fixpos, value, 2); 5753 1.1 christos break; 5754 1.1 christos 5755 1.1 christos case BFD_RELOC_8: 5756 1.1 christos if (fixP->fx_pcrel) 5757 1.1 christos fixP->fx_r_type = BFD_RELOC_8_PCREL; 5758 1.1 christos size = 1; 5759 1.1 christos goto do_reloc_xx; 5760 1.1 christos 5761 1.1 christos case BFD_RELOC_16: 5762 1.1 christos if (fixP->fx_pcrel) 5763 1.1 christos fixP->fx_r_type = BFD_RELOC_16_PCREL; 5764 1.1 christos size = 2; 5765 1.1 christos goto do_reloc_xx; 5766 1.1 christos 5767 1.1 christos case BFD_RELOC_32: 5768 1.1 christos if (fixP->fx_pcrel) 5769 1.1 christos fixP->fx_r_type = BFD_RELOC_32_PCREL; 5770 1.1 christos size = 4; 5771 1.1 christos goto do_reloc_xx; 5772 1.1 christos 5773 1.1 christos case BFD_RELOC_64: 5774 1.1 christos if (fixP->fx_pcrel) 5775 1.1 christos fixP->fx_r_type = BFD_RELOC_64_PCREL; 5776 1.1 christos size = 8; 5777 1.1 christos 5778 1.1 christos do_reloc_xx: 5779 1.1 christos if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0) 5780 1.1 christos { 5781 1.1 christos md_number_to_chars (fixpos, value, size); 5782 1.1 christos goto done; 5783 1.1 christos } 5784 1.1 christos return; 5785 1.1 christos 5786 1.1 christos #ifdef OBJ_ECOFF 5787 1.1 christos case BFD_RELOC_GPREL32: 5788 1.1 christos gas_assert (fixP->fx_subsy == alpha_gp_symbol); 5789 1.1 christos fixP->fx_subsy = 0; 5790 1.1 christos /* FIXME: inherited this obliviousness of `value' -- why? */ 5791 1.1 christos md_number_to_chars (fixpos, -alpha_gp_value, 4); 5792 1.1 christos break; 5793 1.1 christos #else 5794 1.1 christos case BFD_RELOC_GPREL32: 5795 1.1 christos #endif 5796 1.1 christos case BFD_RELOC_GPREL16: 5797 1.1 christos case BFD_RELOC_ALPHA_GPREL_HI16: 5798 1.1 christos case BFD_RELOC_ALPHA_GPREL_LO16: 5799 1.1 christos return; 5800 1.1 christos 5801 1.1 christos case BFD_RELOC_23_PCREL_S2: 5802 1.1 christos if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0) 5803 1.1 christos { 5804 1.1 christos image = bfd_getl32 (fixpos); 5805 1.1 christos image = (image & ~0x1FFFFF) | ((value >> 2) & 0x1FFFFF); 5806 1.1 christos goto write_done; 5807 1.1 christos } 5808 1.1 christos return; 5809 1.1 christos 5810 1.1 christos case BFD_RELOC_ALPHA_HINT: 5811 1.1 christos if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0) 5812 1.1 christos { 5813 1.1 christos image = bfd_getl32 (fixpos); 5814 1.1 christos image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF); 5815 1.1 christos goto write_done; 5816 1.1 christos } 5817 1.1 christos return; 5818 1.1 christos 5819 1.1 christos #ifdef OBJ_ELF 5820 1.1 christos case BFD_RELOC_ALPHA_BRSGP: 5821 1.1 christos return; 5822 1.1 christos 5823 1.1 christos case BFD_RELOC_ALPHA_TLSGD: 5824 1.1 christos case BFD_RELOC_ALPHA_TLSLDM: 5825 1.1 christos case BFD_RELOC_ALPHA_GOTDTPREL16: 5826 1.1 christos case BFD_RELOC_ALPHA_DTPREL_HI16: 5827 1.1 christos case BFD_RELOC_ALPHA_DTPREL_LO16: 5828 1.1 christos case BFD_RELOC_ALPHA_DTPREL16: 5829 1.1 christos case BFD_RELOC_ALPHA_GOTTPREL16: 5830 1.1 christos case BFD_RELOC_ALPHA_TPREL_HI16: 5831 1.1 christos case BFD_RELOC_ALPHA_TPREL_LO16: 5832 1.1 christos case BFD_RELOC_ALPHA_TPREL16: 5833 1.1 christos if (fixP->fx_addsy) 5834 1.1 christos S_SET_THREAD_LOCAL (fixP->fx_addsy); 5835 1.1 christos return; 5836 1.1 christos #endif 5837 1.1 christos 5838 1.1 christos #ifdef OBJ_ECOFF 5839 1.1 christos case BFD_RELOC_ALPHA_LITERAL: 5840 1.1 christos md_number_to_chars (fixpos, value, 2); 5841 1.1 christos return; 5842 1.1 christos #endif 5843 1.1 christos case BFD_RELOC_ALPHA_ELF_LITERAL: 5844 1.1 christos case BFD_RELOC_ALPHA_LITUSE: 5845 1.1 christos case BFD_RELOC_ALPHA_LINKAGE: 5846 1.1 christos case BFD_RELOC_ALPHA_CODEADDR: 5847 1.1 christos return; 5848 1.1 christos 5849 1.1 christos #ifdef OBJ_EVAX 5850 1.7 christos case BFD_RELOC_ALPHA_NOP: 5851 1.1 christos value -= (8 + 4); /* PC-relative, base is jsr+4. */ 5852 1.1 christos 5853 1.1 christos /* From B.4.5.2 of the OpenVMS Linker Utility Manual: 5854 1.1 christos "Finally, the ETIR$C_STC_BSR command passes the same address 5855 1.1 christos as ETIR$C_STC_NOP (so that they will fail or succeed together), 5856 1.1 christos and the same test is done again." */ 5857 1.1 christos if (S_GET_SEGMENT (fixP->fx_addsy) == undefined_section) 5858 1.1 christos { 5859 1.1 christos fixP->fx_addnumber = -value; 5860 1.1 christos return; 5861 1.1 christos } 5862 1.1 christos 5863 1.1 christos if (value + (1u << 22) >= (1u << 23)) 5864 1.1 christos goto done; 5865 1.1 christos else 5866 1.1 christos { 5867 1.1 christos /* Change to a nop. */ 5868 1.1 christos image = 0x47FF041F; 5869 1.7 christos goto write_done; 5870 1.1 christos } 5871 1.1 christos 5872 1.1 christos case BFD_RELOC_ALPHA_LDA: 5873 1.1 christos /* fixup_segment sets fixP->fx_addsy to NULL when it can pre-compute 5874 1.1 christos the value for an O_subtract. */ 5875 1.1 christos if (fixP->fx_addsy 5876 1.1 christos && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section) 5877 1.1 christos { 5878 1.1 christos fixP->fx_addnumber = symbol_get_bfdsym (fixP->fx_subsy)->value; 5879 1.1 christos return; 5880 1.1 christos } 5881 1.1 christos 5882 1.1 christos if (value + (1u << 15) >= (1u << 16)) 5883 1.1 christos goto done; 5884 1.1 christos else 5885 1.1 christos { 5886 1.1 christos /* Change to an lda. */ 5887 1.1 christos image = 0x237B0000 | (value & 0xFFFF); 5888 1.1 christos goto write_done; 5889 1.7 christos } 5890 1.1 christos 5891 1.1 christos case BFD_RELOC_ALPHA_BSR: 5892 1.1 christos case BFD_RELOC_ALPHA_BOH: 5893 1.1 christos value -= 4; /* PC-relative, base is jsr+4. */ 5894 1.1 christos 5895 1.1 christos /* See comment in the BFD_RELOC_ALPHA_NOP case above. */ 5896 1.1 christos if (S_GET_SEGMENT (fixP->fx_addsy) == undefined_section) 5897 1.1 christos { 5898 1.1 christos fixP->fx_addnumber = -value; 5899 1.1 christos return; 5900 1.1 christos } 5901 1.1 christos 5902 1.1 christos if (value + (1u << 22) >= (1u << 23)) 5903 1.1 christos { 5904 1.1 christos /* Out of range. */ 5905 1.1 christos if (fixP->fx_r_type == BFD_RELOC_ALPHA_BOH) 5906 1.1 christos { 5907 1.1 christos /* Add a hint. */ 5908 1.1 christos image = bfd_getl32(fixpos); 5909 1.1 christos image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF); 5910 1.1 christos goto write_done; 5911 1.1 christos } 5912 1.1 christos goto done; 5913 1.1 christos } 5914 1.1 christos else 5915 1.1 christos { 5916 1.1 christos /* Change to a branch. */ 5917 1.1 christos image = 0xD3400000 | ((value >> 2) & 0x1FFFFF); 5918 1.1 christos goto write_done; 5919 1.1 christos } 5920 1.1 christos #endif 5921 1.1 christos 5922 1.1 christos case BFD_RELOC_VTABLE_INHERIT: 5923 1.1 christos case BFD_RELOC_VTABLE_ENTRY: 5924 1.1 christos return; 5925 1.1 christos 5926 1.1 christos default: 5927 1.1 christos { 5928 1.1 christos const struct alpha_operand *operand; 5929 1.1 christos 5930 1.1 christos if ((int) fixP->fx_r_type >= 0) 5931 1.1 christos as_fatal (_("unhandled relocation type %s"), 5932 1.1 christos bfd_get_reloc_code_name (fixP->fx_r_type)); 5933 1.1 christos 5934 1.1 christos gas_assert (-(int) fixP->fx_r_type < (int) alpha_num_operands); 5935 1.1 christos operand = &alpha_operands[-(int) fixP->fx_r_type]; 5936 1.1 christos 5937 1.1 christos /* The rest of these fixups only exist internally during symbol 5938 1.1 christos resolution and have no representation in the object file. 5939 1.1 christos Therefore they must be completely resolved as constants. */ 5940 1.1 christos 5941 1.1 christos if (fixP->fx_addsy != 0 5942 1.1 christos && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section) 5943 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line, 5944 1.1 christos _("non-absolute expression in constant field")); 5945 1.1 christos 5946 1.1 christos image = bfd_getl32 (fixpos); 5947 1.1 christos image = insert_operand (image, operand, (offsetT) value, 5948 1.1 christos fixP->fx_file, fixP->fx_line); 5949 1.8 christos } 5950 1.1 christos goto write_done; 5951 1.1 christos } 5952 1.8 christos 5953 1.1 christos if (fixP->fx_addsy != 0 || fixP->fx_pcrel != 0) 5954 1.1 christos return; 5955 1.1 christos else 5956 1.1 christos { 5957 1.1 christos as_warn_where (fixP->fx_file, fixP->fx_line, 5958 1.1 christos _("type %d reloc done?\n"), (int) fixP->fx_r_type); 5959 1.1 christos goto done; 5960 1.1 christos } 5961 1.1 christos 5962 1.1 christos write_done: 5963 1.1 christos md_number_to_chars (fixpos, image, 4); 5964 1.1 christos 5965 1.1 christos done: 5966 1.1 christos fixP->fx_done = 1; 5967 1.1 christos } 5968 1.1 christos 5969 1.1 christos /* Look for a register name in the given symbol. */ 5970 1.1 christos 5971 1.1 christos symbolS * 5972 1.1 christos md_undefined_symbol (char *name) 5973 1.1 christos { 5974 1.1 christos if (*name == '$') 5975 1.1 christos { 5976 1.1 christos int is_float = 0, num; 5977 1.1 christos 5978 1.1 christos switch (*++name) 5979 1.1 christos { 5980 1.1 christos case 'f': 5981 1.1 christos if (name[1] == 'p' && name[2] == '\0') 5982 1.1 christos return alpha_register_table[AXP_REG_FP]; 5983 1.1 christos is_float = 32; 5984 1.1 christos /* Fall through. */ 5985 1.1 christos 5986 1.1 christos case 'r': 5987 1.1 christos if (!ISDIGIT (*++name)) 5988 1.1 christos break; 5989 1.1 christos /* Fall through. */ 5990 1.1 christos 5991 1.1 christos case '0': case '1': case '2': case '3': case '4': 5992 1.1 christos case '5': case '6': case '7': case '8': case '9': 5993 1.1 christos if (name[1] == '\0') 5994 1.1 christos num = name[0] - '0'; 5995 1.1 christos else if (name[0] != '0' && ISDIGIT (name[1]) && name[2] == '\0') 5996 1.1 christos { 5997 1.1 christos num = (name[0] - '0') * 10 + name[1] - '0'; 5998 1.1 christos if (num >= 32) 5999 1.1 christos break; 6000 1.1 christos } 6001 1.1 christos else 6002 1.1 christos break; 6003 1.1 christos 6004 1.1 christos if (!alpha_noat_on && (num + is_float) == AXP_REG_AT) 6005 1.1 christos as_warn (_("Used $at without \".set noat\"")); 6006 1.1 christos return alpha_register_table[num + is_float]; 6007 1.1 christos 6008 1.1 christos case 'a': 6009 1.1 christos if (name[1] == 't' && name[2] == '\0') 6010 1.1 christos { 6011 1.1 christos if (!alpha_noat_on) 6012 1.1 christos as_warn (_("Used $at without \".set noat\"")); 6013 1.1 christos return alpha_register_table[AXP_REG_AT]; 6014 1.1 christos } 6015 1.1 christos break; 6016 1.1 christos 6017 1.1 christos case 'g': 6018 1.1 christos if (name[1] == 'p' && name[2] == '\0') 6019 1.1 christos return alpha_register_table[alpha_gp_register]; 6020 1.1 christos break; 6021 1.1 christos 6022 1.1 christos case 's': 6023 1.1 christos if (name[1] == 'p' && name[2] == '\0') 6024 1.1 christos return alpha_register_table[AXP_REG_SP]; 6025 1.1 christos break; 6026 1.1 christos } 6027 1.1 christos } 6028 1.1 christos return NULL; 6029 1.1 christos } 6030 1.1 christos 6031 1.1 christos #ifdef OBJ_ECOFF 6032 1.1 christos /* @@@ Magic ECOFF bits. */ 6033 1.1 christos 6034 1.1 christos void 6035 1.1 christos alpha_frob_ecoff_data (void) 6036 1.1 christos { 6037 1.1 christos select_gp_value (); 6038 1.1 christos /* $zero and $f31 are read-only. */ 6039 1.1 christos alpha_gprmask &= ~1; 6040 1.1 christos alpha_fprmask &= ~1; 6041 1.1 christos } 6042 1.1 christos #endif 6043 1.1 christos 6044 1.1 christos /* Hook to remember a recently defined label so that the auto-align 6045 1.1 christos code can adjust the symbol after we know what alignment will be 6046 1.1 christos required. */ 6047 1.1 christos 6048 1.1 christos void 6049 1.1 christos alpha_define_label (symbolS *sym) 6050 1.1 christos { 6051 1.1 christos alpha_insn_label = sym; 6052 1.1 christos #ifdef OBJ_ELF 6053 1.1 christos dwarf2_emit_label (sym); 6054 1.1 christos #endif 6055 1.1 christos } 6056 1.1 christos 6057 1.1 christos /* Return true if we must always emit a reloc for a type and false if 6058 1.1 christos there is some hope of resolving it at assembly time. */ 6059 1.1 christos 6060 1.1 christos int 6061 1.1 christos alpha_force_relocation (fixS *f) 6062 1.1 christos { 6063 1.1 christos if (alpha_flag_relax) 6064 1.1 christos return 1; 6065 1.1 christos 6066 1.1 christos switch (f->fx_r_type) 6067 1.1 christos { 6068 1.1 christos case BFD_RELOC_ALPHA_GPDISP_HI16: 6069 1.1 christos case BFD_RELOC_ALPHA_GPDISP_LO16: 6070 1.1 christos case BFD_RELOC_ALPHA_GPDISP: 6071 1.1 christos case BFD_RELOC_ALPHA_LITERAL: 6072 1.1 christos case BFD_RELOC_ALPHA_ELF_LITERAL: 6073 1.1 christos case BFD_RELOC_ALPHA_LITUSE: 6074 1.1 christos case BFD_RELOC_GPREL16: 6075 1.1 christos case BFD_RELOC_GPREL32: 6076 1.1 christos case BFD_RELOC_ALPHA_GPREL_HI16: 6077 1.1 christos case BFD_RELOC_ALPHA_GPREL_LO16: 6078 1.1 christos case BFD_RELOC_ALPHA_LINKAGE: 6079 1.1 christos case BFD_RELOC_ALPHA_CODEADDR: 6080 1.1 christos case BFD_RELOC_ALPHA_BRSGP: 6081 1.1 christos case BFD_RELOC_ALPHA_TLSGD: 6082 1.1 christos case BFD_RELOC_ALPHA_TLSLDM: 6083 1.1 christos case BFD_RELOC_ALPHA_GOTDTPREL16: 6084 1.1 christos case BFD_RELOC_ALPHA_DTPREL_HI16: 6085 1.1 christos case BFD_RELOC_ALPHA_DTPREL_LO16: 6086 1.1 christos case BFD_RELOC_ALPHA_DTPREL16: 6087 1.1 christos case BFD_RELOC_ALPHA_GOTTPREL16: 6088 1.1 christos case BFD_RELOC_ALPHA_TPREL_HI16: 6089 1.1 christos case BFD_RELOC_ALPHA_TPREL_LO16: 6090 1.1 christos case BFD_RELOC_ALPHA_TPREL16: 6091 1.1 christos #ifdef OBJ_EVAX 6092 1.1 christos case BFD_RELOC_ALPHA_NOP: 6093 1.1 christos case BFD_RELOC_ALPHA_BSR: 6094 1.1 christos case BFD_RELOC_ALPHA_LDA: 6095 1.1 christos case BFD_RELOC_ALPHA_BOH: 6096 1.1 christos #endif 6097 1.1 christos return 1; 6098 1.1 christos 6099 1.1 christos default: 6100 1.1 christos break; 6101 1.1 christos } 6102 1.1 christos 6103 1.1 christos return generic_force_reloc (f); 6104 1.1 christos } 6105 1.1 christos 6106 1.1 christos /* Return true if we can partially resolve a relocation now. */ 6107 1.1 christos 6108 1.1 christos int 6109 1.1 christos alpha_fix_adjustable (fixS *f) 6110 1.1 christos { 6111 1.1 christos /* Are there any relocation types for which we must generate a 6112 1.1 christos reloc but we can adjust the values contained within it? */ 6113 1.1 christos switch (f->fx_r_type) 6114 1.1 christos { 6115 1.1 christos case BFD_RELOC_ALPHA_GPDISP_HI16: 6116 1.1 christos case BFD_RELOC_ALPHA_GPDISP_LO16: 6117 1.1 christos case BFD_RELOC_ALPHA_GPDISP: 6118 1.1 christos return 0; 6119 1.1 christos 6120 1.1 christos case BFD_RELOC_ALPHA_LITERAL: 6121 1.1 christos case BFD_RELOC_ALPHA_ELF_LITERAL: 6122 1.1 christos case BFD_RELOC_ALPHA_LITUSE: 6123 1.1 christos case BFD_RELOC_ALPHA_LINKAGE: 6124 1.1 christos case BFD_RELOC_ALPHA_CODEADDR: 6125 1.1 christos return 1; 6126 1.1 christos 6127 1.1 christos case BFD_RELOC_VTABLE_ENTRY: 6128 1.1 christos case BFD_RELOC_VTABLE_INHERIT: 6129 1.1 christos return 0; 6130 1.1 christos 6131 1.1 christos case BFD_RELOC_GPREL16: 6132 1.1 christos case BFD_RELOC_GPREL32: 6133 1.1 christos case BFD_RELOC_ALPHA_GPREL_HI16: 6134 1.1 christos case BFD_RELOC_ALPHA_GPREL_LO16: 6135 1.1 christos case BFD_RELOC_23_PCREL_S2: 6136 1.1 christos case BFD_RELOC_16: 6137 1.1 christos case BFD_RELOC_32: 6138 1.1 christos case BFD_RELOC_64: 6139 1.1 christos case BFD_RELOC_ALPHA_HINT: 6140 1.1 christos return 1; 6141 1.1 christos 6142 1.1 christos case BFD_RELOC_ALPHA_TLSGD: 6143 1.1 christos case BFD_RELOC_ALPHA_TLSLDM: 6144 1.1 christos case BFD_RELOC_ALPHA_GOTDTPREL16: 6145 1.1 christos case BFD_RELOC_ALPHA_DTPREL_HI16: 6146 1.1 christos case BFD_RELOC_ALPHA_DTPREL_LO16: 6147 1.1 christos case BFD_RELOC_ALPHA_DTPREL16: 6148 1.1 christos case BFD_RELOC_ALPHA_GOTTPREL16: 6149 1.1 christos case BFD_RELOC_ALPHA_TPREL_HI16: 6150 1.1 christos case BFD_RELOC_ALPHA_TPREL_LO16: 6151 1.1 christos case BFD_RELOC_ALPHA_TPREL16: 6152 1.1 christos /* ??? No idea why we can't return a reference to .tbss+10, but 6153 1.1 christos we're preventing this in the other assemblers. Follow for now. */ 6154 1.1 christos return 0; 6155 1.1 christos 6156 1.1 christos #ifdef OBJ_ELF 6157 1.1 christos case BFD_RELOC_ALPHA_BRSGP: 6158 1.1 christos /* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and 6159 1.1 christos let it get resolved at assembly time. */ 6160 1.1 christos { 6161 1.1 christos symbolS *sym = f->fx_addsy; 6162 1.1 christos const char *name; 6163 1.1 christos int offset = 0; 6164 1.1 christos 6165 1.1 christos if (generic_force_reloc (f)) 6166 1.1 christos return 0; 6167 1.1 christos 6168 1.1 christos switch (S_GET_OTHER (sym) & STO_ALPHA_STD_GPLOAD) 6169 1.1 christos { 6170 1.1 christos case STO_ALPHA_NOPV: 6171 1.1 christos break; 6172 1.1 christos case STO_ALPHA_STD_GPLOAD: 6173 1.1 christos offset = 8; 6174 1.1 christos break; 6175 1.1 christos default: 6176 1.1 christos if (S_IS_LOCAL (sym)) 6177 1.1 christos name = "<local>"; 6178 1.1 christos else 6179 1.1 christos name = S_GET_NAME (sym); 6180 1.1 christos as_bad_where (f->fx_file, f->fx_line, 6181 1.1 christos _("!samegp reloc against symbol without .prologue: %s"), 6182 1.1 christos name); 6183 1.1 christos break; 6184 1.1 christos } 6185 1.1 christos f->fx_r_type = BFD_RELOC_23_PCREL_S2; 6186 1.1 christos f->fx_offset += offset; 6187 1.1 christos return 1; 6188 1.1 christos } 6189 1.1 christos #endif 6190 1.1 christos #ifdef OBJ_EVAX 6191 1.1 christos case BFD_RELOC_ALPHA_NOP: 6192 1.1 christos case BFD_RELOC_ALPHA_BSR: 6193 1.1 christos case BFD_RELOC_ALPHA_LDA: 6194 1.1 christos case BFD_RELOC_ALPHA_BOH: 6195 1.1 christos return 1; 6196 1.1 christos #endif 6197 1.1 christos 6198 1.1 christos default: 6199 1.10 christos return 1; 6200 1.10 christos } 6201 1.1 christos } 6202 1.1 christos 6203 1.1 christos /* Generate the BFD reloc to be stuck in the object file from the 6204 1.1 christos fixup used internally in the assembler. */ 6205 1.1 christos 6206 1.1 christos arelent * 6207 1.1 christos tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED, 6208 1.1 christos fixS *fixp) 6209 1.1 christos { 6210 1.1 christos arelent *reloc; 6211 1.1 christos 6212 1.1 christos reloc = notes_alloc (sizeof (arelent)); 6213 1.1 christos reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *)); 6214 1.1 christos *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); 6215 1.1 christos reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; 6216 1.1 christos 6217 1.1 christos /* Make sure none of our internal relocations make it this far. 6218 1.1 christos They'd better have been fully resolved by this point. */ 6219 1.1 christos gas_assert ((int) fixp->fx_r_type > 0); 6220 1.1 christos 6221 1.1 christos reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); 6222 1.1 christos if (reloc->howto == NULL) 6223 1.1 christos { 6224 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line, 6225 1.1 christos _("cannot represent `%s' relocation in object file"), 6226 1.1 christos bfd_get_reloc_code_name (fixp->fx_r_type)); 6227 1.1 christos return NULL; 6228 1.1 christos } 6229 1.1 christos 6230 1.1 christos if (!fixp->fx_pcrel != !reloc->howto->pc_relative) 6231 1.1 christos as_fatal (_("internal error? cannot generate `%s' relocation"), 6232 1.1 christos bfd_get_reloc_code_name (fixp->fx_r_type)); 6233 1.1 christos 6234 1.1 christos gas_assert (!fixp->fx_pcrel == !reloc->howto->pc_relative); 6235 1.1 christos 6236 1.1 christos reloc->addend = fixp->fx_offset; 6237 1.1 christos 6238 1.1 christos #ifdef OBJ_ECOFF 6239 1.1 christos /* Fake out bfd_perform_relocation. sigh. */ 6240 1.1 christos /* ??? Better would be to use the special_function hook. */ 6241 1.1 christos if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL) 6242 1.1 christos reloc->addend = -alpha_gp_value; 6243 1.1 christos #endif 6244 1.1 christos 6245 1.1 christos #ifdef OBJ_EVAX 6246 1.1 christos switch (fixp->fx_r_type) 6247 1.1 christos { 6248 1.1 christos struct evax_private_udata_struct *udata; 6249 1.1 christos const char *pname; 6250 1.1 christos int pname_len; 6251 1.1 christos 6252 1.1 christos case BFD_RELOC_ALPHA_LINKAGE: 6253 1.1 christos /* Copy the linkage index. */ 6254 1.1 christos reloc->addend = fixp->fx_addnumber; 6255 1.1 christos break; 6256 1.5 christos 6257 1.1 christos case BFD_RELOC_ALPHA_NOP: 6258 1.5 christos case BFD_RELOC_ALPHA_BSR: 6259 1.1 christos case BFD_RELOC_ALPHA_LDA: 6260 1.1 christos case BFD_RELOC_ALPHA_BOH: 6261 1.1 christos pname = symbol_get_bfdsym (fixp->fx_addsy)->name; 6262 1.1 christos 6263 1.1 christos /* We need the non-suffixed name of the procedure. Beware that 6264 1.1 christos the main symbol might be equated so look it up and take its name. */ 6265 1.1 christos pname_len = strlen (pname); 6266 1.1 christos if (pname_len > 4 && strcmp (pname + pname_len - 4, "..en") == 0) 6267 1.1 christos { 6268 1.1 christos symbolS *sym; 6269 1.1 christos char *my_pname = xmemdup0 (pname, pname_len - 4); 6270 1.1 christos sym = symbol_find (my_pname); 6271 1.1 christos free (my_pname); 6272 1.1 christos if (sym == NULL) 6273 1.1 christos abort (); 6274 1.1 christos 6275 1.10 christos while (symbol_equated_reloc_p (sym)) 6276 1.1 christos { 6277 1.1 christos symbolS *n = symbol_get_value_expression (sym)->X_add_symbol; 6278 1.1 christos 6279 1.1 christos /* We must avoid looping, as that can occur with a badly 6280 1.1 christos written program. */ 6281 1.1 christos if (n == sym) 6282 1.1 christos break; 6283 1.1 christos sym = n; 6284 1.1 christos } 6285 1.1 christos pname = symbol_get_bfdsym (sym)->name; 6286 1.1 christos } 6287 1.1 christos 6288 1.1 christos udata = notes_alloc (sizeof (*udata)); 6289 1.1 christos udata->enbsym = symbol_get_bfdsym (fixp->fx_addsy); 6290 1.1 christos udata->bsym = symbol_get_bfdsym (fixp->tc_fix_data.info->psym); 6291 1.1 christos udata->origname = (char *)pname; 6292 1.1 christos udata->lkindex = ((struct evax_private_udata_struct *) 6293 1.1 christos symbol_get_bfdsym (fixp->tc_fix_data.info->sym)->udata.p)->lkindex; 6294 1.1 christos reloc->sym_ptr_ptr = (void *)udata; 6295 1.1 christos reloc->addend = fixp->fx_addnumber; 6296 1.1 christos 6297 1.1 christos default: 6298 1.1 christos break; 6299 1.1 christos } 6300 1.1 christos #endif 6301 1.1 christos 6302 1.1 christos return reloc; 6303 1.1 christos } 6304 1.1 christos 6305 1.1 christos /* Parse a register name off of the input_line and return a register 6306 1.3 christos number. Gets md_undefined_symbol above to do the register name 6307 1.3 christos matching for us. 6308 1.1 christos 6309 1.1 christos Only called as a part of processing the ECOFF .frame directive. */ 6310 1.1 christos 6311 1.1 christos int 6312 1.1 christos tc_get_register (int frame ATTRIBUTE_UNUSED) 6313 1.1 christos { 6314 1.1 christos int framereg = AXP_REG_SP; 6315 1.1 christos 6316 1.8 christos SKIP_WHITESPACE (); 6317 1.1 christos if (*input_line_pointer == '$') 6318 1.1 christos { 6319 1.1 christos char *s; 6320 1.1 christos char c = get_symbol_name (&s); 6321 1.1 christos symbolS *sym = md_undefined_symbol (s); 6322 1.1 christos 6323 1.1 christos *strchr (s, '\0') = c; 6324 1.1 christos if (sym && (framereg = S_GET_VALUE (sym)) <= 31) 6325 1.1 christos goto found; 6326 1.1 christos } 6327 1.1 christos as_warn (_("frame reg expected, using $%d."), framereg); 6328 1.1 christos 6329 1.1 christos found: 6330 1.1 christos note_gpreg (framereg); 6331 1.1 christos return framereg; 6332 1.1 christos } 6333 1.1 christos 6334 1.1 christos /* This is called before the symbol table is processed. In order to 6335 1.1 christos work with gcc when using mips-tfile, we must keep all local labels. 6336 1.1 christos However, in other cases, we want to discard them. If we were 6337 1.1 christos called with -g, but we didn't see any debugging information, it may 6338 1.1 christos mean that gcc is smuggling debugging information through to 6339 1.1 christos mips-tfile, in which case we must generate all local labels. */ 6340 1.1 christos 6341 1.1 christos #ifdef OBJ_ECOFF 6342 1.1 christos 6343 1.1 christos void 6344 alpha_frob_file_before_adjust (void) 6345 { 6346 if (alpha_debug != 0 6347 && ! ecoff_debugging_seen) 6348 flag_keep_locals = 1; 6349 } 6350 6351 #endif /* OBJ_ECOFF */ 6352 6353 /* The Alpha has support for some VAX floating point types, as well as for 6354 IEEE floating point. We consider IEEE to be the primary floating point 6355 format, and sneak in the VAX floating point support here. */ 6356 #include "config/atof-vax.c" 6357