tc-alpha.c revision 104834
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/* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and 1416 let it get resolved at assembly time. */ 1417 1418void 1419alpha_validate_fix (f) 1420 fixS *f; 1421{ 1422#ifdef OBJ_ELF 1423 int offset = 0; 1424 const char *name; 1425 1426 if (f->fx_r_type != BFD_RELOC_ALPHA_BRSGP) 1427 return; 1428 1429 if (! S_IS_DEFINED (f->fx_addsy)) 1430 return; 1431 1432 switch (S_GET_OTHER (f->fx_addsy) & STO_ALPHA_STD_GPLOAD) 1433 { 1434 case STO_ALPHA_NOPV: 1435 break; 1436 case STO_ALPHA_STD_GPLOAD: 1437 offset = 8; 1438 break; 1439 default: 1440 if (S_IS_LOCAL (f->fx_addsy)) 1441 name = "<local>"; 1442 else 1443 name = S_GET_NAME (f->fx_addsy); 1444 as_bad_where (f->fx_file, f->fx_line, 1445 _("!samegp reloc against symbol without .prologue: %s"), 1446 name); 1447 break; 1448 } 1449 1450 if (! (S_IS_EXTERN (f->fx_addsy) || S_IS_WEAK (f->fx_addsy))) 1451 { 1452 f->fx_r_type = BFD_RELOC_23_PCREL_S2; 1453 f->fx_offset += offset; 1454 } 1455#endif 1456} 1457 1458/* Return true if we must always emit a reloc for a type and false if 1459 there is some hope of resolving it at assembly time. */ 1460 1461int 1462alpha_force_relocation (f) 1463 fixS *f; 1464{ 1465 if (alpha_flag_relax) 1466 return 1; 1467 1468 switch (f->fx_r_type) 1469 { 1470 case BFD_RELOC_ALPHA_GPDISP_HI16: 1471 case BFD_RELOC_ALPHA_GPDISP_LO16: 1472 case BFD_RELOC_ALPHA_GPDISP: 1473 case BFD_RELOC_ALPHA_LITERAL: 1474 case BFD_RELOC_ALPHA_ELF_LITERAL: 1475 case BFD_RELOC_ALPHA_LITUSE: 1476 case BFD_RELOC_GPREL16: 1477 case BFD_RELOC_GPREL32: 1478 case BFD_RELOC_ALPHA_GPREL_HI16: 1479 case BFD_RELOC_ALPHA_GPREL_LO16: 1480 case BFD_RELOC_ALPHA_LINKAGE: 1481 case BFD_RELOC_ALPHA_CODEADDR: 1482 case BFD_RELOC_ALPHA_BRSGP: 1483 case BFD_RELOC_VTABLE_INHERIT: 1484 case BFD_RELOC_VTABLE_ENTRY: 1485 case BFD_RELOC_ALPHA_TLSGD: 1486 case BFD_RELOC_ALPHA_TLSLDM: 1487 case BFD_RELOC_ALPHA_GOTDTPREL16: 1488 case BFD_RELOC_ALPHA_DTPREL_HI16: 1489 case BFD_RELOC_ALPHA_DTPREL_LO16: 1490 case BFD_RELOC_ALPHA_DTPREL16: 1491 case BFD_RELOC_ALPHA_GOTTPREL16: 1492 case BFD_RELOC_ALPHA_TPREL_HI16: 1493 case BFD_RELOC_ALPHA_TPREL_LO16: 1494 case BFD_RELOC_ALPHA_TPREL16: 1495 return 1; 1496 1497 case BFD_RELOC_23_PCREL_S2: 1498 case BFD_RELOC_32: 1499 case BFD_RELOC_64: 1500 case BFD_RELOC_ALPHA_HINT: 1501 return 0; 1502 1503 default: 1504 return 0; 1505 } 1506} 1507 1508/* Return true if we can partially resolve a relocation now. */ 1509 1510int 1511alpha_fix_adjustable (f) 1512 fixS *f; 1513{ 1514#ifdef OBJ_ELF 1515 /* Prevent all adjustments to global symbols */ 1516 if (S_IS_EXTERN (f->fx_addsy) || S_IS_WEAK (f->fx_addsy)) 1517 return 0; 1518#endif 1519 1520 /* Are there any relocation types for which we must generate a reloc 1521 but we can adjust the values contained within it? */ 1522 switch (f->fx_r_type) 1523 { 1524 case BFD_RELOC_ALPHA_GPDISP_HI16: 1525 case BFD_RELOC_ALPHA_GPDISP_LO16: 1526 case BFD_RELOC_ALPHA_GPDISP: 1527 case BFD_RELOC_ALPHA_BRSGP: 1528 return 0; 1529 1530 case BFD_RELOC_ALPHA_LITERAL: 1531 case BFD_RELOC_ALPHA_ELF_LITERAL: 1532 case BFD_RELOC_ALPHA_LITUSE: 1533 case BFD_RELOC_ALPHA_LINKAGE: 1534 case BFD_RELOC_ALPHA_CODEADDR: 1535 return 1; 1536 1537 case BFD_RELOC_VTABLE_ENTRY: 1538 case BFD_RELOC_VTABLE_INHERIT: 1539 return 0; 1540 1541 case BFD_RELOC_GPREL16: 1542 case BFD_RELOC_GPREL32: 1543 case BFD_RELOC_ALPHA_GPREL_HI16: 1544 case BFD_RELOC_ALPHA_GPREL_LO16: 1545 case BFD_RELOC_23_PCREL_S2: 1546 case BFD_RELOC_32: 1547 case BFD_RELOC_64: 1548 case BFD_RELOC_ALPHA_HINT: 1549 return 1; 1550 1551 case BFD_RELOC_ALPHA_TLSGD: 1552 case BFD_RELOC_ALPHA_TLSLDM: 1553 case BFD_RELOC_ALPHA_GOTDTPREL16: 1554 case BFD_RELOC_ALPHA_DTPREL_HI16: 1555 case BFD_RELOC_ALPHA_DTPREL_LO16: 1556 case BFD_RELOC_ALPHA_DTPREL16: 1557 case BFD_RELOC_ALPHA_GOTTPREL16: 1558 case BFD_RELOC_ALPHA_TPREL_HI16: 1559 case BFD_RELOC_ALPHA_TPREL_LO16: 1560 case BFD_RELOC_ALPHA_TPREL16: 1561 /* ??? No idea why we can't return a reference to .tbss+10, but 1562 we're preventing this in the other assemblers. Follow for now. */ 1563 return 0; 1564 1565 default: 1566 return 1; 1567 } 1568 /*NOTREACHED*/ 1569} 1570 1571/* Generate the BFD reloc to be stuck in the object file from the 1572 fixup used internally in the assembler. */ 1573 1574arelent * 1575tc_gen_reloc (sec, fixp) 1576 asection *sec ATTRIBUTE_UNUSED; 1577 fixS *fixp; 1578{ 1579 arelent *reloc; 1580 1581 reloc = (arelent *) xmalloc (sizeof (arelent)); 1582 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); 1583 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); 1584 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; 1585 1586 /* Make sure none of our internal relocations make it this far. 1587 They'd better have been fully resolved by this point. */ 1588 assert ((int) fixp->fx_r_type > 0); 1589 1590 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); 1591 if (reloc->howto == NULL) 1592 { 1593 as_bad_where (fixp->fx_file, fixp->fx_line, 1594 _("cannot represent `%s' relocation in object file"), 1595 bfd_get_reloc_code_name (fixp->fx_r_type)); 1596 return NULL; 1597 } 1598 1599 if (!fixp->fx_pcrel != !reloc->howto->pc_relative) 1600 { 1601 as_fatal (_("internal error? cannot generate `%s' relocation"), 1602 bfd_get_reloc_code_name (fixp->fx_r_type)); 1603 } 1604 assert (!fixp->fx_pcrel == !reloc->howto->pc_relative); 1605 1606#ifdef OBJ_ECOFF 1607 if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL) 1608 { 1609 /* fake out bfd_perform_relocation. sigh */ 1610 reloc->addend = -alpha_gp_value; 1611 } 1612 else 1613#endif 1614 { 1615 reloc->addend = fixp->fx_offset; 1616#ifdef OBJ_ELF 1617 /* 1618 * Ohhh, this is ugly. The problem is that if this is a local global 1619 * symbol, the relocation will entirely be performed at link time, not 1620 * at assembly time. bfd_perform_reloc doesn't know about this sort 1621 * of thing, and as a result we need to fake it out here. 1622 */ 1623 if ((S_IS_EXTERN (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy) 1624 || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE) 1625 || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_THREAD_LOCAL)) 1626 && !S_IS_COMMON (fixp->fx_addsy)) 1627 reloc->addend -= symbol_get_bfdsym (fixp->fx_addsy)->value; 1628#endif 1629 } 1630 1631 return reloc; 1632} 1633 1634/* Parse a register name off of the input_line and return a register 1635 number. Gets md_undefined_symbol above to do the register name 1636 matching for us. 1637 1638 Only called as a part of processing the ECOFF .frame directive. */ 1639 1640int 1641tc_get_register (frame) 1642 int frame ATTRIBUTE_UNUSED; 1643{ 1644 int framereg = AXP_REG_SP; 1645 1646 SKIP_WHITESPACE (); 1647 if (*input_line_pointer == '$') 1648 { 1649 char *s = input_line_pointer; 1650 char c = get_symbol_end (); 1651 symbolS *sym = md_undefined_symbol (s); 1652 1653 *strchr (s, '\0') = c; 1654 if (sym && (framereg = S_GET_VALUE (sym)) <= 31) 1655 goto found; 1656 } 1657 as_warn (_("frame reg expected, using $%d."), framereg); 1658 1659found: 1660 note_gpreg (framereg); 1661 return framereg; 1662} 1663 1664/* This is called before the symbol table is processed. In order to 1665 work with gcc when using mips-tfile, we must keep all local labels. 1666 However, in other cases, we want to discard them. If we were 1667 called with -g, but we didn't see any debugging information, it may 1668 mean that gcc is smuggling debugging information through to 1669 mips-tfile, in which case we must generate all local labels. */ 1670 1671#ifdef OBJ_ECOFF 1672 1673void 1674alpha_frob_file_before_adjust () 1675{ 1676 if (alpha_debug != 0 1677 && ! ecoff_debugging_seen) 1678 flag_keep_locals = 1; 1679} 1680 1681#endif /* OBJ_ECOFF */ 1682 1683static struct alpha_reloc_tag * 1684get_alpha_reloc_tag (sequence) 1685 long sequence; 1686{ 1687 char buffer[ALPHA_RELOC_DIGITS]; 1688 struct alpha_reloc_tag *info; 1689 1690 sprintf (buffer, "!%ld", sequence); 1691 1692 info = (struct alpha_reloc_tag *) hash_find (alpha_literal_hash, buffer); 1693 if (! info) 1694 { 1695 size_t len = strlen (buffer); 1696 const char *errmsg; 1697 1698 info = (struct alpha_reloc_tag *) 1699 xcalloc (sizeof (struct alpha_reloc_tag) + len, 1); 1700 1701 info->segment = now_seg; 1702 info->sequence = sequence; 1703 strcpy (info->string, buffer); 1704 errmsg = hash_insert (alpha_literal_hash, info->string, (PTR) info); 1705 if (errmsg) 1706 as_fatal (errmsg); 1707 } 1708 1709 return info; 1710} 1711 1712/* Before the relocations are written, reorder them, so that user 1713 supplied !lituse relocations follow the appropriate !literal 1714 relocations, and similarly for !gpdisp relocations. */ 1715 1716void 1717alpha_adjust_symtab () 1718{ 1719 if (alpha_literal_hash) 1720 bfd_map_over_sections (stdoutput, alpha_adjust_symtab_relocs, NULL); 1721} 1722 1723static void 1724alpha_adjust_symtab_relocs (abfd, sec, ptr) 1725 bfd *abfd ATTRIBUTE_UNUSED; 1726 asection *sec; 1727 PTR ptr ATTRIBUTE_UNUSED; 1728{ 1729 segment_info_type *seginfo = seg_info (sec); 1730 fixS **prevP; 1731 fixS *fixp; 1732 fixS *next; 1733 fixS *slave; 1734 1735 /* If seginfo is NULL, we did not create this section; don't do 1736 anything with it. By using a pointer to a pointer, we can update 1737 the links in place. */ 1738 if (seginfo == NULL) 1739 return; 1740 1741 /* If there are no relocations, skip the section. */ 1742 if (! seginfo->fix_root) 1743 return; 1744 1745 /* First rebuild the fixup chain without the expicit lituse and 1746 gpdisp_lo16 relocs. */ 1747 prevP = &seginfo->fix_root; 1748 for (fixp = seginfo->fix_root; fixp; fixp = next) 1749 { 1750 next = fixp->fx_next; 1751 fixp->fx_next = (fixS *) 0; 1752 1753 switch (fixp->fx_r_type) 1754 { 1755 case BFD_RELOC_ALPHA_LITUSE: 1756 if (fixp->tc_fix_data.info->n_master == 0) 1757 as_bad_where (fixp->fx_file, fixp->fx_line, 1758 _("No !literal!%ld was found"), 1759 fixp->tc_fix_data.info->sequence); 1760 if (fixp->fx_offset == LITUSE_ALPHA_TLSGD) 1761 { 1762 if (! fixp->tc_fix_data.info->saw_tlsgd) 1763 as_bad_where (fixp->fx_file, fixp->fx_line, 1764 _("No !tlsgd!%ld was found"), 1765 fixp->tc_fix_data.info->sequence); 1766 } 1767 else if (fixp->fx_offset == LITUSE_ALPHA_TLSLDM) 1768 { 1769 if (! fixp->tc_fix_data.info->saw_tlsldm) 1770 as_bad_where (fixp->fx_file, fixp->fx_line, 1771 _("No !tlsldm!%ld was found"), 1772 fixp->tc_fix_data.info->sequence); 1773 } 1774 break; 1775 1776 case BFD_RELOC_ALPHA_GPDISP_LO16: 1777 if (fixp->tc_fix_data.info->n_master == 0) 1778 as_bad_where (fixp->fx_file, fixp->fx_line, 1779 _("No ldah !gpdisp!%ld was found"), 1780 fixp->tc_fix_data.info->sequence); 1781 break; 1782 1783 case BFD_RELOC_ALPHA_ELF_LITERAL: 1784 if (fixp->tc_fix_data.info 1785 && (fixp->tc_fix_data.info->saw_tlsgd 1786 || fixp->tc_fix_data.info->saw_tlsldm)) 1787 break; 1788 /* FALLTHRU */ 1789 1790 default: 1791 *prevP = fixp; 1792 prevP = &fixp->fx_next; 1793 break; 1794 } 1795 } 1796 1797 /* Go back and re-chain dependent relocations. They are currently 1798 linked through the next_reloc field in reverse order, so as we 1799 go through the next_reloc chain, we effectively reverse the chain 1800 once again. 1801 1802 Except if there is more than one !literal for a given sequence 1803 number. In that case, the programmer and/or compiler is not sure 1804 how control flows from literal to lituse, and we can't be sure to 1805 get the relaxation correct. 1806 1807 ??? Well, actually we could, if there are enough lituses such that 1808 we can make each literal have at least one of each lituse type 1809 present. Not implemented. 1810 1811 Also suppress the optimization if the !literals/!lituses are spread 1812 in different segments. This can happen with "intersting" uses of 1813 inline assembly; examples are present in the Linux kernel semaphores. */ 1814 1815 for (fixp = seginfo->fix_root; fixp; fixp = next) 1816 { 1817 next = fixp->fx_next; 1818 switch (fixp->fx_r_type) 1819 { 1820 case BFD_RELOC_ALPHA_TLSGD: 1821 case BFD_RELOC_ALPHA_TLSLDM: 1822 if (!fixp->tc_fix_data.info) 1823 break; 1824 if (fixp->tc_fix_data.info->n_master == 0) 1825 break; 1826 else if (fixp->tc_fix_data.info->n_master > 1) 1827 { 1828 as_bad_where (fixp->fx_file, fixp->fx_line, 1829 _("too many !literal!%ld for %s"), 1830 fixp->tc_fix_data.info->sequence, 1831 (fixp->fx_r_type == BFD_RELOC_ALPHA_TLSGD 1832 ? "!tlsgd" : "!tlsldm")); 1833 break; 1834 } 1835 1836 fixp->tc_fix_data.info->master->fx_next = fixp->fx_next; 1837 fixp->fx_next = fixp->tc_fix_data.info->master; 1838 fixp = fixp->fx_next; 1839 /* FALLTHRU */ 1840 1841 case BFD_RELOC_ALPHA_ELF_LITERAL: 1842 if (fixp->tc_fix_data.info 1843 && fixp->tc_fix_data.info->n_master == 1 1844 && ! fixp->tc_fix_data.info->multi_section_p) 1845 { 1846 for (slave = fixp->tc_fix_data.info->slaves; 1847 slave != (fixS *) 0; 1848 slave = slave->tc_fix_data.next_reloc) 1849 { 1850 slave->fx_next = fixp->fx_next; 1851 fixp->fx_next = slave; 1852 } 1853 } 1854 break; 1855 1856 case BFD_RELOC_ALPHA_GPDISP_HI16: 1857 if (fixp->tc_fix_data.info->n_slaves == 0) 1858 as_bad_where (fixp->fx_file, fixp->fx_line, 1859 _("No lda !gpdisp!%ld was found"), 1860 fixp->tc_fix_data.info->sequence); 1861 else 1862 { 1863 slave = fixp->tc_fix_data.info->slaves; 1864 slave->fx_next = next; 1865 fixp->fx_next = slave; 1866 } 1867 break; 1868 1869 default: 1870 break; 1871 } 1872 } 1873} 1874 1875#ifdef DEBUG_ALPHA 1876static void 1877debug_exp (tok, ntok) 1878 expressionS tok[]; 1879 int ntok; 1880{ 1881 int i; 1882 1883 fprintf (stderr, "debug_exp: %d tokens", ntok); 1884 for (i = 0; i < ntok; i++) 1885 { 1886 expressionS *t = &tok[i]; 1887 const char *name; 1888 switch (t->X_op) 1889 { 1890 default: name = "unknown"; break; 1891 case O_illegal: name = "O_illegal"; break; 1892 case O_absent: name = "O_absent"; break; 1893 case O_constant: name = "O_constant"; break; 1894 case O_symbol: name = "O_symbol"; break; 1895 case O_symbol_rva: name = "O_symbol_rva"; break; 1896 case O_register: name = "O_register"; break; 1897 case O_big: name = "O_big"; break; 1898 case O_uminus: name = "O_uminus"; break; 1899 case O_bit_not: name = "O_bit_not"; break; 1900 case O_logical_not: name = "O_logical_not"; break; 1901 case O_multiply: name = "O_multiply"; break; 1902 case O_divide: name = "O_divide"; break; 1903 case O_modulus: name = "O_modulus"; break; 1904 case O_left_shift: name = "O_left_shift"; break; 1905 case O_right_shift: name = "O_right_shift"; break; 1906 case O_bit_inclusive_or: name = "O_bit_inclusive_or"; break; 1907 case O_bit_or_not: name = "O_bit_or_not"; break; 1908 case O_bit_exclusive_or: name = "O_bit_exclusive_or"; break; 1909 case O_bit_and: name = "O_bit_and"; break; 1910 case O_add: name = "O_add"; break; 1911 case O_subtract: name = "O_subtract"; break; 1912 case O_eq: name = "O_eq"; break; 1913 case O_ne: name = "O_ne"; break; 1914 case O_lt: name = "O_lt"; break; 1915 case O_le: name = "O_le"; break; 1916 case O_ge: name = "O_ge"; break; 1917 case O_gt: name = "O_gt"; break; 1918 case O_logical_and: name = "O_logical_and"; break; 1919 case O_logical_or: name = "O_logical_or"; break; 1920 case O_index: name = "O_index"; break; 1921 case O_pregister: name = "O_pregister"; break; 1922 case O_cpregister: name = "O_cpregister"; break; 1923 case O_literal: name = "O_literal"; break; 1924 case O_lituse_addr: name = "O_lituse_addr"; break; 1925 case O_lituse_base: name = "O_lituse_base"; break; 1926 case O_lituse_bytoff: name = "O_lituse_bytoff"; break; 1927 case O_lituse_jsr: name = "O_lituse_jsr"; break; 1928 case O_lituse_tlsgd: name = "O_lituse_tlsgd"; break; 1929 case O_lituse_tlsldm: name = "O_lituse_tlsldm"; break; 1930 case O_gpdisp: name = "O_gpdisp"; break; 1931 case O_gprelhigh: name = "O_gprelhigh"; break; 1932 case O_gprellow: name = "O_gprellow"; break; 1933 case O_gprel: name = "O_gprel"; break; 1934 case O_samegp: name = "O_samegp"; break; 1935 case O_tlsgd: name = "O_tlsgd"; break; 1936 case O_tlsldm: name = "O_tlsldm"; break; 1937 case O_gotdtprel: name = "O_gotdtprel"; break; 1938 case O_dtprelhi: name = "O_dtprelhi"; break; 1939 case O_dtprello: name = "O_dtprello"; break; 1940 case O_dtprel: name = "O_dtprel"; break; 1941 case O_gottprel: name = "O_gottprel"; break; 1942 case O_tprelhi: name = "O_tprelhi"; break; 1943 case O_tprello: name = "O_tprello"; break; 1944 case O_tprel: name = "O_tprel"; break; 1945 } 1946 1947 fprintf (stderr, ", %s(%s, %s, %d)", name, 1948 (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--", 1949 (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--", 1950 (int) t->X_add_number); 1951 } 1952 fprintf (stderr, "\n"); 1953 fflush (stderr); 1954} 1955#endif 1956 1957/* Parse the arguments to an opcode. */ 1958 1959static int 1960tokenize_arguments (str, tok, ntok) 1961 char *str; 1962 expressionS tok[]; 1963 int ntok; 1964{ 1965 expressionS *end_tok = tok + ntok; 1966 char *old_input_line_pointer; 1967 int saw_comma = 0, saw_arg = 0; 1968#ifdef DEBUG_ALPHA 1969 expressionS *orig_tok = tok; 1970#endif 1971 char *p; 1972 const struct alpha_reloc_op_tag *r; 1973 int c, i; 1974 size_t len; 1975 int reloc_found_p = 0; 1976 1977 memset (tok, 0, sizeof (*tok) * ntok); 1978 1979 /* Save and restore input_line_pointer around this function */ 1980 old_input_line_pointer = input_line_pointer; 1981 input_line_pointer = str; 1982 1983#ifdef RELOC_OP_P 1984 /* ??? Wrest control of ! away from the regular expression parser. */ 1985 is_end_of_line[(unsigned char) '!'] = 1; 1986#endif 1987 1988 while (tok < end_tok && *input_line_pointer) 1989 { 1990 SKIP_WHITESPACE (); 1991 switch (*input_line_pointer) 1992 { 1993 case '\0': 1994 goto fini; 1995 1996#ifdef RELOC_OP_P 1997 case '!': 1998 /* A relocation operand can be placed after the normal operand on an 1999 assembly language statement, and has the following form: 2000 !relocation_type!sequence_number. */ 2001 if (reloc_found_p) 2002 { /* only support one relocation op per insn */ 2003 as_bad (_("More than one relocation op per insn")); 2004 goto err_report; 2005 } 2006 2007 if (!saw_arg) 2008 goto err; 2009 2010 ++input_line_pointer; 2011 SKIP_WHITESPACE (); 2012 p = input_line_pointer; 2013 c = get_symbol_end (); 2014 2015 /* Parse !relocation_type */ 2016 len = input_line_pointer - p; 2017 if (len == 0) 2018 { 2019 as_bad (_("No relocation operand")); 2020 goto err_report; 2021 } 2022 2023 r = &alpha_reloc_op[0]; 2024 for (i = alpha_num_reloc_op - 1; i >= 0; i--, r++) 2025 if (len == r->length && memcmp (p, r->name, len) == 0) 2026 break; 2027 if (i < 0) 2028 { 2029 as_bad (_("Unknown relocation operand: !%s"), p); 2030 goto err_report; 2031 } 2032 2033 *input_line_pointer = c; 2034 SKIP_WHITESPACE (); 2035 if (*input_line_pointer != '!') 2036 { 2037 if (r->require_seq) 2038 { 2039 as_bad (_("no sequence number after !%s"), p); 2040 goto err_report; 2041 } 2042 2043 tok->X_add_number = 0; 2044 } 2045 else 2046 { 2047 if (! r->allow_seq) 2048 { 2049 as_bad (_("!%s does not use a sequence number"), p); 2050 goto err_report; 2051 } 2052 2053 input_line_pointer++; 2054 2055 /* Parse !sequence_number */ 2056 expression (tok); 2057 if (tok->X_op != O_constant || tok->X_add_number <= 0) 2058 { 2059 as_bad (_("Bad sequence number: !%s!%s"), 2060 r->name, input_line_pointer); 2061 goto err_report; 2062 } 2063 } 2064 2065 tok->X_op = r->op; 2066 reloc_found_p = 1; 2067 ++tok; 2068 break; 2069#endif /* RELOC_OP_P */ 2070 2071 case ',': 2072 ++input_line_pointer; 2073 if (saw_comma || !saw_arg) 2074 goto err; 2075 saw_comma = 1; 2076 break; 2077 2078 case '(': 2079 { 2080 char *hold = input_line_pointer++; 2081 2082 /* First try for parenthesized register ... */ 2083 expression (tok); 2084 if (*input_line_pointer == ')' && tok->X_op == O_register) 2085 { 2086 tok->X_op = (saw_comma ? O_cpregister : O_pregister); 2087 saw_comma = 0; 2088 saw_arg = 1; 2089 ++input_line_pointer; 2090 ++tok; 2091 break; 2092 } 2093 2094 /* ... then fall through to plain expression */ 2095 input_line_pointer = hold; 2096 } 2097 2098 default: 2099 if (saw_arg && !saw_comma) 2100 goto err; 2101 2102 expression (tok); 2103 if (tok->X_op == O_illegal || tok->X_op == O_absent) 2104 goto err; 2105 2106 saw_comma = 0; 2107 saw_arg = 1; 2108 ++tok; 2109 break; 2110 } 2111 } 2112 2113fini: 2114 if (saw_comma) 2115 goto err; 2116 input_line_pointer = old_input_line_pointer; 2117 2118#ifdef DEBUG_ALPHA 2119 debug_exp (orig_tok, ntok - (end_tok - tok)); 2120#endif 2121#ifdef RELOC_OP_P 2122 is_end_of_line[(unsigned char) '!'] = 0; 2123#endif 2124 2125 return ntok - (end_tok - tok); 2126 2127err: 2128#ifdef RELOC_OP_P 2129 is_end_of_line[(unsigned char) '!'] = 0; 2130#endif 2131 input_line_pointer = old_input_line_pointer; 2132 return TOKENIZE_ERROR; 2133 2134err_report: 2135#ifdef RELOC_OP_P 2136 is_end_of_line[(unsigned char) '!'] = 0; 2137#endif 2138 input_line_pointer = old_input_line_pointer; 2139 return TOKENIZE_ERROR_REPORT; 2140} 2141 2142/* Search forward through all variants of an opcode looking for a 2143 syntax match. */ 2144 2145static const struct alpha_opcode * 2146find_opcode_match (first_opcode, tok, pntok, pcpumatch) 2147 const struct alpha_opcode *first_opcode; 2148 const expressionS *tok; 2149 int *pntok; 2150 int *pcpumatch; 2151{ 2152 const struct alpha_opcode *opcode = first_opcode; 2153 int ntok = *pntok; 2154 int got_cpu_match = 0; 2155 2156 do 2157 { 2158 const unsigned char *opidx; 2159 int tokidx = 0; 2160 2161 /* Don't match opcodes that don't exist on this architecture */ 2162 if (!(opcode->flags & alpha_target)) 2163 goto match_failed; 2164 2165 got_cpu_match = 1; 2166 2167 for (opidx = opcode->operands; *opidx; ++opidx) 2168 { 2169 const struct alpha_operand *operand = &alpha_operands[*opidx]; 2170 2171 /* only take input from real operands */ 2172 if (operand->flags & AXP_OPERAND_FAKE) 2173 continue; 2174 2175 /* when we expect input, make sure we have it */ 2176 if (tokidx >= ntok) 2177 { 2178 if ((operand->flags & AXP_OPERAND_OPTIONAL_MASK) == 0) 2179 goto match_failed; 2180 continue; 2181 } 2182 2183 /* match operand type with expression type */ 2184 switch (operand->flags & AXP_OPERAND_TYPECHECK_MASK) 2185 { 2186 case AXP_OPERAND_IR: 2187 if (tok[tokidx].X_op != O_register 2188 || !is_ir_num (tok[tokidx].X_add_number)) 2189 goto match_failed; 2190 break; 2191 case AXP_OPERAND_FPR: 2192 if (tok[tokidx].X_op != O_register 2193 || !is_fpr_num (tok[tokidx].X_add_number)) 2194 goto match_failed; 2195 break; 2196 case AXP_OPERAND_IR | AXP_OPERAND_PARENS: 2197 if (tok[tokidx].X_op != O_pregister 2198 || !is_ir_num (tok[tokidx].X_add_number)) 2199 goto match_failed; 2200 break; 2201 case AXP_OPERAND_IR | AXP_OPERAND_PARENS | AXP_OPERAND_COMMA: 2202 if (tok[tokidx].X_op != O_cpregister 2203 || !is_ir_num (tok[tokidx].X_add_number)) 2204 goto match_failed; 2205 break; 2206 2207 case AXP_OPERAND_RELATIVE: 2208 case AXP_OPERAND_SIGNED: 2209 case AXP_OPERAND_UNSIGNED: 2210 switch (tok[tokidx].X_op) 2211 { 2212 case O_illegal: 2213 case O_absent: 2214 case O_register: 2215 case O_pregister: 2216 case O_cpregister: 2217 goto match_failed; 2218 2219 default: 2220 break; 2221 } 2222 break; 2223 2224 default: 2225 /* everything else should have been fake */ 2226 abort (); 2227 } 2228 ++tokidx; 2229 } 2230 2231 /* possible match -- did we use all of our input? */ 2232 if (tokidx == ntok) 2233 { 2234 *pntok = ntok; 2235 return opcode; 2236 } 2237 2238 match_failed:; 2239 } 2240 while (++opcode - alpha_opcodes < alpha_num_opcodes 2241 && !strcmp (opcode->name, first_opcode->name)); 2242 2243 if (*pcpumatch) 2244 *pcpumatch = got_cpu_match; 2245 2246 return NULL; 2247} 2248 2249/* Search forward through all variants of a macro looking for a syntax 2250 match. */ 2251 2252static const struct alpha_macro * 2253find_macro_match (first_macro, tok, pntok) 2254 const struct alpha_macro *first_macro; 2255 const expressionS *tok; 2256 int *pntok; 2257{ 2258 const struct alpha_macro *macro = first_macro; 2259 int ntok = *pntok; 2260 2261 do 2262 { 2263 const enum alpha_macro_arg *arg = macro->argsets; 2264 int tokidx = 0; 2265 2266 while (*arg) 2267 { 2268 switch (*arg) 2269 { 2270 case MACRO_EOA: 2271 if (tokidx == ntok) 2272 return macro; 2273 else 2274 tokidx = 0; 2275 break; 2276 2277 /* index register */ 2278 case MACRO_IR: 2279 if (tokidx >= ntok || tok[tokidx].X_op != O_register 2280 || !is_ir_num (tok[tokidx].X_add_number)) 2281 goto match_failed; 2282 ++tokidx; 2283 break; 2284 2285 /* parenthesized index register */ 2286 case MACRO_PIR: 2287 if (tokidx >= ntok || tok[tokidx].X_op != O_pregister 2288 || !is_ir_num (tok[tokidx].X_add_number)) 2289 goto match_failed; 2290 ++tokidx; 2291 break; 2292 2293 /* optional parenthesized index register */ 2294 case MACRO_OPIR: 2295 if (tokidx < ntok && tok[tokidx].X_op == O_pregister 2296 && is_ir_num (tok[tokidx].X_add_number)) 2297 ++tokidx; 2298 break; 2299 2300 /* leading comma with a parenthesized index register */ 2301 case MACRO_CPIR: 2302 if (tokidx >= ntok || tok[tokidx].X_op != O_cpregister 2303 || !is_ir_num (tok[tokidx].X_add_number)) 2304 goto match_failed; 2305 ++tokidx; 2306 break; 2307 2308 /* floating point register */ 2309 case MACRO_FPR: 2310 if (tokidx >= ntok || tok[tokidx].X_op != O_register 2311 || !is_fpr_num (tok[tokidx].X_add_number)) 2312 goto match_failed; 2313 ++tokidx; 2314 break; 2315 2316 /* normal expression */ 2317 case MACRO_EXP: 2318 if (tokidx >= ntok) 2319 goto match_failed; 2320 switch (tok[tokidx].X_op) 2321 { 2322 case O_illegal: 2323 case O_absent: 2324 case O_register: 2325 case O_pregister: 2326 case O_cpregister: 2327 case O_literal: 2328 case O_lituse_base: 2329 case O_lituse_bytoff: 2330 case O_lituse_jsr: 2331 case O_gpdisp: 2332 case O_gprelhigh: 2333 case O_gprellow: 2334 case O_gprel: 2335 case O_samegp: 2336 goto match_failed; 2337 2338 default: 2339 break; 2340 } 2341 ++tokidx; 2342 break; 2343 2344 match_failed: 2345 while (*arg != MACRO_EOA) 2346 ++arg; 2347 tokidx = 0; 2348 break; 2349 } 2350 ++arg; 2351 } 2352 } 2353 while (++macro - alpha_macros < alpha_num_macros 2354 && !strcmp (macro->name, first_macro->name)); 2355 2356 return NULL; 2357} 2358 2359/* Insert an operand value into an instruction. */ 2360 2361static unsigned 2362insert_operand (insn, operand, val, file, line) 2363 unsigned insn; 2364 const struct alpha_operand *operand; 2365 offsetT val; 2366 char *file; 2367 unsigned line; 2368{ 2369 if (operand->bits != 32 && !(operand->flags & AXP_OPERAND_NOOVERFLOW)) 2370 { 2371 offsetT min, max; 2372 2373 if (operand->flags & AXP_OPERAND_SIGNED) 2374 { 2375 max = (1 << (operand->bits - 1)) - 1; 2376 min = -(1 << (operand->bits - 1)); 2377 } 2378 else 2379 { 2380 max = (1 << operand->bits) - 1; 2381 min = 0; 2382 } 2383 2384 if (val < min || val > max) 2385 { 2386 const char *err = 2387 _("operand out of range (%s not between %d and %d)"); 2388 char buf[sizeof (val) * 3 + 2]; 2389 2390 sprint_value (buf, val); 2391 if (file) 2392 as_warn_where (file, line, err, buf, min, max); 2393 else 2394 as_warn (err, buf, min, max); 2395 } 2396 } 2397 2398 if (operand->insert) 2399 { 2400 const char *errmsg = NULL; 2401 2402 insn = (*operand->insert) (insn, val, &errmsg); 2403 if (errmsg) 2404 as_warn (errmsg); 2405 } 2406 else 2407 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift); 2408 2409 return insn; 2410} 2411 2412/* 2413 * Turn an opcode description and a set of arguments into 2414 * an instruction and a fixup. 2415 */ 2416 2417static void 2418assemble_insn (opcode, tok, ntok, insn, reloc) 2419 const struct alpha_opcode *opcode; 2420 const expressionS *tok; 2421 int ntok; 2422 struct alpha_insn *insn; 2423 bfd_reloc_code_real_type reloc; 2424{ 2425 const struct alpha_operand *reloc_operand = NULL; 2426 const expressionS *reloc_exp = NULL; 2427 const unsigned char *argidx; 2428 unsigned image; 2429 int tokidx = 0; 2430 2431 memset (insn, 0, sizeof (*insn)); 2432 image = opcode->opcode; 2433 2434 for (argidx = opcode->operands; *argidx; ++argidx) 2435 { 2436 const struct alpha_operand *operand = &alpha_operands[*argidx]; 2437 const expressionS *t = (const expressionS *) 0; 2438 2439 if (operand->flags & AXP_OPERAND_FAKE) 2440 { 2441 /* fake operands take no value and generate no fixup */ 2442 image = insert_operand (image, operand, 0, NULL, 0); 2443 continue; 2444 } 2445 2446 if (tokidx >= ntok) 2447 { 2448 switch (operand->flags & AXP_OPERAND_OPTIONAL_MASK) 2449 { 2450 case AXP_OPERAND_DEFAULT_FIRST: 2451 t = &tok[0]; 2452 break; 2453 case AXP_OPERAND_DEFAULT_SECOND: 2454 t = &tok[1]; 2455 break; 2456 case AXP_OPERAND_DEFAULT_ZERO: 2457 { 2458 static expressionS zero_exp; 2459 t = &zero_exp; 2460 zero_exp.X_op = O_constant; 2461 zero_exp.X_unsigned = 1; 2462 } 2463 break; 2464 default: 2465 abort (); 2466 } 2467 } 2468 else 2469 t = &tok[tokidx++]; 2470 2471 switch (t->X_op) 2472 { 2473 case O_register: 2474 case O_pregister: 2475 case O_cpregister: 2476 image = insert_operand (image, operand, regno (t->X_add_number), 2477 NULL, 0); 2478 break; 2479 2480 case O_constant: 2481 image = insert_operand (image, operand, t->X_add_number, NULL, 0); 2482 assert (reloc_operand == NULL); 2483 reloc_operand = operand; 2484 reloc_exp = t; 2485 break; 2486 2487 default: 2488 /* This is only 0 for fields that should contain registers, 2489 which means this pattern shouldn't have matched. */ 2490 if (operand->default_reloc == 0) 2491 abort (); 2492 2493 /* There is one special case for which an insn receives two 2494 relocations, and thus the user-supplied reloc does not 2495 override the operand reloc. */ 2496 if (operand->default_reloc == BFD_RELOC_ALPHA_HINT) 2497 { 2498 struct alpha_fixup *fixup; 2499 2500 if (insn->nfixups >= MAX_INSN_FIXUPS) 2501 as_fatal (_("too many fixups")); 2502 2503 fixup = &insn->fixups[insn->nfixups++]; 2504 fixup->exp = *t; 2505 fixup->reloc = BFD_RELOC_ALPHA_HINT; 2506 } 2507 else 2508 { 2509 if (reloc == BFD_RELOC_UNUSED) 2510 reloc = operand->default_reloc; 2511 2512 assert (reloc_operand == NULL); 2513 reloc_operand = operand; 2514 reloc_exp = t; 2515 } 2516 break; 2517 } 2518 } 2519 2520 if (reloc != BFD_RELOC_UNUSED) 2521 { 2522 struct alpha_fixup *fixup; 2523 2524 if (insn->nfixups >= MAX_INSN_FIXUPS) 2525 as_fatal (_("too many fixups")); 2526 2527 /* ??? My but this is hacky. But the OSF/1 assembler uses the same 2528 relocation tag for both ldah and lda with gpdisp. Choose the 2529 correct internal relocation based on the opcode. */ 2530 if (reloc == BFD_RELOC_ALPHA_GPDISP) 2531 { 2532 if (strcmp (opcode->name, "ldah") == 0) 2533 reloc = BFD_RELOC_ALPHA_GPDISP_HI16; 2534 else if (strcmp (opcode->name, "lda") == 0) 2535 reloc = BFD_RELOC_ALPHA_GPDISP_LO16; 2536 else 2537 as_bad (_("invalid relocation for instruction")); 2538 } 2539 2540 /* If this is a real relocation (as opposed to a lituse hint), then 2541 the relocation width should match the operand width. */ 2542 else if (reloc < BFD_RELOC_UNUSED) 2543 { 2544 reloc_howto_type *reloc_howto 2545 = bfd_reloc_type_lookup (stdoutput, reloc); 2546 if (reloc_howto->bitsize != reloc_operand->bits) 2547 { 2548 as_bad (_("invalid relocation for field")); 2549 return; 2550 } 2551 } 2552 2553 fixup = &insn->fixups[insn->nfixups++]; 2554 if (reloc_exp) 2555 fixup->exp = *reloc_exp; 2556 else 2557 fixup->exp.X_op = O_absent; 2558 fixup->reloc = reloc; 2559 } 2560 2561 insn->insn = image; 2562} 2563 2564/* 2565 * Actually output an instruction with its fixup. 2566 */ 2567 2568static void 2569emit_insn (insn) 2570 struct alpha_insn *insn; 2571{ 2572 char *f; 2573 int i; 2574 2575 /* Take care of alignment duties. */ 2576 if (alpha_auto_align_on && alpha_current_align < 2) 2577 alpha_align (2, (char *) NULL, alpha_insn_label, 0); 2578 if (alpha_current_align > 2) 2579 alpha_current_align = 2; 2580 alpha_insn_label = NULL; 2581 2582 /* Write out the instruction. */ 2583 f = frag_more (4); 2584 md_number_to_chars (f, insn->insn, 4); 2585 2586#ifdef OBJ_ELF 2587 dwarf2_emit_insn (4); 2588#endif 2589 2590 /* Apply the fixups in order */ 2591 for (i = 0; i < insn->nfixups; ++i) 2592 { 2593 const struct alpha_operand *operand = (const struct alpha_operand *) 0; 2594 struct alpha_fixup *fixup = &insn->fixups[i]; 2595 struct alpha_reloc_tag *info = NULL; 2596 int size, pcrel; 2597 fixS *fixP; 2598 2599 /* Some fixups are only used internally and so have no howto */ 2600 if ((int) fixup->reloc < 0) 2601 { 2602 operand = &alpha_operands[-(int) fixup->reloc]; 2603 size = 4; 2604 pcrel = ((operand->flags & AXP_OPERAND_RELATIVE) != 0); 2605 } 2606 else if (fixup->reloc > BFD_RELOC_UNUSED 2607 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16 2608 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16) 2609 { 2610 size = 2; 2611 pcrel = 0; 2612 } 2613 else 2614 { 2615 reloc_howto_type *reloc_howto 2616 = bfd_reloc_type_lookup (stdoutput, fixup->reloc); 2617 assert (reloc_howto); 2618 2619 size = bfd_get_reloc_size (reloc_howto); 2620 assert (size >= 1 && size <= 4); 2621 2622 pcrel = reloc_howto->pc_relative; 2623 } 2624 2625 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size, 2626 &fixup->exp, pcrel, fixup->reloc); 2627 2628 /* Turn off complaints that the addend is too large for some fixups, 2629 and copy in the sequence number for the explicit relocations. */ 2630 switch (fixup->reloc) 2631 { 2632 case BFD_RELOC_ALPHA_HINT: 2633 case BFD_RELOC_GPREL32: 2634 case BFD_RELOC_GPREL16: 2635 case BFD_RELOC_ALPHA_GPREL_HI16: 2636 case BFD_RELOC_ALPHA_GPREL_LO16: 2637 case BFD_RELOC_ALPHA_GOTDTPREL16: 2638 case BFD_RELOC_ALPHA_DTPREL_HI16: 2639 case BFD_RELOC_ALPHA_DTPREL_LO16: 2640 case BFD_RELOC_ALPHA_DTPREL16: 2641 case BFD_RELOC_ALPHA_GOTTPREL16: 2642 case BFD_RELOC_ALPHA_TPREL_HI16: 2643 case BFD_RELOC_ALPHA_TPREL_LO16: 2644 case BFD_RELOC_ALPHA_TPREL16: 2645 fixP->fx_no_overflow = 1; 2646 break; 2647 2648 case BFD_RELOC_ALPHA_GPDISP_HI16: 2649 fixP->fx_no_overflow = 1; 2650 fixP->fx_addsy = section_symbol (now_seg); 2651 fixP->fx_offset = 0; 2652 2653 info = get_alpha_reloc_tag (insn->sequence); 2654 if (++info->n_master > 1) 2655 as_bad (_("too many ldah insns for !gpdisp!%ld"), insn->sequence); 2656 if (info->segment != now_seg) 2657 as_bad (_("both insns for !gpdisp!%ld must be in the same section"), 2658 insn->sequence); 2659 fixP->tc_fix_data.info = info; 2660 break; 2661 2662 case BFD_RELOC_ALPHA_GPDISP_LO16: 2663 fixP->fx_no_overflow = 1; 2664 2665 info = get_alpha_reloc_tag (insn->sequence); 2666 if (++info->n_slaves > 1) 2667 as_bad (_("too many lda insns for !gpdisp!%ld"), insn->sequence); 2668 if (info->segment != now_seg) 2669 as_bad (_("both insns for !gpdisp!%ld must be in the same section"), 2670 insn->sequence); 2671 fixP->tc_fix_data.info = info; 2672 info->slaves = fixP; 2673 break; 2674 2675 case BFD_RELOC_ALPHA_LITERAL: 2676 case BFD_RELOC_ALPHA_ELF_LITERAL: 2677 fixP->fx_no_overflow = 1; 2678 2679 if (insn->sequence == 0) 2680 break; 2681 info = get_alpha_reloc_tag (insn->sequence); 2682 info->master = fixP; 2683 info->n_master++; 2684 if (info->segment != now_seg) 2685 info->multi_section_p = 1; 2686 fixP->tc_fix_data.info = info; 2687 break; 2688 2689 case DUMMY_RELOC_LITUSE_ADDR: 2690 fixP->fx_offset = LITUSE_ALPHA_ADDR; 2691 goto do_lituse; 2692 case DUMMY_RELOC_LITUSE_BASE: 2693 fixP->fx_offset = LITUSE_ALPHA_BASE; 2694 goto do_lituse; 2695 case DUMMY_RELOC_LITUSE_BYTOFF: 2696 fixP->fx_offset = LITUSE_ALPHA_BYTOFF; 2697 goto do_lituse; 2698 case DUMMY_RELOC_LITUSE_JSR: 2699 fixP->fx_offset = LITUSE_ALPHA_JSR; 2700 goto do_lituse; 2701 case DUMMY_RELOC_LITUSE_TLSGD: 2702 fixP->fx_offset = LITUSE_ALPHA_TLSGD; 2703 goto do_lituse; 2704 case DUMMY_RELOC_LITUSE_TLSLDM: 2705 fixP->fx_offset = LITUSE_ALPHA_TLSLDM; 2706 goto do_lituse; 2707 do_lituse: 2708 fixP->fx_addsy = section_symbol (now_seg); 2709 fixP->fx_r_type = BFD_RELOC_ALPHA_LITUSE; 2710 2711 info = get_alpha_reloc_tag (insn->sequence); 2712 if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSGD) 2713 info->saw_lu_tlsgd = 1; 2714 else if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSLDM) 2715 info->saw_lu_tlsldm = 1; 2716 if (++info->n_slaves > 1) 2717 { 2718 if (info->saw_lu_tlsgd) 2719 as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"), 2720 insn->sequence); 2721 else if (info->saw_lu_tlsldm) 2722 as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"), 2723 insn->sequence); 2724 } 2725 fixP->tc_fix_data.info = info; 2726 fixP->tc_fix_data.next_reloc = info->slaves; 2727 info->slaves = fixP; 2728 if (info->segment != now_seg) 2729 info->multi_section_p = 1; 2730 break; 2731 2732 case BFD_RELOC_ALPHA_TLSGD: 2733 fixP->fx_no_overflow = 1; 2734 2735 if (insn->sequence == 0) 2736 break; 2737 info = get_alpha_reloc_tag (insn->sequence); 2738 if (info->saw_tlsgd) 2739 as_bad (_("duplicate !tlsgd!%ld"), insn->sequence); 2740 else if (info->saw_tlsldm) 2741 as_bad (_("sequence number in use for !tlsldm!%ld"), 2742 insn->sequence); 2743 else 2744 info->saw_tlsgd = 1; 2745 fixP->tc_fix_data.info = info; 2746 break; 2747 2748 case BFD_RELOC_ALPHA_TLSLDM: 2749 fixP->fx_no_overflow = 1; 2750 2751 if (insn->sequence == 0) 2752 break; 2753 info = get_alpha_reloc_tag (insn->sequence); 2754 if (info->saw_tlsldm) 2755 as_bad (_("duplicate !tlsldm!%ld"), insn->sequence); 2756 else if (info->saw_tlsgd) 2757 as_bad (_("sequence number in use for !tlsgd!%ld"), 2758 insn->sequence); 2759 else 2760 info->saw_tlsldm = 1; 2761 fixP->tc_fix_data.info = info; 2762 break; 2763 2764 default: 2765 if ((int) fixup->reloc < 0) 2766 { 2767 if (operand->flags & AXP_OPERAND_NOOVERFLOW) 2768 fixP->fx_no_overflow = 1; 2769 } 2770 break; 2771 } 2772 } 2773} 2774 2775/* Given an opcode name and a pre-tokenized set of arguments, assemble 2776 the insn, but do not emit it. 2777 2778 Note that this implies no macros allowed, since we can't store more 2779 than one insn in an insn structure. */ 2780 2781static void 2782assemble_tokens_to_insn (opname, tok, ntok, insn) 2783 const char *opname; 2784 const expressionS *tok; 2785 int ntok; 2786 struct alpha_insn *insn; 2787{ 2788 const struct alpha_opcode *opcode; 2789 2790 /* search opcodes */ 2791 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname); 2792 if (opcode) 2793 { 2794 int cpumatch; 2795 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch); 2796 if (opcode) 2797 { 2798 assemble_insn (opcode, tok, ntok, insn, BFD_RELOC_UNUSED); 2799 return; 2800 } 2801 else if (cpumatch) 2802 as_bad (_("inappropriate arguments for opcode `%s'"), opname); 2803 else 2804 as_bad (_("opcode `%s' not supported for target %s"), opname, 2805 alpha_target_name); 2806 } 2807 else 2808 as_bad (_("unknown opcode `%s'"), opname); 2809} 2810 2811/* Given an opcode name and a pre-tokenized set of arguments, take the 2812 opcode all the way through emission. */ 2813 2814static void 2815assemble_tokens (opname, tok, ntok, local_macros_on) 2816 const char *opname; 2817 const expressionS *tok; 2818 int ntok; 2819 int local_macros_on; 2820{ 2821 int found_something = 0; 2822 const struct alpha_opcode *opcode; 2823 const struct alpha_macro *macro; 2824 int cpumatch = 1; 2825 bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED; 2826 2827#ifdef RELOC_OP_P 2828 /* If a user-specified relocation is present, this is not a macro. */ 2829 if (ntok && USER_RELOC_P (tok[ntok - 1].X_op)) 2830 { 2831 reloc = ALPHA_RELOC_TABLE (tok[ntok - 1].X_op)->reloc; 2832 ntok--; 2833 } 2834 else 2835#endif 2836 if (local_macros_on) 2837 { 2838 macro = ((const struct alpha_macro *) 2839 hash_find (alpha_macro_hash, opname)); 2840 if (macro) 2841 { 2842 found_something = 1; 2843 macro = find_macro_match (macro, tok, &ntok); 2844 if (macro) 2845 { 2846 (*macro->emit) (tok, ntok, macro->arg); 2847 return; 2848 } 2849 } 2850 } 2851 2852 /* search opcodes */ 2853 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname); 2854 if (opcode) 2855 { 2856 found_something = 1; 2857 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch); 2858 if (opcode) 2859 { 2860 struct alpha_insn insn; 2861 assemble_insn (opcode, tok, ntok, &insn, reloc); 2862 2863 /* Copy the sequence number for the reloc from the reloc token. */ 2864 if (reloc != BFD_RELOC_UNUSED) 2865 insn.sequence = tok[ntok].X_add_number; 2866 2867 emit_insn (&insn); 2868 return; 2869 } 2870 } 2871 2872 if (found_something) 2873 { 2874 if (cpumatch) 2875 as_bad (_("inappropriate arguments for opcode `%s'"), opname); 2876 else 2877 as_bad (_("opcode `%s' not supported for target %s"), opname, 2878 alpha_target_name); 2879 } 2880 else 2881 as_bad (_("unknown opcode `%s'"), opname); 2882} 2883 2884/* Some instruction sets indexed by lg(size) */ 2885static const char * const sextX_op[] = { "sextb", "sextw", "sextl", NULL }; 2886static const char * const insXl_op[] = { "insbl", "inswl", "insll", "insql" }; 2887static const char * const insXh_op[] = { NULL, "inswh", "inslh", "insqh" }; 2888static const char * const extXl_op[] = { "extbl", "extwl", "extll", "extql" }; 2889static const char * const extXh_op[] = { NULL, "extwh", "extlh", "extqh" }; 2890static const char * const mskXl_op[] = { "mskbl", "mskwl", "mskll", "mskql" }; 2891static const char * const mskXh_op[] = { NULL, "mskwh", "msklh", "mskqh" }; 2892static const char * const stX_op[] = { "stb", "stw", "stl", "stq" }; 2893static const char * const ldXu_op[] = { "ldbu", "ldwu", NULL, NULL }; 2894 2895/* Implement the ldgp macro. */ 2896 2897static void 2898emit_ldgp (tok, ntok, unused) 2899 const expressionS *tok; 2900 int ntok ATTRIBUTE_UNUSED; 2901 const PTR unused ATTRIBUTE_UNUSED; 2902{ 2903#ifdef OBJ_AOUT 2904FIXME 2905#endif 2906#if defined(OBJ_ECOFF) || defined(OBJ_ELF) 2907 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)" 2908 with appropriate constants and relocations. */ 2909 struct alpha_insn insn; 2910 expressionS newtok[3]; 2911 expressionS addend; 2912 2913#ifdef OBJ_ECOFF 2914 if (regno (tok[2].X_add_number) == AXP_REG_PV) 2915 ecoff_set_gp_prolog_size (0); 2916#endif 2917 2918 newtok[0] = tok[0]; 2919 set_tok_const (newtok[1], 0); 2920 newtok[2] = tok[2]; 2921 2922 assemble_tokens_to_insn ("ldah", newtok, 3, &insn); 2923 2924 addend = tok[1]; 2925 2926#ifdef OBJ_ECOFF 2927 if (addend.X_op != O_constant) 2928 as_bad (_("can not resolve expression")); 2929 addend.X_op = O_symbol; 2930 addend.X_add_symbol = alpha_gp_symbol; 2931#endif 2932 2933 insn.nfixups = 1; 2934 insn.fixups[0].exp = addend; 2935 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_HI16; 2936 insn.sequence = next_sequence_num; 2937 2938 emit_insn (&insn); 2939 2940 set_tok_preg (newtok[2], tok[0].X_add_number); 2941 2942 assemble_tokens_to_insn ("lda", newtok, 3, &insn); 2943 2944#ifdef OBJ_ECOFF 2945 addend.X_add_number += 4; 2946#endif 2947 2948 insn.nfixups = 1; 2949 insn.fixups[0].exp = addend; 2950 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_LO16; 2951 insn.sequence = next_sequence_num--; 2952 2953 emit_insn (&insn); 2954#endif /* OBJ_ECOFF || OBJ_ELF */ 2955} 2956 2957#ifdef OBJ_EVAX 2958 2959/* Add symbol+addend to link pool. 2960 Return offset from basesym to entry in link pool. 2961 2962 Add new fixup only if offset isn't 16bit. */ 2963 2964valueT 2965add_to_link_pool (basesym, sym, addend) 2966 symbolS *basesym; 2967 symbolS *sym; 2968 offsetT addend; 2969{ 2970 segT current_section = now_seg; 2971 int current_subsec = now_subseg; 2972 valueT offset; 2973 bfd_reloc_code_real_type reloc_type; 2974 char *p; 2975 segment_info_type *seginfo = seg_info (alpha_link_section); 2976 fixS *fixp; 2977 2978 offset = - *symbol_get_obj (basesym); 2979 2980 /* @@ This assumes all entries in a given section will be of the same 2981 size... Probably correct, but unwise to rely on. */ 2982 /* This must always be called with the same subsegment. */ 2983 2984 if (seginfo->frchainP) 2985 for (fixp = seginfo->frchainP->fix_root; 2986 fixp != (fixS *) NULL; 2987 fixp = fixp->fx_next, offset += 8) 2988 { 2989 if (fixp->fx_addsy == sym && fixp->fx_offset == addend) 2990 { 2991 if (range_signed_16 (offset)) 2992 { 2993 return offset; 2994 } 2995 } 2996 } 2997 2998 /* Not found in 16bit signed range. */ 2999 3000 subseg_set (alpha_link_section, 0); 3001 p = frag_more (8); 3002 memset (p, 0, 8); 3003 3004 fix_new (frag_now, p - frag_now->fr_literal, 8, sym, addend, 0, 3005 BFD_RELOC_64); 3006 3007 subseg_set (current_section, current_subsec); 3008 seginfo->literal_pool_size += 8; 3009 return offset; 3010} 3011 3012#endif /* OBJ_EVAX */ 3013 3014/* Load a (partial) expression into a target register. 3015 3016 If poffset is not null, after the call it will either contain 3017 O_constant 0, or a 16-bit offset appropriate for any MEM format 3018 instruction. In addition, pbasereg will be modified to point to 3019 the base register to use in that MEM format instruction. 3020 3021 In any case, *pbasereg should contain a base register to add to the 3022 expression. This will normally be either AXP_REG_ZERO or 3023 alpha_gp_register. Symbol addresses will always be loaded via $gp, 3024 so "foo($0)" is interpreted as adding the address of foo to $0; 3025 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps, 3026 but this is what OSF/1 does. 3027 3028 If explicit relocations of the form !literal!<number> are allowed, 3029 and used, then explict_reloc with be an expression pointer. 3030 3031 Finally, the return value is nonzero if the calling macro may emit 3032 a LITUSE reloc if otherwise appropriate; the return value is the 3033 sequence number to use. */ 3034 3035static long 3036load_expression (targreg, exp, pbasereg, poffset) 3037 int targreg; 3038 const expressionS *exp; 3039 int *pbasereg; 3040 expressionS *poffset; 3041{ 3042 long emit_lituse = 0; 3043 offsetT addend = exp->X_add_number; 3044 int basereg = *pbasereg; 3045 struct alpha_insn insn; 3046 expressionS newtok[3]; 3047 3048 switch (exp->X_op) 3049 { 3050 case O_symbol: 3051 { 3052#ifdef OBJ_ECOFF 3053 offsetT lit; 3054 3055 /* attempt to reduce .lit load by splitting the offset from 3056 its symbol when possible, but don't create a situation in 3057 which we'd fail. */ 3058 if (!range_signed_32 (addend) && 3059 (alpha_noat_on || targreg == AXP_REG_AT)) 3060 { 3061 lit = add_to_literal_pool (exp->X_add_symbol, addend, 3062 alpha_lita_section, 8); 3063 addend = 0; 3064 } 3065 else 3066 { 3067 lit = add_to_literal_pool (exp->X_add_symbol, 0, 3068 alpha_lita_section, 8); 3069 } 3070 3071 if (lit >= 0x8000) 3072 as_fatal (_("overflow in literal (.lita) table")); 3073 3074 /* emit "ldq r, lit(gp)" */ 3075 3076 if (basereg != alpha_gp_register && targreg == basereg) 3077 { 3078 if (alpha_noat_on) 3079 as_bad (_("macro requires $at register while noat in effect")); 3080 if (targreg == AXP_REG_AT) 3081 as_bad (_("macro requires $at while $at in use")); 3082 3083 set_tok_reg (newtok[0], AXP_REG_AT); 3084 } 3085 else 3086 set_tok_reg (newtok[0], targreg); 3087 set_tok_sym (newtok[1], alpha_lita_symbol, lit); 3088 set_tok_preg (newtok[2], alpha_gp_register); 3089 3090 assemble_tokens_to_insn ("ldq", newtok, 3, &insn); 3091 3092 assert (insn.nfixups == 1); 3093 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL; 3094 insn.sequence = emit_lituse = next_sequence_num--; 3095#endif /* OBJ_ECOFF */ 3096#ifdef OBJ_ELF 3097 /* emit "ldq r, gotoff(gp)" */ 3098 3099 if (basereg != alpha_gp_register && targreg == basereg) 3100 { 3101 if (alpha_noat_on) 3102 as_bad (_("macro requires $at register while noat in effect")); 3103 if (targreg == AXP_REG_AT) 3104 as_bad (_("macro requires $at while $at in use")); 3105 3106 set_tok_reg (newtok[0], AXP_REG_AT); 3107 } 3108 else 3109 set_tok_reg (newtok[0], targreg); 3110 3111 /* XXX: Disable this .got minimizing optimization so that we can get 3112 better instruction offset knowledge in the compiler. This happens 3113 very infrequently anyway. */ 3114 if (1 3115 || (!range_signed_32 (addend) 3116 && (alpha_noat_on || targreg == AXP_REG_AT))) 3117 { 3118 newtok[1] = *exp; 3119 addend = 0; 3120 } 3121 else 3122 { 3123 set_tok_sym (newtok[1], exp->X_add_symbol, 0); 3124 } 3125 3126 set_tok_preg (newtok[2], alpha_gp_register); 3127 3128 assemble_tokens_to_insn ("ldq", newtok, 3, &insn); 3129 3130 assert (insn.nfixups == 1); 3131 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL; 3132 insn.sequence = emit_lituse = next_sequence_num--; 3133#endif /* OBJ_ELF */ 3134#ifdef OBJ_EVAX 3135 offsetT link; 3136 3137 /* Find symbol or symbol pointer in link section. */ 3138 3139 if (exp->X_add_symbol == alpha_evax_proc.symbol) 3140 { 3141 if (range_signed_16 (addend)) 3142 { 3143 set_tok_reg (newtok[0], targreg); 3144 set_tok_const (newtok[1], addend); 3145 set_tok_preg (newtok[2], basereg); 3146 assemble_tokens_to_insn ("lda", newtok, 3, &insn); 3147 addend = 0; 3148 } 3149 else 3150 { 3151 set_tok_reg (newtok[0], targreg); 3152 set_tok_const (newtok[1], 0); 3153 set_tok_preg (newtok[2], basereg); 3154 assemble_tokens_to_insn ("lda", newtok, 3, &insn); 3155 } 3156 } 3157 else 3158 { 3159 if (!range_signed_32 (addend)) 3160 { 3161 link = add_to_link_pool (alpha_evax_proc.symbol, 3162 exp->X_add_symbol, addend); 3163 addend = 0; 3164 } 3165 else 3166 { 3167 link = add_to_link_pool (alpha_evax_proc.symbol, 3168 exp->X_add_symbol, 0); 3169 } 3170 set_tok_reg (newtok[0], targreg); 3171 set_tok_const (newtok[1], link); 3172 set_tok_preg (newtok[2], basereg); 3173 assemble_tokens_to_insn ("ldq", newtok, 3, &insn); 3174 } 3175#endif /* OBJ_EVAX */ 3176 3177 emit_insn (&insn); 3178 3179#ifndef OBJ_EVAX 3180 if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO) 3181 { 3182 /* emit "addq r, base, r" */ 3183 3184 set_tok_reg (newtok[1], basereg); 3185 set_tok_reg (newtok[2], targreg); 3186 assemble_tokens ("addq", newtok, 3, 0); 3187 } 3188#endif 3189 3190 basereg = targreg; 3191 } 3192 break; 3193 3194 case O_constant: 3195 break; 3196 3197 case O_subtract: 3198 /* Assume that this difference expression will be resolved to an 3199 absolute value and that that value will fit in 16 bits. */ 3200 3201 set_tok_reg (newtok[0], targreg); 3202 newtok[1] = *exp; 3203 set_tok_preg (newtok[2], basereg); 3204 assemble_tokens ("lda", newtok, 3, 0); 3205 3206 if (poffset) 3207 set_tok_const (*poffset, 0); 3208 return 0; 3209 3210 case O_big: 3211 if (exp->X_add_number > 0) 3212 as_bad (_("bignum invalid; zero assumed")); 3213 else 3214 as_bad (_("floating point number invalid; zero assumed")); 3215 addend = 0; 3216 break; 3217 3218 default: 3219 as_bad (_("can't handle expression")); 3220 addend = 0; 3221 break; 3222 } 3223 3224 if (!range_signed_32 (addend)) 3225 { 3226 offsetT lit; 3227 long seq_num = next_sequence_num--; 3228 3229 /* For 64-bit addends, just put it in the literal pool. */ 3230 3231#ifdef OBJ_EVAX 3232 /* emit "ldq targreg, lit(basereg)" */ 3233 lit = add_to_link_pool (alpha_evax_proc.symbol, 3234 section_symbol (absolute_section), addend); 3235 set_tok_reg (newtok[0], targreg); 3236 set_tok_const (newtok[1], lit); 3237 set_tok_preg (newtok[2], alpha_gp_register); 3238 assemble_tokens ("ldq", newtok, 3, 0); 3239#else 3240 3241 if (alpha_lit8_section == NULL) 3242 { 3243 create_literal_section (".lit8", 3244 &alpha_lit8_section, 3245 &alpha_lit8_symbol); 3246 3247#ifdef OBJ_ECOFF 3248 alpha_lit8_literal = add_to_literal_pool (alpha_lit8_symbol, 0x8000, 3249 alpha_lita_section, 8); 3250 if (alpha_lit8_literal >= 0x8000) 3251 as_fatal (_("overflow in literal (.lita) table")); 3252#endif 3253 } 3254 3255 lit = add_to_literal_pool (NULL, addend, alpha_lit8_section, 8) - 0x8000; 3256 if (lit >= 0x8000) 3257 as_fatal (_("overflow in literal (.lit8) table")); 3258 3259 /* emit "lda litreg, .lit8+0x8000" */ 3260 3261 if (targreg == basereg) 3262 { 3263 if (alpha_noat_on) 3264 as_bad (_("macro requires $at register while noat in effect")); 3265 if (targreg == AXP_REG_AT) 3266 as_bad (_("macro requires $at while $at in use")); 3267 3268 set_tok_reg (newtok[0], AXP_REG_AT); 3269 } 3270 else 3271 set_tok_reg (newtok[0], targreg); 3272#ifdef OBJ_ECOFF 3273 set_tok_sym (newtok[1], alpha_lita_symbol, alpha_lit8_literal); 3274#endif 3275#ifdef OBJ_ELF 3276 set_tok_sym (newtok[1], alpha_lit8_symbol, 0x8000); 3277#endif 3278 set_tok_preg (newtok[2], alpha_gp_register); 3279 3280 assemble_tokens_to_insn ("ldq", newtok, 3, &insn); 3281 3282 assert (insn.nfixups == 1); 3283#ifdef OBJ_ECOFF 3284 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL; 3285#endif 3286#ifdef OBJ_ELF 3287 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL; 3288#endif 3289 insn.sequence = seq_num; 3290 3291 emit_insn (&insn); 3292 3293 /* emit "ldq litreg, lit(litreg)" */ 3294 3295 set_tok_const (newtok[1], lit); 3296 set_tok_preg (newtok[2], newtok[0].X_add_number); 3297 3298 assemble_tokens_to_insn ("ldq", newtok, 3, &insn); 3299 3300 assert (insn.nfixups < MAX_INSN_FIXUPS); 3301 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE; 3302 insn.fixups[insn.nfixups].exp.X_op = O_absent; 3303 insn.nfixups++; 3304 insn.sequence = seq_num; 3305 emit_lituse = 0; 3306 3307 emit_insn (&insn); 3308 3309 /* emit "addq litreg, base, target" */ 3310 3311 if (basereg != AXP_REG_ZERO) 3312 { 3313 set_tok_reg (newtok[1], basereg); 3314 set_tok_reg (newtok[2], targreg); 3315 assemble_tokens ("addq", newtok, 3, 0); 3316 } 3317#endif /* !OBJ_EVAX */ 3318 3319 if (poffset) 3320 set_tok_const (*poffset, 0); 3321 *pbasereg = targreg; 3322 } 3323 else 3324 { 3325 offsetT low, high, extra, tmp; 3326 3327 /* for 32-bit operands, break up the addend */ 3328 3329 low = sign_extend_16 (addend); 3330 tmp = addend - low; 3331 high = sign_extend_16 (tmp >> 16); 3332 3333 if (tmp - (high << 16)) 3334 { 3335 extra = 0x4000; 3336 tmp -= 0x40000000; 3337 high = sign_extend_16 (tmp >> 16); 3338 } 3339 else 3340 extra = 0; 3341 3342 set_tok_reg (newtok[0], targreg); 3343 set_tok_preg (newtok[2], basereg); 3344 3345 if (extra) 3346 { 3347 /* emit "ldah r, extra(r) */ 3348 set_tok_const (newtok[1], extra); 3349 assemble_tokens ("ldah", newtok, 3, 0); 3350 set_tok_preg (newtok[2], basereg = targreg); 3351 } 3352 3353 if (high) 3354 { 3355 /* emit "ldah r, high(r) */ 3356 set_tok_const (newtok[1], high); 3357 assemble_tokens ("ldah", newtok, 3, 0); 3358 basereg = targreg; 3359 set_tok_preg (newtok[2], basereg); 3360 } 3361 3362 if ((low && !poffset) || (!poffset && basereg != targreg)) 3363 { 3364 /* emit "lda r, low(base)" */ 3365 set_tok_const (newtok[1], low); 3366 assemble_tokens ("lda", newtok, 3, 0); 3367 basereg = targreg; 3368 low = 0; 3369 } 3370 3371 if (poffset) 3372 set_tok_const (*poffset, low); 3373 *pbasereg = basereg; 3374 } 3375 3376 return emit_lituse; 3377} 3378 3379/* The lda macro differs from the lda instruction in that it handles 3380 most simple expressions, particualrly symbol address loads and 3381 large constants. */ 3382 3383static void 3384emit_lda (tok, ntok, unused) 3385 const expressionS *tok; 3386 int ntok; 3387 const PTR unused ATTRIBUTE_UNUSED; 3388{ 3389 int basereg; 3390 3391 if (ntok == 2) 3392 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register); 3393 else 3394 basereg = tok[2].X_add_number; 3395 3396 (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL); 3397} 3398 3399/* The ldah macro differs from the ldah instruction in that it has $31 3400 as an implied base register. */ 3401 3402static void 3403emit_ldah (tok, ntok, unused) 3404 const expressionS *tok; 3405 int ntok ATTRIBUTE_UNUSED; 3406 const PTR unused ATTRIBUTE_UNUSED; 3407{ 3408 expressionS newtok[3]; 3409 3410 newtok[0] = tok[0]; 3411 newtok[1] = tok[1]; 3412 set_tok_preg (newtok[2], AXP_REG_ZERO); 3413 3414 assemble_tokens ("ldah", newtok, 3, 0); 3415} 3416 3417/* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u, 3418 etc. They differ from the real instructions in that they do simple 3419 expressions like the lda macro. */ 3420 3421static void 3422emit_ir_load (tok, ntok, opname) 3423 const expressionS *tok; 3424 int ntok; 3425 const PTR opname; 3426{ 3427 int basereg; 3428 long lituse; 3429 expressionS newtok[3]; 3430 struct alpha_insn insn; 3431 3432 if (ntok == 2) 3433 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register); 3434 else 3435 basereg = tok[2].X_add_number; 3436 3437 lituse = load_expression (tok[0].X_add_number, &tok[1], &basereg, 3438 &newtok[1]); 3439 3440 newtok[0] = tok[0]; 3441 set_tok_preg (newtok[2], basereg); 3442 3443 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn); 3444 3445 if (lituse) 3446 { 3447 assert (insn.nfixups < MAX_INSN_FIXUPS); 3448 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE; 3449 insn.fixups[insn.nfixups].exp.X_op = O_absent; 3450 insn.nfixups++; 3451 insn.sequence = lituse; 3452 } 3453 3454 emit_insn (&insn); 3455} 3456 3457/* Handle fp register loads, and both integer and fp register stores. 3458 Again, we handle simple expressions. */ 3459 3460static void 3461emit_loadstore (tok, ntok, opname) 3462 const expressionS *tok; 3463 int ntok; 3464 const PTR opname; 3465{ 3466 int basereg; 3467 long lituse; 3468 expressionS newtok[3]; 3469 struct alpha_insn insn; 3470 3471 if (ntok == 2) 3472 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register); 3473 else 3474 basereg = tok[2].X_add_number; 3475 3476 if (tok[1].X_op != O_constant || !range_signed_16 (tok[1].X_add_number)) 3477 { 3478 if (alpha_noat_on) 3479 as_bad (_("macro requires $at register while noat in effect")); 3480 3481 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, &newtok[1]); 3482 } 3483 else 3484 { 3485 newtok[1] = tok[1]; 3486 lituse = 0; 3487 } 3488 3489 newtok[0] = tok[0]; 3490 set_tok_preg (newtok[2], basereg); 3491 3492 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn); 3493 3494 if (lituse) 3495 { 3496 assert (insn.nfixups < MAX_INSN_FIXUPS); 3497 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE; 3498 insn.fixups[insn.nfixups].exp.X_op = O_absent; 3499 insn.nfixups++; 3500 insn.sequence = lituse; 3501 } 3502 3503 emit_insn (&insn); 3504} 3505 3506/* Load a half-word or byte as an unsigned value. */ 3507 3508static void 3509emit_ldXu (tok, ntok, vlgsize) 3510 const expressionS *tok; 3511 int ntok; 3512 const PTR vlgsize; 3513{ 3514 if (alpha_target & AXP_OPCODE_BWX) 3515 emit_ir_load (tok, ntok, ldXu_op[(long) vlgsize]); 3516 else 3517 { 3518 expressionS newtok[3]; 3519 struct alpha_insn insn; 3520 int basereg; 3521 long lituse; 3522 3523 if (alpha_noat_on) 3524 as_bad (_("macro requires $at register while noat in effect")); 3525 3526 if (ntok == 2) 3527 basereg = (tok[1].X_op == O_constant 3528 ? AXP_REG_ZERO : alpha_gp_register); 3529 else 3530 basereg = tok[2].X_add_number; 3531 3532 /* emit "lda $at, exp" */ 3533 3534 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL); 3535 3536 /* emit "ldq_u targ, 0($at)" */ 3537 3538 newtok[0] = tok[0]; 3539 set_tok_const (newtok[1], 0); 3540 set_tok_preg (newtok[2], basereg); 3541 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn); 3542 3543 if (lituse) 3544 { 3545 assert (insn.nfixups < MAX_INSN_FIXUPS); 3546 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE; 3547 insn.fixups[insn.nfixups].exp.X_op = O_absent; 3548 insn.nfixups++; 3549 insn.sequence = lituse; 3550 } 3551 3552 emit_insn (&insn); 3553 3554 /* emit "extXl targ, $at, targ" */ 3555 3556 set_tok_reg (newtok[1], basereg); 3557 newtok[2] = newtok[0]; 3558 assemble_tokens_to_insn (extXl_op[(long) vlgsize], newtok, 3, &insn); 3559 3560 if (lituse) 3561 { 3562 assert (insn.nfixups < MAX_INSN_FIXUPS); 3563 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF; 3564 insn.fixups[insn.nfixups].exp.X_op = O_absent; 3565 insn.nfixups++; 3566 insn.sequence = lituse; 3567 } 3568 3569 emit_insn (&insn); 3570 } 3571} 3572 3573/* Load a half-word or byte as a signed value. */ 3574 3575static void 3576emit_ldX (tok, ntok, vlgsize) 3577 const expressionS *tok; 3578 int ntok; 3579 const PTR vlgsize; 3580{ 3581 emit_ldXu (tok, ntok, vlgsize); 3582 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1); 3583} 3584 3585/* Load an integral value from an unaligned address as an unsigned 3586 value. */ 3587 3588static void 3589emit_uldXu (tok, ntok, vlgsize) 3590 const expressionS *tok; 3591 int ntok; 3592 const PTR vlgsize; 3593{ 3594 long lgsize = (long) vlgsize; 3595 expressionS newtok[3]; 3596 3597 if (alpha_noat_on) 3598 as_bad (_("macro requires $at register while noat in effect")); 3599 3600 /* emit "lda $at, exp" */ 3601 3602 memcpy (newtok, tok, sizeof (expressionS) * ntok); 3603 newtok[0].X_add_number = AXP_REG_AT; 3604 assemble_tokens ("lda", newtok, ntok, 1); 3605 3606 /* emit "ldq_u $t9, 0($at)" */ 3607 3608 set_tok_reg (newtok[0], AXP_REG_T9); 3609 set_tok_const (newtok[1], 0); 3610 set_tok_preg (newtok[2], AXP_REG_AT); 3611 assemble_tokens ("ldq_u", newtok, 3, 1); 3612 3613 /* emit "ldq_u $t10, size-1($at)" */ 3614 3615 set_tok_reg (newtok[0], AXP_REG_T10); 3616 set_tok_const (newtok[1], (1 << lgsize) - 1); 3617 assemble_tokens ("ldq_u", newtok, 3, 1); 3618 3619 /* emit "extXl $t9, $at, $t9" */ 3620 3621 set_tok_reg (newtok[0], AXP_REG_T9); 3622 set_tok_reg (newtok[1], AXP_REG_AT); 3623 set_tok_reg (newtok[2], AXP_REG_T9); 3624 assemble_tokens (extXl_op[lgsize], newtok, 3, 1); 3625 3626 /* emit "extXh $t10, $at, $t10" */ 3627 3628 set_tok_reg (newtok[0], AXP_REG_T10); 3629 set_tok_reg (newtok[2], AXP_REG_T10); 3630 assemble_tokens (extXh_op[lgsize], newtok, 3, 1); 3631 3632 /* emit "or $t9, $t10, targ" */ 3633 3634 set_tok_reg (newtok[0], AXP_REG_T9); 3635 set_tok_reg (newtok[1], AXP_REG_T10); 3636 newtok[2] = tok[0]; 3637 assemble_tokens ("or", newtok, 3, 1); 3638} 3639 3640/* Load an integral value from an unaligned address as a signed value. 3641 Note that quads should get funneled to the unsigned load since we 3642 don't have to do the sign extension. */ 3643 3644static void 3645emit_uldX (tok, ntok, vlgsize) 3646 const expressionS *tok; 3647 int ntok; 3648 const PTR vlgsize; 3649{ 3650 emit_uldXu (tok, ntok, vlgsize); 3651 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1); 3652} 3653 3654/* Implement the ldil macro. */ 3655 3656static void 3657emit_ldil (tok, ntok, unused) 3658 const expressionS *tok; 3659 int ntok; 3660 const PTR unused ATTRIBUTE_UNUSED; 3661{ 3662 expressionS newtok[2]; 3663 3664 memcpy (newtok, tok, sizeof (newtok)); 3665 newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number); 3666 3667 assemble_tokens ("lda", newtok, ntok, 1); 3668} 3669 3670/* Store a half-word or byte. */ 3671 3672static void 3673emit_stX (tok, ntok, vlgsize) 3674 const expressionS *tok; 3675 int ntok; 3676 const PTR vlgsize; 3677{ 3678 int lgsize = (int) (long) vlgsize; 3679 3680 if (alpha_target & AXP_OPCODE_BWX) 3681 emit_loadstore (tok, ntok, stX_op[lgsize]); 3682 else 3683 { 3684 expressionS newtok[3]; 3685 struct alpha_insn insn; 3686 int basereg; 3687 long lituse; 3688 3689 if (alpha_noat_on) 3690 as_bad (_("macro requires $at register while noat in effect")); 3691 3692 if (ntok == 2) 3693 basereg = (tok[1].X_op == O_constant 3694 ? AXP_REG_ZERO : alpha_gp_register); 3695 else 3696 basereg = tok[2].X_add_number; 3697 3698 /* emit "lda $at, exp" */ 3699 3700 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL); 3701 3702 /* emit "ldq_u $t9, 0($at)" */ 3703 3704 set_tok_reg (newtok[0], AXP_REG_T9); 3705 set_tok_const (newtok[1], 0); 3706 set_tok_preg (newtok[2], basereg); 3707 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn); 3708 3709 if (lituse) 3710 { 3711 assert (insn.nfixups < MAX_INSN_FIXUPS); 3712 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE; 3713 insn.fixups[insn.nfixups].exp.X_op = O_absent; 3714 insn.nfixups++; 3715 insn.sequence = lituse; 3716 } 3717 3718 emit_insn (&insn); 3719 3720 /* emit "insXl src, $at, $t10" */ 3721 3722 newtok[0] = tok[0]; 3723 set_tok_reg (newtok[1], basereg); 3724 set_tok_reg (newtok[2], AXP_REG_T10); 3725 assemble_tokens_to_insn (insXl_op[lgsize], newtok, 3, &insn); 3726 3727 if (lituse) 3728 { 3729 assert (insn.nfixups < MAX_INSN_FIXUPS); 3730 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF; 3731 insn.fixups[insn.nfixups].exp.X_op = O_absent; 3732 insn.nfixups++; 3733 insn.sequence = lituse; 3734 } 3735 3736 emit_insn (&insn); 3737 3738 /* emit "mskXl $t9, $at, $t9" */ 3739 3740 set_tok_reg (newtok[0], AXP_REG_T9); 3741 newtok[2] = newtok[0]; 3742 assemble_tokens_to_insn (mskXl_op[lgsize], newtok, 3, &insn); 3743 3744 if (lituse) 3745 { 3746 assert (insn.nfixups < MAX_INSN_FIXUPS); 3747 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF; 3748 insn.fixups[insn.nfixups].exp.X_op = O_absent; 3749 insn.nfixups++; 3750 insn.sequence = lituse; 3751 } 3752 3753 emit_insn (&insn); 3754 3755 /* emit "or $t9, $t10, $t9" */ 3756 3757 set_tok_reg (newtok[1], AXP_REG_T10); 3758 assemble_tokens ("or", newtok, 3, 1); 3759 3760 /* emit "stq_u $t9, 0($at) */ 3761 3762 set_tok_const(newtok[1], 0); 3763 set_tok_preg (newtok[2], AXP_REG_AT); 3764 assemble_tokens_to_insn ("stq_u", newtok, 3, &insn); 3765 3766 if (lituse) 3767 { 3768 assert (insn.nfixups < MAX_INSN_FIXUPS); 3769 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE; 3770 insn.fixups[insn.nfixups].exp.X_op = O_absent; 3771 insn.nfixups++; 3772 insn.sequence = lituse; 3773 } 3774 3775 emit_insn (&insn); 3776 } 3777} 3778 3779/* Store an integer to an unaligned address. */ 3780 3781static void 3782emit_ustX (tok, ntok, vlgsize) 3783 const expressionS *tok; 3784 int ntok; 3785 const PTR vlgsize; 3786{ 3787 int lgsize = (int) (long) vlgsize; 3788 expressionS newtok[3]; 3789 3790 /* emit "lda $at, exp" */ 3791 3792 memcpy (newtok, tok, sizeof (expressionS) * ntok); 3793 newtok[0].X_add_number = AXP_REG_AT; 3794 assemble_tokens ("lda", newtok, ntok, 1); 3795 3796 /* emit "ldq_u $9, 0($at)" */ 3797 3798 set_tok_reg (newtok[0], AXP_REG_T9); 3799 set_tok_const (newtok[1], 0); 3800 set_tok_preg (newtok[2], AXP_REG_AT); 3801 assemble_tokens ("ldq_u", newtok, 3, 1); 3802 3803 /* emit "ldq_u $10, size-1($at)" */ 3804 3805 set_tok_reg (newtok[0], AXP_REG_T10); 3806 set_tok_const (newtok[1], (1 << lgsize) - 1); 3807 assemble_tokens ("ldq_u", newtok, 3, 1); 3808 3809 /* emit "insXl src, $at, $t11" */ 3810 3811 newtok[0] = tok[0]; 3812 set_tok_reg (newtok[1], AXP_REG_AT); 3813 set_tok_reg (newtok[2], AXP_REG_T11); 3814 assemble_tokens (insXl_op[lgsize], newtok, 3, 1); 3815 3816 /* emit "insXh src, $at, $t12" */ 3817 3818 set_tok_reg (newtok[2], AXP_REG_T12); 3819 assemble_tokens (insXh_op[lgsize], newtok, 3, 1); 3820 3821 /* emit "mskXl $t9, $at, $t9" */ 3822 3823 set_tok_reg (newtok[0], AXP_REG_T9); 3824 newtok[2] = newtok[0]; 3825 assemble_tokens (mskXl_op[lgsize], newtok, 3, 1); 3826 3827 /* emit "mskXh $t10, $at, $t10" */ 3828 3829 set_tok_reg (newtok[0], AXP_REG_T10); 3830 newtok[2] = newtok[0]; 3831 assemble_tokens (mskXh_op[lgsize], newtok, 3, 1); 3832 3833 /* emit "or $t9, $t11, $t9" */ 3834 3835 set_tok_reg (newtok[0], AXP_REG_T9); 3836 set_tok_reg (newtok[1], AXP_REG_T11); 3837 newtok[2] = newtok[0]; 3838 assemble_tokens ("or", newtok, 3, 1); 3839 3840 /* emit "or $t10, $t12, $t10" */ 3841 3842 set_tok_reg (newtok[0], AXP_REG_T10); 3843 set_tok_reg (newtok[1], AXP_REG_T12); 3844 newtok[2] = newtok[0]; 3845 assemble_tokens ("or", newtok, 3, 1); 3846 3847 /* emit "stq_u $t9, 0($at)" */ 3848 3849 set_tok_reg (newtok[0], AXP_REG_T9); 3850 set_tok_const (newtok[1], 0); 3851 set_tok_preg (newtok[2], AXP_REG_AT); 3852 assemble_tokens ("stq_u", newtok, 3, 1); 3853 3854 /* emit "stq_u $t10, size-1($at)" */ 3855 3856 set_tok_reg (newtok[0], AXP_REG_T10); 3857 set_tok_const (newtok[1], (1 << lgsize) - 1); 3858 assemble_tokens ("stq_u", newtok, 3, 1); 3859} 3860 3861/* Sign extend a half-word or byte. The 32-bit sign extend is 3862 implemented as "addl $31, $r, $t" in the opcode table. */ 3863 3864static void 3865emit_sextX (tok, ntok, vlgsize) 3866 const expressionS *tok; 3867 int ntok; 3868 const PTR vlgsize; 3869{ 3870 long lgsize = (long) vlgsize; 3871 3872 if (alpha_target & AXP_OPCODE_BWX) 3873 assemble_tokens (sextX_op[lgsize], tok, ntok, 0); 3874 else 3875 { 3876 int bitshift = 64 - 8 * (1 << lgsize); 3877 expressionS newtok[3]; 3878 3879 /* emit "sll src,bits,dst" */ 3880 3881 newtok[0] = tok[0]; 3882 set_tok_const (newtok[1], bitshift); 3883 newtok[2] = tok[ntok - 1]; 3884 assemble_tokens ("sll", newtok, 3, 1); 3885 3886 /* emit "sra dst,bits,dst" */ 3887 3888 newtok[0] = newtok[2]; 3889 assemble_tokens ("sra", newtok, 3, 1); 3890 } 3891} 3892 3893/* Implement the division and modulus macros. */ 3894 3895#ifdef OBJ_EVAX 3896 3897/* Make register usage like in normal procedure call. 3898 Don't clobber PV and RA. */ 3899 3900static void 3901emit_division (tok, ntok, symname) 3902 const expressionS *tok; 3903 int ntok; 3904 const PTR symname; 3905{ 3906 /* DIVISION and MODULUS. Yech. 3907 * 3908 * Convert 3909 * OP x,y,result 3910 * to 3911 * mov x,R16 # if x != R16 3912 * mov y,R17 # if y != R17 3913 * lda AT,__OP 3914 * jsr AT,(AT),0 3915 * mov R0,result 3916 * 3917 * with appropriate optimizations if R0,R16,R17 are the registers 3918 * specified by the compiler. 3919 */ 3920 3921 int xr, yr, rr; 3922 symbolS *sym; 3923 expressionS newtok[3]; 3924 3925 xr = regno (tok[0].X_add_number); 3926 yr = regno (tok[1].X_add_number); 3927 3928 if (ntok < 3) 3929 rr = xr; 3930 else 3931 rr = regno (tok[2].X_add_number); 3932 3933 /* Move the operands into the right place */ 3934 if (yr == AXP_REG_R16 && xr == AXP_REG_R17) 3935 { 3936 /* They are in exactly the wrong order -- swap through AT */ 3937 3938 if (alpha_noat_on) 3939 as_bad (_("macro requires $at register while noat in effect")); 3940 3941 set_tok_reg (newtok[0], AXP_REG_R16); 3942 set_tok_reg (newtok[1], AXP_REG_AT); 3943 assemble_tokens ("mov", newtok, 2, 1); 3944 3945 set_tok_reg (newtok[0], AXP_REG_R17); 3946 set_tok_reg (newtok[1], AXP_REG_R16); 3947 assemble_tokens ("mov", newtok, 2, 1); 3948 3949 set_tok_reg (newtok[0], AXP_REG_AT); 3950 set_tok_reg (newtok[1], AXP_REG_R17); 3951 assemble_tokens ("mov", newtok, 2, 1); 3952 } 3953 else 3954 { 3955 if (yr == AXP_REG_R16) 3956 { 3957 set_tok_reg (newtok[0], AXP_REG_R16); 3958 set_tok_reg (newtok[1], AXP_REG_R17); 3959 assemble_tokens ("mov", newtok, 2, 1); 3960 } 3961 3962 if (xr != AXP_REG_R16) 3963 { 3964 set_tok_reg (newtok[0], xr); 3965 set_tok_reg (newtok[1], AXP_REG_R16); 3966 assemble_tokens ("mov", newtok, 2, 1); 3967 } 3968 3969 if (yr != AXP_REG_R16 && yr != AXP_REG_R17) 3970 { 3971 set_tok_reg (newtok[0], yr); 3972 set_tok_reg (newtok[1], AXP_REG_R17); 3973 assemble_tokens ("mov", newtok, 2, 1); 3974 } 3975 } 3976 3977 sym = symbol_find_or_make ((const char *) symname); 3978 3979 set_tok_reg (newtok[0], AXP_REG_AT); 3980 set_tok_sym (newtok[1], sym, 0); 3981 assemble_tokens ("lda", newtok, 2, 1); 3982 3983 /* Call the division routine */ 3984 set_tok_reg (newtok[0], AXP_REG_AT); 3985 set_tok_cpreg (newtok[1], AXP_REG_AT); 3986 set_tok_const (newtok[2], 0); 3987 assemble_tokens ("jsr", newtok, 3, 1); 3988 3989 /* Move the result to the right place */ 3990 if (rr != AXP_REG_R0) 3991 { 3992 set_tok_reg (newtok[0], AXP_REG_R0); 3993 set_tok_reg (newtok[1], rr); 3994 assemble_tokens ("mov", newtok, 2, 1); 3995 } 3996} 3997 3998#else /* !OBJ_EVAX */ 3999 4000static void 4001emit_division (tok, ntok, symname) 4002 const expressionS *tok; 4003 int ntok; 4004 const PTR symname; 4005{ 4006 /* DIVISION and MODULUS. Yech. 4007 * Convert 4008 * OP x,y,result 4009 * to 4010 * lda pv,__OP 4011 * mov x,t10 4012 * mov y,t11 4013 * jsr t9,(pv),__OP 4014 * mov t12,result 4015 * 4016 * with appropriate optimizations if t10,t11,t12 are the registers 4017 * specified by the compiler. 4018 */ 4019 4020 int xr, yr, rr; 4021 symbolS *sym; 4022 expressionS newtok[3]; 4023 4024 xr = regno (tok[0].X_add_number); 4025 yr = regno (tok[1].X_add_number); 4026 4027 if (ntok < 3) 4028 rr = xr; 4029 else 4030 rr = regno (tok[2].X_add_number); 4031 4032 sym = symbol_find_or_make ((const char *) symname); 4033 4034 /* Move the operands into the right place */ 4035 if (yr == AXP_REG_T10 && xr == AXP_REG_T11) 4036 { 4037 /* They are in exactly the wrong order -- swap through AT */ 4038 4039 if (alpha_noat_on) 4040 as_bad (_("macro requires $at register while noat in effect")); 4041 4042 set_tok_reg (newtok[0], AXP_REG_T10); 4043 set_tok_reg (newtok[1], AXP_REG_AT); 4044 assemble_tokens ("mov", newtok, 2, 1); 4045 4046 set_tok_reg (newtok[0], AXP_REG_T11); 4047 set_tok_reg (newtok[1], AXP_REG_T10); 4048 assemble_tokens ("mov", newtok, 2, 1); 4049 4050 set_tok_reg (newtok[0], AXP_REG_AT); 4051 set_tok_reg (newtok[1], AXP_REG_T11); 4052 assemble_tokens ("mov", newtok, 2, 1); 4053 } 4054 else 4055 { 4056 if (yr == AXP_REG_T10) 4057 { 4058 set_tok_reg (newtok[0], AXP_REG_T10); 4059 set_tok_reg (newtok[1], AXP_REG_T11); 4060 assemble_tokens ("mov", newtok, 2, 1); 4061 } 4062 4063 if (xr != AXP_REG_T10) 4064 { 4065 set_tok_reg (newtok[0], xr); 4066 set_tok_reg (newtok[1], AXP_REG_T10); 4067 assemble_tokens ("mov", newtok, 2, 1); 4068 } 4069 4070 if (yr != AXP_REG_T10 && yr != AXP_REG_T11) 4071 { 4072 set_tok_reg (newtok[0], yr); 4073 set_tok_reg (newtok[1], AXP_REG_T11); 4074 assemble_tokens ("mov", newtok, 2, 1); 4075 } 4076 } 4077 4078 /* Call the division routine */ 4079 set_tok_reg (newtok[0], AXP_REG_T9); 4080 set_tok_sym (newtok[1], sym, 0); 4081 assemble_tokens ("jsr", newtok, 2, 1); 4082 4083 /* Reload the GP register */ 4084#ifdef OBJ_AOUT 4085FIXME 4086#endif 4087#if defined(OBJ_ECOFF) || defined(OBJ_ELF) 4088 set_tok_reg (newtok[0], alpha_gp_register); 4089 set_tok_const (newtok[1], 0); 4090 set_tok_preg (newtok[2], AXP_REG_T9); 4091 assemble_tokens ("ldgp", newtok, 3, 1); 4092#endif 4093 4094 /* Move the result to the right place */ 4095 if (rr != AXP_REG_T12) 4096 { 4097 set_tok_reg (newtok[0], AXP_REG_T12); 4098 set_tok_reg (newtok[1], rr); 4099 assemble_tokens ("mov", newtok, 2, 1); 4100 } 4101} 4102 4103#endif /* !OBJ_EVAX */ 4104 4105/* The jsr and jmp macros differ from their instruction counterparts 4106 in that they can load the target address and default most 4107 everything. */ 4108 4109static void 4110emit_jsrjmp (tok, ntok, vopname) 4111 const expressionS *tok; 4112 int ntok; 4113 const PTR vopname; 4114{ 4115 const char *opname = (const char *) vopname; 4116 struct alpha_insn insn; 4117 expressionS newtok[3]; 4118 int r, tokidx = 0; 4119 long lituse = 0; 4120 4121 if (tokidx < ntok && tok[tokidx].X_op == O_register) 4122 r = regno (tok[tokidx++].X_add_number); 4123 else 4124 r = strcmp (opname, "jmp") == 0 ? AXP_REG_ZERO : AXP_REG_RA; 4125 4126 set_tok_reg (newtok[0], r); 4127 4128 if (tokidx < ntok && 4129 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister)) 4130 r = regno (tok[tokidx++].X_add_number); 4131#ifdef OBJ_EVAX 4132 /* keep register if jsr $n.<sym> */ 4133#else 4134 else 4135 { 4136 int basereg = alpha_gp_register; 4137 lituse = load_expression (r = AXP_REG_PV, &tok[tokidx], &basereg, NULL); 4138 } 4139#endif 4140 4141 set_tok_cpreg (newtok[1], r); 4142 4143#ifdef OBJ_EVAX 4144 /* FIXME: Add hint relocs to BFD for evax. */ 4145#else 4146 if (tokidx < ntok) 4147 newtok[2] = tok[tokidx]; 4148 else 4149#endif 4150 set_tok_const (newtok[2], 0); 4151 4152 assemble_tokens_to_insn (opname, newtok, 3, &insn); 4153 4154 if (lituse) 4155 { 4156 assert (insn.nfixups < MAX_INSN_FIXUPS); 4157 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_JSR; 4158 insn.fixups[insn.nfixups].exp.X_op = O_absent; 4159 insn.nfixups++; 4160 insn.sequence = lituse; 4161 } 4162 4163 emit_insn (&insn); 4164} 4165 4166/* The ret and jcr instructions differ from their instruction 4167 counterparts in that everything can be defaulted. */ 4168 4169static void 4170emit_retjcr (tok, ntok, vopname) 4171 const expressionS *tok; 4172 int ntok; 4173 const PTR vopname; 4174{ 4175 const char *opname = (const char *) vopname; 4176 expressionS newtok[3]; 4177 int r, tokidx = 0; 4178 4179 if (tokidx < ntok && tok[tokidx].X_op == O_register) 4180 r = regno (tok[tokidx++].X_add_number); 4181 else 4182 r = AXP_REG_ZERO; 4183 4184 set_tok_reg (newtok[0], r); 4185 4186 if (tokidx < ntok && 4187 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister)) 4188 r = regno (tok[tokidx++].X_add_number); 4189 else 4190 r = AXP_REG_RA; 4191 4192 set_tok_cpreg (newtok[1], r); 4193 4194 if (tokidx < ntok) 4195 newtok[2] = tok[tokidx]; 4196 else 4197 set_tok_const (newtok[2], strcmp (opname, "ret") == 0); 4198 4199 assemble_tokens (opname, newtok, 3, 0); 4200} 4201 4202/* Assembler directives */ 4203 4204/* Handle the .text pseudo-op. This is like the usual one, but it 4205 clears alpha_insn_label and restores auto alignment. */ 4206 4207static void 4208s_alpha_text (i) 4209 int i; 4210 4211{ 4212#ifdef OBJ_ELF 4213 obj_elf_text (i); 4214#else 4215 s_text (i); 4216#endif 4217 alpha_insn_label = NULL; 4218 alpha_auto_align_on = 1; 4219 alpha_current_align = 0; 4220} 4221 4222/* Handle the .data pseudo-op. This is like the usual one, but it 4223 clears alpha_insn_label and restores auto alignment. */ 4224 4225static void 4226s_alpha_data (i) 4227 int i; 4228{ 4229#ifdef OBJ_ELF 4230 obj_elf_data (i); 4231#else 4232 s_data (i); 4233#endif 4234 alpha_insn_label = NULL; 4235 alpha_auto_align_on = 1; 4236 alpha_current_align = 0; 4237} 4238 4239#if defined (OBJ_ECOFF) || defined (OBJ_EVAX) 4240 4241/* Handle the OSF/1 and openVMS .comm pseudo quirks. 4242 openVMS constructs a section for every common symbol. */ 4243 4244static void 4245s_alpha_comm (ignore) 4246 int ignore; 4247{ 4248 register char *name; 4249 register char c; 4250 register char *p; 4251 offsetT temp; 4252 register symbolS *symbolP; 4253 4254#ifdef OBJ_EVAX 4255 segT current_section = now_seg; 4256 int current_subsec = now_subseg; 4257 segT new_seg; 4258#endif 4259 4260 name = input_line_pointer; 4261 c = get_symbol_end (); 4262 4263 /* just after name is now '\0' */ 4264 p = input_line_pointer; 4265 *p = c; 4266 4267 SKIP_WHITESPACE (); 4268 4269 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */ 4270 if (*input_line_pointer == ',') 4271 { 4272 input_line_pointer++; 4273 SKIP_WHITESPACE (); 4274 } 4275 if ((temp = get_absolute_expression ()) < 0) 4276 { 4277 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp); 4278 ignore_rest_of_line (); 4279 return; 4280 } 4281 4282 *p = 0; 4283 symbolP = symbol_find_or_make (name); 4284 4285#ifdef OBJ_EVAX 4286 /* Make a section for the common symbol. */ 4287 new_seg = subseg_new (xstrdup (name), 0); 4288#endif 4289 4290 *p = c; 4291 4292#ifdef OBJ_EVAX 4293 /* alignment might follow */ 4294 if (*input_line_pointer == ',') 4295 { 4296 offsetT align; 4297 4298 input_line_pointer++; 4299 align = get_absolute_expression (); 4300 bfd_set_section_alignment (stdoutput, new_seg, align); 4301 } 4302#endif 4303 4304 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP)) 4305 { 4306 as_bad (_("Ignoring attempt to re-define symbol")); 4307 ignore_rest_of_line (); 4308 return; 4309 } 4310 4311#ifdef OBJ_EVAX 4312 if (bfd_section_size (stdoutput, new_seg) > 0) 4313 { 4314 if (bfd_section_size (stdoutput, new_seg) != temp) 4315 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."), 4316 S_GET_NAME (symbolP), 4317 (long) bfd_section_size (stdoutput, new_seg), 4318 (long) temp); 4319 } 4320#else 4321 if (S_GET_VALUE (symbolP)) 4322 { 4323 if (S_GET_VALUE (symbolP) != (valueT) temp) 4324 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."), 4325 S_GET_NAME (symbolP), 4326 (long) S_GET_VALUE (symbolP), 4327 (long) temp); 4328 } 4329#endif 4330 else 4331 { 4332#ifdef OBJ_EVAX 4333 subseg_set (new_seg, 0); 4334 p = frag_more (temp); 4335 new_seg->flags |= SEC_IS_COMMON; 4336 if (! S_IS_DEFINED (symbolP)) 4337 S_SET_SEGMENT (symbolP, new_seg); 4338#else 4339 S_SET_VALUE (symbolP, (valueT) temp); 4340#endif 4341 S_SET_EXTERNAL (symbolP); 4342 } 4343 4344#ifdef OBJ_EVAX 4345 subseg_set (current_section, current_subsec); 4346#endif 4347 4348 know (symbol_get_frag (symbolP) == &zero_address_frag); 4349 4350 demand_empty_rest_of_line (); 4351} 4352 4353#endif /* ! OBJ_ELF */ 4354 4355#ifdef OBJ_ECOFF 4356 4357/* Handle the .rdata pseudo-op. This is like the usual one, but it 4358 clears alpha_insn_label and restores auto alignment. */ 4359 4360static void 4361s_alpha_rdata (ignore) 4362 int ignore; 4363{ 4364 int temp; 4365 4366 temp = get_absolute_expression (); 4367 subseg_new (".rdata", 0); 4368 demand_empty_rest_of_line (); 4369 alpha_insn_label = NULL; 4370 alpha_auto_align_on = 1; 4371 alpha_current_align = 0; 4372} 4373 4374#endif 4375 4376#ifdef OBJ_ECOFF 4377 4378/* Handle the .sdata pseudo-op. This is like the usual one, but it 4379 clears alpha_insn_label and restores auto alignment. */ 4380 4381static void 4382s_alpha_sdata (ignore) 4383 int ignore; 4384{ 4385 int temp; 4386 4387 temp = get_absolute_expression (); 4388 subseg_new (".sdata", 0); 4389 demand_empty_rest_of_line (); 4390 alpha_insn_label = NULL; 4391 alpha_auto_align_on = 1; 4392 alpha_current_align = 0; 4393} 4394#endif 4395 4396#ifdef OBJ_ELF 4397 4398/* Handle the .section pseudo-op. This is like the usual one, but it 4399 clears alpha_insn_label and restores auto alignment. */ 4400 4401static void 4402s_alpha_section (ignore) 4403 int ignore; 4404{ 4405 obj_elf_section (ignore); 4406 4407 alpha_insn_label = NULL; 4408 alpha_auto_align_on = 1; 4409 alpha_current_align = 0; 4410} 4411 4412static void 4413s_alpha_ent (dummy) 4414 int dummy ATTRIBUTE_UNUSED; 4415{ 4416 if (ECOFF_DEBUGGING) 4417 ecoff_directive_ent (0); 4418 else 4419 { 4420 char *name, name_end; 4421 name = input_line_pointer; 4422 name_end = get_symbol_end (); 4423 4424 if (! is_name_beginner (*name)) 4425 { 4426 as_warn (_(".ent directive has no name")); 4427 *input_line_pointer = name_end; 4428 } 4429 else 4430 { 4431 symbolS *sym; 4432 4433 if (alpha_cur_ent_sym) 4434 as_warn (_("nested .ent directives")); 4435 4436 sym = symbol_find_or_make (name); 4437 symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION; 4438 alpha_cur_ent_sym = sym; 4439 4440 /* The .ent directive is sometimes followed by a number. Not sure 4441 what it really means, but ignore it. */ 4442 *input_line_pointer = name_end; 4443 SKIP_WHITESPACE (); 4444 if (*input_line_pointer == ',') 4445 { 4446 input_line_pointer++; 4447 SKIP_WHITESPACE (); 4448 } 4449 if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-') 4450 (void) get_absolute_expression (); 4451 } 4452 demand_empty_rest_of_line (); 4453 } 4454} 4455 4456static void 4457s_alpha_end (dummy) 4458 int dummy ATTRIBUTE_UNUSED; 4459{ 4460 if (ECOFF_DEBUGGING) 4461 ecoff_directive_end (0); 4462 else 4463 { 4464 char *name, name_end; 4465 name = input_line_pointer; 4466 name_end = get_symbol_end (); 4467 4468 if (! is_name_beginner (*name)) 4469 { 4470 as_warn (_(".end directive has no name")); 4471 *input_line_pointer = name_end; 4472 } 4473 else 4474 { 4475 symbolS *sym; 4476 4477 sym = symbol_find (name); 4478 if (sym != alpha_cur_ent_sym) 4479 as_warn (_(".end directive names different symbol than .ent")); 4480 4481 /* Create an expression to calculate the size of the function. */ 4482 if (sym) 4483 { 4484 symbol_get_obj (sym)->size = 4485 (expressionS *) xmalloc (sizeof (expressionS)); 4486 symbol_get_obj (sym)->size->X_op = O_subtract; 4487 symbol_get_obj (sym)->size->X_add_symbol 4488 = symbol_new ("L0\001", now_seg, frag_now_fix (), frag_now); 4489 symbol_get_obj (sym)->size->X_op_symbol = sym; 4490 symbol_get_obj (sym)->size->X_add_number = 0; 4491 } 4492 4493 alpha_cur_ent_sym = NULL; 4494 4495 *input_line_pointer = name_end; 4496 } 4497 demand_empty_rest_of_line (); 4498 } 4499} 4500 4501static void 4502s_alpha_mask (fp) 4503 int fp; 4504{ 4505 if (ECOFF_DEBUGGING) 4506 { 4507 if (fp) 4508 ecoff_directive_fmask (0); 4509 else 4510 ecoff_directive_mask (0); 4511 } 4512 else 4513 discard_rest_of_line (); 4514} 4515 4516static void 4517s_alpha_frame (dummy) 4518 int dummy ATTRIBUTE_UNUSED; 4519{ 4520 if (ECOFF_DEBUGGING) 4521 ecoff_directive_frame (0); 4522 else 4523 discard_rest_of_line (); 4524} 4525 4526static void 4527s_alpha_prologue (ignore) 4528 int ignore ATTRIBUTE_UNUSED; 4529{ 4530 symbolS *sym; 4531 int arg; 4532 4533 arg = get_absolute_expression (); 4534 demand_empty_rest_of_line (); 4535 4536 if (ECOFF_DEBUGGING) 4537 sym = ecoff_get_cur_proc_sym (); 4538 else 4539 sym = alpha_cur_ent_sym; 4540 know (sym != NULL); 4541 4542 switch (arg) 4543 { 4544 case 0: /* No PV required. */ 4545 S_SET_OTHER (sym, STO_ALPHA_NOPV 4546 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD)); 4547 break; 4548 case 1: /* Std GP load. */ 4549 S_SET_OTHER (sym, STO_ALPHA_STD_GPLOAD 4550 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD)); 4551 break; 4552 case 2: /* Non-std use of PV. */ 4553 break; 4554 4555 default: 4556 as_bad (_("Invalid argument %d to .prologue."), arg); 4557 break; 4558 } 4559} 4560 4561static char *first_file_directive; 4562 4563static void 4564s_alpha_file (ignore) 4565 int ignore ATTRIBUTE_UNUSED; 4566{ 4567 /* Save the first .file directive we see, so that we can change our 4568 minds about whether ecoff debugging should or shouldn't be enabled. */ 4569 if (alpha_flag_mdebug < 0 && ! first_file_directive) 4570 { 4571 char *start = input_line_pointer; 4572 size_t len; 4573 4574 discard_rest_of_line (); 4575 4576 len = input_line_pointer - start; 4577 first_file_directive = xmalloc (len + 1); 4578 memcpy (first_file_directive, start, len); 4579 first_file_directive[len] = '\0'; 4580 4581 input_line_pointer = start; 4582 } 4583 4584 if (ECOFF_DEBUGGING) 4585 ecoff_directive_file (0); 4586 else 4587 dwarf2_directive_file (0); 4588} 4589 4590static void 4591s_alpha_loc (ignore) 4592 int ignore ATTRIBUTE_UNUSED; 4593{ 4594 if (ECOFF_DEBUGGING) 4595 ecoff_directive_loc (0); 4596 else 4597 dwarf2_directive_loc (0); 4598} 4599 4600static void 4601s_alpha_stab (n) 4602 int n; 4603{ 4604 /* If we've been undecided about mdebug, make up our minds in favour. */ 4605 if (alpha_flag_mdebug < 0) 4606 { 4607 segT sec = subseg_new (".mdebug", 0); 4608 bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY); 4609 bfd_set_section_alignment (stdoutput, sec, 3); 4610 4611 ecoff_read_begin_hook (); 4612 4613 if (first_file_directive) 4614 { 4615 char *save_ilp = input_line_pointer; 4616 input_line_pointer = first_file_directive; 4617 ecoff_directive_file (0); 4618 input_line_pointer = save_ilp; 4619 free (first_file_directive); 4620 } 4621 4622 alpha_flag_mdebug = 1; 4623 } 4624 s_stab (n); 4625} 4626 4627static void 4628s_alpha_coff_wrapper (which) 4629 int which; 4630{ 4631 static void (* const fns[]) PARAMS ((int)) = { 4632 ecoff_directive_begin, 4633 ecoff_directive_bend, 4634 ecoff_directive_def, 4635 ecoff_directive_dim, 4636 ecoff_directive_endef, 4637 ecoff_directive_scl, 4638 ecoff_directive_tag, 4639 ecoff_directive_val, 4640 }; 4641 4642 assert (which >= 0 && which < (int) (sizeof (fns)/sizeof (*fns))); 4643 4644 if (ECOFF_DEBUGGING) 4645 (*fns[which]) (0); 4646 else 4647 { 4648 as_bad (_("ECOFF debugging is disabled.")); 4649 ignore_rest_of_line (); 4650 } 4651} 4652#endif /* OBJ_ELF */ 4653 4654#ifdef OBJ_EVAX 4655 4656/* Handle the section specific pseudo-op. */ 4657 4658static void 4659s_alpha_section (secid) 4660 int secid; 4661{ 4662 int temp; 4663#define EVAX_SECTION_COUNT 5 4664 static char *section_name[EVAX_SECTION_COUNT + 1] = 4665 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" }; 4666 4667 if ((secid <= 0) || (secid > EVAX_SECTION_COUNT)) 4668 { 4669 as_fatal (_("Unknown section directive")); 4670 demand_empty_rest_of_line (); 4671 return; 4672 } 4673 temp = get_absolute_expression (); 4674 subseg_new (section_name[secid], 0); 4675 demand_empty_rest_of_line (); 4676 alpha_insn_label = NULL; 4677 alpha_auto_align_on = 1; 4678 alpha_current_align = 0; 4679} 4680 4681/* Parse .ent directives. */ 4682 4683static void 4684s_alpha_ent (ignore) 4685 int ignore; 4686{ 4687 symbolS *symbol; 4688 expressionS symexpr; 4689 4690 alpha_evax_proc.pdsckind = 0; 4691 alpha_evax_proc.framereg = -1; 4692 alpha_evax_proc.framesize = 0; 4693 alpha_evax_proc.rsa_offset = 0; 4694 alpha_evax_proc.ra_save = AXP_REG_RA; 4695 alpha_evax_proc.fp_save = -1; 4696 alpha_evax_proc.imask = 0; 4697 alpha_evax_proc.fmask = 0; 4698 alpha_evax_proc.prologue = 0; 4699 alpha_evax_proc.type = 0; 4700 4701 expression (&symexpr); 4702 4703 if (symexpr.X_op != O_symbol) 4704 { 4705 as_fatal (_(".ent directive has no symbol")); 4706 demand_empty_rest_of_line (); 4707 return; 4708 } 4709 4710 symbol = make_expr_symbol (&symexpr); 4711 symbol_get_bfdsym (symbol)->flags |= BSF_FUNCTION; 4712 alpha_evax_proc.symbol = symbol; 4713 4714 demand_empty_rest_of_line (); 4715 return; 4716} 4717 4718/* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */ 4719 4720static void 4721s_alpha_frame (ignore) 4722 int ignore; 4723{ 4724 long val; 4725 4726 alpha_evax_proc.framereg = tc_get_register (1); 4727 4728 SKIP_WHITESPACE (); 4729 if (*input_line_pointer++ != ',' 4730 || get_absolute_expression_and_terminator (&val) != ',') 4731 { 4732 as_warn (_("Bad .frame directive 1./2. param")); 4733 --input_line_pointer; 4734 demand_empty_rest_of_line (); 4735 return; 4736 } 4737 4738 alpha_evax_proc.framesize = val; 4739 4740 (void) tc_get_register (1); 4741 SKIP_WHITESPACE (); 4742 if (*input_line_pointer++ != ',') 4743 { 4744 as_warn (_("Bad .frame directive 3./4. param")); 4745 --input_line_pointer; 4746 demand_empty_rest_of_line (); 4747 return; 4748 } 4749 alpha_evax_proc.rsa_offset = get_absolute_expression (); 4750 4751 return; 4752} 4753 4754static void 4755s_alpha_pdesc (ignore) 4756 int ignore; 4757{ 4758 char *name; 4759 char name_end; 4760 long val; 4761 register char *p; 4762 expressionS exp; 4763 symbolS *entry_sym; 4764 fixS *fixp; 4765 segment_info_type *seginfo = seg_info (alpha_link_section); 4766 4767 if (now_seg != alpha_link_section) 4768 { 4769 as_bad (_(".pdesc directive not in link (.link) section")); 4770 demand_empty_rest_of_line (); 4771 return; 4772 } 4773 4774 if ((alpha_evax_proc.symbol == 0) 4775 || (!S_IS_DEFINED (alpha_evax_proc.symbol))) 4776 { 4777 as_fatal (_(".pdesc has no matching .ent")); 4778 demand_empty_rest_of_line (); 4779 return; 4780 } 4781 4782 *symbol_get_obj (alpha_evax_proc.symbol) = 4783 (valueT) seginfo->literal_pool_size; 4784 4785 expression (&exp); 4786 if (exp.X_op != O_symbol) 4787 { 4788 as_warn (_(".pdesc directive has no entry symbol")); 4789 demand_empty_rest_of_line (); 4790 return; 4791 } 4792 4793 entry_sym = make_expr_symbol (&exp); 4794 /* Save bfd symbol of proc desc in function symbol. */ 4795 symbol_get_bfdsym (alpha_evax_proc.symbol)->udata.p 4796 = symbol_get_bfdsym (entry_sym); 4797 4798 SKIP_WHITESPACE (); 4799 if (*input_line_pointer++ != ',') 4800 { 4801 as_warn (_("No comma after .pdesc <entryname>")); 4802 demand_empty_rest_of_line (); 4803 return; 4804 } 4805 4806 SKIP_WHITESPACE (); 4807 name = input_line_pointer; 4808 name_end = get_symbol_end (); 4809 4810 if (strncmp (name, "stack", 5) == 0) 4811 { 4812 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_STACK; 4813 } 4814 else if (strncmp (name, "reg", 3) == 0) 4815 { 4816 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_REGISTER; 4817 } 4818 else if (strncmp (name, "null", 4) == 0) 4819 { 4820 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_NULL; 4821 } 4822 else 4823 { 4824 as_fatal (_("unknown procedure kind")); 4825 demand_empty_rest_of_line (); 4826 return; 4827 } 4828 4829 *input_line_pointer = name_end; 4830 demand_empty_rest_of_line (); 4831 4832#ifdef md_flush_pending_output 4833 md_flush_pending_output (); 4834#endif 4835 4836 frag_align (3, 0, 0); 4837 p = frag_more (16); 4838 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0); 4839 fixp->fx_done = 1; 4840 seginfo->literal_pool_size += 16; 4841 4842 *p = alpha_evax_proc.pdsckind 4843 | ((alpha_evax_proc.framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0); 4844 *(p + 1) = PDSC_S_M_NATIVE | PDSC_S_M_NO_JACKET; 4845 4846 switch (alpha_evax_proc.pdsckind) 4847 { 4848 case PDSC_S_K_KIND_NULL: 4849 *(p + 2) = 0; 4850 *(p + 3) = 0; 4851 break; 4852 case PDSC_S_K_KIND_FP_REGISTER: 4853 *(p + 2) = alpha_evax_proc.fp_save; 4854 *(p + 3) = alpha_evax_proc.ra_save; 4855 break; 4856 case PDSC_S_K_KIND_FP_STACK: 4857 md_number_to_chars (p + 2, (valueT) alpha_evax_proc.rsa_offset, 2); 4858 break; 4859 default: /* impossible */ 4860 break; 4861 } 4862 4863 *(p + 4) = 0; 4864 *(p + 5) = alpha_evax_proc.type & 0x0f; 4865 4866 /* Signature offset. */ 4867 md_number_to_chars (p + 6, (valueT) 0, 2); 4868 4869 fix_new_exp (frag_now, p - frag_now->fr_literal+8, 8, &exp, 0, BFD_RELOC_64); 4870 4871 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_NULL) 4872 return; 4873 4874 /* Add dummy fix to make add_to_link_pool work. */ 4875 p = frag_more (8); 4876 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0); 4877 fixp->fx_done = 1; 4878 seginfo->literal_pool_size += 8; 4879 4880 /* pdesc+16: Size. */ 4881 md_number_to_chars (p, (valueT) alpha_evax_proc.framesize, 4); 4882 4883 md_number_to_chars (p + 4, (valueT) 0, 2); 4884 4885 /* Entry length. */ 4886 md_number_to_chars (p + 6, alpha_evax_proc.prologue, 2); 4887 4888 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_FP_REGISTER) 4889 return; 4890 4891 /* Add dummy fix to make add_to_link_pool work. */ 4892 p = frag_more (8); 4893 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0); 4894 fixp->fx_done = 1; 4895 seginfo->literal_pool_size += 8; 4896 4897 /* pdesc+24: register masks. */ 4898 4899 md_number_to_chars (p, alpha_evax_proc.imask, 4); 4900 md_number_to_chars (p + 4, alpha_evax_proc.fmask, 4); 4901 4902 return; 4903} 4904 4905/* Support for crash debug on vms. */ 4906 4907static void 4908s_alpha_name (ignore) 4909 int ignore; 4910{ 4911 register char *p; 4912 expressionS exp; 4913 segment_info_type *seginfo = seg_info (alpha_link_section); 4914 4915 if (now_seg != alpha_link_section) 4916 { 4917 as_bad (_(".name directive not in link (.link) section")); 4918 demand_empty_rest_of_line (); 4919 return; 4920 } 4921 4922 expression (&exp); 4923 if (exp.X_op != O_symbol) 4924 { 4925 as_warn (_(".name directive has no symbol")); 4926 demand_empty_rest_of_line (); 4927 return; 4928 } 4929 4930 demand_empty_rest_of_line (); 4931 4932#ifdef md_flush_pending_output 4933 md_flush_pending_output (); 4934#endif 4935 4936 frag_align (3, 0, 0); 4937 p = frag_more (8); 4938 seginfo->literal_pool_size += 8; 4939 4940 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64); 4941 4942 return; 4943} 4944 4945static void 4946s_alpha_linkage (ignore) 4947 int ignore; 4948{ 4949 expressionS exp; 4950 char *p; 4951 4952#ifdef md_flush_pending_output 4953 md_flush_pending_output (); 4954#endif 4955 4956 expression (&exp); 4957 if (exp.X_op != O_symbol) 4958 { 4959 as_fatal (_("No symbol after .linkage")); 4960 } 4961 else 4962 { 4963 p = frag_more (LKP_S_K_SIZE); 4964 memset (p, 0, LKP_S_K_SIZE); 4965 fix_new_exp (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0,\ 4966 BFD_RELOC_ALPHA_LINKAGE); 4967 } 4968 demand_empty_rest_of_line (); 4969 4970 return; 4971} 4972 4973static void 4974s_alpha_code_address (ignore) 4975 int ignore; 4976{ 4977 expressionS exp; 4978 char *p; 4979 4980#ifdef md_flush_pending_output 4981 md_flush_pending_output (); 4982#endif 4983 4984 expression (&exp); 4985 if (exp.X_op != O_symbol) 4986 { 4987 as_fatal (_("No symbol after .code_address")); 4988 } 4989 else 4990 { 4991 p = frag_more (8); 4992 memset (p, 0, 8); 4993 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0,\ 4994 BFD_RELOC_ALPHA_CODEADDR); 4995 } 4996 demand_empty_rest_of_line (); 4997 4998 return; 4999} 5000 5001static void 5002s_alpha_fp_save (ignore) 5003 int ignore; 5004{ 5005 5006 alpha_evax_proc.fp_save = tc_get_register (1); 5007 5008 demand_empty_rest_of_line (); 5009 return; 5010} 5011 5012static void 5013s_alpha_mask (ignore) 5014 int ignore; 5015{ 5016 long val; 5017 5018 if (get_absolute_expression_and_terminator (&val) != ',') 5019 { 5020 as_warn (_("Bad .mask directive")); 5021 --input_line_pointer; 5022 } 5023 else 5024 { 5025 alpha_evax_proc.imask = val; 5026 (void) get_absolute_expression (); 5027 } 5028 demand_empty_rest_of_line (); 5029 5030 return; 5031} 5032 5033static void 5034s_alpha_fmask (ignore) 5035 int ignore; 5036{ 5037 long val; 5038 5039 if (get_absolute_expression_and_terminator (&val) != ',') 5040 { 5041 as_warn (_("Bad .fmask directive")); 5042 --input_line_pointer; 5043 } 5044 else 5045 { 5046 alpha_evax_proc.fmask = val; 5047 (void) get_absolute_expression (); 5048 } 5049 demand_empty_rest_of_line (); 5050 5051 return; 5052} 5053 5054static void 5055s_alpha_end (ignore) 5056 int ignore; 5057{ 5058 char c; 5059 5060 c = get_symbol_end (); 5061 *input_line_pointer = c; 5062 demand_empty_rest_of_line (); 5063 alpha_evax_proc.symbol = 0; 5064 5065 return; 5066} 5067 5068static void 5069s_alpha_file (ignore) 5070 int ignore; 5071{ 5072 symbolS *s; 5073 int length; 5074 static char case_hack[32]; 5075 5076 extern char *demand_copy_string PARAMS ((int *lenP)); 5077 5078 sprintf (case_hack, "<CASE:%01d%01d>", 5079 alpha_flag_hash_long_names, alpha_flag_show_after_trunc); 5080 5081 s = symbol_find_or_make (case_hack); 5082 symbol_get_bfdsym (s)->flags |= BSF_FILE; 5083 5084 get_absolute_expression (); 5085 s = symbol_find_or_make (demand_copy_string (&length)); 5086 symbol_get_bfdsym (s)->flags |= BSF_FILE; 5087 demand_empty_rest_of_line (); 5088 5089 return; 5090} 5091#endif /* OBJ_EVAX */ 5092 5093/* Handle the .gprel32 pseudo op. */ 5094 5095static void 5096s_alpha_gprel32 (ignore) 5097 int ignore ATTRIBUTE_UNUSED; 5098{ 5099 expressionS e; 5100 char *p; 5101 5102 SKIP_WHITESPACE (); 5103 expression (&e); 5104 5105#ifdef OBJ_ELF 5106 switch (e.X_op) 5107 { 5108 case O_constant: 5109 e.X_add_symbol = section_symbol (absolute_section); 5110 e.X_op = O_symbol; 5111 /* FALLTHRU */ 5112 case O_symbol: 5113 break; 5114 default: 5115 abort (); 5116 } 5117#else 5118#ifdef OBJ_ECOFF 5119 switch (e.X_op) 5120 { 5121 case O_constant: 5122 e.X_add_symbol = section_symbol (absolute_section); 5123 /* fall through */ 5124 case O_symbol: 5125 e.X_op = O_subtract; 5126 e.X_op_symbol = alpha_gp_symbol; 5127 break; 5128 default: 5129 abort (); 5130 } 5131#endif 5132#endif 5133 5134 if (alpha_auto_align_on && alpha_current_align < 2) 5135 alpha_align (2, (char *) NULL, alpha_insn_label, 0); 5136 if (alpha_current_align > 2) 5137 alpha_current_align = 2; 5138 alpha_insn_label = NULL; 5139 5140 p = frag_more (4); 5141 memset (p, 0, 4); 5142 fix_new_exp (frag_now, p - frag_now->fr_literal, 4, 5143 &e, 0, BFD_RELOC_GPREL32); 5144} 5145 5146/* Handle floating point allocation pseudo-ops. This is like the 5147 generic vresion, but it makes sure the current label, if any, is 5148 correctly aligned. */ 5149 5150static void 5151s_alpha_float_cons (type) 5152 int type; 5153{ 5154 int log_size; 5155 5156 switch (type) 5157 { 5158 default: 5159 case 'f': 5160 case 'F': 5161 log_size = 2; 5162 break; 5163 5164 case 'd': 5165 case 'D': 5166 case 'G': 5167 log_size = 3; 5168 break; 5169 5170 case 'x': 5171 case 'X': 5172 case 'p': 5173 case 'P': 5174 log_size = 4; 5175 break; 5176 } 5177 5178 if (alpha_auto_align_on && alpha_current_align < log_size) 5179 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0); 5180 if (alpha_current_align > log_size) 5181 alpha_current_align = log_size; 5182 alpha_insn_label = NULL; 5183 5184 float_cons (type); 5185} 5186 5187/* Handle the .proc pseudo op. We don't really do much with it except 5188 parse it. */ 5189 5190static void 5191s_alpha_proc (is_static) 5192 int is_static ATTRIBUTE_UNUSED; 5193{ 5194 char *name; 5195 char c; 5196 char *p; 5197 symbolS *symbolP; 5198 int temp; 5199 5200 /* Takes ".proc name,nargs" */ 5201 SKIP_WHITESPACE (); 5202 name = input_line_pointer; 5203 c = get_symbol_end (); 5204 p = input_line_pointer; 5205 symbolP = symbol_find_or_make (name); 5206 *p = c; 5207 SKIP_WHITESPACE (); 5208 if (*input_line_pointer != ',') 5209 { 5210 *p = 0; 5211 as_warn (_("Expected comma after name \"%s\""), name); 5212 *p = c; 5213 temp = 0; 5214 ignore_rest_of_line (); 5215 } 5216 else 5217 { 5218 input_line_pointer++; 5219 temp = get_absolute_expression (); 5220 } 5221 /* *symbol_get_obj (symbolP) = (signed char) temp; */ 5222 as_warn (_("unhandled: .proc %s,%d"), name, temp); 5223 demand_empty_rest_of_line (); 5224} 5225 5226/* Handle the .set pseudo op. This is used to turn on and off most of 5227 the assembler features. */ 5228 5229static void 5230s_alpha_set (x) 5231 int x ATTRIBUTE_UNUSED; 5232{ 5233 char *name, ch, *s; 5234 int yesno = 1; 5235 5236 SKIP_WHITESPACE (); 5237 name = input_line_pointer; 5238 ch = get_symbol_end (); 5239 5240 s = name; 5241 if (s[0] == 'n' && s[1] == 'o') 5242 { 5243 yesno = 0; 5244 s += 2; 5245 } 5246 if (!strcmp ("reorder", s)) 5247 /* ignore */ ; 5248 else if (!strcmp ("at", s)) 5249 alpha_noat_on = !yesno; 5250 else if (!strcmp ("macro", s)) 5251 alpha_macros_on = yesno; 5252 else if (!strcmp ("move", s)) 5253 /* ignore */ ; 5254 else if (!strcmp ("volatile", s)) 5255 /* ignore */ ; 5256 else 5257 as_warn (_("Tried to .set unrecognized mode `%s'"), name); 5258 5259 *input_line_pointer = ch; 5260 demand_empty_rest_of_line (); 5261} 5262 5263/* Handle the .base pseudo op. This changes the assembler's notion of 5264 the $gp register. */ 5265 5266static void 5267s_alpha_base (ignore) 5268 int ignore ATTRIBUTE_UNUSED; 5269{ 5270#if 0 5271 if (first_32bit_quadrant) 5272 { 5273 /* not fatal, but it might not work in the end */ 5274 as_warn (_("File overrides no-base-register option.")); 5275 first_32bit_quadrant = 0; 5276 } 5277#endif 5278 5279 SKIP_WHITESPACE (); 5280 if (*input_line_pointer == '$') 5281 { /* $rNN form */ 5282 input_line_pointer++; 5283 if (*input_line_pointer == 'r') 5284 input_line_pointer++; 5285 } 5286 5287 alpha_gp_register = get_absolute_expression (); 5288 if (alpha_gp_register < 0 || alpha_gp_register > 31) 5289 { 5290 alpha_gp_register = AXP_REG_GP; 5291 as_warn (_("Bad base register, using $%d."), alpha_gp_register); 5292 } 5293 5294 demand_empty_rest_of_line (); 5295} 5296 5297/* Handle the .align pseudo-op. This aligns to a power of two. It 5298 also adjusts any current instruction label. We treat this the same 5299 way the MIPS port does: .align 0 turns off auto alignment. */ 5300 5301static void 5302s_alpha_align (ignore) 5303 int ignore ATTRIBUTE_UNUSED; 5304{ 5305 int align; 5306 char fill, *pfill; 5307 long max_alignment = 15; 5308 5309 align = get_absolute_expression (); 5310 if (align > max_alignment) 5311 { 5312 align = max_alignment; 5313 as_bad (_("Alignment too large: %d. assumed"), align); 5314 } 5315 else if (align < 0) 5316 { 5317 as_warn (_("Alignment negative: 0 assumed")); 5318 align = 0; 5319 } 5320 5321 if (*input_line_pointer == ',') 5322 { 5323 input_line_pointer++; 5324 fill = get_absolute_expression (); 5325 pfill = &fill; 5326 } 5327 else 5328 pfill = NULL; 5329 5330 if (align != 0) 5331 { 5332 alpha_auto_align_on = 1; 5333 alpha_align (align, pfill, alpha_insn_label, 1); 5334 } 5335 else 5336 { 5337 alpha_auto_align_on = 0; 5338 } 5339 5340 demand_empty_rest_of_line (); 5341} 5342 5343/* Hook the normal string processor to reset known alignment. */ 5344 5345static void 5346s_alpha_stringer (terminate) 5347 int terminate; 5348{ 5349 alpha_current_align = 0; 5350 alpha_insn_label = NULL; 5351 stringer (terminate); 5352} 5353 5354/* Hook the normal space processing to reset known alignment. */ 5355 5356static void 5357s_alpha_space (ignore) 5358 int ignore; 5359{ 5360 alpha_current_align = 0; 5361 alpha_insn_label = NULL; 5362 s_space (ignore); 5363} 5364 5365/* Hook into cons for auto-alignment. */ 5366 5367void 5368alpha_cons_align (size) 5369 int size; 5370{ 5371 int log_size; 5372 5373 log_size = 0; 5374 while ((size >>= 1) != 0) 5375 ++log_size; 5376 5377 if (alpha_auto_align_on && alpha_current_align < log_size) 5378 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0); 5379 if (alpha_current_align > log_size) 5380 alpha_current_align = log_size; 5381 alpha_insn_label = NULL; 5382} 5383 5384/* Here come the .uword, .ulong, and .uquad explicitly unaligned 5385 pseudos. We just turn off auto-alignment and call down to cons. */ 5386 5387static void 5388s_alpha_ucons (bytes) 5389 int bytes; 5390{ 5391 int hold = alpha_auto_align_on; 5392 alpha_auto_align_on = 0; 5393 cons (bytes); 5394 alpha_auto_align_on = hold; 5395} 5396 5397/* Switch the working cpu type. */ 5398 5399static void 5400s_alpha_arch (ignored) 5401 int ignored ATTRIBUTE_UNUSED; 5402{ 5403 char *name, ch; 5404 const struct cpu_type *p; 5405 5406 SKIP_WHITESPACE (); 5407 name = input_line_pointer; 5408 ch = get_symbol_end (); 5409 5410 for (p = cpu_types; p->name; ++p) 5411 if (strcmp (name, p->name) == 0) 5412 { 5413 alpha_target_name = p->name, alpha_target = p->flags; 5414 goto found; 5415 } 5416 as_warn ("Unknown CPU identifier `%s'", name); 5417 5418found: 5419 *input_line_pointer = ch; 5420 demand_empty_rest_of_line (); 5421} 5422 5423#ifdef DEBUG1 5424/* print token expression with alpha specific extension. */ 5425 5426static void 5427alpha_print_token (f, exp) 5428 FILE *f; 5429 const expressionS *exp; 5430{ 5431 switch (exp->X_op) 5432 { 5433 case O_cpregister: 5434 putc (',', f); 5435 /* FALLTHRU */ 5436 case O_pregister: 5437 putc ('(', f); 5438 { 5439 expressionS nexp = *exp; 5440 nexp.X_op = O_register; 5441 print_expr (f, &nexp); 5442 } 5443 putc (')', f); 5444 break; 5445 default: 5446 print_expr (f, exp); 5447 break; 5448 } 5449 return; 5450} 5451#endif 5452 5453/* The target specific pseudo-ops which we support. */ 5454 5455const pseudo_typeS md_pseudo_table[] = { 5456#ifdef OBJ_ECOFF 5457 {"comm", s_alpha_comm, 0}, /* osf1 compiler does this */ 5458 {"rdata", s_alpha_rdata, 0}, 5459#endif 5460 {"text", s_alpha_text, 0}, 5461 {"data", s_alpha_data, 0}, 5462#ifdef OBJ_ECOFF 5463 {"sdata", s_alpha_sdata, 0}, 5464#endif 5465#ifdef OBJ_ELF 5466 {"section", s_alpha_section, 0}, 5467 {"section.s", s_alpha_section, 0}, 5468 {"sect", s_alpha_section, 0}, 5469 {"sect.s", s_alpha_section, 0}, 5470#endif 5471#ifdef OBJ_EVAX 5472 { "pdesc", s_alpha_pdesc, 0}, 5473 { "name", s_alpha_name, 0}, 5474 { "linkage", s_alpha_linkage, 0}, 5475 { "code_address", s_alpha_code_address, 0}, 5476 { "ent", s_alpha_ent, 0}, 5477 { "frame", s_alpha_frame, 0}, 5478 { "fp_save", s_alpha_fp_save, 0}, 5479 { "mask", s_alpha_mask, 0}, 5480 { "fmask", s_alpha_fmask, 0}, 5481 { "end", s_alpha_end, 0}, 5482 { "file", s_alpha_file, 0}, 5483 { "rdata", s_alpha_section, 1}, 5484 { "comm", s_alpha_comm, 0}, 5485 { "link", s_alpha_section, 3}, 5486 { "ctors", s_alpha_section, 4}, 5487 { "dtors", s_alpha_section, 5}, 5488#endif 5489#ifdef OBJ_ELF 5490 /* Frame related pseudos. */ 5491 {"ent", s_alpha_ent, 0}, 5492 {"end", s_alpha_end, 0}, 5493 {"mask", s_alpha_mask, 0}, 5494 {"fmask", s_alpha_mask, 1}, 5495 {"frame", s_alpha_frame, 0}, 5496 {"prologue", s_alpha_prologue, 0}, 5497 {"file", s_alpha_file, 5}, 5498 {"loc", s_alpha_loc, 9}, 5499 {"stabs", s_alpha_stab, 's'}, 5500 {"stabn", s_alpha_stab, 'n'}, 5501 /* COFF debugging related pseudos. */ 5502 {"begin", s_alpha_coff_wrapper, 0}, 5503 {"bend", s_alpha_coff_wrapper, 1}, 5504 {"def", s_alpha_coff_wrapper, 2}, 5505 {"dim", s_alpha_coff_wrapper, 3}, 5506 {"endef", s_alpha_coff_wrapper, 4}, 5507 {"scl", s_alpha_coff_wrapper, 5}, 5508 {"tag", s_alpha_coff_wrapper, 6}, 5509 {"val", s_alpha_coff_wrapper, 7}, 5510#else 5511 {"prologue", s_ignore, 0}, 5512#endif 5513 {"gprel32", s_alpha_gprel32, 0}, 5514 {"t_floating", s_alpha_float_cons, 'd'}, 5515 {"s_floating", s_alpha_float_cons, 'f'}, 5516 {"f_floating", s_alpha_float_cons, 'F'}, 5517 {"g_floating", s_alpha_float_cons, 'G'}, 5518 {"d_floating", s_alpha_float_cons, 'D'}, 5519 5520 {"proc", s_alpha_proc, 0}, 5521 {"aproc", s_alpha_proc, 1}, 5522 {"set", s_alpha_set, 0}, 5523 {"reguse", s_ignore, 0}, 5524 {"livereg", s_ignore, 0}, 5525 {"base", s_alpha_base, 0}, /*??*/ 5526 {"option", s_ignore, 0}, 5527 {"aent", s_ignore, 0}, 5528 {"ugen", s_ignore, 0}, 5529 {"eflag", s_ignore, 0}, 5530 5531 {"align", s_alpha_align, 0}, 5532 {"double", s_alpha_float_cons, 'd'}, 5533 {"float", s_alpha_float_cons, 'f'}, 5534 {"single", s_alpha_float_cons, 'f'}, 5535 {"ascii", s_alpha_stringer, 0}, 5536 {"asciz", s_alpha_stringer, 1}, 5537 {"string", s_alpha_stringer, 1}, 5538 {"space", s_alpha_space, 0}, 5539 {"skip", s_alpha_space, 0}, 5540 {"zero", s_alpha_space, 0}, 5541 5542/* Unaligned data pseudos. */ 5543 {"uword", s_alpha_ucons, 2}, 5544 {"ulong", s_alpha_ucons, 4}, 5545 {"uquad", s_alpha_ucons, 8}, 5546 5547#ifdef OBJ_ELF 5548/* Dwarf wants these versions of unaligned. */ 5549 {"2byte", s_alpha_ucons, 2}, 5550 {"4byte", s_alpha_ucons, 4}, 5551 {"8byte", s_alpha_ucons, 8}, 5552#endif 5553 5554/* We don't do any optimizing, so we can safely ignore these. */ 5555 {"noalias", s_ignore, 0}, 5556 {"alias", s_ignore, 0}, 5557 5558 {"arch", s_alpha_arch, 0}, 5559 5560 {NULL, 0, 0}, 5561}; 5562 5563/* Build a BFD section with its flags set appropriately for the .lita, 5564 .lit8, or .lit4 sections. */ 5565 5566static void 5567create_literal_section (name, secp, symp) 5568 const char *name; 5569 segT *secp; 5570 symbolS **symp; 5571{ 5572 segT current_section = now_seg; 5573 int current_subsec = now_subseg; 5574 segT new_sec; 5575 5576 *secp = new_sec = subseg_new (name, 0); 5577 subseg_set (current_section, current_subsec); 5578 bfd_set_section_alignment (stdoutput, new_sec, 4); 5579 bfd_set_section_flags (stdoutput, new_sec, 5580 SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY 5581 | SEC_DATA); 5582 5583 S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec)); 5584} 5585 5586#ifdef OBJ_ECOFF 5587 5588/* @@@ GP selection voodoo. All of this seems overly complicated and 5589 unnecessary; which is the primary reason it's for ECOFF only. */ 5590 5591static inline void 5592maybe_set_gp (sec) 5593 asection *sec; 5594{ 5595 bfd_vma vma; 5596 if (!sec) 5597 return; 5598 vma = bfd_get_section_vma (foo, sec); 5599 if (vma && vma < alpha_gp_value) 5600 alpha_gp_value = vma; 5601} 5602 5603static void 5604select_gp_value () 5605{ 5606 assert (alpha_gp_value == 0); 5607 5608 /* Get minus-one in whatever width... */ 5609 alpha_gp_value = 0; 5610 alpha_gp_value--; 5611 5612 /* Select the smallest VMA of these existing sections. */ 5613 maybe_set_gp (alpha_lita_section); 5614#if 0 5615 /* These were disabled before -- should we use them? */ 5616 maybe_set_gp (sdata); 5617 maybe_set_gp (lit8_sec); 5618 maybe_set_gp (lit4_sec); 5619#endif 5620 5621/* @@ Will a simple 0x8000 work here? If not, why not? */ 5622#define GP_ADJUSTMENT (0x8000 - 0x10) 5623 5624 alpha_gp_value += GP_ADJUSTMENT; 5625 5626 S_SET_VALUE (alpha_gp_symbol, alpha_gp_value); 5627 5628#ifdef DEBUG1 5629 printf (_("Chose GP value of %lx\n"), alpha_gp_value); 5630#endif 5631} 5632#endif /* OBJ_ECOFF */ 5633 5634#ifdef OBJ_ELF 5635/* Map 's' to SHF_ALPHA_GPREL. */ 5636 5637int 5638alpha_elf_section_letter (letter, ptr_msg) 5639 int letter; 5640 char **ptr_msg; 5641{ 5642 if (letter == 's') 5643 return SHF_ALPHA_GPREL; 5644 5645 *ptr_msg = _("Bad .section directive: want a,s,w,x,M,S,G,T in string"); 5646 return 0; 5647} 5648 5649/* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */ 5650 5651flagword 5652alpha_elf_section_flags (flags, attr, type) 5653 flagword flags; 5654 int attr, type ATTRIBUTE_UNUSED; 5655{ 5656 if (attr & SHF_ALPHA_GPREL) 5657 flags |= SEC_SMALL_DATA; 5658 return flags; 5659} 5660#endif /* OBJ_ELF */ 5661 5662/* Called internally to handle all alignment needs. This takes care 5663 of eliding calls to frag_align if'n the cached current alignment 5664 says we've already got it, as well as taking care of the auto-align 5665 feature wrt labels. */ 5666 5667static void 5668alpha_align (n, pfill, label, force) 5669 int n; 5670 char *pfill; 5671 symbolS *label; 5672 int force ATTRIBUTE_UNUSED; 5673{ 5674 if (alpha_current_align >= n) 5675 return; 5676 5677 if (pfill == NULL) 5678 { 5679 if (subseg_text_p (now_seg)) 5680 frag_align_code (n, 0); 5681 else 5682 frag_align (n, 0, 0); 5683 } 5684 else 5685 frag_align (n, *pfill, 0); 5686 5687 alpha_current_align = n; 5688 5689 if (label != NULL && S_GET_SEGMENT (label) == now_seg) 5690 { 5691 symbol_set_frag (label, frag_now); 5692 S_SET_VALUE (label, (valueT) frag_now_fix ()); 5693 } 5694 5695 record_alignment (now_seg, n); 5696 5697 /* ??? If alpha_flag_relax && force && elf, record the requested alignment 5698 in a reloc for the linker to see. */ 5699} 5700 5701/* This is called from HANDLE_ALIGN in write.c. Fill in the contents 5702 of an rs_align_code fragment. */ 5703 5704void 5705alpha_handle_align (fragp) 5706 fragS *fragp; 5707{ 5708 static char const unop[4] = { 0x00, 0x00, 0xfe, 0x2f }; 5709 static char const nopunop[8] = { 5710 0x1f, 0x04, 0xff, 0x47, 5711 0x00, 0x00, 0xfe, 0x2f 5712 }; 5713 5714 int bytes, fix; 5715 char *p; 5716 5717 if (fragp->fr_type != rs_align_code) 5718 return; 5719 5720 bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix; 5721 p = fragp->fr_literal + fragp->fr_fix; 5722 fix = 0; 5723 5724 if (bytes & 3) 5725 { 5726 fix = bytes & 3; 5727 memset (p, 0, fix); 5728 p += fix; 5729 bytes -= fix; 5730 } 5731 5732 if (bytes & 4) 5733 { 5734 memcpy (p, unop, 4); 5735 p += 4; 5736 bytes -= 4; 5737 fix += 4; 5738 } 5739 5740 memcpy (p, nopunop, 8); 5741 5742 fragp->fr_fix += fix; 5743 fragp->fr_var = 8; 5744} 5745 5746/* The Alpha has support for some VAX floating point types, as well as for 5747 IEEE floating point. We consider IEEE to be the primary floating point 5748 format, and sneak in the VAX floating point support here. */ 5749#define md_atof vax_md_atof 5750#include "config/atof-vax.c" 5751