1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU. 2 Copyright (C) 1989-2014 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 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 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 p = input_line_pointer; 932 c = get_symbol_end (); 933 934 /* Parse !relocation_type. */ 935 len = input_line_pointer - p; 936 if (len == 0) 937 { 938 as_bad (_("No relocation operand")); 939 goto err_report; 940 } 941 942 r = &alpha_reloc_op[0]; 943 for (i = alpha_num_reloc_op - 1; i >= 0; i--, r++) 944 if (len == r->length && memcmp (p, r->name, len) == 0) 945 break; 946 if (i < 0) 947 { 948 as_bad (_("Unknown relocation operand: !%s"), p); 949 goto err_report; 950 } 951 952 *input_line_pointer = c; 953 SKIP_WHITESPACE (); 954 if (*input_line_pointer != '!') 955 { 956 if (r->require_seq) 957 { 958 as_bad (_("no sequence number after !%s"), p); 959 goto err_report; 960 } 961 962 tok->X_add_number = 0; 963 } 964 else 965 { 966 if (! r->allow_seq) 967 { 968 as_bad (_("!%s does not use a sequence number"), p); 969 goto err_report; 970 } 971 972 input_line_pointer++; 973 974 /* Parse !sequence_number. */ 975 expression (tok); 976 if (tok->X_op != O_constant || tok->X_add_number <= 0) 977 { 978 as_bad (_("Bad sequence number: !%s!%s"), 979 r->name, input_line_pointer); 980 goto err_report; 981 } 982 } 983 984 tok->X_op = r->op; 985 reloc_found_p = 1; 986 ++tok; 987 break; 988 #endif /* RELOC_OP_P */ 989 990 case ',': 991 ++input_line_pointer; 992 if (saw_comma || !saw_arg) 993 goto err; 994 saw_comma = 1; 995 break; 996 997 case '(': 998 { 999 char *hold = input_line_pointer++; 1000 1001 /* First try for parenthesized register ... */ 1002 expression (tok); 1003 if (*input_line_pointer == ')' && tok->X_op == O_register) 1004 { 1005 tok->X_op = (saw_comma ? O_cpregister : O_pregister); 1006 saw_comma = 0; 1007 saw_arg = 1; 1008 ++input_line_pointer; 1009 ++tok; 1010 break; 1011 } 1012 1013 /* ... then fall through to plain expression. */ 1014 input_line_pointer = hold; 1015 } 1016 1017 default: 1018 if (saw_arg && !saw_comma) 1019 goto err; 1020 1021 expression (tok); 1022 if (tok->X_op == O_illegal || tok->X_op == O_absent) 1023 goto err; 1024 1025 saw_comma = 0; 1026 saw_arg = 1; 1027 ++tok; 1028 break; 1029 } 1030 } 1031 1032 fini: 1033 if (saw_comma) 1034 goto err; 1035 input_line_pointer = old_input_line_pointer; 1036 1037 #ifdef DEBUG_ALPHA 1038 debug_exp (orig_tok, ntok - (end_tok - tok)); 1039 #endif 1040 #ifdef RELOC_OP_P 1041 is_end_of_line[(unsigned char) '!'] = 0; 1042 #endif 1043 1044 return ntok - (end_tok - tok); 1045 1046 err: 1047 #ifdef RELOC_OP_P 1048 is_end_of_line[(unsigned char) '!'] = 0; 1049 #endif 1050 input_line_pointer = old_input_line_pointer; 1051 return TOKENIZE_ERROR; 1052 1053 #ifdef RELOC_OP_P 1054 err_report: 1055 is_end_of_line[(unsigned char) '!'] = 0; 1056 #endif 1057 input_line_pointer = old_input_line_pointer; 1058 return TOKENIZE_ERROR_REPORT; 1059 } 1060 1061 /* Search forward through all variants of an opcode looking for a 1062 syntax match. */ 1063 1064 static const struct alpha_opcode * 1065 find_opcode_match (const struct alpha_opcode *first_opcode, 1066 const expressionS *tok, 1067 int *pntok, 1068 int *pcpumatch) 1069 { 1070 const struct alpha_opcode *opcode = first_opcode; 1071 int ntok = *pntok; 1072 int got_cpu_match = 0; 1073 1074 do 1075 { 1076 const unsigned char *opidx; 1077 int tokidx = 0; 1078 1079 /* Don't match opcodes that don't exist on this architecture. */ 1080 if (!(opcode->flags & alpha_target)) 1081 goto match_failed; 1082 1083 got_cpu_match = 1; 1084 1085 for (opidx = opcode->operands; *opidx; ++opidx) 1086 { 1087 const struct alpha_operand *operand = &alpha_operands[*opidx]; 1088 1089 /* Only take input from real operands. */ 1090 if (operand->flags & AXP_OPERAND_FAKE) 1091 continue; 1092 1093 /* When we expect input, make sure we have it. */ 1094 if (tokidx >= ntok) 1095 { 1096 if ((operand->flags & AXP_OPERAND_OPTIONAL_MASK) == 0) 1097 goto match_failed; 1098 continue; 1099 } 1100 1101 /* Match operand type with expression type. */ 1102 switch (operand->flags & AXP_OPERAND_TYPECHECK_MASK) 1103 { 1104 case AXP_OPERAND_IR: 1105 if (tok[tokidx].X_op != O_register 1106 || !is_ir_num (tok[tokidx].X_add_number)) 1107 goto match_failed; 1108 break; 1109 case AXP_OPERAND_FPR: 1110 if (tok[tokidx].X_op != O_register 1111 || !is_fpr_num (tok[tokidx].X_add_number)) 1112 goto match_failed; 1113 break; 1114 case AXP_OPERAND_IR | AXP_OPERAND_PARENS: 1115 if (tok[tokidx].X_op != O_pregister 1116 || !is_ir_num (tok[tokidx].X_add_number)) 1117 goto match_failed; 1118 break; 1119 case AXP_OPERAND_IR | AXP_OPERAND_PARENS | AXP_OPERAND_COMMA: 1120 if (tok[tokidx].X_op != O_cpregister 1121 || !is_ir_num (tok[tokidx].X_add_number)) 1122 goto match_failed; 1123 break; 1124 1125 case AXP_OPERAND_RELATIVE: 1126 case AXP_OPERAND_SIGNED: 1127 case AXP_OPERAND_UNSIGNED: 1128 switch (tok[tokidx].X_op) 1129 { 1130 case O_illegal: 1131 case O_absent: 1132 case O_register: 1133 case O_pregister: 1134 case O_cpregister: 1135 goto match_failed; 1136 1137 default: 1138 break; 1139 } 1140 break; 1141 1142 default: 1143 /* Everything else should have been fake. */ 1144 abort (); 1145 } 1146 ++tokidx; 1147 } 1148 1149 /* Possible match -- did we use all of our input? */ 1150 if (tokidx == ntok) 1151 { 1152 *pntok = ntok; 1153 return opcode; 1154 } 1155 1156 match_failed:; 1157 } 1158 while (++opcode - alpha_opcodes < (int) alpha_num_opcodes 1159 && !strcmp (opcode->name, first_opcode->name)); 1160 1161 if (*pcpumatch) 1162 *pcpumatch = got_cpu_match; 1163 1164 return NULL; 1165 } 1166 1167 /* Given an opcode name and a pre-tokenized set of arguments, assemble 1168 the insn, but do not emit it. 1169 1170 Note that this implies no macros allowed, since we can't store more 1171 than one insn in an insn structure. */ 1172 1173 static void 1174 assemble_tokens_to_insn (const char *opname, 1175 const expressionS *tok, 1176 int ntok, 1177 struct alpha_insn *insn) 1178 { 1179 const struct alpha_opcode *opcode; 1180 1181 /* Search opcodes. */ 1182 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname); 1183 if (opcode) 1184 { 1185 int cpumatch; 1186 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch); 1187 if (opcode) 1188 { 1189 assemble_insn (opcode, tok, ntok, insn, BFD_RELOC_UNUSED); 1190 return; 1191 } 1192 else if (cpumatch) 1193 as_bad (_("inappropriate arguments for opcode `%s'"), opname); 1194 else 1195 as_bad (_("opcode `%s' not supported for target %s"), opname, 1196 alpha_target_name); 1197 } 1198 else 1199 as_bad (_("unknown opcode `%s'"), opname); 1200 } 1201 1202 /* Build a BFD section with its flags set appropriately for the .lita, 1203 .lit8, or .lit4 sections. */ 1204 1205 static void 1206 create_literal_section (const char *name, 1207 segT *secp, 1208 symbolS **symp) 1209 { 1210 segT current_section = now_seg; 1211 int current_subsec = now_subseg; 1212 segT new_sec; 1213 1214 *secp = new_sec = subseg_new (name, 0); 1215 subseg_set (current_section, current_subsec); 1216 bfd_set_section_alignment (stdoutput, new_sec, 4); 1217 bfd_set_section_flags (stdoutput, new_sec, 1218 SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY 1219 | SEC_DATA); 1220 1221 S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec)); 1222 } 1223 1224 /* Load a (partial) expression into a target register. 1225 1226 If poffset is not null, after the call it will either contain 1227 O_constant 0, or a 16-bit offset appropriate for any MEM format 1228 instruction. In addition, pbasereg will be modified to point to 1229 the base register to use in that MEM format instruction. 1230 1231 In any case, *pbasereg should contain a base register to add to the 1232 expression. This will normally be either AXP_REG_ZERO or 1233 alpha_gp_register. Symbol addresses will always be loaded via $gp, 1234 so "foo($0)" is interpreted as adding the address of foo to $0; 1235 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps, 1236 but this is what OSF/1 does. 1237 1238 If explicit relocations of the form !literal!<number> are allowed, 1239 and used, then explicit_reloc with be an expression pointer. 1240 1241 Finally, the return value is nonzero if the calling macro may emit 1242 a LITUSE reloc if otherwise appropriate; the return value is the 1243 sequence number to use. */ 1244 1245 static long 1246 load_expression (int targreg, 1247 const expressionS *exp, 1248 int *pbasereg, 1249 expressionS *poffset, 1250 const char *opname) 1251 { 1252 long emit_lituse = 0; 1253 offsetT addend = exp->X_add_number; 1254 int basereg = *pbasereg; 1255 struct alpha_insn insn; 1256 expressionS newtok[3]; 1257 1258 switch (exp->X_op) 1259 { 1260 case O_symbol: 1261 { 1262 #ifdef OBJ_ECOFF 1263 offsetT lit; 1264 1265 /* Attempt to reduce .lit load by splitting the offset from 1266 its symbol when possible, but don't create a situation in 1267 which we'd fail. */ 1268 if (!range_signed_32 (addend) && 1269 (alpha_noat_on || targreg == AXP_REG_AT)) 1270 { 1271 lit = add_to_literal_pool (exp->X_add_symbol, addend, 1272 alpha_lita_section, 8); 1273 addend = 0; 1274 } 1275 else 1276 lit = add_to_literal_pool (exp->X_add_symbol, 0, 1277 alpha_lita_section, 8); 1278 1279 if (lit >= 0x8000) 1280 as_fatal (_("overflow in literal (.lita) table")); 1281 1282 /* Emit "ldq r, lit(gp)". */ 1283 1284 if (basereg != alpha_gp_register && targreg == basereg) 1285 { 1286 if (alpha_noat_on) 1287 as_bad (_("macro requires $at register while noat in effect")); 1288 if (targreg == AXP_REG_AT) 1289 as_bad (_("macro requires $at while $at in use")); 1290 1291 set_tok_reg (newtok[0], AXP_REG_AT); 1292 } 1293 else 1294 set_tok_reg (newtok[0], targreg); 1295 1296 set_tok_sym (newtok[1], alpha_lita_symbol, lit); 1297 set_tok_preg (newtok[2], alpha_gp_register); 1298 1299 assemble_tokens_to_insn ("ldq", newtok, 3, &insn); 1300 1301 gas_assert (insn.nfixups == 1); 1302 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL; 1303 insn.sequence = emit_lituse = next_sequence_num--; 1304 #endif /* OBJ_ECOFF */ 1305 #ifdef OBJ_ELF 1306 /* Emit "ldq r, gotoff(gp)". */ 1307 1308 if (basereg != alpha_gp_register && targreg == basereg) 1309 { 1310 if (alpha_noat_on) 1311 as_bad (_("macro requires $at register while noat in effect")); 1312 if (targreg == AXP_REG_AT) 1313 as_bad (_("macro requires $at while $at in use")); 1314 1315 set_tok_reg (newtok[0], AXP_REG_AT); 1316 } 1317 else 1318 set_tok_reg (newtok[0], targreg); 1319 1320 /* XXX: Disable this .got minimizing optimization so that we can get 1321 better instruction offset knowledge in the compiler. This happens 1322 very infrequently anyway. */ 1323 if (1 1324 || (!range_signed_32 (addend) 1325 && (alpha_noat_on || targreg == AXP_REG_AT))) 1326 { 1327 newtok[1] = *exp; 1328 addend = 0; 1329 } 1330 else 1331 set_tok_sym (newtok[1], exp->X_add_symbol, 0); 1332 1333 set_tok_preg (newtok[2], alpha_gp_register); 1334 1335 assemble_tokens_to_insn ("ldq", newtok, 3, &insn); 1336 1337 gas_assert (insn.nfixups == 1); 1338 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL; 1339 insn.sequence = emit_lituse = next_sequence_num--; 1340 #endif /* OBJ_ELF */ 1341 #ifdef OBJ_EVAX 1342 /* Find symbol or symbol pointer in link section. */ 1343 1344 if (exp->X_add_symbol == alpha_evax_proc->symbol) 1345 { 1346 /* Linkage-relative expression. */ 1347 set_tok_reg (newtok[0], targreg); 1348 1349 if (range_signed_16 (addend)) 1350 { 1351 set_tok_const (newtok[1], addend); 1352 addend = 0; 1353 } 1354 else 1355 { 1356 set_tok_const (newtok[1], 0); 1357 } 1358 set_tok_preg (newtok[2], basereg); 1359 assemble_tokens_to_insn ("lda", newtok, 3, &insn); 1360 } 1361 else 1362 { 1363 const char *symname = S_GET_NAME (exp->X_add_symbol); 1364 const char *ptr1, *ptr2; 1365 int symlen = strlen (symname); 1366 1367 if ((symlen > 4 && 1368 strcmp (ptr2 = &symname [symlen - 4], "..lk") == 0)) 1369 { 1370 /* Access to an item whose address is stored in the linkage 1371 section. Just read the address. */ 1372 set_tok_reg (newtok[0], targreg); 1373 1374 newtok[1] = *exp; 1375 newtok[1].X_op = O_subtract; 1376 newtok[1].X_op_symbol = alpha_evax_proc->symbol; 1377 1378 set_tok_preg (newtok[2], basereg); 1379 assemble_tokens_to_insn ("ldq", newtok, 3, &insn); 1380 alpha_linkage_symbol = exp->X_add_symbol; 1381 1382 if (poffset) 1383 set_tok_const (*poffset, 0); 1384 1385 if (alpha_flag_replace && targreg == 26) 1386 { 1387 /* Add a NOP fixup for 'ldX $26,YYY..NAME..lk'. */ 1388 char *ensymname; 1389 symbolS *ensym; 1390 1391 /* Build the entry name as 'NAME..en'. */ 1392 ptr1 = strstr (symname, "..") + 2; 1393 if (ptr1 > ptr2) 1394 ptr1 = symname; 1395 ensymname = (char *) alloca (ptr2 - ptr1 + 5); 1396 memcpy (ensymname, ptr1, ptr2 - ptr1); 1397 memcpy (ensymname + (ptr2 - ptr1), "..en", 5); 1398 1399 gas_assert (insn.nfixups + 1 <= MAX_INSN_FIXUPS); 1400 insn.fixups[insn.nfixups].reloc = BFD_RELOC_ALPHA_NOP; 1401 ensym = symbol_find_or_make (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 = (char *) alloca (ptr2 - ptr1 + 1); 1428 memcpy (psymname, ptr1, ptr2 - ptr1); 1429 psymname [ptr2 - ptr1] = 0; 1430 1431 gas_assert (insn.nfixups + 1 <= MAX_INSN_FIXUPS); 1432 insn.fixups[insn.nfixups].reloc = BFD_RELOC_ALPHA_LDA; 1433 psym = symbol_find_or_make (psymname); 1434 symbol_mark_used (psym); 1435 insn.fixups[insn.nfixups].exp.X_op = O_subtract; 1436 insn.fixups[insn.nfixups].exp.X_add_symbol = psym; 1437 insn.fixups[insn.nfixups].exp.X_op_symbol = alpha_evax_proc->symbol; 1438 insn.fixups[insn.nfixups].exp.X_add_number = 0; 1439 insn.fixups[insn.nfixups].xtrasym = alpha_linkage_symbol; 1440 insn.fixups[insn.nfixups].procsym = alpha_evax_proc->symbol; 1441 insn.nfixups++; 1442 } 1443 1444 emit_insn (&insn); 1445 return 0; 1446 } 1447 else 1448 { 1449 /* Not in the linkage section. Put the value into the linkage 1450 section. */ 1451 symbolS *linkexp; 1452 1453 if (!range_signed_32 (addend)) 1454 addend = sign_extend_32 (addend); 1455 linkexp = add_to_link_pool (exp->X_add_symbol, 0); 1456 set_tok_reg (newtok[0], targreg); 1457 set_tok_sym (newtok[1], linkexp, 0); 1458 set_tok_preg (newtok[2], basereg); 1459 assemble_tokens_to_insn ("ldq", newtok, 3, &insn); 1460 } 1461 } 1462 #endif /* OBJ_EVAX */ 1463 1464 emit_insn (&insn); 1465 1466 #ifndef OBJ_EVAX 1467 if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO) 1468 { 1469 /* Emit "addq r, base, r". */ 1470 1471 set_tok_reg (newtok[1], basereg); 1472 set_tok_reg (newtok[2], targreg); 1473 assemble_tokens ("addq", newtok, 3, 0); 1474 } 1475 #endif 1476 basereg = targreg; 1477 } 1478 break; 1479 1480 case O_constant: 1481 break; 1482 1483 case O_subtract: 1484 /* Assume that this difference expression will be resolved to an 1485 absolute value and that that value will fit in 16 bits. */ 1486 1487 set_tok_reg (newtok[0], targreg); 1488 newtok[1] = *exp; 1489 set_tok_preg (newtok[2], basereg); 1490 assemble_tokens (opname, newtok, 3, 0); 1491 1492 if (poffset) 1493 set_tok_const (*poffset, 0); 1494 return 0; 1495 1496 case O_big: 1497 if (exp->X_add_number > 0) 1498 as_bad (_("bignum invalid; zero assumed")); 1499 else 1500 as_bad (_("floating point number invalid; zero assumed")); 1501 addend = 0; 1502 break; 1503 1504 default: 1505 as_bad (_("can't handle expression")); 1506 addend = 0; 1507 break; 1508 } 1509 1510 if (!range_signed_32 (addend)) 1511 { 1512 #ifdef OBJ_EVAX 1513 symbolS *litexp; 1514 #else 1515 offsetT lit; 1516 long seq_num = next_sequence_num--; 1517 #endif 1518 1519 /* For 64-bit addends, just put it in the literal pool. */ 1520 #ifdef OBJ_EVAX 1521 /* Emit "ldq targreg, lit(basereg)". */ 1522 litexp = add_to_link_pool (section_symbol (absolute_section), addend); 1523 set_tok_reg (newtok[0], targreg); 1524 set_tok_sym (newtok[1], litexp, 0); 1525 set_tok_preg (newtok[2], alpha_gp_register); 1526 assemble_tokens ("ldq", newtok, 3, 0); 1527 #else 1528 1529 if (alpha_lit8_section == NULL) 1530 { 1531 create_literal_section (".lit8", 1532 &alpha_lit8_section, 1533 &alpha_lit8_symbol); 1534 1535 #ifdef OBJ_ECOFF 1536 alpha_lit8_literal = add_to_literal_pool (alpha_lit8_symbol, 0x8000, 1537 alpha_lita_section, 8); 1538 if (alpha_lit8_literal >= 0x8000) 1539 as_fatal (_("overflow in literal (.lita) table")); 1540 #endif 1541 } 1542 1543 lit = add_to_literal_pool (NULL, addend, alpha_lit8_section, 8) - 0x8000; 1544 if (lit >= 0x8000) 1545 as_fatal (_("overflow in literal (.lit8) table")); 1546 1547 /* Emit "lda litreg, .lit8+0x8000". */ 1548 1549 if (targreg == basereg) 1550 { 1551 if (alpha_noat_on) 1552 as_bad (_("macro requires $at register while noat in effect")); 1553 if (targreg == AXP_REG_AT) 1554 as_bad (_("macro requires $at while $at in use")); 1555 1556 set_tok_reg (newtok[0], AXP_REG_AT); 1557 } 1558 else 1559 set_tok_reg (newtok[0], targreg); 1560 #ifdef OBJ_ECOFF 1561 set_tok_sym (newtok[1], alpha_lita_symbol, alpha_lit8_literal); 1562 #endif 1563 #ifdef OBJ_ELF 1564 set_tok_sym (newtok[1], alpha_lit8_symbol, 0x8000); 1565 #endif 1566 set_tok_preg (newtok[2], alpha_gp_register); 1567 1568 assemble_tokens_to_insn ("ldq", newtok, 3, &insn); 1569 1570 gas_assert (insn.nfixups == 1); 1571 #ifdef OBJ_ECOFF 1572 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL; 1573 #endif 1574 #ifdef OBJ_ELF 1575 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL; 1576 #endif 1577 insn.sequence = seq_num; 1578 1579 emit_insn (&insn); 1580 1581 /* Emit "ldq litreg, lit(litreg)". */ 1582 1583 set_tok_const (newtok[1], lit); 1584 set_tok_preg (newtok[2], newtok[0].X_add_number); 1585 1586 assemble_tokens_to_insn ("ldq", newtok, 3, &insn); 1587 1588 gas_assert (insn.nfixups < MAX_INSN_FIXUPS); 1589 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE; 1590 insn.fixups[insn.nfixups].exp.X_op = O_absent; 1591 insn.nfixups++; 1592 insn.sequence = seq_num; 1593 emit_lituse = 0; 1594 1595 emit_insn (&insn); 1596 1597 /* Emit "addq litreg, base, target". */ 1598 1599 if (basereg != AXP_REG_ZERO) 1600 { 1601 set_tok_reg (newtok[1], basereg); 1602 set_tok_reg (newtok[2], targreg); 1603 assemble_tokens ("addq", newtok, 3, 0); 1604 } 1605 #endif /* !OBJ_EVAX */ 1606 1607 if (poffset) 1608 set_tok_const (*poffset, 0); 1609 *pbasereg = targreg; 1610 } 1611 else 1612 { 1613 offsetT low, high, extra, tmp; 1614 1615 /* For 32-bit operands, break up the addend. */ 1616 1617 low = sign_extend_16 (addend); 1618 tmp = addend - low; 1619 high = sign_extend_16 (tmp >> 16); 1620 1621 if (tmp - (high << 16)) 1622 { 1623 extra = 0x4000; 1624 tmp -= 0x40000000; 1625 high = sign_extend_16 (tmp >> 16); 1626 } 1627 else 1628 extra = 0; 1629 1630 set_tok_reg (newtok[0], targreg); 1631 set_tok_preg (newtok[2], basereg); 1632 1633 if (extra) 1634 { 1635 /* Emit "ldah r, extra(r). */ 1636 set_tok_const (newtok[1], extra); 1637 assemble_tokens ("ldah", newtok, 3, 0); 1638 set_tok_preg (newtok[2], basereg = targreg); 1639 } 1640 1641 if (high) 1642 { 1643 /* Emit "ldah r, high(r). */ 1644 set_tok_const (newtok[1], high); 1645 assemble_tokens ("ldah", newtok, 3, 0); 1646 basereg = targreg; 1647 set_tok_preg (newtok[2], basereg); 1648 } 1649 1650 if ((low && !poffset) || (!poffset && basereg != targreg)) 1651 { 1652 /* Emit "lda r, low(base)". */ 1653 set_tok_const (newtok[1], low); 1654 assemble_tokens ("lda", newtok, 3, 0); 1655 basereg = targreg; 1656 low = 0; 1657 } 1658 1659 if (poffset) 1660 set_tok_const (*poffset, low); 1661 *pbasereg = basereg; 1662 } 1663 1664 return emit_lituse; 1665 } 1666 1667 /* The lda macro differs from the lda instruction in that it handles 1668 most simple expressions, particularly symbol address loads and 1669 large constants. */ 1670 1671 static void 1672 emit_lda (const expressionS *tok, 1673 int ntok, 1674 const void * unused ATTRIBUTE_UNUSED) 1675 { 1676 int basereg; 1677 1678 if (ntok == 2) 1679 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register); 1680 else 1681 basereg = tok[2].X_add_number; 1682 1683 (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL, "lda"); 1684 } 1685 1686 /* The ldah macro differs from the ldah instruction in that it has $31 1687 as an implied base register. */ 1688 1689 static void 1690 emit_ldah (const expressionS *tok, 1691 int ntok ATTRIBUTE_UNUSED, 1692 const void * unused ATTRIBUTE_UNUSED) 1693 { 1694 expressionS newtok[3]; 1695 1696 newtok[0] = tok[0]; 1697 newtok[1] = tok[1]; 1698 set_tok_preg (newtok[2], AXP_REG_ZERO); 1699 1700 assemble_tokens ("ldah", newtok, 3, 0); 1701 } 1702 1703 /* Called internally to handle all alignment needs. This takes care 1704 of eliding calls to frag_align if'n the cached current alignment 1705 says we've already got it, as well as taking care of the auto-align 1706 feature wrt labels. */ 1707 1708 static void 1709 alpha_align (int n, 1710 char *pfill, 1711 symbolS *label, 1712 int force ATTRIBUTE_UNUSED) 1713 { 1714 if (alpha_current_align >= n) 1715 return; 1716 1717 if (pfill == NULL) 1718 { 1719 if (subseg_text_p (now_seg)) 1720 frag_align_code (n, 0); 1721 else 1722 frag_align (n, 0, 0); 1723 } 1724 else 1725 frag_align (n, *pfill, 0); 1726 1727 alpha_current_align = n; 1728 1729 if (label != NULL && S_GET_SEGMENT (label) == now_seg) 1730 { 1731 symbol_set_frag (label, frag_now); 1732 S_SET_VALUE (label, (valueT) frag_now_fix ()); 1733 } 1734 1735 record_alignment (now_seg, n); 1736 1737 /* ??? If alpha_flag_relax && force && elf, record the requested alignment 1738 in a reloc for the linker to see. */ 1739 } 1740 1741 /* Actually output an instruction with its fixup. */ 1742 1743 static void 1744 emit_insn (struct alpha_insn *insn) 1745 { 1746 char *f; 1747 int i; 1748 1749 /* Take care of alignment duties. */ 1750 if (alpha_auto_align_on && alpha_current_align < 2) 1751 alpha_align (2, (char *) NULL, alpha_insn_label, 0); 1752 if (alpha_current_align > 2) 1753 alpha_current_align = 2; 1754 alpha_insn_label = NULL; 1755 1756 /* Write out the instruction. */ 1757 f = frag_more (4); 1758 md_number_to_chars (f, insn->insn, 4); 1759 1760 #ifdef OBJ_ELF 1761 dwarf2_emit_insn (4); 1762 #endif 1763 1764 /* Apply the fixups in order. */ 1765 for (i = 0; i < insn->nfixups; ++i) 1766 { 1767 const struct alpha_operand *operand = (const struct alpha_operand *) 0; 1768 struct alpha_fixup *fixup = &insn->fixups[i]; 1769 struct alpha_reloc_tag *info = NULL; 1770 int size, pcrel; 1771 fixS *fixP; 1772 1773 /* Some fixups are only used internally and so have no howto. */ 1774 if ((int) fixup->reloc < 0) 1775 { 1776 operand = &alpha_operands[-(int) fixup->reloc]; 1777 size = 4; 1778 pcrel = ((operand->flags & AXP_OPERAND_RELATIVE) != 0); 1779 } 1780 else if (fixup->reloc > BFD_RELOC_UNUSED 1781 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16 1782 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16) 1783 { 1784 size = 2; 1785 pcrel = 0; 1786 } 1787 else 1788 { 1789 reloc_howto_type *reloc_howto = 1790 bfd_reloc_type_lookup (stdoutput, 1791 (bfd_reloc_code_real_type) fixup->reloc); 1792 gas_assert (reloc_howto); 1793 1794 size = bfd_get_reloc_size (reloc_howto); 1795 1796 switch (fixup->reloc) 1797 { 1798 #ifdef OBJ_EVAX 1799 case BFD_RELOC_ALPHA_NOP: 1800 case BFD_RELOC_ALPHA_BSR: 1801 case BFD_RELOC_ALPHA_LDA: 1802 case BFD_RELOC_ALPHA_BOH: 1803 break; 1804 #endif 1805 default: 1806 gas_assert (size >= 1 && size <= 4); 1807 } 1808 1809 pcrel = reloc_howto->pc_relative; 1810 } 1811 1812 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size, 1813 &fixup->exp, pcrel, (bfd_reloc_code_real_type) fixup->reloc); 1814 1815 /* Turn off complaints that the addend is too large for some fixups, 1816 and copy in the sequence number for the explicit relocations. */ 1817 switch (fixup->reloc) 1818 { 1819 case BFD_RELOC_ALPHA_HINT: 1820 case BFD_RELOC_GPREL32: 1821 case BFD_RELOC_GPREL16: 1822 case BFD_RELOC_ALPHA_GPREL_HI16: 1823 case BFD_RELOC_ALPHA_GPREL_LO16: 1824 case BFD_RELOC_ALPHA_GOTDTPREL16: 1825 case BFD_RELOC_ALPHA_DTPREL_HI16: 1826 case BFD_RELOC_ALPHA_DTPREL_LO16: 1827 case BFD_RELOC_ALPHA_DTPREL16: 1828 case BFD_RELOC_ALPHA_GOTTPREL16: 1829 case BFD_RELOC_ALPHA_TPREL_HI16: 1830 case BFD_RELOC_ALPHA_TPREL_LO16: 1831 case BFD_RELOC_ALPHA_TPREL16: 1832 fixP->fx_no_overflow = 1; 1833 break; 1834 1835 case BFD_RELOC_ALPHA_GPDISP_HI16: 1836 fixP->fx_no_overflow = 1; 1837 fixP->fx_addsy = section_symbol (now_seg); 1838 fixP->fx_offset = 0; 1839 1840 info = get_alpha_reloc_tag (insn->sequence); 1841 if (++info->n_master > 1) 1842 as_bad (_("too many ldah insns for !gpdisp!%ld"), insn->sequence); 1843 if (info->segment != now_seg) 1844 as_bad (_("both insns for !gpdisp!%ld must be in the same section"), 1845 insn->sequence); 1846 fixP->tc_fix_data.info = info; 1847 break; 1848 1849 case BFD_RELOC_ALPHA_GPDISP_LO16: 1850 fixP->fx_no_overflow = 1; 1851 1852 info = get_alpha_reloc_tag (insn->sequence); 1853 if (++info->n_slaves > 1) 1854 as_bad (_("too many lda insns for !gpdisp!%ld"), insn->sequence); 1855 if (info->segment != now_seg) 1856 as_bad (_("both insns for !gpdisp!%ld must be in the same section"), 1857 insn->sequence); 1858 fixP->tc_fix_data.info = info; 1859 info->slaves = fixP; 1860 break; 1861 1862 case BFD_RELOC_ALPHA_LITERAL: 1863 case BFD_RELOC_ALPHA_ELF_LITERAL: 1864 fixP->fx_no_overflow = 1; 1865 1866 if (insn->sequence == 0) 1867 break; 1868 info = get_alpha_reloc_tag (insn->sequence); 1869 info->master = fixP; 1870 info->n_master++; 1871 if (info->segment != now_seg) 1872 info->multi_section_p = 1; 1873 fixP->tc_fix_data.info = info; 1874 break; 1875 1876 #ifdef RELOC_OP_P 1877 case DUMMY_RELOC_LITUSE_ADDR: 1878 fixP->fx_offset = LITUSE_ALPHA_ADDR; 1879 goto do_lituse; 1880 case DUMMY_RELOC_LITUSE_BASE: 1881 fixP->fx_offset = LITUSE_ALPHA_BASE; 1882 goto do_lituse; 1883 case DUMMY_RELOC_LITUSE_BYTOFF: 1884 fixP->fx_offset = LITUSE_ALPHA_BYTOFF; 1885 goto do_lituse; 1886 case DUMMY_RELOC_LITUSE_JSR: 1887 fixP->fx_offset = LITUSE_ALPHA_JSR; 1888 goto do_lituse; 1889 case DUMMY_RELOC_LITUSE_TLSGD: 1890 fixP->fx_offset = LITUSE_ALPHA_TLSGD; 1891 goto do_lituse; 1892 case DUMMY_RELOC_LITUSE_TLSLDM: 1893 fixP->fx_offset = LITUSE_ALPHA_TLSLDM; 1894 goto do_lituse; 1895 case DUMMY_RELOC_LITUSE_JSRDIRECT: 1896 fixP->fx_offset = LITUSE_ALPHA_JSRDIRECT; 1897 goto do_lituse; 1898 do_lituse: 1899 fixP->fx_addsy = section_symbol (now_seg); 1900 fixP->fx_r_type = BFD_RELOC_ALPHA_LITUSE; 1901 1902 info = get_alpha_reloc_tag (insn->sequence); 1903 if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSGD) 1904 info->saw_lu_tlsgd = 1; 1905 else if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSLDM) 1906 info->saw_lu_tlsldm = 1; 1907 if (++info->n_slaves > 1) 1908 { 1909 if (info->saw_lu_tlsgd) 1910 as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"), 1911 insn->sequence); 1912 else if (info->saw_lu_tlsldm) 1913 as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"), 1914 insn->sequence); 1915 } 1916 fixP->tc_fix_data.info = info; 1917 fixP->tc_fix_data.next_reloc = info->slaves; 1918 info->slaves = fixP; 1919 if (info->segment != now_seg) 1920 info->multi_section_p = 1; 1921 break; 1922 1923 case BFD_RELOC_ALPHA_TLSGD: 1924 fixP->fx_no_overflow = 1; 1925 1926 if (insn->sequence == 0) 1927 break; 1928 info = get_alpha_reloc_tag (insn->sequence); 1929 if (info->saw_tlsgd) 1930 as_bad (_("duplicate !tlsgd!%ld"), insn->sequence); 1931 else if (info->saw_tlsldm) 1932 as_bad (_("sequence number in use for !tlsldm!%ld"), 1933 insn->sequence); 1934 else 1935 info->saw_tlsgd = 1; 1936 fixP->tc_fix_data.info = info; 1937 break; 1938 1939 case BFD_RELOC_ALPHA_TLSLDM: 1940 fixP->fx_no_overflow = 1; 1941 1942 if (insn->sequence == 0) 1943 break; 1944 info = get_alpha_reloc_tag (insn->sequence); 1945 if (info->saw_tlsldm) 1946 as_bad (_("duplicate !tlsldm!%ld"), insn->sequence); 1947 else if (info->saw_tlsgd) 1948 as_bad (_("sequence number in use for !tlsgd!%ld"), 1949 insn->sequence); 1950 else 1951 info->saw_tlsldm = 1; 1952 fixP->tc_fix_data.info = info; 1953 break; 1954 #endif 1955 #ifdef OBJ_EVAX 1956 case BFD_RELOC_ALPHA_NOP: 1957 case BFD_RELOC_ALPHA_LDA: 1958 case BFD_RELOC_ALPHA_BSR: 1959 case BFD_RELOC_ALPHA_BOH: 1960 info = get_alpha_reloc_tag (next_sequence_num--); 1961 fixP->tc_fix_data.info = info; 1962 fixP->tc_fix_data.info->sym = fixup->xtrasym; 1963 fixP->tc_fix_data.info->psym = fixup->procsym; 1964 break; 1965 #endif 1966 1967 default: 1968 if ((int) fixup->reloc < 0) 1969 { 1970 if (operand->flags & AXP_OPERAND_NOOVERFLOW) 1971 fixP->fx_no_overflow = 1; 1972 } 1973 break; 1974 } 1975 } 1976 } 1977 1978 /* Insert an operand value into an instruction. */ 1979 1980 static unsigned 1981 insert_operand (unsigned insn, 1982 const struct alpha_operand *operand, 1983 offsetT val, 1984 char *file, 1985 unsigned line) 1986 { 1987 if (operand->bits != 32 && !(operand->flags & AXP_OPERAND_NOOVERFLOW)) 1988 { 1989 offsetT min, max; 1990 1991 if (operand->flags & AXP_OPERAND_SIGNED) 1992 { 1993 max = (1 << (operand->bits - 1)) - 1; 1994 min = -(1 << (operand->bits - 1)); 1995 } 1996 else 1997 { 1998 max = (1 << operand->bits) - 1; 1999 min = 0; 2000 } 2001 2002 if (val < min || val > max) 2003 as_bad_value_out_of_range (_("operand"), val, min, max, file, line); 2004 } 2005 2006 if (operand->insert) 2007 { 2008 const char *errmsg = NULL; 2009 2010 insn = (*operand->insert) (insn, val, &errmsg); 2011 if (errmsg) 2012 as_warn ("%s", errmsg); 2013 } 2014 else 2015 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift); 2016 2017 return insn; 2018 } 2019 2020 /* Turn an opcode description and a set of arguments into 2021 an instruction and a fixup. */ 2022 2023 static void 2024 assemble_insn (const struct alpha_opcode *opcode, 2025 const expressionS *tok, 2026 int ntok, 2027 struct alpha_insn *insn, 2028 extended_bfd_reloc_code_real_type reloc) 2029 { 2030 const struct alpha_operand *reloc_operand = NULL; 2031 const expressionS *reloc_exp = NULL; 2032 const unsigned char *argidx; 2033 unsigned image; 2034 int tokidx = 0; 2035 2036 memset (insn, 0, sizeof (*insn)); 2037 image = opcode->opcode; 2038 2039 for (argidx = opcode->operands; *argidx; ++argidx) 2040 { 2041 const struct alpha_operand *operand = &alpha_operands[*argidx]; 2042 const expressionS *t = (const expressionS *) 0; 2043 2044 if (operand->flags & AXP_OPERAND_FAKE) 2045 { 2046 /* Fake operands take no value and generate no fixup. */ 2047 image = insert_operand (image, operand, 0, NULL, 0); 2048 continue; 2049 } 2050 2051 if (tokidx >= ntok) 2052 { 2053 switch (operand->flags & AXP_OPERAND_OPTIONAL_MASK) 2054 { 2055 case AXP_OPERAND_DEFAULT_FIRST: 2056 t = &tok[0]; 2057 break; 2058 case AXP_OPERAND_DEFAULT_SECOND: 2059 t = &tok[1]; 2060 break; 2061 case AXP_OPERAND_DEFAULT_ZERO: 2062 { 2063 static expressionS zero_exp; 2064 t = &zero_exp; 2065 zero_exp.X_op = O_constant; 2066 zero_exp.X_unsigned = 1; 2067 } 2068 break; 2069 default: 2070 abort (); 2071 } 2072 } 2073 else 2074 t = &tok[tokidx++]; 2075 2076 switch (t->X_op) 2077 { 2078 case O_register: 2079 case O_pregister: 2080 case O_cpregister: 2081 image = insert_operand (image, operand, regno (t->X_add_number), 2082 NULL, 0); 2083 break; 2084 2085 case O_constant: 2086 image = insert_operand (image, operand, t->X_add_number, NULL, 0); 2087 gas_assert (reloc_operand == NULL); 2088 reloc_operand = operand; 2089 reloc_exp = t; 2090 break; 2091 2092 default: 2093 /* This is only 0 for fields that should contain registers, 2094 which means this pattern shouldn't have matched. */ 2095 if (operand->default_reloc == 0) 2096 abort (); 2097 2098 /* There is one special case for which an insn receives two 2099 relocations, and thus the user-supplied reloc does not 2100 override the operand reloc. */ 2101 if (operand->default_reloc == BFD_RELOC_ALPHA_HINT) 2102 { 2103 struct alpha_fixup *fixup; 2104 2105 if (insn->nfixups >= MAX_INSN_FIXUPS) 2106 as_fatal (_("too many fixups")); 2107 2108 fixup = &insn->fixups[insn->nfixups++]; 2109 fixup->exp = *t; 2110 fixup->reloc = BFD_RELOC_ALPHA_HINT; 2111 } 2112 else 2113 { 2114 if (reloc == BFD_RELOC_UNUSED) 2115 reloc = operand->default_reloc; 2116 2117 gas_assert (reloc_operand == NULL); 2118 reloc_operand = operand; 2119 reloc_exp = t; 2120 } 2121 break; 2122 } 2123 } 2124 2125 if (reloc != BFD_RELOC_UNUSED) 2126 { 2127 struct alpha_fixup *fixup; 2128 2129 if (insn->nfixups >= MAX_INSN_FIXUPS) 2130 as_fatal (_("too many fixups")); 2131 2132 /* ??? My but this is hacky. But the OSF/1 assembler uses the same 2133 relocation tag for both ldah and lda with gpdisp. Choose the 2134 correct internal relocation based on the opcode. */ 2135 if (reloc == BFD_RELOC_ALPHA_GPDISP) 2136 { 2137 if (strcmp (opcode->name, "ldah") == 0) 2138 reloc = BFD_RELOC_ALPHA_GPDISP_HI16; 2139 else if (strcmp (opcode->name, "lda") == 0) 2140 reloc = BFD_RELOC_ALPHA_GPDISP_LO16; 2141 else 2142 as_bad (_("invalid relocation for instruction")); 2143 } 2144 2145 /* If this is a real relocation (as opposed to a lituse hint), then 2146 the relocation width should match the operand width. 2147 Take care of -MDISP in operand table. */ 2148 else if (reloc < BFD_RELOC_UNUSED && reloc > 0) 2149 { 2150 reloc_howto_type *reloc_howto 2151 = bfd_reloc_type_lookup (stdoutput, 2152 (bfd_reloc_code_real_type) reloc); 2153 if (reloc_operand == NULL 2154 || reloc_howto->bitsize != reloc_operand->bits) 2155 { 2156 as_bad (_("invalid relocation for field")); 2157 return; 2158 } 2159 } 2160 2161 fixup = &insn->fixups[insn->nfixups++]; 2162 if (reloc_exp) 2163 fixup->exp = *reloc_exp; 2164 else 2165 fixup->exp.X_op = O_absent; 2166 fixup->reloc = reloc; 2167 } 2168 2169 insn->insn = image; 2170 } 2171 2172 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u, 2173 etc. They differ from the real instructions in that they do simple 2174 expressions like the lda macro. */ 2175 2176 static void 2177 emit_ir_load (const expressionS *tok, 2178 int ntok, 2179 const void * opname) 2180 { 2181 int basereg; 2182 long lituse; 2183 expressionS newtok[3]; 2184 struct alpha_insn insn; 2185 const char *symname 2186 = tok[1].X_add_symbol ? S_GET_NAME (tok[1].X_add_symbol): ""; 2187 int symlen = strlen (symname); 2188 2189 if (ntok == 2) 2190 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register); 2191 else 2192 basereg = tok[2].X_add_number; 2193 2194 lituse = load_expression (tok[0].X_add_number, &tok[1], 2195 &basereg, &newtok[1], (const char *) opname); 2196 2197 if (basereg == alpha_gp_register && 2198 (symlen > 4 && strcmp (&symname [symlen - 4], "..lk") == 0)) 2199 return; 2200 2201 newtok[0] = tok[0]; 2202 set_tok_preg (newtok[2], basereg); 2203 2204 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn); 2205 2206 if (lituse) 2207 { 2208 gas_assert (insn.nfixups < MAX_INSN_FIXUPS); 2209 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE; 2210 insn.fixups[insn.nfixups].exp.X_op = O_absent; 2211 insn.nfixups++; 2212 insn.sequence = lituse; 2213 } 2214 2215 emit_insn (&insn); 2216 } 2217 2218 /* Handle fp register loads, and both integer and fp register stores. 2219 Again, we handle simple expressions. */ 2220 2221 static void 2222 emit_loadstore (const expressionS *tok, 2223 int ntok, 2224 const void * opname) 2225 { 2226 int basereg; 2227 long lituse; 2228 expressionS newtok[3]; 2229 struct alpha_insn insn; 2230 2231 if (ntok == 2) 2232 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register); 2233 else 2234 basereg = tok[2].X_add_number; 2235 2236 if (tok[1].X_op != O_constant || !range_signed_16 (tok[1].X_add_number)) 2237 { 2238 if (alpha_noat_on) 2239 as_bad (_("macro requires $at register while noat in effect")); 2240 2241 lituse = load_expression (AXP_REG_AT, &tok[1], 2242 &basereg, &newtok[1], (const char *) opname); 2243 } 2244 else 2245 { 2246 newtok[1] = tok[1]; 2247 lituse = 0; 2248 } 2249 2250 newtok[0] = tok[0]; 2251 set_tok_preg (newtok[2], basereg); 2252 2253 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn); 2254 2255 if (lituse) 2256 { 2257 gas_assert (insn.nfixups < MAX_INSN_FIXUPS); 2258 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE; 2259 insn.fixups[insn.nfixups].exp.X_op = O_absent; 2260 insn.nfixups++; 2261 insn.sequence = lituse; 2262 } 2263 2264 emit_insn (&insn); 2265 } 2266 2267 /* Load a half-word or byte as an unsigned value. */ 2268 2269 static void 2270 emit_ldXu (const expressionS *tok, 2271 int ntok, 2272 const void * vlgsize) 2273 { 2274 if (alpha_target & AXP_OPCODE_BWX) 2275 emit_ir_load (tok, ntok, ldXu_op[(long) vlgsize]); 2276 else 2277 { 2278 expressionS newtok[3]; 2279 struct alpha_insn insn; 2280 int basereg; 2281 long lituse; 2282 2283 if (alpha_noat_on) 2284 as_bad (_("macro requires $at register while noat in effect")); 2285 2286 if (ntok == 2) 2287 basereg = (tok[1].X_op == O_constant 2288 ? AXP_REG_ZERO : alpha_gp_register); 2289 else 2290 basereg = tok[2].X_add_number; 2291 2292 /* Emit "lda $at, exp". */ 2293 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL, "lda"); 2294 2295 /* Emit "ldq_u targ, 0($at)". */ 2296 newtok[0] = tok[0]; 2297 set_tok_const (newtok[1], 0); 2298 set_tok_preg (newtok[2], basereg); 2299 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn); 2300 2301 if (lituse) 2302 { 2303 gas_assert (insn.nfixups < MAX_INSN_FIXUPS); 2304 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE; 2305 insn.fixups[insn.nfixups].exp.X_op = O_absent; 2306 insn.nfixups++; 2307 insn.sequence = lituse; 2308 } 2309 2310 emit_insn (&insn); 2311 2312 /* Emit "extXl targ, $at, targ". */ 2313 set_tok_reg (newtok[1], basereg); 2314 newtok[2] = newtok[0]; 2315 assemble_tokens_to_insn (extXl_op[(long) vlgsize], newtok, 3, &insn); 2316 2317 if (lituse) 2318 { 2319 gas_assert (insn.nfixups < MAX_INSN_FIXUPS); 2320 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF; 2321 insn.fixups[insn.nfixups].exp.X_op = O_absent; 2322 insn.nfixups++; 2323 insn.sequence = lituse; 2324 } 2325 2326 emit_insn (&insn); 2327 } 2328 } 2329 2330 /* Load a half-word or byte as a signed value. */ 2331 2332 static void 2333 emit_ldX (const expressionS *tok, 2334 int ntok, 2335 const void * vlgsize) 2336 { 2337 emit_ldXu (tok, ntok, vlgsize); 2338 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1); 2339 } 2340 2341 /* Load an integral value from an unaligned address as an unsigned 2342 value. */ 2343 2344 static void 2345 emit_uldXu (const expressionS *tok, 2346 int ntok, 2347 const void * vlgsize) 2348 { 2349 long lgsize = (long) vlgsize; 2350 expressionS newtok[3]; 2351 2352 if (alpha_noat_on) 2353 as_bad (_("macro requires $at register while noat in effect")); 2354 2355 /* Emit "lda $at, exp". */ 2356 memcpy (newtok, tok, sizeof (expressionS) * ntok); 2357 newtok[0].X_add_number = AXP_REG_AT; 2358 assemble_tokens ("lda", newtok, ntok, 1); 2359 2360 /* Emit "ldq_u $t9, 0($at)". */ 2361 set_tok_reg (newtok[0], AXP_REG_T9); 2362 set_tok_const (newtok[1], 0); 2363 set_tok_preg (newtok[2], AXP_REG_AT); 2364 assemble_tokens ("ldq_u", newtok, 3, 1); 2365 2366 /* Emit "ldq_u $t10, size-1($at)". */ 2367 set_tok_reg (newtok[0], AXP_REG_T10); 2368 set_tok_const (newtok[1], (1 << lgsize) - 1); 2369 assemble_tokens ("ldq_u", newtok, 3, 1); 2370 2371 /* Emit "extXl $t9, $at, $t9". */ 2372 set_tok_reg (newtok[0], AXP_REG_T9); 2373 set_tok_reg (newtok[1], AXP_REG_AT); 2374 set_tok_reg (newtok[2], AXP_REG_T9); 2375 assemble_tokens (extXl_op[lgsize], newtok, 3, 1); 2376 2377 /* Emit "extXh $t10, $at, $t10". */ 2378 set_tok_reg (newtok[0], AXP_REG_T10); 2379 set_tok_reg (newtok[2], AXP_REG_T10); 2380 assemble_tokens (extXh_op[lgsize], newtok, 3, 1); 2381 2382 /* Emit "or $t9, $t10, targ". */ 2383 set_tok_reg (newtok[0], AXP_REG_T9); 2384 set_tok_reg (newtok[1], AXP_REG_T10); 2385 newtok[2] = tok[0]; 2386 assemble_tokens ("or", newtok, 3, 1); 2387 } 2388 2389 /* Load an integral value from an unaligned address as a signed value. 2390 Note that quads should get funneled to the unsigned load since we 2391 don't have to do the sign extension. */ 2392 2393 static void 2394 emit_uldX (const expressionS *tok, 2395 int ntok, 2396 const void * vlgsize) 2397 { 2398 emit_uldXu (tok, ntok, vlgsize); 2399 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1); 2400 } 2401 2402 /* Implement the ldil macro. */ 2403 2404 static void 2405 emit_ldil (const expressionS *tok, 2406 int ntok, 2407 const void * unused ATTRIBUTE_UNUSED) 2408 { 2409 expressionS newtok[2]; 2410 2411 memcpy (newtok, tok, sizeof (newtok)); 2412 newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number); 2413 2414 assemble_tokens ("lda", newtok, ntok, 1); 2415 } 2416 2417 /* Store a half-word or byte. */ 2418 2419 static void 2420 emit_stX (const expressionS *tok, 2421 int ntok, 2422 const void * vlgsize) 2423 { 2424 int lgsize = (int) (long) vlgsize; 2425 2426 if (alpha_target & AXP_OPCODE_BWX) 2427 emit_loadstore (tok, ntok, stX_op[lgsize]); 2428 else 2429 { 2430 expressionS newtok[3]; 2431 struct alpha_insn insn; 2432 int basereg; 2433 long lituse; 2434 2435 if (alpha_noat_on) 2436 as_bad (_("macro requires $at register while noat in effect")); 2437 2438 if (ntok == 2) 2439 basereg = (tok[1].X_op == O_constant 2440 ? AXP_REG_ZERO : alpha_gp_register); 2441 else 2442 basereg = tok[2].X_add_number; 2443 2444 /* Emit "lda $at, exp". */ 2445 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL, "lda"); 2446 2447 /* Emit "ldq_u $t9, 0($at)". */ 2448 set_tok_reg (newtok[0], AXP_REG_T9); 2449 set_tok_const (newtok[1], 0); 2450 set_tok_preg (newtok[2], basereg); 2451 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn); 2452 2453 if (lituse) 2454 { 2455 gas_assert (insn.nfixups < MAX_INSN_FIXUPS); 2456 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE; 2457 insn.fixups[insn.nfixups].exp.X_op = O_absent; 2458 insn.nfixups++; 2459 insn.sequence = lituse; 2460 } 2461 2462 emit_insn (&insn); 2463 2464 /* Emit "insXl src, $at, $t10". */ 2465 newtok[0] = tok[0]; 2466 set_tok_reg (newtok[1], basereg); 2467 set_tok_reg (newtok[2], AXP_REG_T10); 2468 assemble_tokens_to_insn (insXl_op[lgsize], newtok, 3, &insn); 2469 2470 if (lituse) 2471 { 2472 gas_assert (insn.nfixups < MAX_INSN_FIXUPS); 2473 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF; 2474 insn.fixups[insn.nfixups].exp.X_op = O_absent; 2475 insn.nfixups++; 2476 insn.sequence = lituse; 2477 } 2478 2479 emit_insn (&insn); 2480 2481 /* Emit "mskXl $t9, $at, $t9". */ 2482 set_tok_reg (newtok[0], AXP_REG_T9); 2483 newtok[2] = newtok[0]; 2484 assemble_tokens_to_insn (mskXl_op[lgsize], newtok, 3, &insn); 2485 2486 if (lituse) 2487 { 2488 gas_assert (insn.nfixups < MAX_INSN_FIXUPS); 2489 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF; 2490 insn.fixups[insn.nfixups].exp.X_op = O_absent; 2491 insn.nfixups++; 2492 insn.sequence = lituse; 2493 } 2494 2495 emit_insn (&insn); 2496 2497 /* Emit "or $t9, $t10, $t9". */ 2498 set_tok_reg (newtok[1], AXP_REG_T10); 2499 assemble_tokens ("or", newtok, 3, 1); 2500 2501 /* Emit "stq_u $t9, 0($at). */ 2502 set_tok_const(newtok[1], 0); 2503 set_tok_preg (newtok[2], AXP_REG_AT); 2504 assemble_tokens_to_insn ("stq_u", newtok, 3, &insn); 2505 2506 if (lituse) 2507 { 2508 gas_assert (insn.nfixups < MAX_INSN_FIXUPS); 2509 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE; 2510 insn.fixups[insn.nfixups].exp.X_op = O_absent; 2511 insn.nfixups++; 2512 insn.sequence = lituse; 2513 } 2514 2515 emit_insn (&insn); 2516 } 2517 } 2518 2519 /* Store an integer to an unaligned address. */ 2520 2521 static void 2522 emit_ustX (const expressionS *tok, 2523 int ntok, 2524 const void * vlgsize) 2525 { 2526 int lgsize = (int) (long) vlgsize; 2527 expressionS newtok[3]; 2528 2529 /* Emit "lda $at, exp". */ 2530 memcpy (newtok, tok, sizeof (expressionS) * ntok); 2531 newtok[0].X_add_number = AXP_REG_AT; 2532 assemble_tokens ("lda", newtok, ntok, 1); 2533 2534 /* Emit "ldq_u $9, 0($at)". */ 2535 set_tok_reg (newtok[0], AXP_REG_T9); 2536 set_tok_const (newtok[1], 0); 2537 set_tok_preg (newtok[2], AXP_REG_AT); 2538 assemble_tokens ("ldq_u", newtok, 3, 1); 2539 2540 /* Emit "ldq_u $10, size-1($at)". */ 2541 set_tok_reg (newtok[0], AXP_REG_T10); 2542 set_tok_const (newtok[1], (1 << lgsize) - 1); 2543 assemble_tokens ("ldq_u", newtok, 3, 1); 2544 2545 /* Emit "insXl src, $at, $t11". */ 2546 newtok[0] = tok[0]; 2547 set_tok_reg (newtok[1], AXP_REG_AT); 2548 set_tok_reg (newtok[2], AXP_REG_T11); 2549 assemble_tokens (insXl_op[lgsize], newtok, 3, 1); 2550 2551 /* Emit "insXh src, $at, $t12". */ 2552 set_tok_reg (newtok[2], AXP_REG_T12); 2553 assemble_tokens (insXh_op[lgsize], newtok, 3, 1); 2554 2555 /* Emit "mskXl $t9, $at, $t9". */ 2556 set_tok_reg (newtok[0], AXP_REG_T9); 2557 newtok[2] = newtok[0]; 2558 assemble_tokens (mskXl_op[lgsize], newtok, 3, 1); 2559 2560 /* Emit "mskXh $t10, $at, $t10". */ 2561 set_tok_reg (newtok[0], AXP_REG_T10); 2562 newtok[2] = newtok[0]; 2563 assemble_tokens (mskXh_op[lgsize], newtok, 3, 1); 2564 2565 /* Emit "or $t9, $t11, $t9". */ 2566 set_tok_reg (newtok[0], AXP_REG_T9); 2567 set_tok_reg (newtok[1], AXP_REG_T11); 2568 newtok[2] = newtok[0]; 2569 assemble_tokens ("or", newtok, 3, 1); 2570 2571 /* Emit "or $t10, $t12, $t10". */ 2572 set_tok_reg (newtok[0], AXP_REG_T10); 2573 set_tok_reg (newtok[1], AXP_REG_T12); 2574 newtok[2] = newtok[0]; 2575 assemble_tokens ("or", newtok, 3, 1); 2576 2577 /* Emit "stq_u $t10, size-1($at)". */ 2578 set_tok_reg (newtok[0], AXP_REG_T10); 2579 set_tok_const (newtok[1], (1 << lgsize) - 1); 2580 set_tok_preg (newtok[2], AXP_REG_AT); 2581 assemble_tokens ("stq_u", newtok, 3, 1); 2582 2583 /* Emit "stq_u $t9, 0($at)". */ 2584 set_tok_reg (newtok[0], AXP_REG_T9); 2585 set_tok_const (newtok[1], 0); 2586 assemble_tokens ("stq_u", newtok, 3, 1); 2587 } 2588 2589 /* Sign extend a half-word or byte. The 32-bit sign extend is 2590 implemented as "addl $31, $r, $t" in the opcode table. */ 2591 2592 static void 2593 emit_sextX (const expressionS *tok, 2594 int ntok, 2595 const void * vlgsize) 2596 { 2597 long lgsize = (long) vlgsize; 2598 2599 if (alpha_target & AXP_OPCODE_BWX) 2600 assemble_tokens (sextX_op[lgsize], tok, ntok, 0); 2601 else 2602 { 2603 int bitshift = 64 - 8 * (1 << lgsize); 2604 expressionS newtok[3]; 2605 2606 /* Emit "sll src,bits,dst". */ 2607 newtok[0] = tok[0]; 2608 set_tok_const (newtok[1], bitshift); 2609 newtok[2] = tok[ntok - 1]; 2610 assemble_tokens ("sll", newtok, 3, 1); 2611 2612 /* Emit "sra dst,bits,dst". */ 2613 newtok[0] = newtok[2]; 2614 assemble_tokens ("sra", newtok, 3, 1); 2615 } 2616 } 2617 2618 /* Implement the division and modulus macros. */ 2619 2620 #ifdef OBJ_EVAX 2621 2622 /* Make register usage like in normal procedure call. 2623 Don't clobber PV and RA. */ 2624 2625 static void 2626 emit_division (const expressionS *tok, 2627 int ntok, 2628 const void * symname) 2629 { 2630 /* DIVISION and MODULUS. Yech. 2631 2632 Convert 2633 OP x,y,result 2634 to 2635 mov x,R16 # if x != R16 2636 mov y,R17 # if y != R17 2637 lda AT,__OP 2638 jsr AT,(AT),0 2639 mov R0,result 2640 2641 with appropriate optimizations if R0,R16,R17 are the registers 2642 specified by the compiler. */ 2643 2644 int xr, yr, rr; 2645 symbolS *sym; 2646 expressionS newtok[3]; 2647 2648 xr = regno (tok[0].X_add_number); 2649 yr = regno (tok[1].X_add_number); 2650 2651 if (ntok < 3) 2652 rr = xr; 2653 else 2654 rr = regno (tok[2].X_add_number); 2655 2656 /* Move the operands into the right place. */ 2657 if (yr == AXP_REG_R16 && xr == AXP_REG_R17) 2658 { 2659 /* They are in exactly the wrong order -- swap through AT. */ 2660 if (alpha_noat_on) 2661 as_bad (_("macro requires $at register while noat in effect")); 2662 2663 set_tok_reg (newtok[0], AXP_REG_R16); 2664 set_tok_reg (newtok[1], AXP_REG_AT); 2665 assemble_tokens ("mov", newtok, 2, 1); 2666 2667 set_tok_reg (newtok[0], AXP_REG_R17); 2668 set_tok_reg (newtok[1], AXP_REG_R16); 2669 assemble_tokens ("mov", newtok, 2, 1); 2670 2671 set_tok_reg (newtok[0], AXP_REG_AT); 2672 set_tok_reg (newtok[1], AXP_REG_R17); 2673 assemble_tokens ("mov", newtok, 2, 1); 2674 } 2675 else 2676 { 2677 if (yr == AXP_REG_R16) 2678 { 2679 set_tok_reg (newtok[0], AXP_REG_R16); 2680 set_tok_reg (newtok[1], AXP_REG_R17); 2681 assemble_tokens ("mov", newtok, 2, 1); 2682 } 2683 2684 if (xr != AXP_REG_R16) 2685 { 2686 set_tok_reg (newtok[0], xr); 2687 set_tok_reg (newtok[1], AXP_REG_R16); 2688 assemble_tokens ("mov", newtok, 2, 1); 2689 } 2690 2691 if (yr != AXP_REG_R16 && yr != AXP_REG_R17) 2692 { 2693 set_tok_reg (newtok[0], yr); 2694 set_tok_reg (newtok[1], AXP_REG_R17); 2695 assemble_tokens ("mov", newtok, 2, 1); 2696 } 2697 } 2698 2699 sym = symbol_find_or_make ((const char *) symname); 2700 2701 set_tok_reg (newtok[0], AXP_REG_AT); 2702 set_tok_sym (newtok[1], sym, 0); 2703 assemble_tokens ("lda", newtok, 2, 1); 2704 2705 /* Call the division routine. */ 2706 set_tok_reg (newtok[0], AXP_REG_AT); 2707 set_tok_cpreg (newtok[1], AXP_REG_AT); 2708 set_tok_const (newtok[2], 0); 2709 assemble_tokens ("jsr", newtok, 3, 1); 2710 2711 /* Move the result to the right place. */ 2712 if (rr != AXP_REG_R0) 2713 { 2714 set_tok_reg (newtok[0], AXP_REG_R0); 2715 set_tok_reg (newtok[1], rr); 2716 assemble_tokens ("mov", newtok, 2, 1); 2717 } 2718 } 2719 2720 #else /* !OBJ_EVAX */ 2721 2722 static void 2723 emit_division (const expressionS *tok, 2724 int ntok, 2725 const void * symname) 2726 { 2727 /* DIVISION and MODULUS. Yech. 2728 Convert 2729 OP x,y,result 2730 to 2731 lda pv,__OP 2732 mov x,t10 2733 mov y,t11 2734 jsr t9,(pv),__OP 2735 mov t12,result 2736 2737 with appropriate optimizations if t10,t11,t12 are the registers 2738 specified by the compiler. */ 2739 2740 int xr, yr, rr; 2741 symbolS *sym; 2742 expressionS newtok[3]; 2743 2744 xr = regno (tok[0].X_add_number); 2745 yr = regno (tok[1].X_add_number); 2746 2747 if (ntok < 3) 2748 rr = xr; 2749 else 2750 rr = regno (tok[2].X_add_number); 2751 2752 sym = symbol_find_or_make ((const char *) symname); 2753 2754 /* Move the operands into the right place. */ 2755 if (yr == AXP_REG_T10 && xr == AXP_REG_T11) 2756 { 2757 /* They are in exactly the wrong order -- swap through AT. */ 2758 if (alpha_noat_on) 2759 as_bad (_("macro requires $at register while noat in effect")); 2760 2761 set_tok_reg (newtok[0], AXP_REG_T10); 2762 set_tok_reg (newtok[1], AXP_REG_AT); 2763 assemble_tokens ("mov", newtok, 2, 1); 2764 2765 set_tok_reg (newtok[0], AXP_REG_T11); 2766 set_tok_reg (newtok[1], AXP_REG_T10); 2767 assemble_tokens ("mov", newtok, 2, 1); 2768 2769 set_tok_reg (newtok[0], AXP_REG_AT); 2770 set_tok_reg (newtok[1], AXP_REG_T11); 2771 assemble_tokens ("mov", newtok, 2, 1); 2772 } 2773 else 2774 { 2775 if (yr == AXP_REG_T10) 2776 { 2777 set_tok_reg (newtok[0], AXP_REG_T10); 2778 set_tok_reg (newtok[1], AXP_REG_T11); 2779 assemble_tokens ("mov", newtok, 2, 1); 2780 } 2781 2782 if (xr != AXP_REG_T10) 2783 { 2784 set_tok_reg (newtok[0], xr); 2785 set_tok_reg (newtok[1], AXP_REG_T10); 2786 assemble_tokens ("mov", newtok, 2, 1); 2787 } 2788 2789 if (yr != AXP_REG_T10 && yr != AXP_REG_T11) 2790 { 2791 set_tok_reg (newtok[0], yr); 2792 set_tok_reg (newtok[1], AXP_REG_T11); 2793 assemble_tokens ("mov", newtok, 2, 1); 2794 } 2795 } 2796 2797 /* Call the division routine. */ 2798 set_tok_reg (newtok[0], AXP_REG_T9); 2799 set_tok_sym (newtok[1], sym, 0); 2800 assemble_tokens ("jsr", newtok, 2, 1); 2801 2802 /* Reload the GP register. */ 2803 #ifdef OBJ_AOUT 2804 FIXME 2805 #endif 2806 #if defined(OBJ_ECOFF) || defined(OBJ_ELF) 2807 set_tok_reg (newtok[0], alpha_gp_register); 2808 set_tok_const (newtok[1], 0); 2809 set_tok_preg (newtok[2], AXP_REG_T9); 2810 assemble_tokens ("ldgp", newtok, 3, 1); 2811 #endif 2812 2813 /* Move the result to the right place. */ 2814 if (rr != AXP_REG_T12) 2815 { 2816 set_tok_reg (newtok[0], AXP_REG_T12); 2817 set_tok_reg (newtok[1], rr); 2818 assemble_tokens ("mov", newtok, 2, 1); 2819 } 2820 } 2821 2822 #endif /* !OBJ_EVAX */ 2823 2824 /* The jsr and jmp macros differ from their instruction counterparts 2825 in that they can load the target address and default most 2826 everything. */ 2827 2828 static void 2829 emit_jsrjmp (const expressionS *tok, 2830 int ntok, 2831 const void * vopname) 2832 { 2833 const char *opname = (const char *) vopname; 2834 struct alpha_insn insn; 2835 expressionS newtok[3]; 2836 int r, tokidx = 0; 2837 long lituse = 0; 2838 2839 if (tokidx < ntok && tok[tokidx].X_op == O_register) 2840 r = regno (tok[tokidx++].X_add_number); 2841 else 2842 r = strcmp (opname, "jmp") == 0 ? AXP_REG_ZERO : AXP_REG_RA; 2843 2844 set_tok_reg (newtok[0], r); 2845 2846 if (tokidx < ntok && 2847 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister)) 2848 r = regno (tok[tokidx++].X_add_number); 2849 #ifdef OBJ_EVAX 2850 /* Keep register if jsr $n.<sym>. */ 2851 #else 2852 else 2853 { 2854 int basereg = alpha_gp_register; 2855 lituse = load_expression (r = AXP_REG_PV, &tok[tokidx], 2856 &basereg, NULL, opname); 2857 } 2858 #endif 2859 2860 set_tok_cpreg (newtok[1], r); 2861 2862 #ifndef OBJ_EVAX 2863 if (tokidx < ntok) 2864 newtok[2] = tok[tokidx]; 2865 else 2866 #endif 2867 set_tok_const (newtok[2], 0); 2868 2869 assemble_tokens_to_insn (opname, newtok, 3, &insn); 2870 2871 if (lituse) 2872 { 2873 gas_assert (insn.nfixups < MAX_INSN_FIXUPS); 2874 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_JSR; 2875 insn.fixups[insn.nfixups].exp.X_op = O_absent; 2876 insn.nfixups++; 2877 insn.sequence = lituse; 2878 } 2879 2880 #ifdef OBJ_EVAX 2881 if (alpha_flag_replace 2882 && r == AXP_REG_RA 2883 && tok[tokidx].X_add_symbol 2884 && alpha_linkage_symbol) 2885 { 2886 /* Create a BOH reloc for 'jsr $27,NAME'. */ 2887 const char *symname = S_GET_NAME (tok[tokidx].X_add_symbol); 2888 int symlen = strlen (symname); 2889 char *ensymname; 2890 2891 /* Build the entry name as 'NAME..en'. */ 2892 ensymname = (char *) alloca (symlen + 5); 2893 memcpy (ensymname, symname, symlen); 2894 memcpy (ensymname + symlen, "..en", 5); 2895 2896 gas_assert (insn.nfixups < MAX_INSN_FIXUPS); 2897 if (insn.nfixups > 0) 2898 { 2899 memmove (&insn.fixups[1], &insn.fixups[0], 2900 sizeof(struct alpha_fixup) * insn.nfixups); 2901 } 2902 2903 /* The fixup must be the same as the BFD_RELOC_ALPHA_NOP 2904 case in load_expression. See B.4.5.2 of the OpenVMS 2905 Linker Utility Manual. */ 2906 insn.fixups[0].reloc = BFD_RELOC_ALPHA_BOH; 2907 insn.fixups[0].exp.X_op = O_symbol; 2908 insn.fixups[0].exp.X_add_symbol = symbol_find_or_make (ensymname); 2909 insn.fixups[0].exp.X_add_number = 0; 2910 insn.fixups[0].xtrasym = alpha_linkage_symbol; 2911 insn.fixups[0].procsym = alpha_evax_proc->symbol; 2912 insn.nfixups++; 2913 alpha_linkage_symbol = 0; 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 name = input_line_pointer; 3507 c = get_symbol_end (); 3508 3509 /* Just after name is now '\0'. */ 3510 p = input_line_pointer; 3511 *p = c; 3512 3513 SKIP_WHITESPACE (); 3514 3515 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */ 3516 if (*input_line_pointer == ',') 3517 { 3518 input_line_pointer++; 3519 SKIP_WHITESPACE (); 3520 } 3521 if ((size = get_absolute_expression ()) < 0) 3522 { 3523 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size); 3524 ignore_rest_of_line (); 3525 return; 3526 } 3527 3528 *p = 0; 3529 symbolP = symbol_find_or_make (name); 3530 *p = c; 3531 3532 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP)) 3533 { 3534 as_bad (_("Ignoring attempt to re-define symbol")); 3535 ignore_rest_of_line (); 3536 return; 3537 } 3538 3539 #ifdef OBJ_EVAX 3540 if (*input_line_pointer != ',') 3541 temp = 8; /* Default alignment. */ 3542 else 3543 { 3544 input_line_pointer++; 3545 SKIP_WHITESPACE (); 3546 temp = get_absolute_expression (); 3547 } 3548 3549 /* ??? Unlike on OSF/1, the alignment factor is not in log units. */ 3550 while ((temp >>= 1) != 0) 3551 ++log_align; 3552 3553 if (*input_line_pointer == ',') 3554 { 3555 /* Extended form of the directive 3556 3557 .comm symbol, size, alignment, section 3558 3559 where the "common" semantics is transferred to the section. 3560 The symbol is effectively an alias for the section name. */ 3561 3562 segT sec; 3563 char *sec_name; 3564 symbolS *sec_symbol; 3565 segT current_seg = now_seg; 3566 subsegT current_subseg = now_subseg; 3567 int cur_size; 3568 3569 input_line_pointer++; 3570 SKIP_WHITESPACE (); 3571 sec_name = s_alpha_section_name (); 3572 sec_symbol = symbol_find_or_make (sec_name); 3573 sec = subseg_new (sec_name, 0); 3574 S_SET_SEGMENT (sec_symbol, sec); 3575 symbol_get_bfdsym (sec_symbol)->flags |= BSF_SECTION_SYM; 3576 bfd_vms_set_section_flags (stdoutput, sec, 0, 3577 EGPS__V_OVR | EGPS__V_GBL | EGPS__V_NOMOD); 3578 record_alignment (sec, log_align); 3579 3580 /* Reuse stab_string_size to store the size of the section. */ 3581 cur_size = seg_info (sec)->stabu.stab_string_size; 3582 if ((int) size > cur_size) 3583 { 3584 char *pfrag 3585 = frag_var (rs_fill, 1, 1, (relax_substateT)0, NULL, 3586 (valueT)size - (valueT)cur_size, NULL); 3587 *pfrag = 0; 3588 seg_info (sec)->stabu.stab_string_size = (int)size; 3589 } 3590 3591 S_SET_SEGMENT (symbolP, sec); 3592 3593 subseg_set (current_seg, current_subseg); 3594 } 3595 else 3596 { 3597 /* Regular form of the directive 3598 3599 .comm symbol, size, alignment 3600 3601 where the "common" semantics in on the symbol. 3602 These symbols are assembled in the .bss section. */ 3603 3604 char *pfrag; 3605 segT current_seg = now_seg; 3606 subsegT current_subseg = now_subseg; 3607 3608 subseg_set (bss_section, 1); 3609 frag_align (log_align, 0, 0); 3610 record_alignment (bss_section, log_align); 3611 3612 symbol_set_frag (symbolP, frag_now); 3613 pfrag = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP, 3614 size, NULL); 3615 *pfrag = 0; 3616 3617 S_SET_SEGMENT (symbolP, bss_section); 3618 3619 subseg_set (current_seg, current_subseg); 3620 } 3621 #endif 3622 3623 if (S_GET_VALUE (symbolP)) 3624 { 3625 if (S_GET_VALUE (symbolP) != (valueT) size) 3626 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."), 3627 S_GET_NAME (symbolP), 3628 (long) S_GET_VALUE (symbolP), 3629 (long) size); 3630 } 3631 else 3632 { 3633 #ifndef OBJ_EVAX 3634 S_SET_VALUE (symbolP, (valueT) size); 3635 #endif 3636 S_SET_EXTERNAL (symbolP); 3637 } 3638 3639 #ifndef OBJ_EVAX 3640 know (symbolP->sy_frag == &zero_address_frag); 3641 #endif 3642 demand_empty_rest_of_line (); 3643 } 3644 3645 #endif /* ! OBJ_ELF */ 3646 3647 #ifdef OBJ_ECOFF 3648 3649 /* Handle the .rdata pseudo-op. This is like the usual one, but it 3650 clears alpha_insn_label and restores auto alignment. */ 3651 3652 static void 3653 s_alpha_rdata (int ignore ATTRIBUTE_UNUSED) 3654 { 3655 get_absolute_expression (); 3656 subseg_new (".rdata", 0); 3657 demand_empty_rest_of_line (); 3658 alpha_insn_label = NULL; 3659 alpha_auto_align_on = 1; 3660 alpha_current_align = 0; 3661 } 3662 3663 #endif 3664 3665 #ifdef OBJ_ECOFF 3666 3667 /* Handle the .sdata pseudo-op. This is like the usual one, but it 3668 clears alpha_insn_label and restores auto alignment. */ 3669 3670 static void 3671 s_alpha_sdata (int ignore ATTRIBUTE_UNUSED) 3672 { 3673 get_absolute_expression (); 3674 subseg_new (".sdata", 0); 3675 demand_empty_rest_of_line (); 3676 alpha_insn_label = NULL; 3677 alpha_auto_align_on = 1; 3678 alpha_current_align = 0; 3679 } 3680 #endif 3681 3682 #ifdef OBJ_ELF 3683 struct alpha_elf_frame_data 3684 { 3685 symbolS *func_sym; 3686 symbolS *func_end_sym; 3687 symbolS *prologue_sym; 3688 unsigned int mask; 3689 unsigned int fmask; 3690 int fp_regno; 3691 int ra_regno; 3692 offsetT frame_size; 3693 offsetT mask_offset; 3694 offsetT fmask_offset; 3695 3696 struct alpha_elf_frame_data *next; 3697 }; 3698 3699 static struct alpha_elf_frame_data *all_frame_data; 3700 static struct alpha_elf_frame_data **plast_frame_data = &all_frame_data; 3701 static struct alpha_elf_frame_data *cur_frame_data; 3702 3703 /* Handle the .section pseudo-op. This is like the usual one, but it 3704 clears alpha_insn_label and restores auto alignment. */ 3705 3706 static void 3707 s_alpha_section (int ignore ATTRIBUTE_UNUSED) 3708 { 3709 obj_elf_section (ignore); 3710 3711 alpha_insn_label = NULL; 3712 alpha_auto_align_on = 1; 3713 alpha_current_align = 0; 3714 } 3715 3716 static void 3717 s_alpha_ent (int dummy ATTRIBUTE_UNUSED) 3718 { 3719 if (ECOFF_DEBUGGING) 3720 ecoff_directive_ent (0); 3721 else 3722 { 3723 char *name, name_end; 3724 name = input_line_pointer; 3725 name_end = get_symbol_end (); 3726 3727 if (! is_name_beginner (*name)) 3728 { 3729 as_warn (_(".ent directive has no name")); 3730 *input_line_pointer = name_end; 3731 } 3732 else 3733 { 3734 symbolS *sym; 3735 3736 if (cur_frame_data) 3737 as_warn (_("nested .ent directives")); 3738 3739 sym = symbol_find_or_make (name); 3740 symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION; 3741 3742 cur_frame_data = (struct alpha_elf_frame_data *) 3743 calloc (1, sizeof (*cur_frame_data)); 3744 cur_frame_data->func_sym = sym; 3745 3746 /* Provide sensible defaults. */ 3747 cur_frame_data->fp_regno = 30; /* sp */ 3748 cur_frame_data->ra_regno = 26; /* ra */ 3749 3750 *plast_frame_data = cur_frame_data; 3751 plast_frame_data = &cur_frame_data->next; 3752 3753 /* The .ent directive is sometimes followed by a number. Not sure 3754 what it really means, but ignore it. */ 3755 *input_line_pointer = name_end; 3756 SKIP_WHITESPACE (); 3757 if (*input_line_pointer == ',') 3758 { 3759 input_line_pointer++; 3760 SKIP_WHITESPACE (); 3761 } 3762 if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-') 3763 (void) get_absolute_expression (); 3764 } 3765 demand_empty_rest_of_line (); 3766 } 3767 } 3768 3769 static void 3770 s_alpha_end (int dummy ATTRIBUTE_UNUSED) 3771 { 3772 if (ECOFF_DEBUGGING) 3773 ecoff_directive_end (0); 3774 else 3775 { 3776 char *name, name_end; 3777 name = input_line_pointer; 3778 name_end = get_symbol_end (); 3779 3780 if (! is_name_beginner (*name)) 3781 { 3782 as_warn (_(".end directive has no name")); 3783 *input_line_pointer = name_end; 3784 } 3785 else 3786 { 3787 symbolS *sym; 3788 3789 sym = symbol_find (name); 3790 if (!cur_frame_data) 3791 as_warn (_(".end directive without matching .ent")); 3792 else if (sym != cur_frame_data->func_sym) 3793 as_warn (_(".end directive names different symbol than .ent")); 3794 3795 /* Create an expression to calculate the size of the function. */ 3796 if (sym && cur_frame_data) 3797 { 3798 OBJ_SYMFIELD_TYPE *obj = symbol_get_obj (sym); 3799 expressionS *exp = (expressionS *) xmalloc (sizeof (expressionS)); 3800 3801 obj->size = exp; 3802 exp->X_op = O_subtract; 3803 exp->X_add_symbol = symbol_temp_new_now (); 3804 exp->X_op_symbol = sym; 3805 exp->X_add_number = 0; 3806 3807 cur_frame_data->func_end_sym = exp->X_add_symbol; 3808 } 3809 3810 cur_frame_data = NULL; 3811 3812 *input_line_pointer = name_end; 3813 } 3814 demand_empty_rest_of_line (); 3815 } 3816 } 3817 3818 static void 3819 s_alpha_mask (int fp) 3820 { 3821 if (ECOFF_DEBUGGING) 3822 { 3823 if (fp) 3824 ecoff_directive_fmask (0); 3825 else 3826 ecoff_directive_mask (0); 3827 } 3828 else 3829 { 3830 long val; 3831 offsetT offset; 3832 3833 if (!cur_frame_data) 3834 { 3835 if (fp) 3836 as_warn (_(".fmask outside of .ent")); 3837 else 3838 as_warn (_(".mask outside of .ent")); 3839 discard_rest_of_line (); 3840 return; 3841 } 3842 3843 if (get_absolute_expression_and_terminator (&val) != ',') 3844 { 3845 if (fp) 3846 as_warn (_("bad .fmask directive")); 3847 else 3848 as_warn (_("bad .mask directive")); 3849 --input_line_pointer; 3850 discard_rest_of_line (); 3851 return; 3852 } 3853 3854 offset = get_absolute_expression (); 3855 demand_empty_rest_of_line (); 3856 3857 if (fp) 3858 { 3859 cur_frame_data->fmask = val; 3860 cur_frame_data->fmask_offset = offset; 3861 } 3862 else 3863 { 3864 cur_frame_data->mask = val; 3865 cur_frame_data->mask_offset = offset; 3866 } 3867 } 3868 } 3869 3870 static void 3871 s_alpha_frame (int dummy ATTRIBUTE_UNUSED) 3872 { 3873 if (ECOFF_DEBUGGING) 3874 ecoff_directive_frame (0); 3875 else 3876 { 3877 long val; 3878 3879 if (!cur_frame_data) 3880 { 3881 as_warn (_(".frame outside of .ent")); 3882 discard_rest_of_line (); 3883 return; 3884 } 3885 3886 cur_frame_data->fp_regno = tc_get_register (1); 3887 3888 SKIP_WHITESPACE (); 3889 if (*input_line_pointer++ != ',' 3890 || get_absolute_expression_and_terminator (&val) != ',') 3891 { 3892 as_warn (_("bad .frame directive")); 3893 --input_line_pointer; 3894 discard_rest_of_line (); 3895 return; 3896 } 3897 cur_frame_data->frame_size = val; 3898 3899 cur_frame_data->ra_regno = tc_get_register (0); 3900 3901 /* Next comes the "offset of saved $a0 from $sp". In gcc terms 3902 this is current_function_pretend_args_size. There's no place 3903 to put this value, so ignore it. */ 3904 s_ignore (42); 3905 } 3906 } 3907 3908 static void 3909 s_alpha_prologue (int ignore ATTRIBUTE_UNUSED) 3910 { 3911 symbolS *sym; 3912 int arg; 3913 3914 arg = get_absolute_expression (); 3915 demand_empty_rest_of_line (); 3916 alpha_prologue_label = symbol_new 3917 (FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (), frag_now); 3918 3919 if (ECOFF_DEBUGGING) 3920 sym = ecoff_get_cur_proc_sym (); 3921 else 3922 sym = cur_frame_data ? cur_frame_data->func_sym : NULL; 3923 3924 if (sym == NULL) 3925 { 3926 as_bad (_(".prologue directive without a preceding .ent directive")); 3927 return; 3928 } 3929 3930 switch (arg) 3931 { 3932 case 0: /* No PV required. */ 3933 S_SET_OTHER (sym, STO_ALPHA_NOPV 3934 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD)); 3935 break; 3936 case 1: /* Std GP load. */ 3937 S_SET_OTHER (sym, STO_ALPHA_STD_GPLOAD 3938 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD)); 3939 break; 3940 case 2: /* Non-std use of PV. */ 3941 break; 3942 3943 default: 3944 as_bad (_("Invalid argument %d to .prologue."), arg); 3945 break; 3946 } 3947 3948 if (cur_frame_data) 3949 cur_frame_data->prologue_sym = symbol_temp_new_now (); 3950 } 3951 3952 static char *first_file_directive; 3953 3954 static void 3955 s_alpha_file (int ignore ATTRIBUTE_UNUSED) 3956 { 3957 /* Save the first .file directive we see, so that we can change our 3958 minds about whether ecoff debugging should or shouldn't be enabled. */ 3959 if (alpha_flag_mdebug < 0 && ! first_file_directive) 3960 { 3961 char *start = input_line_pointer; 3962 size_t len; 3963 3964 discard_rest_of_line (); 3965 3966 len = input_line_pointer - start; 3967 first_file_directive = (char *) xmalloc (len + 1); 3968 memcpy (first_file_directive, start, len); 3969 first_file_directive[len] = '\0'; 3970 3971 input_line_pointer = start; 3972 } 3973 3974 if (ECOFF_DEBUGGING) 3975 ecoff_directive_file (0); 3976 else 3977 dwarf2_directive_file (0); 3978 } 3979 3980 static void 3981 s_alpha_loc (int ignore ATTRIBUTE_UNUSED) 3982 { 3983 if (ECOFF_DEBUGGING) 3984 ecoff_directive_loc (0); 3985 else 3986 dwarf2_directive_loc (0); 3987 } 3988 3989 static void 3990 s_alpha_stab (int n) 3991 { 3992 /* If we've been undecided about mdebug, make up our minds in favour. */ 3993 if (alpha_flag_mdebug < 0) 3994 { 3995 segT sec = subseg_new (".mdebug", 0); 3996 bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY); 3997 bfd_set_section_alignment (stdoutput, sec, 3); 3998 3999 ecoff_read_begin_hook (); 4000 4001 if (first_file_directive) 4002 { 4003 char *save_ilp = input_line_pointer; 4004 input_line_pointer = first_file_directive; 4005 ecoff_directive_file (0); 4006 input_line_pointer = save_ilp; 4007 free (first_file_directive); 4008 } 4009 4010 alpha_flag_mdebug = 1; 4011 } 4012 s_stab (n); 4013 } 4014 4015 static void 4016 s_alpha_coff_wrapper (int which) 4017 { 4018 static void (* const fns[]) (int) = { 4019 ecoff_directive_begin, 4020 ecoff_directive_bend, 4021 ecoff_directive_def, 4022 ecoff_directive_dim, 4023 ecoff_directive_endef, 4024 ecoff_directive_scl, 4025 ecoff_directive_tag, 4026 ecoff_directive_val, 4027 }; 4028 4029 gas_assert (which >= 0 && which < (int) (sizeof (fns)/sizeof (*fns))); 4030 4031 if (ECOFF_DEBUGGING) 4032 (*fns[which]) (0); 4033 else 4034 { 4035 as_bad (_("ECOFF debugging is disabled.")); 4036 ignore_rest_of_line (); 4037 } 4038 } 4039 4040 /* Called at the end of assembly. Here we emit unwind info for frames 4041 unless the compiler has done it for us. */ 4042 4043 void 4044 alpha_elf_md_end (void) 4045 { 4046 struct alpha_elf_frame_data *p; 4047 4048 if (cur_frame_data) 4049 as_warn (_(".ent directive without matching .end")); 4050 4051 /* If someone has generated the unwind info themselves, great. */ 4052 if (bfd_get_section_by_name (stdoutput, ".eh_frame") != NULL) 4053 return; 4054 4055 /* ??? In theory we could look for functions for which we have 4056 generated unwind info via CFI directives, and those we have not. 4057 Those we have not could still get their unwind info from here. 4058 For now, do nothing if we've seen any CFI directives. Note that 4059 the above test will not trigger, as we've not emitted data yet. */ 4060 if (all_fde_data != NULL) 4061 return; 4062 4063 /* Generate .eh_frame data for the unwind directives specified. */ 4064 for (p = all_frame_data; p ; p = p->next) 4065 if (p->prologue_sym) 4066 { 4067 /* Create a temporary symbol at the same location as our 4068 function symbol. This prevents problems with globals. */ 4069 cfi_new_fde (symbol_temp_new (S_GET_SEGMENT (p->func_sym), 4070 S_GET_VALUE (p->func_sym), 4071 symbol_get_frag (p->func_sym))); 4072 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 = input_line_pointer; 4138 name_end = get_symbol_end (); 4139 4140 if (! is_name_beginner (*name)) 4141 { 4142 as_bad (_(".usepv directive has no name")); 4143 *input_line_pointer = name_end; 4144 ignore_rest_of_line (); 4145 return; 4146 } 4147 4148 sym = symbol_find_or_make (name); 4149 *input_line_pointer++ = name_end; 4150 4151 if (name_end != ',') 4152 { 4153 as_bad (_(".usepv directive has no type")); 4154 ignore_rest_of_line (); 4155 return; 4156 } 4157 4158 SKIP_WHITESPACE (); 4159 which = input_line_pointer; 4160 which_end = get_symbol_end (); 4161 4162 if (strcmp (which, "no") == 0) 4163 other = STO_ALPHA_NOPV; 4164 else if (strcmp (which, "std") == 0) 4165 other = STO_ALPHA_STD_GPLOAD; 4166 else 4167 { 4168 as_bad (_("unknown argument for .usepv")); 4169 other = 0; 4170 } 4171 4172 *input_line_pointer = which_end; 4173 demand_empty_rest_of_line (); 4174 4175 S_SET_OTHER (sym, other | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD)); 4176 } 4177 #endif /* OBJ_ELF */ 4178 4179 /* Standard calling conventions leaves the CFA at $30 on entry. */ 4180 4181 void 4182 alpha_cfi_frame_initial_instructions (void) 4183 { 4184 cfi_add_CFA_def_cfa_register (30); 4185 } 4186 4187 #ifdef OBJ_EVAX 4188 4189 /* Get name of section. */ 4190 static char * 4191 s_alpha_section_name (void) 4192 { 4193 char *name; 4194 4195 SKIP_WHITESPACE (); 4196 if (*input_line_pointer == '"') 4197 { 4198 int dummy; 4199 4200 name = demand_copy_C_string (&dummy); 4201 if (name == NULL) 4202 { 4203 ignore_rest_of_line (); 4204 return NULL; 4205 } 4206 } 4207 else 4208 { 4209 char *end = input_line_pointer; 4210 4211 while (0 == strchr ("\n\t,; ", *end)) 4212 end++; 4213 if (end == input_line_pointer) 4214 { 4215 as_warn (_("missing name")); 4216 ignore_rest_of_line (); 4217 return NULL; 4218 } 4219 4220 name = xmalloc (end - input_line_pointer + 1); 4221 memcpy (name, input_line_pointer, end - input_line_pointer); 4222 name[end - input_line_pointer] = '\0'; 4223 input_line_pointer = end; 4224 } 4225 SKIP_WHITESPACE (); 4226 return name; 4227 } 4228 4229 /* Put clear/set flags in one flagword. The LSBs are flags to be set, 4230 the MSBs are the flags to be cleared. */ 4231 4232 #define EGPS__V_NO_SHIFT 16 4233 #define EGPS__V_MASK 0xffff 4234 4235 /* Parse one VMS section flag. */ 4236 4237 static flagword 4238 s_alpha_section_word (char *str, size_t len) 4239 { 4240 int no = 0; 4241 flagword flag = 0; 4242 4243 if (len == 5 && strncmp (str, "NO", 2) == 0) 4244 { 4245 no = 1; 4246 str += 2; 4247 len -= 2; 4248 } 4249 4250 if (len == 3) 4251 { 4252 if (strncmp (str, "PIC", 3) == 0) 4253 flag = EGPS__V_PIC; 4254 else if (strncmp (str, "LIB", 3) == 0) 4255 flag = EGPS__V_LIB; 4256 else if (strncmp (str, "OVR", 3) == 0) 4257 flag = EGPS__V_OVR; 4258 else if (strncmp (str, "REL", 3) == 0) 4259 flag = EGPS__V_REL; 4260 else if (strncmp (str, "GBL", 3) == 0) 4261 flag = EGPS__V_GBL; 4262 else if (strncmp (str, "SHR", 3) == 0) 4263 flag = EGPS__V_SHR; 4264 else if (strncmp (str, "EXE", 3) == 0) 4265 flag = EGPS__V_EXE; 4266 else if (strncmp (str, "WRT", 3) == 0) 4267 flag = EGPS__V_WRT; 4268 else if (strncmp (str, "VEC", 3) == 0) 4269 flag = EGPS__V_VEC; 4270 else if (strncmp (str, "MOD", 3) == 0) 4271 { 4272 flag = no ? EGPS__V_NOMOD : EGPS__V_NOMOD << EGPS__V_NO_SHIFT; 4273 no = 0; 4274 } 4275 else if (strncmp (str, "COM", 3) == 0) 4276 flag = EGPS__V_COM; 4277 } 4278 4279 if (flag == 0) 4280 { 4281 char c = str[len]; 4282 str[len] = 0; 4283 as_warn (_("unknown section attribute %s"), str); 4284 str[len] = c; 4285 return 0; 4286 } 4287 4288 if (no) 4289 return flag << EGPS__V_NO_SHIFT; 4290 else 4291 return flag; 4292 } 4293 4294 /* Handle the section specific pseudo-op. */ 4295 4296 #define EVAX_SECTION_COUNT 5 4297 4298 static char *section_name[EVAX_SECTION_COUNT + 1] = 4299 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" }; 4300 4301 static void 4302 s_alpha_section (int secid) 4303 { 4304 char *name, *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 beg = input_line_pointer; 4327 c = get_symbol_end (); 4328 *input_line_pointer = c; 4329 4330 vms_flags |= s_alpha_section_word (beg, input_line_pointer - beg); 4331 4332 SKIP_WHITESPACE (); 4333 } 4334 while (*input_line_pointer++ == ','); 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 name = input_line_pointer; 4419 name_end = get_symbol_end (); 4420 4421 if (! is_name_beginner (*name)) 4422 { 4423 as_warn (_(".handler directive has no name")); 4424 *input_line_pointer = name_end; 4425 } 4426 else 4427 { 4428 symbolS *sym; 4429 4430 sym = symbol_find_or_make (name); 4431 symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION; 4432 alpha_evax_proc->handler = sym; 4433 *input_line_pointer = name_end; 4434 } 4435 } 4436 demand_empty_rest_of_line (); 4437 } 4438 4439 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */ 4440 4441 static void 4442 s_alpha_frame (int ignore ATTRIBUTE_UNUSED) 4443 { 4444 long val; 4445 int ra; 4446 4447 alpha_evax_proc->framereg = tc_get_register (1); 4448 4449 SKIP_WHITESPACE (); 4450 if (*input_line_pointer++ != ',' 4451 || get_absolute_expression_and_terminator (&val) != ',') 4452 { 4453 as_warn (_("Bad .frame directive 1./2. param")); 4454 --input_line_pointer; 4455 demand_empty_rest_of_line (); 4456 return; 4457 } 4458 4459 alpha_evax_proc->framesize = val; 4460 4461 ra = tc_get_register (1); 4462 if (ra != AXP_REG_RA) 4463 as_warn (_("Bad RA (%d) register for .frame"), ra); 4464 4465 SKIP_WHITESPACE (); 4466 if (*input_line_pointer++ != ',') 4467 { 4468 as_warn (_("Bad .frame directive 3./4. param")); 4469 --input_line_pointer; 4470 demand_empty_rest_of_line (); 4471 return; 4472 } 4473 alpha_evax_proc->rsa_offset = get_absolute_expression (); 4474 } 4475 4476 /* Parse .prologue. */ 4477 4478 static void 4479 s_alpha_prologue (int ignore ATTRIBUTE_UNUSED) 4480 { 4481 demand_empty_rest_of_line (); 4482 alpha_prologue_label = symbol_new 4483 (FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (), frag_now); 4484 } 4485 4486 /* Parse .pdesc <entry_name>,{null|stack|reg} 4487 Insert a procedure descriptor. */ 4488 4489 static void 4490 s_alpha_pdesc (int ignore ATTRIBUTE_UNUSED) 4491 { 4492 char *name; 4493 char name_end; 4494 char *p; 4495 expressionS exp; 4496 symbolS *entry_sym; 4497 const char *entry_sym_name; 4498 const char *pdesc_sym_name; 4499 fixS *fixp; 4500 size_t len; 4501 4502 if (now_seg != alpha_link_section) 4503 { 4504 as_bad (_(".pdesc directive not in link (.link) section")); 4505 return; 4506 } 4507 4508 expression (&exp); 4509 if (exp.X_op != O_symbol) 4510 { 4511 as_bad (_(".pdesc directive has no entry symbol")); 4512 return; 4513 } 4514 4515 entry_sym = make_expr_symbol (&exp); 4516 entry_sym_name = S_GET_NAME (entry_sym); 4517 4518 /* Strip "..en". */ 4519 len = strlen (entry_sym_name); 4520 if (len < 4 || strcmp (entry_sym_name + len - 4, "..en") != 0) 4521 { 4522 as_bad (_(".pdesc has a bad entry symbol")); 4523 return; 4524 } 4525 len -= 4; 4526 pdesc_sym_name = S_GET_NAME (alpha_evax_proc->symbol); 4527 4528 if (!alpha_evax_proc 4529 || !S_IS_DEFINED (alpha_evax_proc->symbol) 4530 || strlen (pdesc_sym_name) != len 4531 || memcmp (entry_sym_name, pdesc_sym_name, len) != 0) 4532 { 4533 as_fatal (_(".pdesc doesn't match with last .ent")); 4534 return; 4535 } 4536 4537 /* Define pdesc symbol. */ 4538 symbol_set_value_now (alpha_evax_proc->symbol); 4539 4540 /* Save bfd symbol of proc entry in function symbol. */ 4541 ((struct evax_private_udata_struct *) 4542 symbol_get_bfdsym (alpha_evax_proc->symbol)->udata.p)->enbsym 4543 = symbol_get_bfdsym (entry_sym); 4544 4545 SKIP_WHITESPACE (); 4546 if (*input_line_pointer++ != ',') 4547 { 4548 as_warn (_("No comma after .pdesc <entryname>")); 4549 demand_empty_rest_of_line (); 4550 return; 4551 } 4552 4553 SKIP_WHITESPACE (); 4554 name = input_line_pointer; 4555 name_end = get_symbol_end (); 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 as_fatal (_("unknown procedure kind")); 4569 demand_empty_rest_of_line (); 4570 return; 4571 } 4572 4573 *input_line_pointer = name_end; 4574 demand_empty_rest_of_line (); 4575 4576 #ifdef md_flush_pending_output 4577 md_flush_pending_output (); 4578 #endif 4579 4580 frag_align (3, 0, 0); 4581 p = frag_more (16); 4582 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0); 4583 fixp->fx_done = 1; 4584 4585 *p = alpha_evax_proc->pdsckind 4586 | ((alpha_evax_proc->framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0) 4587 | ((alpha_evax_proc->handler) ? PDSC_S_M_HANDLER_VALID : 0) 4588 | ((alpha_evax_proc->handler_data) ? PDSC_S_M_HANDLER_DATA_VALID : 0); 4589 *(p + 1) = PDSC_S_M_NATIVE | PDSC_S_M_NO_JACKET; 4590 4591 switch (alpha_evax_proc->pdsckind) 4592 { 4593 case PDSC_S_K_KIND_NULL: 4594 *(p + 2) = 0; 4595 *(p + 3) = 0; 4596 break; 4597 case PDSC_S_K_KIND_FP_REGISTER: 4598 *(p + 2) = alpha_evax_proc->fp_save; 4599 *(p + 3) = alpha_evax_proc->ra_save; 4600 break; 4601 case PDSC_S_K_KIND_FP_STACK: 4602 md_number_to_chars (p + 2, (valueT) alpha_evax_proc->rsa_offset, 2); 4603 break; 4604 default: /* impossible */ 4605 break; 4606 } 4607 4608 *(p + 4) = 0; 4609 *(p + 5) = alpha_evax_proc->type & 0x0f; 4610 4611 /* Signature offset. */ 4612 md_number_to_chars (p + 6, (valueT) 0, 2); 4613 4614 fix_new_exp (frag_now, p - frag_now->fr_literal + 8, 4615 8, &exp, 0, BFD_RELOC_64); 4616 4617 if (alpha_evax_proc->pdsckind == PDSC_S_K_KIND_NULL) 4618 return; 4619 4620 /* pdesc+16: Size. */ 4621 p = frag_more (6); 4622 md_number_to_chars (p, (valueT) alpha_evax_proc->framesize, 4); 4623 md_number_to_chars (p + 4, (valueT) 0, 2); 4624 4625 /* Entry length. */ 4626 exp.X_op = O_subtract; 4627 exp.X_add_symbol = alpha_prologue_label; 4628 exp.X_op_symbol = entry_sym; 4629 emit_expr (&exp, 2); 4630 4631 if (alpha_evax_proc->pdsckind == PDSC_S_K_KIND_FP_REGISTER) 4632 return; 4633 4634 /* pdesc+24: register masks. */ 4635 p = frag_more (8); 4636 md_number_to_chars (p, alpha_evax_proc->imask, 4); 4637 md_number_to_chars (p + 4, alpha_evax_proc->fmask, 4); 4638 4639 if (alpha_evax_proc->handler) 4640 { 4641 p = frag_more (8); 4642 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 4643 alpha_evax_proc->handler, 0, 0, BFD_RELOC_64); 4644 } 4645 4646 if (alpha_evax_proc->handler_data) 4647 { 4648 p = frag_more (8); 4649 md_number_to_chars (p, alpha_evax_proc->handler_data, 8); 4650 } 4651 } 4652 4653 /* Support for crash debug on vms. */ 4654 4655 static void 4656 s_alpha_name (int ignore ATTRIBUTE_UNUSED) 4657 { 4658 char *p; 4659 expressionS exp; 4660 4661 if (now_seg != alpha_link_section) 4662 { 4663 as_bad (_(".name directive not in link (.link) section")); 4664 demand_empty_rest_of_line (); 4665 return; 4666 } 4667 4668 expression (&exp); 4669 if (exp.X_op != O_symbol) 4670 { 4671 as_warn (_(".name directive has no symbol")); 4672 demand_empty_rest_of_line (); 4673 return; 4674 } 4675 4676 demand_empty_rest_of_line (); 4677 4678 #ifdef md_flush_pending_output 4679 md_flush_pending_output (); 4680 #endif 4681 4682 frag_align (3, 0, 0); 4683 p = frag_more (8); 4684 4685 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64); 4686 } 4687 4688 /* Parse .linkage <symbol>. 4689 Create a linkage pair relocation. */ 4690 4691 static void 4692 s_alpha_linkage (int ignore ATTRIBUTE_UNUSED) 4693 { 4694 expressionS exp; 4695 char *p; 4696 fixS *fixp; 4697 4698 #ifdef md_flush_pending_output 4699 md_flush_pending_output (); 4700 #endif 4701 4702 expression (&exp); 4703 if (exp.X_op != O_symbol) 4704 { 4705 as_fatal (_("No symbol after .linkage")); 4706 } 4707 else 4708 { 4709 struct alpha_linkage_fixups *linkage_fixup; 4710 4711 p = frag_more (LKP_S_K_SIZE); 4712 memset (p, 0, LKP_S_K_SIZE); 4713 fixp = fix_new_exp 4714 (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0, 4715 BFD_RELOC_ALPHA_LINKAGE); 4716 4717 if (alpha_insn_label == NULL) 4718 alpha_insn_label = symbol_new 4719 (FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (), frag_now); 4720 4721 /* Create a linkage element. */ 4722 linkage_fixup = (struct alpha_linkage_fixups *) 4723 xmalloc (sizeof (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 c; 4812 4813 c = get_symbol_end (); 4814 *input_line_pointer = c; 4815 demand_empty_rest_of_line (); 4816 alpha_evax_proc = NULL; 4817 } 4818 4819 static void 4820 s_alpha_file (int ignore ATTRIBUTE_UNUSED) 4821 { 4822 symbolS *s; 4823 int length; 4824 static char case_hack[32]; 4825 4826 sprintf (case_hack, "<CASE:%01d%01d>", 4827 alpha_flag_hash_long_names, alpha_flag_show_after_trunc); 4828 4829 s = symbol_find_or_make (case_hack); 4830 symbol_get_bfdsym (s)->flags |= BSF_FILE; 4831 4832 get_absolute_expression (); 4833 s = symbol_find_or_make (demand_copy_string (&length)); 4834 symbol_get_bfdsym (s)->flags |= BSF_FILE; 4835 demand_empty_rest_of_line (); 4836 } 4837 #endif /* OBJ_EVAX */ 4838 4839 /* Handle the .gprel32 pseudo op. */ 4840 4841 static void 4842 s_alpha_gprel32 (int ignore ATTRIBUTE_UNUSED) 4843 { 4844 expressionS e; 4845 char *p; 4846 4847 SKIP_WHITESPACE (); 4848 expression (&e); 4849 4850 #ifdef OBJ_ELF 4851 switch (e.X_op) 4852 { 4853 case O_constant: 4854 e.X_add_symbol = section_symbol (absolute_section); 4855 e.X_op = O_symbol; 4856 /* FALLTHRU */ 4857 case O_symbol: 4858 break; 4859 default: 4860 abort (); 4861 } 4862 #else 4863 #ifdef OBJ_ECOFF 4864 switch (e.X_op) 4865 { 4866 case O_constant: 4867 e.X_add_symbol = section_symbol (absolute_section); 4868 /* fall through */ 4869 case O_symbol: 4870 e.X_op = O_subtract; 4871 e.X_op_symbol = alpha_gp_symbol; 4872 break; 4873 default: 4874 abort (); 4875 } 4876 #endif 4877 #endif 4878 4879 if (alpha_auto_align_on && alpha_current_align < 2) 4880 alpha_align (2, (char *) NULL, alpha_insn_label, 0); 4881 if (alpha_current_align > 2) 4882 alpha_current_align = 2; 4883 alpha_insn_label = NULL; 4884 4885 p = frag_more (4); 4886 memset (p, 0, 4); 4887 fix_new_exp (frag_now, p - frag_now->fr_literal, 4, 4888 &e, 0, BFD_RELOC_GPREL32); 4889 } 4890 4891 /* Handle floating point allocation pseudo-ops. This is like the 4892 generic vresion, but it makes sure the current label, if any, is 4893 correctly aligned. */ 4894 4895 static void 4896 s_alpha_float_cons (int type) 4897 { 4898 int log_size; 4899 4900 switch (type) 4901 { 4902 default: 4903 case 'f': 4904 case 'F': 4905 log_size = 2; 4906 break; 4907 4908 case 'd': 4909 case 'D': 4910 case 'G': 4911 log_size = 3; 4912 break; 4913 4914 case 'x': 4915 case 'X': 4916 case 'p': 4917 case 'P': 4918 log_size = 4; 4919 break; 4920 } 4921 4922 if (alpha_auto_align_on && alpha_current_align < log_size) 4923 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0); 4924 if (alpha_current_align > log_size) 4925 alpha_current_align = log_size; 4926 alpha_insn_label = NULL; 4927 4928 float_cons (type); 4929 } 4930 4931 /* Handle the .proc pseudo op. We don't really do much with it except 4932 parse it. */ 4933 4934 static void 4935 s_alpha_proc (int is_static ATTRIBUTE_UNUSED) 4936 { 4937 char *name; 4938 char c; 4939 char *p; 4940 symbolS *symbolP; 4941 int temp; 4942 4943 /* Takes ".proc name,nargs". */ 4944 SKIP_WHITESPACE (); 4945 name = input_line_pointer; 4946 c = get_symbol_end (); 4947 p = input_line_pointer; 4948 symbolP = symbol_find_or_make (name); 4949 *p = c; 4950 SKIP_WHITESPACE (); 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 name = input_line_pointer; 4981 ch = get_symbol_end (); 4982 4983 s = name; 4984 if (s[0] == 'n' && s[1] == 'o') 4985 { 4986 yesno = 0; 4987 s += 2; 4988 } 4989 if (!strcmp ("reorder", s)) 4990 /* ignore */ ; 4991 else if (!strcmp ("at", s)) 4992 alpha_noat_on = !yesno; 4993 else if (!strcmp ("macro", s)) 4994 alpha_macros_on = yesno; 4995 else if (!strcmp ("move", s)) 4996 /* ignore */ ; 4997 else if (!strcmp ("volatile", s)) 4998 /* ignore */ ; 4999 else 5000 as_warn (_("Tried to .set unrecognized mode `%s'"), name); 5001 5002 *input_line_pointer = ch; 5003 demand_empty_rest_of_line (); 5004 } 5005 5006 /* Handle the .base pseudo op. This changes the assembler's notion of 5007 the $gp register. */ 5008 5009 static void 5010 s_alpha_base (int ignore ATTRIBUTE_UNUSED) 5011 { 5012 SKIP_WHITESPACE (); 5013 5014 if (*input_line_pointer == '$') 5015 { 5016 /* $rNN form. */ 5017 input_line_pointer++; 5018 if (*input_line_pointer == 'r') 5019 input_line_pointer++; 5020 } 5021 5022 alpha_gp_register = get_absolute_expression (); 5023 if (alpha_gp_register < 0 || alpha_gp_register > 31) 5024 { 5025 alpha_gp_register = AXP_REG_GP; 5026 as_warn (_("Bad base register, using $%d."), alpha_gp_register); 5027 } 5028 5029 demand_empty_rest_of_line (); 5030 } 5031 5032 /* Handle the .align pseudo-op. This aligns to a power of two. It 5033 also adjusts any current instruction label. We treat this the same 5034 way the MIPS port does: .align 0 turns off auto alignment. */ 5035 5036 static void 5037 s_alpha_align (int ignore ATTRIBUTE_UNUSED) 5038 { 5039 int align; 5040 char fill, *pfill; 5041 long max_alignment = 16; 5042 5043 align = get_absolute_expression (); 5044 if (align > max_alignment) 5045 { 5046 align = max_alignment; 5047 as_bad (_("Alignment too large: %d. assumed"), align); 5048 } 5049 else if (align < 0) 5050 { 5051 as_warn (_("Alignment negative: 0 assumed")); 5052 align = 0; 5053 } 5054 5055 if (*input_line_pointer == ',') 5056 { 5057 input_line_pointer++; 5058 fill = get_absolute_expression (); 5059 pfill = &fill; 5060 } 5061 else 5062 pfill = NULL; 5063 5064 if (align != 0) 5065 { 5066 alpha_auto_align_on = 1; 5067 alpha_align (align, pfill, NULL, 1); 5068 } 5069 else 5070 { 5071 alpha_auto_align_on = 0; 5072 } 5073 alpha_insn_label = NULL; 5074 5075 demand_empty_rest_of_line (); 5076 } 5077 5078 /* Hook the normal string processor to reset known alignment. */ 5079 5080 static void 5081 s_alpha_stringer (int terminate) 5082 { 5083 alpha_current_align = 0; 5084 alpha_insn_label = NULL; 5085 stringer (8 + terminate); 5086 } 5087 5088 /* Hook the normal space processing to reset known alignment. */ 5089 5090 static void 5091 s_alpha_space (int ignore) 5092 { 5093 alpha_current_align = 0; 5094 alpha_insn_label = NULL; 5095 s_space (ignore); 5096 } 5097 5098 /* Hook into cons for auto-alignment. */ 5099 5100 void 5101 alpha_cons_align (int size) 5102 { 5103 int log_size; 5104 5105 log_size = 0; 5106 while ((size >>= 1) != 0) 5107 ++log_size; 5108 5109 if (alpha_auto_align_on && alpha_current_align < log_size) 5110 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0); 5111 if (alpha_current_align > log_size) 5112 alpha_current_align = log_size; 5113 alpha_insn_label = NULL; 5114 } 5115 5116 /* Here come the .uword, .ulong, and .uquad explicitly unaligned 5117 pseudos. We just turn off auto-alignment and call down to cons. */ 5118 5119 static void 5120 s_alpha_ucons (int bytes) 5121 { 5122 int hold = alpha_auto_align_on; 5123 alpha_auto_align_on = 0; 5124 cons (bytes); 5125 alpha_auto_align_on = hold; 5126 } 5127 5128 /* Switch the working cpu type. */ 5129 5130 static void 5131 s_alpha_arch (int ignored ATTRIBUTE_UNUSED) 5132 { 5133 char *name, ch; 5134 const struct cpu_type *p; 5135 5136 SKIP_WHITESPACE (); 5137 name = input_line_pointer; 5138 ch = get_symbol_end (); 5139 5140 for (p = cpu_types; p->name; ++p) 5141 if (strcmp (name, p->name) == 0) 5142 { 5143 alpha_target_name = p->name, alpha_target = p->flags; 5144 goto found; 5145 } 5146 as_warn (_("Unknown CPU identifier `%s'"), name); 5147 5148 found: 5149 *input_line_pointer = ch; 5150 demand_empty_rest_of_line (); 5151 } 5152 5153 #ifdef DEBUG1 5155 /* print token expression with alpha specific extension. */ 5156 5157 static void 5158 alpha_print_token (FILE *f, const expressionS *exp) 5159 { 5160 switch (exp->X_op) 5161 { 5162 case O_cpregister: 5163 putc (',', f); 5164 /* FALLTHRU */ 5165 case O_pregister: 5166 putc ('(', f); 5167 { 5168 expressionS nexp = *exp; 5169 nexp.X_op = O_register; 5170 print_expr_1 (f, &nexp); 5171 } 5172 putc (')', f); 5173 break; 5174 default: 5175 print_expr_1 (f, exp); 5176 break; 5177 } 5178 } 5179 #endif 5180 5181 /* The target specific pseudo-ops which we support. */ 5183 5184 const pseudo_typeS md_pseudo_table[] = 5185 { 5186 #ifdef OBJ_ECOFF 5187 {"comm", s_alpha_comm, 0}, /* OSF1 compiler does this. */ 5188 {"rdata", s_alpha_rdata, 0}, 5189 #endif 5190 {"text", s_alpha_text, 0}, 5191 {"data", s_alpha_data, 0}, 5192 #ifdef OBJ_ECOFF 5193 {"sdata", s_alpha_sdata, 0}, 5194 #endif 5195 #ifdef OBJ_ELF 5196 {"section", s_alpha_section, 0}, 5197 {"section.s", s_alpha_section, 0}, 5198 {"sect", s_alpha_section, 0}, 5199 {"sect.s", s_alpha_section, 0}, 5200 #endif 5201 #ifdef OBJ_EVAX 5202 {"section", s_alpha_section, 0}, 5203 {"literals", s_alpha_literals, 0}, 5204 {"pdesc", s_alpha_pdesc, 0}, 5205 {"name", s_alpha_name, 0}, 5206 {"linkage", s_alpha_linkage, 0}, 5207 {"code_address", s_alpha_code_address, 0}, 5208 {"ent", s_alpha_ent, 0}, 5209 {"frame", s_alpha_frame, 0}, 5210 {"fp_save", s_alpha_fp_save, 0}, 5211 {"mask", s_alpha_mask, 0}, 5212 {"fmask", s_alpha_fmask, 0}, 5213 {"end", s_alpha_end, 0}, 5214 {"file", s_alpha_file, 0}, 5215 {"rdata", s_alpha_section, 1}, 5216 {"comm", s_alpha_comm, 0}, 5217 {"link", s_alpha_section, 3}, 5218 {"ctors", s_alpha_section, 4}, 5219 {"dtors", s_alpha_section, 5}, 5220 {"handler", s_alpha_handler, 0}, 5221 {"handler_data", s_alpha_handler, 1}, 5222 #endif 5223 #ifdef OBJ_ELF 5224 /* Frame related pseudos. */ 5225 {"ent", s_alpha_ent, 0}, 5226 {"end", s_alpha_end, 0}, 5227 {"mask", s_alpha_mask, 0}, 5228 {"fmask", s_alpha_mask, 1}, 5229 {"frame", s_alpha_frame, 0}, 5230 {"prologue", s_alpha_prologue, 0}, 5231 {"file", s_alpha_file, 5}, 5232 {"loc", s_alpha_loc, 9}, 5233 {"stabs", s_alpha_stab, 's'}, 5234 {"stabn", s_alpha_stab, 'n'}, 5235 {"usepv", s_alpha_usepv, 0}, 5236 /* COFF debugging related pseudos. */ 5237 {"begin", s_alpha_coff_wrapper, 0}, 5238 {"bend", s_alpha_coff_wrapper, 1}, 5239 {"def", s_alpha_coff_wrapper, 2}, 5240 {"dim", s_alpha_coff_wrapper, 3}, 5241 {"endef", s_alpha_coff_wrapper, 4}, 5242 {"scl", s_alpha_coff_wrapper, 5}, 5243 {"tag", s_alpha_coff_wrapper, 6}, 5244 {"val", s_alpha_coff_wrapper, 7}, 5245 #else 5246 #ifdef OBJ_EVAX 5247 {"prologue", s_alpha_prologue, 0}, 5248 #else 5249 {"prologue", s_ignore, 0}, 5250 #endif 5251 #endif 5252 {"gprel32", s_alpha_gprel32, 0}, 5253 {"t_floating", s_alpha_float_cons, 'd'}, 5254 {"s_floating", s_alpha_float_cons, 'f'}, 5255 {"f_floating", s_alpha_float_cons, 'F'}, 5256 {"g_floating", s_alpha_float_cons, 'G'}, 5257 {"d_floating", s_alpha_float_cons, 'D'}, 5258 5259 {"proc", s_alpha_proc, 0}, 5260 {"aproc", s_alpha_proc, 1}, 5261 {"set", s_alpha_set, 0}, 5262 {"reguse", s_ignore, 0}, 5263 {"livereg", s_ignore, 0}, 5264 {"base", s_alpha_base, 0}, /*??*/ 5265 {"option", s_ignore, 0}, 5266 {"aent", s_ignore, 0}, 5267 {"ugen", s_ignore, 0}, 5268 {"eflag", s_ignore, 0}, 5269 5270 {"align", s_alpha_align, 0}, 5271 {"double", s_alpha_float_cons, 'd'}, 5272 {"float", s_alpha_float_cons, 'f'}, 5273 {"single", s_alpha_float_cons, 'f'}, 5274 {"ascii", s_alpha_stringer, 0}, 5275 {"asciz", s_alpha_stringer, 1}, 5276 {"string", s_alpha_stringer, 1}, 5277 {"space", s_alpha_space, 0}, 5278 {"skip", s_alpha_space, 0}, 5279 {"zero", s_alpha_space, 0}, 5280 5281 /* Unaligned data pseudos. */ 5282 {"uword", s_alpha_ucons, 2}, 5283 {"ulong", s_alpha_ucons, 4}, 5284 {"uquad", s_alpha_ucons, 8}, 5285 5286 #ifdef OBJ_ELF 5287 /* Dwarf wants these versions of unaligned. */ 5288 {"2byte", s_alpha_ucons, 2}, 5289 {"4byte", s_alpha_ucons, 4}, 5290 {"8byte", s_alpha_ucons, 8}, 5291 #endif 5292 5293 /* We don't do any optimizing, so we can safely ignore these. */ 5294 {"noalias", s_ignore, 0}, 5295 {"alias", s_ignore, 0}, 5296 5297 {"arch", s_alpha_arch, 0}, 5298 5299 {NULL, 0, 0}, 5300 }; 5301 5302 #ifdef OBJ_ECOFF 5304 5305 /* @@@ GP selection voodoo. All of this seems overly complicated and 5306 unnecessary; which is the primary reason it's for ECOFF only. */ 5307 5308 static inline void 5309 maybe_set_gp (asection *sec) 5310 { 5311 bfd_vma vma; 5312 5313 if (!sec) 5314 return; 5315 vma = bfd_get_section_vma (sec->owner, sec); 5316 if (vma && vma < alpha_gp_value) 5317 alpha_gp_value = vma; 5318 } 5319 5320 static void 5321 select_gp_value (void) 5322 { 5323 gas_assert (alpha_gp_value == 0); 5324 5325 /* Get minus-one in whatever width... */ 5326 alpha_gp_value = 0; 5327 alpha_gp_value--; 5328 5329 /* Select the smallest VMA of these existing sections. */ 5330 maybe_set_gp (alpha_lita_section); 5331 5332 /* @@ Will a simple 0x8000 work here? If not, why not? */ 5333 #define GP_ADJUSTMENT (0x8000 - 0x10) 5334 5335 alpha_gp_value += GP_ADJUSTMENT; 5336 5337 S_SET_VALUE (alpha_gp_symbol, alpha_gp_value); 5338 5339 #ifdef DEBUG1 5340 printf (_("Chose GP value of %lx\n"), alpha_gp_value); 5341 #endif 5342 } 5343 #endif /* OBJ_ECOFF */ 5344 5345 #ifdef OBJ_ELF 5346 /* Map 's' to SHF_ALPHA_GPREL. */ 5347 5348 bfd_vma 5349 alpha_elf_section_letter (int letter, char **ptr_msg) 5350 { 5351 if (letter == 's') 5352 return SHF_ALPHA_GPREL; 5353 5354 *ptr_msg = _("bad .section directive: want a,s,w,x,M,S,G,T in string"); 5355 return -1; 5356 } 5357 5358 /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */ 5359 5360 flagword 5361 alpha_elf_section_flags (flagword flags, bfd_vma attr, int type ATTRIBUTE_UNUSED) 5362 { 5363 if (attr & SHF_ALPHA_GPREL) 5364 flags |= SEC_SMALL_DATA; 5365 return flags; 5366 } 5367 #endif /* OBJ_ELF */ 5368 5369 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents 5370 of an rs_align_code fragment. */ 5371 5372 void 5373 alpha_handle_align (fragS *fragp) 5374 { 5375 static char const unop[4] = { 0x00, 0x00, 0xfe, 0x2f }; 5376 static char const nopunop[8] = 5377 { 5378 0x1f, 0x04, 0xff, 0x47, 5379 0x00, 0x00, 0xfe, 0x2f 5380 }; 5381 5382 int bytes, fix; 5383 char *p; 5384 5385 if (fragp->fr_type != rs_align_code) 5386 return; 5387 5388 bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix; 5389 p = fragp->fr_literal + fragp->fr_fix; 5390 fix = 0; 5391 5392 if (bytes & 3) 5393 { 5394 fix = bytes & 3; 5395 memset (p, 0, fix); 5396 p += fix; 5397 bytes -= fix; 5398 } 5399 5400 if (bytes & 4) 5401 { 5402 memcpy (p, unop, 4); 5403 p += 4; 5404 bytes -= 4; 5405 fix += 4; 5406 } 5407 5408 memcpy (p, nopunop, 8); 5409 5410 fragp->fr_fix += fix; 5411 fragp->fr_var = 8; 5412 } 5413 5414 /* Public interface functions. */ 5416 5417 /* This function is called once, at assembler startup time. It sets 5418 up all the tables, etc. that the MD part of the assembler will 5419 need, that can be determined before arguments are parsed. */ 5420 5421 void 5422 md_begin (void) 5423 { 5424 unsigned int i; 5425 5426 /* Verify that X_op field is wide enough. */ 5427 { 5428 expressionS e; 5429 5430 e.X_op = O_max; 5431 gas_assert (e.X_op == O_max); 5432 } 5433 5434 /* Create the opcode hash table. */ 5435 alpha_opcode_hash = hash_new (); 5436 5437 for (i = 0; i < alpha_num_opcodes;) 5438 { 5439 const char *name, *retval, *slash; 5440 5441 name = alpha_opcodes[i].name; 5442 retval = hash_insert (alpha_opcode_hash, name, (void *) &alpha_opcodes[i]); 5443 if (retval) 5444 as_fatal (_("internal error: can't hash opcode `%s': %s"), 5445 name, retval); 5446 5447 /* Some opcodes include modifiers of various sorts with a "/mod" 5448 syntax, like the architecture manual suggests. However, for 5449 use with gcc at least, we also need access to those same opcodes 5450 without the "/". */ 5451 5452 if ((slash = strchr (name, '/')) != NULL) 5453 { 5454 char *p = (char *) xmalloc (strlen (name)); 5455 5456 memcpy (p, name, slash - name); 5457 strcpy (p + (slash - name), slash + 1); 5458 5459 (void) hash_insert (alpha_opcode_hash, p, (void *) &alpha_opcodes[i]); 5460 /* Ignore failures -- the opcode table does duplicate some 5461 variants in different forms, like "hw_stq" and "hw_st/q". */ 5462 } 5463 5464 while (++i < alpha_num_opcodes 5465 && (alpha_opcodes[i].name == name 5466 || !strcmp (alpha_opcodes[i].name, name))) 5467 continue; 5468 } 5469 5470 /* Create the macro hash table. */ 5471 alpha_macro_hash = hash_new (); 5472 5473 for (i = 0; i < alpha_num_macros;) 5474 { 5475 const char *name, *retval; 5476 5477 name = alpha_macros[i].name; 5478 retval = hash_insert (alpha_macro_hash, name, (void *) &alpha_macros[i]); 5479 if (retval) 5480 as_fatal (_("internal error: can't hash macro `%s': %s"), 5481 name, retval); 5482 5483 while (++i < alpha_num_macros 5484 && (alpha_macros[i].name == name 5485 || !strcmp (alpha_macros[i].name, name))) 5486 continue; 5487 } 5488 5489 /* Construct symbols for each of the registers. */ 5490 for (i = 0; i < 32; ++i) 5491 { 5492 char name[4]; 5493 5494 sprintf (name, "$%d", i); 5495 alpha_register_table[i] = symbol_create (name, reg_section, i, 5496 &zero_address_frag); 5497 } 5498 5499 for (; i < 64; ++i) 5500 { 5501 char name[5]; 5502 5503 sprintf (name, "$f%d", i - 32); 5504 alpha_register_table[i] = symbol_create (name, reg_section, i, 5505 &zero_address_frag); 5506 } 5507 5508 /* Create the special symbols and sections we'll be using. */ 5509 5510 /* So .sbss will get used for tiny objects. */ 5511 bfd_set_gp_size (stdoutput, g_switch_value); 5512 5513 #ifdef OBJ_ECOFF 5514 create_literal_section (".lita", &alpha_lita_section, &alpha_lita_symbol); 5515 5516 /* For handling the GP, create a symbol that won't be output in the 5517 symbol table. We'll edit it out of relocs later. */ 5518 alpha_gp_symbol = symbol_create ("<GP value>", alpha_lita_section, 0x8000, 5519 &zero_address_frag); 5520 #endif 5521 5522 #ifdef OBJ_EVAX 5523 create_literal_section (".link", &alpha_link_section, &alpha_link_symbol); 5524 #endif 5525 5526 #ifdef OBJ_ELF 5527 if (ECOFF_DEBUGGING) 5528 { 5529 segT sec = subseg_new (".mdebug", (subsegT) 0); 5530 bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY); 5531 bfd_set_section_alignment (stdoutput, sec, 3); 5532 } 5533 #endif 5534 5535 /* Create literal lookup hash table. */ 5536 alpha_literal_hash = hash_new (); 5537 5538 subseg_set (text_section, 0); 5539 } 5540 5541 /* The public interface to the instruction assembler. */ 5542 5543 void 5544 md_assemble (char *str) 5545 { 5546 /* Current maximum is 13. */ 5547 char opname[32]; 5548 expressionS tok[MAX_INSN_ARGS]; 5549 int ntok, trunclen; 5550 size_t opnamelen; 5551 5552 /* Split off the opcode. */ 5553 opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_/46819"); 5554 trunclen = (opnamelen < sizeof (opname) - 1 5555 ? opnamelen 5556 : sizeof (opname) - 1); 5557 memcpy (opname, str, trunclen); 5558 opname[trunclen] = '\0'; 5559 5560 /* Tokenize the rest of the line. */ 5561 if ((ntok = tokenize_arguments (str + opnamelen, tok, MAX_INSN_ARGS)) < 0) 5562 { 5563 if (ntok != TOKENIZE_ERROR_REPORT) 5564 as_bad (_("syntax error")); 5565 5566 return; 5567 } 5568 5569 /* Finish it off. */ 5570 assemble_tokens (opname, tok, ntok, alpha_macros_on); 5571 } 5572 5573 /* Round up a section's size to the appropriate boundary. */ 5574 5575 valueT 5576 md_section_align (segT seg, valueT size) 5577 { 5578 int align = bfd_get_section_alignment (stdoutput, seg); 5579 valueT mask = ((valueT) 1 << align) - 1; 5580 5581 return (size + mask) & ~mask; 5582 } 5583 5584 /* Turn a string in input_line_pointer into a floating point constant 5585 of type TYPE, and store the appropriate bytes in *LITP. The number 5586 of LITTLENUMS emitted is stored in *SIZEP. An error message is 5587 returned, or NULL on OK. */ 5588 5589 char * 5590 md_atof (int type, char *litP, int *sizeP) 5591 { 5592 extern char *vax_md_atof (int, char *, int *); 5593 5594 switch (type) 5595 { 5596 /* VAX floats. */ 5597 case 'G': 5598 /* vax_md_atof() doesn't like "G" for some reason. */ 5599 type = 'g'; 5600 case 'F': 5601 case 'D': 5602 return vax_md_atof (type, litP, sizeP); 5603 5604 default: 5605 return ieee_md_atof (type, litP, sizeP, FALSE); 5606 } 5607 } 5608 5609 /* Take care of the target-specific command-line options. */ 5610 5611 int 5612 md_parse_option (int c, char *arg) 5613 { 5614 switch (c) 5615 { 5616 case 'F': 5617 alpha_nofloats_on = 1; 5618 break; 5619 5620 case OPTION_32ADDR: 5621 alpha_addr32_on = 1; 5622 break; 5623 5624 case 'g': 5625 alpha_debug = 1; 5626 break; 5627 5628 case 'G': 5629 g_switch_value = atoi (arg); 5630 break; 5631 5632 case 'm': 5633 { 5634 const struct cpu_type *p; 5635 5636 for (p = cpu_types; p->name; ++p) 5637 if (strcmp (arg, p->name) == 0) 5638 { 5639 alpha_target_name = p->name, alpha_target = p->flags; 5640 goto found; 5641 } 5642 as_warn (_("Unknown CPU identifier `%s'"), arg); 5643 found:; 5644 } 5645 break; 5646 5647 #ifdef OBJ_EVAX 5648 case '+': /* For g++. Hash any name > 63 chars long. */ 5649 alpha_flag_hash_long_names = 1; 5650 break; 5651 5652 case 'H': /* Show new symbol after hash truncation. */ 5653 alpha_flag_show_after_trunc = 1; 5654 break; 5655 5656 case 'h': /* For gnu-c/vax compatibility. */ 5657 break; 5658 5659 case OPTION_REPLACE: 5660 alpha_flag_replace = 1; 5661 break; 5662 5663 case OPTION_NOREPLACE: 5664 alpha_flag_replace = 0; 5665 break; 5666 #endif 5667 5668 case OPTION_RELAX: 5669 alpha_flag_relax = 1; 5670 break; 5671 5672 #ifdef OBJ_ELF 5673 case OPTION_MDEBUG: 5674 alpha_flag_mdebug = 1; 5675 break; 5676 case OPTION_NO_MDEBUG: 5677 alpha_flag_mdebug = 0; 5678 break; 5679 #endif 5680 5681 default: 5682 return 0; 5683 } 5684 5685 return 1; 5686 } 5687 5688 /* Print a description of the command-line options that we accept. */ 5689 5690 void 5691 md_show_usage (FILE *stream) 5692 { 5693 fputs (_("\ 5694 Alpha options:\n\ 5695 -32addr treat addresses as 32-bit values\n\ 5696 -F lack floating point instructions support\n\ 5697 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mev67 | -mev68 | -mall\n\ 5698 specify variant of Alpha architecture\n\ 5699 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264 | -m21264a | -m21264b\n\ 5700 these variants include PALcode opcodes\n"), 5701 stream); 5702 #ifdef OBJ_EVAX 5703 fputs (_("\ 5704 VMS options:\n\ 5705 -+ encode (don't truncate) names longer than 64 characters\n\ 5706 -H show new symbol after hash truncation\n\ 5707 -replace/-noreplace enable or disable the optimization of procedure calls\n"), 5708 stream); 5709 #endif 5710 } 5711 5712 /* Decide from what point a pc-relative relocation is relative to, 5713 relative to the pc-relative fixup. Er, relatively speaking. */ 5714 5715 long 5716 md_pcrel_from (fixS *fixP) 5717 { 5718 valueT addr = fixP->fx_where + fixP->fx_frag->fr_address; 5719 5720 switch (fixP->fx_r_type) 5721 { 5722 case BFD_RELOC_23_PCREL_S2: 5723 case BFD_RELOC_ALPHA_HINT: 5724 case BFD_RELOC_ALPHA_BRSGP: 5725 return addr + 4; 5726 default: 5727 return addr; 5728 } 5729 } 5730 5731 /* Attempt to simplify or even eliminate a fixup. The return value is 5732 ignored; perhaps it was once meaningful, but now it is historical. 5733 To indicate that a fixup has been eliminated, set fixP->fx_done. 5734 5735 For ELF, here it is that we transform the GPDISP_HI16 reloc we used 5736 internally into the GPDISP reloc used externally. We had to do 5737 this so that we'd have the GPDISP_LO16 reloc as a tag to compute 5738 the distance to the "lda" instruction for setting the addend to 5739 GPDISP. */ 5740 5741 void 5742 md_apply_fix (fixS *fixP, valueT * valP, segT seg) 5743 { 5744 char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where; 5745 valueT value = * valP; 5746 unsigned image, size; 5747 5748 switch (fixP->fx_r_type) 5749 { 5750 /* The GPDISP relocations are processed internally with a symbol 5751 referring to the current function's section; we need to drop 5752 in a value which, when added to the address of the start of 5753 the function, gives the desired GP. */ 5754 case BFD_RELOC_ALPHA_GPDISP_HI16: 5755 { 5756 fixS *next = fixP->fx_next; 5757 5758 /* With user-specified !gpdisp relocations, we can be missing 5759 the matching LO16 reloc. We will have already issued an 5760 error message. */ 5761 if (next) 5762 fixP->fx_offset = (next->fx_frag->fr_address + next->fx_where 5763 - fixP->fx_frag->fr_address - fixP->fx_where); 5764 5765 value = (value - sign_extend_16 (value)) >> 16; 5766 } 5767 #ifdef OBJ_ELF 5768 fixP->fx_r_type = BFD_RELOC_ALPHA_GPDISP; 5769 #endif 5770 goto do_reloc_gp; 5771 5772 case BFD_RELOC_ALPHA_GPDISP_LO16: 5773 value = sign_extend_16 (value); 5774 fixP->fx_offset = 0; 5775 #ifdef OBJ_ELF 5776 fixP->fx_done = 1; 5777 #endif 5778 5779 do_reloc_gp: 5780 fixP->fx_addsy = section_symbol (seg); 5781 md_number_to_chars (fixpos, value, 2); 5782 break; 5783 5784 case BFD_RELOC_16: 5785 if (fixP->fx_pcrel) 5786 fixP->fx_r_type = BFD_RELOC_16_PCREL; 5787 size = 2; 5788 goto do_reloc_xx; 5789 5790 case BFD_RELOC_32: 5791 if (fixP->fx_pcrel) 5792 fixP->fx_r_type = BFD_RELOC_32_PCREL; 5793 size = 4; 5794 goto do_reloc_xx; 5795 5796 case BFD_RELOC_64: 5797 if (fixP->fx_pcrel) 5798 fixP->fx_r_type = BFD_RELOC_64_PCREL; 5799 size = 8; 5800 5801 do_reloc_xx: 5802 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0) 5803 { 5804 md_number_to_chars (fixpos, value, size); 5805 goto done; 5806 } 5807 return; 5808 5809 #ifdef OBJ_ECOFF 5810 case BFD_RELOC_GPREL32: 5811 gas_assert (fixP->fx_subsy == alpha_gp_symbol); 5812 fixP->fx_subsy = 0; 5813 /* FIXME: inherited this obliviousness of `value' -- why? */ 5814 md_number_to_chars (fixpos, -alpha_gp_value, 4); 5815 break; 5816 #else 5817 case BFD_RELOC_GPREL32: 5818 #endif 5819 case BFD_RELOC_GPREL16: 5820 case BFD_RELOC_ALPHA_GPREL_HI16: 5821 case BFD_RELOC_ALPHA_GPREL_LO16: 5822 return; 5823 5824 case BFD_RELOC_23_PCREL_S2: 5825 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0) 5826 { 5827 image = bfd_getl32 (fixpos); 5828 image = (image & ~0x1FFFFF) | ((value >> 2) & 0x1FFFFF); 5829 goto write_done; 5830 } 5831 return; 5832 5833 case BFD_RELOC_ALPHA_HINT: 5834 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0) 5835 { 5836 image = bfd_getl32 (fixpos); 5837 image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF); 5838 goto write_done; 5839 } 5840 return; 5841 5842 #ifdef OBJ_ELF 5843 case BFD_RELOC_ALPHA_BRSGP: 5844 return; 5845 5846 case BFD_RELOC_ALPHA_TLSGD: 5847 case BFD_RELOC_ALPHA_TLSLDM: 5848 case BFD_RELOC_ALPHA_GOTDTPREL16: 5849 case BFD_RELOC_ALPHA_DTPREL_HI16: 5850 case BFD_RELOC_ALPHA_DTPREL_LO16: 5851 case BFD_RELOC_ALPHA_DTPREL16: 5852 case BFD_RELOC_ALPHA_GOTTPREL16: 5853 case BFD_RELOC_ALPHA_TPREL_HI16: 5854 case BFD_RELOC_ALPHA_TPREL_LO16: 5855 case BFD_RELOC_ALPHA_TPREL16: 5856 if (fixP->fx_addsy) 5857 S_SET_THREAD_LOCAL (fixP->fx_addsy); 5858 return; 5859 #endif 5860 5861 #ifdef OBJ_ECOFF 5862 case BFD_RELOC_ALPHA_LITERAL: 5863 md_number_to_chars (fixpos, value, 2); 5864 return; 5865 #endif 5866 case BFD_RELOC_ALPHA_ELF_LITERAL: 5867 case BFD_RELOC_ALPHA_LITUSE: 5868 case BFD_RELOC_ALPHA_LINKAGE: 5869 case BFD_RELOC_ALPHA_CODEADDR: 5870 return; 5871 5872 #ifdef OBJ_EVAX 5873 case BFD_RELOC_ALPHA_NOP: 5874 value -= (8 + 4); /* PC-relative, base is jsr+4. */ 5875 5876 /* From B.4.5.2 of the OpenVMS Linker Utility Manual: 5877 "Finally, the ETIR$C_STC_BSR command passes the same address 5878 as ETIR$C_STC_NOP (so that they will fail or succeed together), 5879 and the same test is done again." */ 5880 if (S_GET_SEGMENT (fixP->fx_addsy) == undefined_section) 5881 { 5882 fixP->fx_addnumber = -value; 5883 return; 5884 } 5885 5886 if ((abs (value) >> 2) & ~0xfffff) 5887 goto done; 5888 else 5889 { 5890 /* Change to a nop. */ 5891 image = 0x47FF041F; 5892 goto write_done; 5893 } 5894 5895 case BFD_RELOC_ALPHA_LDA: 5896 /* fixup_segment sets fixP->fx_addsy to NULL when it can pre-compute 5897 the value for an O_subtract. */ 5898 if (fixP->fx_addsy 5899 && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section) 5900 { 5901 fixP->fx_addnumber = symbol_get_bfdsym (fixP->fx_subsy)->value; 5902 return; 5903 } 5904 5905 if ((abs (value)) & ~0x7fff) 5906 goto done; 5907 else 5908 { 5909 /* Change to an lda. */ 5910 image = 0x237B0000 | (value & 0xFFFF); 5911 goto write_done; 5912 } 5913 5914 case BFD_RELOC_ALPHA_BSR: 5915 case BFD_RELOC_ALPHA_BOH: 5916 value -= 4; /* PC-relative, base is jsr+4. */ 5917 5918 /* See comment in the BFD_RELOC_ALPHA_NOP case above. */ 5919 if (S_GET_SEGMENT (fixP->fx_addsy) == undefined_section) 5920 { 5921 fixP->fx_addnumber = -value; 5922 return; 5923 } 5924 5925 if ((abs (value) >> 2) & ~0xfffff) 5926 { 5927 /* Out of range. */ 5928 if (fixP->fx_r_type == BFD_RELOC_ALPHA_BOH) 5929 { 5930 /* Add a hint. */ 5931 image = bfd_getl32(fixpos); 5932 image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF); 5933 goto write_done; 5934 } 5935 goto done; 5936 } 5937 else 5938 { 5939 /* Change to a branch. */ 5940 image = 0xD3400000 | ((value >> 2) & 0x1FFFFF); 5941 goto write_done; 5942 } 5943 #endif 5944 5945 case BFD_RELOC_VTABLE_INHERIT: 5946 case BFD_RELOC_VTABLE_ENTRY: 5947 return; 5948 5949 default: 5950 { 5951 const struct alpha_operand *operand; 5952 5953 if ((int) fixP->fx_r_type >= 0) 5954 as_fatal (_("unhandled relocation type %s"), 5955 bfd_get_reloc_code_name (fixP->fx_r_type)); 5956 5957 gas_assert (-(int) fixP->fx_r_type < (int) alpha_num_operands); 5958 operand = &alpha_operands[-(int) fixP->fx_r_type]; 5959 5960 /* The rest of these fixups only exist internally during symbol 5961 resolution and have no representation in the object file. 5962 Therefore they must be completely resolved as constants. */ 5963 5964 if (fixP->fx_addsy != 0 5965 && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section) 5966 as_bad_where (fixP->fx_file, fixP->fx_line, 5967 _("non-absolute expression in constant field")); 5968 5969 image = bfd_getl32 (fixpos); 5970 image = insert_operand (image, operand, (offsetT) value, 5971 fixP->fx_file, fixP->fx_line); 5972 } 5973 goto write_done; 5974 } 5975 5976 if (fixP->fx_addsy != 0 || fixP->fx_pcrel != 0) 5977 return; 5978 else 5979 { 5980 as_warn_where (fixP->fx_file, fixP->fx_line, 5981 _("type %d reloc done?\n"), (int) fixP->fx_r_type); 5982 goto done; 5983 } 5984 5985 write_done: 5986 md_number_to_chars (fixpos, image, 4); 5987 5988 done: 5989 fixP->fx_done = 1; 5990 } 5991 5992 /* Look for a register name in the given symbol. */ 5993 5994 symbolS * 5995 md_undefined_symbol (char *name) 5996 { 5997 if (*name == '$') 5998 { 5999 int is_float = 0, num; 6000 6001 switch (*++name) 6002 { 6003 case 'f': 6004 if (name[1] == 'p' && name[2] == '\0') 6005 return alpha_register_table[AXP_REG_FP]; 6006 is_float = 32; 6007 /* Fall through. */ 6008 6009 case 'r': 6010 if (!ISDIGIT (*++name)) 6011 break; 6012 /* Fall through. */ 6013 6014 case '0': case '1': case '2': case '3': case '4': 6015 case '5': case '6': case '7': case '8': case '9': 6016 if (name[1] == '\0') 6017 num = name[0] - '0'; 6018 else if (name[0] != '0' && ISDIGIT (name[1]) && name[2] == '\0') 6019 { 6020 num = (name[0] - '0') * 10 + name[1] - '0'; 6021 if (num >= 32) 6022 break; 6023 } 6024 else 6025 break; 6026 6027 if (!alpha_noat_on && (num + is_float) == AXP_REG_AT) 6028 as_warn (_("Used $at without \".set noat\"")); 6029 return alpha_register_table[num + is_float]; 6030 6031 case 'a': 6032 if (name[1] == 't' && name[2] == '\0') 6033 { 6034 if (!alpha_noat_on) 6035 as_warn (_("Used $at without \".set noat\"")); 6036 return alpha_register_table[AXP_REG_AT]; 6037 } 6038 break; 6039 6040 case 'g': 6041 if (name[1] == 'p' && name[2] == '\0') 6042 return alpha_register_table[alpha_gp_register]; 6043 break; 6044 6045 case 's': 6046 if (name[1] == 'p' && name[2] == '\0') 6047 return alpha_register_table[AXP_REG_SP]; 6048 break; 6049 } 6050 } 6051 return NULL; 6052 } 6053 6054 #ifdef OBJ_ECOFF 6055 /* @@@ Magic ECOFF bits. */ 6056 6057 void 6058 alpha_frob_ecoff_data (void) 6059 { 6060 select_gp_value (); 6061 /* $zero and $f31 are read-only. */ 6062 alpha_gprmask &= ~1; 6063 alpha_fprmask &= ~1; 6064 } 6065 #endif 6066 6067 /* Hook to remember a recently defined label so that the auto-align 6068 code can adjust the symbol after we know what alignment will be 6069 required. */ 6070 6071 void 6072 alpha_define_label (symbolS *sym) 6073 { 6074 alpha_insn_label = sym; 6075 #ifdef OBJ_ELF 6076 dwarf2_emit_label (sym); 6077 #endif 6078 } 6079 6080 /* Return true if we must always emit a reloc for a type and false if 6081 there is some hope of resolving it at assembly time. */ 6082 6083 int 6084 alpha_force_relocation (fixS *f) 6085 { 6086 if (alpha_flag_relax) 6087 return 1; 6088 6089 switch (f->fx_r_type) 6090 { 6091 case BFD_RELOC_ALPHA_GPDISP_HI16: 6092 case BFD_RELOC_ALPHA_GPDISP_LO16: 6093 case BFD_RELOC_ALPHA_GPDISP: 6094 case BFD_RELOC_ALPHA_LITERAL: 6095 case BFD_RELOC_ALPHA_ELF_LITERAL: 6096 case BFD_RELOC_ALPHA_LITUSE: 6097 case BFD_RELOC_GPREL16: 6098 case BFD_RELOC_GPREL32: 6099 case BFD_RELOC_ALPHA_GPREL_HI16: 6100 case BFD_RELOC_ALPHA_GPREL_LO16: 6101 case BFD_RELOC_ALPHA_LINKAGE: 6102 case BFD_RELOC_ALPHA_CODEADDR: 6103 case BFD_RELOC_ALPHA_BRSGP: 6104 case BFD_RELOC_ALPHA_TLSGD: 6105 case BFD_RELOC_ALPHA_TLSLDM: 6106 case BFD_RELOC_ALPHA_GOTDTPREL16: 6107 case BFD_RELOC_ALPHA_DTPREL_HI16: 6108 case BFD_RELOC_ALPHA_DTPREL_LO16: 6109 case BFD_RELOC_ALPHA_DTPREL16: 6110 case BFD_RELOC_ALPHA_GOTTPREL16: 6111 case BFD_RELOC_ALPHA_TPREL_HI16: 6112 case BFD_RELOC_ALPHA_TPREL_LO16: 6113 case BFD_RELOC_ALPHA_TPREL16: 6114 #ifdef OBJ_EVAX 6115 case BFD_RELOC_ALPHA_NOP: 6116 case BFD_RELOC_ALPHA_BSR: 6117 case BFD_RELOC_ALPHA_LDA: 6118 case BFD_RELOC_ALPHA_BOH: 6119 #endif 6120 return 1; 6121 6122 default: 6123 break; 6124 } 6125 6126 return generic_force_reloc (f); 6127 } 6128 6129 /* Return true if we can partially resolve a relocation now. */ 6130 6131 int 6132 alpha_fix_adjustable (fixS *f) 6133 { 6134 /* Are there any relocation types for which we must generate a 6135 reloc but we can adjust the values contained within it? */ 6136 switch (f->fx_r_type) 6137 { 6138 case BFD_RELOC_ALPHA_GPDISP_HI16: 6139 case BFD_RELOC_ALPHA_GPDISP_LO16: 6140 case BFD_RELOC_ALPHA_GPDISP: 6141 return 0; 6142 6143 case BFD_RELOC_ALPHA_LITERAL: 6144 case BFD_RELOC_ALPHA_ELF_LITERAL: 6145 case BFD_RELOC_ALPHA_LITUSE: 6146 case BFD_RELOC_ALPHA_LINKAGE: 6147 case BFD_RELOC_ALPHA_CODEADDR: 6148 return 1; 6149 6150 case BFD_RELOC_VTABLE_ENTRY: 6151 case BFD_RELOC_VTABLE_INHERIT: 6152 return 0; 6153 6154 case BFD_RELOC_GPREL16: 6155 case BFD_RELOC_GPREL32: 6156 case BFD_RELOC_ALPHA_GPREL_HI16: 6157 case BFD_RELOC_ALPHA_GPREL_LO16: 6158 case BFD_RELOC_23_PCREL_S2: 6159 case BFD_RELOC_16: 6160 case BFD_RELOC_32: 6161 case BFD_RELOC_64: 6162 case BFD_RELOC_ALPHA_HINT: 6163 return 1; 6164 6165 case BFD_RELOC_ALPHA_TLSGD: 6166 case BFD_RELOC_ALPHA_TLSLDM: 6167 case BFD_RELOC_ALPHA_GOTDTPREL16: 6168 case BFD_RELOC_ALPHA_DTPREL_HI16: 6169 case BFD_RELOC_ALPHA_DTPREL_LO16: 6170 case BFD_RELOC_ALPHA_DTPREL16: 6171 case BFD_RELOC_ALPHA_GOTTPREL16: 6172 case BFD_RELOC_ALPHA_TPREL_HI16: 6173 case BFD_RELOC_ALPHA_TPREL_LO16: 6174 case BFD_RELOC_ALPHA_TPREL16: 6175 /* ??? No idea why we can't return a reference to .tbss+10, but 6176 we're preventing this in the other assemblers. Follow for now. */ 6177 return 0; 6178 6179 #ifdef OBJ_ELF 6180 case BFD_RELOC_ALPHA_BRSGP: 6181 /* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and 6182 let it get resolved at assembly time. */ 6183 { 6184 symbolS *sym = f->fx_addsy; 6185 const char *name; 6186 int offset = 0; 6187 6188 if (generic_force_reloc (f)) 6189 return 0; 6190 6191 switch (S_GET_OTHER (sym) & STO_ALPHA_STD_GPLOAD) 6192 { 6193 case STO_ALPHA_NOPV: 6194 break; 6195 case STO_ALPHA_STD_GPLOAD: 6196 offset = 8; 6197 break; 6198 default: 6199 if (S_IS_LOCAL (sym)) 6200 name = "<local>"; 6201 else 6202 name = S_GET_NAME (sym); 6203 as_bad_where (f->fx_file, f->fx_line, 6204 _("!samegp reloc against symbol without .prologue: %s"), 6205 name); 6206 break; 6207 } 6208 f->fx_r_type = BFD_RELOC_23_PCREL_S2; 6209 f->fx_offset += offset; 6210 return 1; 6211 } 6212 #endif 6213 #ifdef OBJ_EVAX 6214 case BFD_RELOC_ALPHA_NOP: 6215 case BFD_RELOC_ALPHA_BSR: 6216 case BFD_RELOC_ALPHA_LDA: 6217 case BFD_RELOC_ALPHA_BOH: 6218 return 1; 6219 #endif 6220 6221 default: 6222 return 1; 6223 } 6224 } 6225 6226 /* Generate the BFD reloc to be stuck in the object file from the 6227 fixup used internally in the assembler. */ 6228 6229 arelent * 6230 tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED, 6231 fixS *fixp) 6232 { 6233 arelent *reloc; 6234 6235 reloc = (arelent *) xmalloc (sizeof (* reloc)); 6236 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); 6237 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); 6238 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; 6239 6240 /* Make sure none of our internal relocations make it this far. 6241 They'd better have been fully resolved by this point. */ 6242 gas_assert ((int) fixp->fx_r_type > 0); 6243 6244 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); 6245 if (reloc->howto == NULL) 6246 { 6247 as_bad_where (fixp->fx_file, fixp->fx_line, 6248 _("cannot represent `%s' relocation in object file"), 6249 bfd_get_reloc_code_name (fixp->fx_r_type)); 6250 return NULL; 6251 } 6252 6253 if (!fixp->fx_pcrel != !reloc->howto->pc_relative) 6254 as_fatal (_("internal error? cannot generate `%s' relocation"), 6255 bfd_get_reloc_code_name (fixp->fx_r_type)); 6256 6257 gas_assert (!fixp->fx_pcrel == !reloc->howto->pc_relative); 6258 6259 reloc->addend = fixp->fx_offset; 6260 6261 #ifdef OBJ_ECOFF 6262 /* Fake out bfd_perform_relocation. sigh. */ 6263 /* ??? Better would be to use the special_function hook. */ 6264 if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL) 6265 reloc->addend = -alpha_gp_value; 6266 #endif 6267 6268 #ifdef OBJ_EVAX 6269 switch (fixp->fx_r_type) 6270 { 6271 struct evax_private_udata_struct *udata; 6272 const char *pname; 6273 int pname_len; 6274 6275 case BFD_RELOC_ALPHA_LINKAGE: 6276 /* Copy the linkage index. */ 6277 reloc->addend = fixp->fx_addnumber; 6278 break; 6279 6280 case BFD_RELOC_ALPHA_NOP: 6281 case BFD_RELOC_ALPHA_BSR: 6282 case BFD_RELOC_ALPHA_LDA: 6283 case BFD_RELOC_ALPHA_BOH: 6284 pname = symbol_get_bfdsym (fixp->fx_addsy)->name; 6285 6286 /* We need the non-suffixed name of the procedure. Beware that 6287 the main symbol might be equated so look it up and take its name. */ 6288 pname_len = strlen (pname); 6289 if (pname_len > 4 && strcmp (pname + pname_len - 4, "..en") == 0) 6290 { 6291 symbolS *sym; 6292 char *my_pname = (char *) alloca (pname_len - 4 + 1); 6293 6294 memcpy (my_pname, pname, pname_len - 4); 6295 my_pname [pname_len - 4] = 0; 6296 sym = symbol_find (my_pname); 6297 if (sym == NULL) 6298 abort (); 6299 6300 while (symbol_equated_reloc_p (sym)) 6301 { 6302 symbolS *n = symbol_get_value_expression (sym)->X_add_symbol; 6303 6304 /* We must avoid looping, as that can occur with a badly 6305 written program. */ 6306 if (n == sym) 6307 break; 6308 sym = n; 6309 } 6310 pname = symbol_get_bfdsym (sym)->name; 6311 } 6312 6313 udata = (struct evax_private_udata_struct *) 6314 xmalloc (sizeof (struct evax_private_udata_struct)); 6315 udata->enbsym = symbol_get_bfdsym (fixp->fx_addsy); 6316 udata->bsym = symbol_get_bfdsym (fixp->tc_fix_data.info->psym); 6317 udata->origname = (char *)pname; 6318 udata->lkindex = ((struct evax_private_udata_struct *) 6319 symbol_get_bfdsym (fixp->tc_fix_data.info->sym)->udata.p)->lkindex; 6320 reloc->sym_ptr_ptr = (void *)udata; 6321 reloc->addend = fixp->fx_addnumber; 6322 6323 default: 6324 break; 6325 } 6326 #endif 6327 6328 return reloc; 6329 } 6330 6331 /* Parse a register name off of the input_line and return a register 6332 number. Gets md_undefined_symbol above to do the register name 6333 matching for us. 6334 6335 Only called as a part of processing the ECOFF .frame directive. */ 6336 6337 int 6338 tc_get_register (int frame ATTRIBUTE_UNUSED) 6339 { 6340 int framereg = AXP_REG_SP; 6341 6342 SKIP_WHITESPACE (); 6343 if (*input_line_pointer == '$') 6344 { 6345 char *s = input_line_pointer; 6346 char c = get_symbol_end (); 6347 symbolS *sym = md_undefined_symbol (s); 6348 6349 *strchr (s, '\0') = c; 6350 if (sym && (framereg = S_GET_VALUE (sym)) <= 31) 6351 goto found; 6352 } 6353 as_warn (_("frame reg expected, using $%d."), framereg); 6354 6355 found: 6356 note_gpreg (framereg); 6357 return framereg; 6358 } 6359 6360 /* This is called before the symbol table is processed. In order to 6361 work with gcc when using mips-tfile, we must keep all local labels. 6362 However, in other cases, we want to discard them. If we were 6363 called with -g, but we didn't see any debugging information, it may 6364 mean that gcc is smuggling debugging information through to 6365 mips-tfile, in which case we must generate all local labels. */ 6366 6367 #ifdef OBJ_ECOFF 6368 6369 void 6370 alpha_frob_file_before_adjust (void) 6371 { 6372 if (alpha_debug != 0 6373 && ! ecoff_debugging_seen) 6374 flag_keep_locals = 1; 6375 } 6376 6377 #endif /* OBJ_ECOFF */ 6378 6379 /* The Alpha has support for some VAX floating point types, as well as for 6380 IEEE floating point. We consider IEEE to be the primary floating point 6381 format, and sneak in the VAX floating point support here. */ 6382 #include "config/atof-vax.c" 6383