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