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