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