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