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