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