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