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