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