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