tc-arm.c revision 77298
1/* tc-arm.c -- Assemble for the ARM 2 Copyright (C) 1994, 95, 96, 97, 98, 1999, 2000 3 Free Software Foundation, Inc. 4 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org) 5 Modified by David Taylor (dtaylor@armltd.co.uk) 6 7 This file is part of GAS, the GNU Assembler. 8 9 GAS is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 2, or (at your option) 12 any later version. 13 14 GAS is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with GAS; see the file COPYING. If not, write to the Free 21 Software Foundation, 59 Temple Place - Suite 330, Boston, MA 22 02111-1307, USA. */ 23 24#include <ctype.h> 25#include <string.h> 26#define NO_RELOC 0 27#include "as.h" 28 29/* Need TARGET_CPU. */ 30#include "config.h" 31#include "subsegs.h" 32#include "obstack.h" 33#include "symbols.h" 34#include "listing.h" 35 36#ifdef OBJ_ELF 37#include "elf/arm.h" 38#include "dwarf2dbg.h" 39#endif 40 41/* Types of processor to assemble for. */ 42#define ARM_1 0x00000001 43#define ARM_2 0x00000002 44#define ARM_3 0x00000004 45#define ARM_250 ARM_3 46#define ARM_6 0x00000008 47#define ARM_7 ARM_6 /* Same core instruction set. */ 48#define ARM_8 ARM_6 /* Same core instruction set. */ 49#define ARM_9 ARM_6 /* Same core instruction set. */ 50#define ARM_CPU_MASK 0x0000000f 51 52/* The following bitmasks control CPU extensions (ARM7 onwards): */ 53#define ARM_EXT_LONGMUL 0x00000010 /* Allow long multiplies. */ 54#define ARM_EXT_HALFWORD 0x00000020 /* Allow half word loads. */ 55#define ARM_EXT_THUMB 0x00000040 /* Allow BX instruction. */ 56#define ARM_EXT_V5 0x00000080 /* Allow CLZ, etc. */ 57#define ARM_EXT_V5E 0x00000100 /* "El Segundo". */ 58#define ARM_EXT_XSCALE 0x00000200 /* Allow MIA etc. */ 59 60/* Architectures are the sum of the base and extensions. */ 61#define ARM_ARCH_V3M ARM_EXT_LONGMUL 62#define ARM_ARCH_V4 (ARM_ARCH_V3M | ARM_EXT_HALFWORD) 63#define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_EXT_THUMB) 64#define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5) 65#define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_EXT_THUMB) 66#define ARM_ARCH_V5TE (ARM_ARCH_V5T | ARM_EXT_V5E) 67#define ARM_ARCH_XSCALE (ARM_ARCH_V5TE | ARM_EXT_XSCALE) 68 69/* Some useful combinations: */ 70#define ARM_ANY 0x00ffffff 71#define ARM_2UP (ARM_ANY - ARM_1) 72#define ARM_ALL ARM_2UP /* Not arm1 only. */ 73#define ARM_3UP 0x00fffffc 74#define ARM_6UP 0x00fffff8 /* Includes ARM7. */ 75 76#define FPU_CORE 0x80000000 77#define FPU_FPA10 0x40000000 78#define FPU_FPA11 0x40000000 79#define FPU_NONE 0 80 81/* Some useful combinations. */ 82#define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY. */ 83#define FPU_MEMMULTI 0x7f000000 /* Not fpu_core. */ 84 85#ifndef CPU_DEFAULT 86#if defined __XSCALE__ 87#define CPU_DEFAULT (ARM_9 | ARM_ARCH_XSCALE) 88#else 89#if defined __thumb__ 90#define CPU_DEFAULT (ARM_7 | ARM_ARCH_V4T) 91#else 92#define CPU_DEFAULT ARM_ALL 93#endif 94#endif 95#endif 96 97#ifndef FPU_DEFAULT 98#define FPU_DEFAULT FPU_ALL 99#endif 100 101#define streq(a, b) (strcmp (a, b) == 0) 102#define skip_whitespace(str) while (*(str) == ' ') ++(str) 103 104static unsigned long cpu_variant = CPU_DEFAULT | FPU_DEFAULT; 105static int target_oabi = 0; 106 107#if defined OBJ_COFF || defined OBJ_ELF 108/* Flags stored in private area of BFD structure. */ 109static boolean uses_apcs_26 = false; 110static boolean atpcs = false; 111static boolean support_interwork = false; 112static boolean uses_apcs_float = false; 113static boolean pic_code = false; 114#endif 115 116/* This array holds the chars that always start a comment. If the 117 pre-processor is disabled, these aren't very useful. */ 118CONST char comment_chars[] = "@"; 119 120/* This array holds the chars that only start a comment at the beginning of 121 a line. If the line seems to have the form '# 123 filename' 122 .line and .file directives will appear in the pre-processed output. */ 123/* Note that input_file.c hand checks for '#' at the beginning of the 124 first line of the input file. This is because the compiler outputs 125 #NO_APP at the beginning of its output. */ 126/* Also note that comments like this one will always work. */ 127CONST char line_comment_chars[] = "#"; 128 129CONST char line_separator_chars[] = ";"; 130 131/* Chars that can be used to separate mant 132 from exp in floating point numbers. */ 133CONST char EXP_CHARS[] = "eE"; 134 135/* Chars that mean this number is a floating point constant. */ 136/* As in 0f12.456 */ 137/* or 0d1.2345e12 */ 138 139CONST char FLT_CHARS[] = "rRsSfFdDxXeEpP"; 140 141/* Prefix characters that indicate the start of an immediate 142 value. */ 143#define is_immediate_prefix(C) ((C) == '#' || (C) == '$') 144 145#ifdef OBJ_ELF 146/* Pre-defined "_GLOBAL_OFFSET_TABLE_" */ 147symbolS * GOT_symbol; 148#endif 149 150/* Size of relocation record. */ 151CONST int md_reloc_size = 8; 152 153/* 0: assemble for ARM, 154 1: assemble for Thumb, 155 2: assemble for Thumb even though target CPU does not support thumb 156 instructions. */ 157static int thumb_mode = 0; 158 159typedef struct arm_fix 160{ 161 int thumb_mode; 162} arm_fix_data; 163 164struct arm_it 165{ 166 CONST char * error; 167 unsigned long instruction; 168 int suffix; 169 int size; 170 struct 171 { 172 bfd_reloc_code_real_type type; 173 expressionS exp; 174 int pc_rel; 175 } reloc; 176}; 177 178struct arm_it inst; 179 180enum asm_shift_index 181{ 182 SHIFT_LSL = 0, 183 SHIFT_LSR, 184 SHIFT_ASR, 185 SHIFT_ROR, 186 SHIFT_RRX 187}; 188 189struct asm_shift_properties 190{ 191 enum asm_shift_index index; 192 unsigned long bit_field; 193 unsigned int allows_0 : 1; 194 unsigned int allows_32 : 1; 195}; 196 197static const struct asm_shift_properties shift_properties [] = 198{ 199 { SHIFT_LSL, 0, 1, 0}, 200 { SHIFT_LSR, 0x20, 0, 1}, 201 { SHIFT_ASR, 0x40, 0, 1}, 202 { SHIFT_ROR, 0x60, 0, 0}, 203 { SHIFT_RRX, 0x60, 0, 0} 204}; 205 206struct asm_shift_name 207{ 208 const char * name; 209 const struct asm_shift_properties * properties; 210}; 211 212static const struct asm_shift_name shift_names [] = 213{ 214 { "asl", shift_properties + SHIFT_LSL }, 215 { "lsl", shift_properties + SHIFT_LSL }, 216 { "lsr", shift_properties + SHIFT_LSR }, 217 { "asr", shift_properties + SHIFT_ASR }, 218 { "ror", shift_properties + SHIFT_ROR }, 219 { "rrx", shift_properties + SHIFT_RRX }, 220 { "ASL", shift_properties + SHIFT_LSL }, 221 { "LSL", shift_properties + SHIFT_LSL }, 222 { "LSR", shift_properties + SHIFT_LSR }, 223 { "ASR", shift_properties + SHIFT_ASR }, 224 { "ROR", shift_properties + SHIFT_ROR }, 225 { "RRX", shift_properties + SHIFT_RRX } 226}; 227 228#define NO_SHIFT_RESTRICT 1 229#define SHIFT_RESTRICT 0 230 231#define NUM_FLOAT_VALS 8 232 233CONST char * fp_const[] = 234{ 235 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0 236}; 237 238/* Number of littlenums required to hold an extended precision number. */ 239#define MAX_LITTLENUMS 6 240 241LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS]; 242 243#define FAIL (-1) 244#define SUCCESS (0) 245 246#define SUFF_S 1 247#define SUFF_D 2 248#define SUFF_E 3 249#define SUFF_P 4 250 251#define CP_T_X 0x00008000 252#define CP_T_Y 0x00400000 253#define CP_T_Pre 0x01000000 254#define CP_T_UD 0x00800000 255#define CP_T_WB 0x00200000 256 257#define CONDS_BIT 0x00100000 258#define LOAD_BIT 0x00100000 259#define TRANS_BIT 0x00200000 260 261#define DOUBLE_LOAD_FLAG 0x00000001 262 263struct asm_cond 264{ 265 CONST char * template; 266 unsigned long value; 267}; 268 269/* This is to save a hash look-up in the common case. */ 270#define COND_ALWAYS 0xe0000000 271 272static CONST struct asm_cond conds[] = 273{ 274 {"eq", 0x00000000}, 275 {"ne", 0x10000000}, 276 {"cs", 0x20000000}, {"hs", 0x20000000}, 277 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000}, 278 {"mi", 0x40000000}, 279 {"pl", 0x50000000}, 280 {"vs", 0x60000000}, 281 {"vc", 0x70000000}, 282 {"hi", 0x80000000}, 283 {"ls", 0x90000000}, 284 {"ge", 0xa0000000}, 285 {"lt", 0xb0000000}, 286 {"gt", 0xc0000000}, 287 {"le", 0xd0000000}, 288 {"al", 0xe0000000}, 289 {"nv", 0xf0000000} 290}; 291 292/* Warning: If the top bit of the set_bits is set, then the standard 293 instruction bitmask is ignored, and the new bitmask is taken from 294 the set_bits: */ 295struct asm_flg 296{ 297 CONST char * template; /* Basic flag string. */ 298 unsigned long set_bits; /* Bits to set. */ 299}; 300 301static CONST struct asm_flg s_flag[] = 302{ 303 {"s", CONDS_BIT}, 304 {NULL, 0} 305}; 306 307static CONST struct asm_flg ldr_flags[] = 308{ 309 {"d", DOUBLE_LOAD_FLAG}, 310 {"b", 0x00400000}, 311 {"t", TRANS_BIT}, 312 {"bt", 0x00400000 | TRANS_BIT}, 313 {"h", 0x801000b0}, 314 {"sh", 0x801000f0}, 315 {"sb", 0x801000d0}, 316 {NULL, 0} 317}; 318 319static CONST struct asm_flg str_flags[] = 320{ 321 {"d", DOUBLE_LOAD_FLAG}, 322 {"b", 0x00400000}, 323 {"t", TRANS_BIT}, 324 {"bt", 0x00400000 | TRANS_BIT}, 325 {"h", 0x800000b0}, 326 {NULL, 0} 327}; 328 329static CONST struct asm_flg byte_flag[] = 330{ 331 {"b", 0x00400000}, 332 {NULL, 0} 333}; 334 335static CONST struct asm_flg cmp_flags[] = 336{ 337 {"s", CONDS_BIT}, 338 {"p", 0x0010f000}, 339 {NULL, 0} 340}; 341 342static CONST struct asm_flg ldm_flags[] = 343{ 344 {"ed", 0x01800000}, 345 {"fd", 0x00800000}, 346 {"ea", 0x01000000}, 347 {"fa", 0x00000000}, 348 {"ib", 0x01800000}, 349 {"ia", 0x00800000}, 350 {"db", 0x01000000}, 351 {"da", 0x00000000}, 352 {NULL, 0} 353}; 354 355static CONST struct asm_flg stm_flags[] = 356{ 357 {"ed", 0x00000000}, 358 {"fd", 0x01000000}, 359 {"ea", 0x00800000}, 360 {"fa", 0x01800000}, 361 {"ib", 0x01800000}, 362 {"ia", 0x00800000}, 363 {"db", 0x01000000}, 364 {"da", 0x00000000}, 365 {NULL, 0} 366}; 367 368static CONST struct asm_flg lfm_flags[] = 369{ 370 {"fd", 0x00800000}, 371 {"ea", 0x01000000}, 372 {NULL, 0} 373}; 374 375static CONST struct asm_flg sfm_flags[] = 376{ 377 {"fd", 0x01000000}, 378 {"ea", 0x00800000}, 379 {NULL, 0} 380}; 381 382static CONST struct asm_flg round_flags[] = 383{ 384 {"p", 0x00000020}, 385 {"m", 0x00000040}, 386 {"z", 0x00000060}, 387 {NULL, 0} 388}; 389 390/* The implementation of the FIX instruction is broken on some assemblers, 391 in that it accepts a precision specifier as well as a rounding specifier, 392 despite the fact that this is meaningless. To be more compatible, we 393 accept it as well, though of course it does not set any bits. */ 394static CONST struct asm_flg fix_flags[] = 395{ 396 {"p", 0x00000020}, 397 {"m", 0x00000040}, 398 {"z", 0x00000060}, 399 {"sp", 0x00000020}, 400 {"sm", 0x00000040}, 401 {"sz", 0x00000060}, 402 {"dp", 0x00000020}, 403 {"dm", 0x00000040}, 404 {"dz", 0x00000060}, 405 {"ep", 0x00000020}, 406 {"em", 0x00000040}, 407 {"ez", 0x00000060}, 408 {NULL, 0} 409}; 410 411static CONST struct asm_flg except_flag[] = 412{ 413 {"e", 0x00400000}, 414 {NULL, 0} 415}; 416 417static CONST struct asm_flg cplong_flag[] = 418{ 419 {"l", 0x00400000}, 420 {NULL, 0} 421}; 422 423struct asm_psr 424{ 425 CONST char * template; 426 boolean cpsr; 427 unsigned long field; 428}; 429 430/* The bit that distnguishes CPSR and SPSR. */ 431#define SPSR_BIT (1 << 22) 432 433/* How many bits to shift the PSR_xxx bits up by. */ 434#define PSR_SHIFT 16 435 436#define PSR_c (1 << 0) 437#define PSR_x (1 << 1) 438#define PSR_s (1 << 2) 439#define PSR_f (1 << 3) 440 441static CONST struct asm_psr psrs[] = 442{ 443 {"CPSR", true, PSR_c | PSR_f}, 444 {"CPSR_all", true, PSR_c | PSR_f}, 445 {"SPSR", false, PSR_c | PSR_f}, 446 {"SPSR_all", false, PSR_c | PSR_f}, 447 {"CPSR_flg", true, PSR_f}, 448 {"CPSR_f", true, PSR_f}, 449 {"SPSR_flg", false, PSR_f}, 450 {"SPSR_f", false, PSR_f}, 451 {"CPSR_c", true, PSR_c}, 452 {"CPSR_ctl", true, PSR_c}, 453 {"SPSR_c", false, PSR_c}, 454 {"SPSR_ctl", false, PSR_c}, 455 {"CPSR_x", true, PSR_x}, 456 {"CPSR_s", true, PSR_s}, 457 {"SPSR_x", false, PSR_x}, 458 {"SPSR_s", false, PSR_s}, 459 /* Combinations of flags. */ 460 {"CPSR_fs", true, PSR_f | PSR_s}, 461 {"CPSR_fx", true, PSR_f | PSR_x}, 462 {"CPSR_fc", true, PSR_f | PSR_c}, 463 {"CPSR_sf", true, PSR_s | PSR_f}, 464 {"CPSR_sx", true, PSR_s | PSR_x}, 465 {"CPSR_sc", true, PSR_s | PSR_c}, 466 {"CPSR_xf", true, PSR_x | PSR_f}, 467 {"CPSR_xs", true, PSR_x | PSR_s}, 468 {"CPSR_xc", true, PSR_x | PSR_c}, 469 {"CPSR_cf", true, PSR_c | PSR_f}, 470 {"CPSR_cs", true, PSR_c | PSR_s}, 471 {"CPSR_cx", true, PSR_c | PSR_x}, 472 {"CPSR_fsx", true, PSR_f | PSR_s | PSR_x}, 473 {"CPSR_fsc", true, PSR_f | PSR_s | PSR_c}, 474 {"CPSR_fxs", true, PSR_f | PSR_x | PSR_s}, 475 {"CPSR_fxc", true, PSR_f | PSR_x | PSR_c}, 476 {"CPSR_fcs", true, PSR_f | PSR_c | PSR_s}, 477 {"CPSR_fcx", true, PSR_f | PSR_c | PSR_x}, 478 {"CPSR_sfx", true, PSR_s | PSR_f | PSR_x}, 479 {"CPSR_sfc", true, PSR_s | PSR_f | PSR_c}, 480 {"CPSR_sxf", true, PSR_s | PSR_x | PSR_f}, 481 {"CPSR_sxc", true, PSR_s | PSR_x | PSR_c}, 482 {"CPSR_scf", true, PSR_s | PSR_c | PSR_f}, 483 {"CPSR_scx", true, PSR_s | PSR_c | PSR_x}, 484 {"CPSR_xfs", true, PSR_x | PSR_f | PSR_s}, 485 {"CPSR_xfc", true, PSR_x | PSR_f | PSR_c}, 486 {"CPSR_xsf", true, PSR_x | PSR_s | PSR_f}, 487 {"CPSR_xsc", true, PSR_x | PSR_s | PSR_c}, 488 {"CPSR_xcf", true, PSR_x | PSR_c | PSR_f}, 489 {"CPSR_xcs", true, PSR_x | PSR_c | PSR_s}, 490 {"CPSR_cfs", true, PSR_c | PSR_f | PSR_s}, 491 {"CPSR_cfx", true, PSR_c | PSR_f | PSR_x}, 492 {"CPSR_csf", true, PSR_c | PSR_s | PSR_f}, 493 {"CPSR_csx", true, PSR_c | PSR_s | PSR_x}, 494 {"CPSR_cxf", true, PSR_c | PSR_x | PSR_f}, 495 {"CPSR_cxs", true, PSR_c | PSR_x | PSR_s}, 496 {"CPSR_fsxc", true, PSR_f | PSR_s | PSR_x | PSR_c}, 497 {"CPSR_fscx", true, PSR_f | PSR_s | PSR_c | PSR_x}, 498 {"CPSR_fxsc", true, PSR_f | PSR_x | PSR_s | PSR_c}, 499 {"CPSR_fxcs", true, PSR_f | PSR_x | PSR_c | PSR_s}, 500 {"CPSR_fcsx", true, PSR_f | PSR_c | PSR_s | PSR_x}, 501 {"CPSR_fcxs", true, PSR_f | PSR_c | PSR_x | PSR_s}, 502 {"CPSR_sfxc", true, PSR_s | PSR_f | PSR_x | PSR_c}, 503 {"CPSR_sfcx", true, PSR_s | PSR_f | PSR_c | PSR_x}, 504 {"CPSR_sxfc", true, PSR_s | PSR_x | PSR_f | PSR_c}, 505 {"CPSR_sxcf", true, PSR_s | PSR_x | PSR_c | PSR_f}, 506 {"CPSR_scfx", true, PSR_s | PSR_c | PSR_f | PSR_x}, 507 {"CPSR_scxf", true, PSR_s | PSR_c | PSR_x | PSR_f}, 508 {"CPSR_xfsc", true, PSR_x | PSR_f | PSR_s | PSR_c}, 509 {"CPSR_xfcs", true, PSR_x | PSR_f | PSR_c | PSR_s}, 510 {"CPSR_xsfc", true, PSR_x | PSR_s | PSR_f | PSR_c}, 511 {"CPSR_xscf", true, PSR_x | PSR_s | PSR_c | PSR_f}, 512 {"CPSR_xcfs", true, PSR_x | PSR_c | PSR_f | PSR_s}, 513 {"CPSR_xcsf", true, PSR_x | PSR_c | PSR_s | PSR_f}, 514 {"CPSR_cfsx", true, PSR_c | PSR_f | PSR_s | PSR_x}, 515 {"CPSR_cfxs", true, PSR_c | PSR_f | PSR_x | PSR_s}, 516 {"CPSR_csfx", true, PSR_c | PSR_s | PSR_f | PSR_x}, 517 {"CPSR_csxf", true, PSR_c | PSR_s | PSR_x | PSR_f}, 518 {"CPSR_cxfs", true, PSR_c | PSR_x | PSR_f | PSR_s}, 519 {"CPSR_cxsf", true, PSR_c | PSR_x | PSR_s | PSR_f}, 520 {"SPSR_fs", false, PSR_f | PSR_s}, 521 {"SPSR_fx", false, PSR_f | PSR_x}, 522 {"SPSR_fc", false, PSR_f | PSR_c}, 523 {"SPSR_sf", false, PSR_s | PSR_f}, 524 {"SPSR_sx", false, PSR_s | PSR_x}, 525 {"SPSR_sc", false, PSR_s | PSR_c}, 526 {"SPSR_xf", false, PSR_x | PSR_f}, 527 {"SPSR_xs", false, PSR_x | PSR_s}, 528 {"SPSR_xc", false, PSR_x | PSR_c}, 529 {"SPSR_cf", false, PSR_c | PSR_f}, 530 {"SPSR_cs", false, PSR_c | PSR_s}, 531 {"SPSR_cx", false, PSR_c | PSR_x}, 532 {"SPSR_fsx", false, PSR_f | PSR_s | PSR_x}, 533 {"SPSR_fsc", false, PSR_f | PSR_s | PSR_c}, 534 {"SPSR_fxs", false, PSR_f | PSR_x | PSR_s}, 535 {"SPSR_fxc", false, PSR_f | PSR_x | PSR_c}, 536 {"SPSR_fcs", false, PSR_f | PSR_c | PSR_s}, 537 {"SPSR_fcx", false, PSR_f | PSR_c | PSR_x}, 538 {"SPSR_sfx", false, PSR_s | PSR_f | PSR_x}, 539 {"SPSR_sfc", false, PSR_s | PSR_f | PSR_c}, 540 {"SPSR_sxf", false, PSR_s | PSR_x | PSR_f}, 541 {"SPSR_sxc", false, PSR_s | PSR_x | PSR_c}, 542 {"SPSR_scf", false, PSR_s | PSR_c | PSR_f}, 543 {"SPSR_scx", false, PSR_s | PSR_c | PSR_x}, 544 {"SPSR_xfs", false, PSR_x | PSR_f | PSR_s}, 545 {"SPSR_xfc", false, PSR_x | PSR_f | PSR_c}, 546 {"SPSR_xsf", false, PSR_x | PSR_s | PSR_f}, 547 {"SPSR_xsc", false, PSR_x | PSR_s | PSR_c}, 548 {"SPSR_xcf", false, PSR_x | PSR_c | PSR_f}, 549 {"SPSR_xcs", false, PSR_x | PSR_c | PSR_s}, 550 {"SPSR_cfs", false, PSR_c | PSR_f | PSR_s}, 551 {"SPSR_cfx", false, PSR_c | PSR_f | PSR_x}, 552 {"SPSR_csf", false, PSR_c | PSR_s | PSR_f}, 553 {"SPSR_csx", false, PSR_c | PSR_s | PSR_x}, 554 {"SPSR_cxf", false, PSR_c | PSR_x | PSR_f}, 555 {"SPSR_cxs", false, PSR_c | PSR_x | PSR_s}, 556 {"SPSR_fsxc", false, PSR_f | PSR_s | PSR_x | PSR_c}, 557 {"SPSR_fscx", false, PSR_f | PSR_s | PSR_c | PSR_x}, 558 {"SPSR_fxsc", false, PSR_f | PSR_x | PSR_s | PSR_c}, 559 {"SPSR_fxcs", false, PSR_f | PSR_x | PSR_c | PSR_s}, 560 {"SPSR_fcsx", false, PSR_f | PSR_c | PSR_s | PSR_x}, 561 {"SPSR_fcxs", false, PSR_f | PSR_c | PSR_x | PSR_s}, 562 {"SPSR_sfxc", false, PSR_s | PSR_f | PSR_x | PSR_c}, 563 {"SPSR_sfcx", false, PSR_s | PSR_f | PSR_c | PSR_x}, 564 {"SPSR_sxfc", false, PSR_s | PSR_x | PSR_f | PSR_c}, 565 {"SPSR_sxcf", false, PSR_s | PSR_x | PSR_c | PSR_f}, 566 {"SPSR_scfx", false, PSR_s | PSR_c | PSR_f | PSR_x}, 567 {"SPSR_scxf", false, PSR_s | PSR_c | PSR_x | PSR_f}, 568 {"SPSR_xfsc", false, PSR_x | PSR_f | PSR_s | PSR_c}, 569 {"SPSR_xfcs", false, PSR_x | PSR_f | PSR_c | PSR_s}, 570 {"SPSR_xsfc", false, PSR_x | PSR_s | PSR_f | PSR_c}, 571 {"SPSR_xscf", false, PSR_x | PSR_s | PSR_c | PSR_f}, 572 {"SPSR_xcfs", false, PSR_x | PSR_c | PSR_f | PSR_s}, 573 {"SPSR_xcsf", false, PSR_x | PSR_c | PSR_s | PSR_f}, 574 {"SPSR_cfsx", false, PSR_c | PSR_f | PSR_s | PSR_x}, 575 {"SPSR_cfxs", false, PSR_c | PSR_f | PSR_x | PSR_s}, 576 {"SPSR_csfx", false, PSR_c | PSR_s | PSR_f | PSR_x}, 577 {"SPSR_csxf", false, PSR_c | PSR_s | PSR_x | PSR_f}, 578 {"SPSR_cxfs", false, PSR_c | PSR_x | PSR_f | PSR_s}, 579 {"SPSR_cxsf", false, PSR_c | PSR_x | PSR_s | PSR_f}, 580}; 581 582/* Functions called by parser. */ 583/* ARM instructions. */ 584static void do_arit PARAMS ((char *, unsigned long)); 585static void do_cmp PARAMS ((char *, unsigned long)); 586static void do_mov PARAMS ((char *, unsigned long)); 587static void do_ldst PARAMS ((char *, unsigned long)); 588static void do_ldmstm PARAMS ((char *, unsigned long)); 589static void do_branch PARAMS ((char *, unsigned long)); 590static void do_swi PARAMS ((char *, unsigned long)); 591/* Pseudo Op codes. */ 592static void do_adr PARAMS ((char *, unsigned long)); 593static void do_adrl PARAMS ((char *, unsigned long)); 594static void do_nop PARAMS ((char *, unsigned long)); 595/* ARM 2. */ 596static void do_mul PARAMS ((char *, unsigned long)); 597static void do_mla PARAMS ((char *, unsigned long)); 598/* ARM 3. */ 599static void do_swap PARAMS ((char *, unsigned long)); 600/* ARM 6. */ 601static void do_msr PARAMS ((char *, unsigned long)); 602static void do_mrs PARAMS ((char *, unsigned long)); 603/* ARM 7M. */ 604static void do_mull PARAMS ((char *, unsigned long)); 605/* ARM THUMB. */ 606static void do_bx PARAMS ((char *, unsigned long)); 607 608/* ARM_EXT_XScale. */ 609static void do_mia PARAMS ((char *, unsigned long)); 610static void do_mar PARAMS ((char *, unsigned long)); 611static void do_mra PARAMS ((char *, unsigned long)); 612static void do_pld PARAMS ((char *, unsigned long)); 613static void do_ldrd PARAMS ((char *, unsigned long)); 614 615/* ARM_EXT_V5. */ 616static void do_blx PARAMS ((char *, unsigned long)); 617static void do_bkpt PARAMS ((char *, unsigned long)); 618static void do_clz PARAMS ((char *, unsigned long)); 619static void do_lstc2 PARAMS ((char *, unsigned long)); 620static void do_cdp2 PARAMS ((char *, unsigned long)); 621static void do_co_reg2 PARAMS ((char *, unsigned long)); 622 623static void do_t_blx PARAMS ((char *)); 624static void do_t_bkpt PARAMS ((char *)); 625 626/* ARM_EXT_V5E. */ 627static void do_smla PARAMS ((char *, unsigned long)); 628static void do_smlal PARAMS ((char *, unsigned long)); 629static void do_smul PARAMS ((char *, unsigned long)); 630static void do_qadd PARAMS ((char *, unsigned long)); 631static void do_co_reg2c PARAMS ((char *, unsigned long)); 632 633/* Coprocessor Instructions. */ 634static void do_cdp PARAMS ((char *, unsigned long)); 635static void do_lstc PARAMS ((char *, unsigned long)); 636static void do_co_reg PARAMS ((char *, unsigned long)); 637static void do_fp_ctrl PARAMS ((char *, unsigned long)); 638static void do_fp_ldst PARAMS ((char *, unsigned long)); 639static void do_fp_ldmstm PARAMS ((char *, unsigned long)); 640static void do_fp_dyadic PARAMS ((char *, unsigned long)); 641static void do_fp_monadic PARAMS ((char *, unsigned long)); 642static void do_fp_cmp PARAMS ((char *, unsigned long)); 643static void do_fp_from_reg PARAMS ((char *, unsigned long)); 644static void do_fp_to_reg PARAMS ((char *, unsigned long)); 645 646static void fix_new_arm PARAMS ((fragS *, int, short, expressionS *, int, int)); 647static int arm_reg_parse PARAMS ((char **)); 648static CONST struct asm_psr * arm_psr_parse PARAMS ((char **)); 649static void symbol_locate PARAMS ((symbolS *, CONST char *, segT, valueT, fragS *)); 650static int add_to_lit_pool PARAMS ((void)); 651static unsigned validate_immediate PARAMS ((unsigned)); 652static unsigned validate_immediate_twopart PARAMS ((unsigned int, unsigned int *)); 653static int validate_offset_imm PARAMS ((unsigned int, int)); 654static void opcode_select PARAMS ((int)); 655static void end_of_line PARAMS ((char *)); 656static int reg_required_here PARAMS ((char **, int)); 657static int psr_required_here PARAMS ((char **)); 658static int co_proc_number PARAMS ((char **)); 659static int cp_opc_expr PARAMS ((char **, int, int)); 660static int cp_reg_required_here PARAMS ((char **, int)); 661static int fp_reg_required_here PARAMS ((char **, int)); 662static int cp_address_offset PARAMS ((char **)); 663static int cp_address_required_here PARAMS ((char **)); 664static int my_get_float_expression PARAMS ((char **)); 665static int skip_past_comma PARAMS ((char **)); 666static int walk_no_bignums PARAMS ((symbolS *)); 667static int negate_data_op PARAMS ((unsigned long *, unsigned long)); 668static int data_op2 PARAMS ((char **)); 669static int fp_op2 PARAMS ((char **)); 670static long reg_list PARAMS ((char **)); 671static void thumb_load_store PARAMS ((char *, int, int)); 672static int decode_shift PARAMS ((char **, int)); 673static int ldst_extend PARAMS ((char **, int)); 674static void thumb_add_sub PARAMS ((char *, int)); 675static void insert_reg PARAMS ((int)); 676static void thumb_shift PARAMS ((char *, int)); 677static void thumb_mov_compare PARAMS ((char *, int)); 678static void set_constant_flonums PARAMS ((void)); 679static valueT md_chars_to_number PARAMS ((char *, int)); 680static void insert_reg_alias PARAMS ((char *, int)); 681static void output_inst PARAMS ((void)); 682#ifdef OBJ_ELF 683static bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void)); 684#endif 685 686/* ARM instructions take 4bytes in the object file, Thumb instructions 687 take 2: */ 688#define INSN_SIZE 4 689 690/* LONGEST_INST is the longest basic instruction name without 691 conditions or flags. ARM7M has 4 of length 5. El Segundo 692 has one basic instruction name of length 7 (SMLALxy). */ 693#define LONGEST_INST 7 694 695struct asm_opcode 696{ 697 /* Basic string to match. */ 698 CONST char * template; 699 700 /* Basic instruction code. */ 701 unsigned long value; 702 703 /* Compulsory suffix that must follow conds. If "", then the 704 instruction is not conditional and must have no suffix. */ 705 CONST char * comp_suffix; 706 707 /* Bits to toggle if flag 'n' set. */ 708 CONST struct asm_flg * flags; 709 710 /* Which CPU variants this exists for. */ 711 unsigned long variants; 712 713 /* Function to call to parse args. */ 714 void (* parms) PARAMS ((char *, unsigned long)); 715}; 716 717static CONST struct asm_opcode insns[] = 718{ 719/* Intel XScale extensions to ARM V5 ISA. */ 720 {"mia", 0x0e200010, NULL, NULL, ARM_EXT_XSCALE, do_mia}, 721 {"miaph", 0x0e280010, NULL, NULL, ARM_EXT_XSCALE, do_mia}, 722 {"miabb", 0x0e2c0010, NULL, NULL, ARM_EXT_XSCALE, do_mia}, 723 {"miabt", 0x0e2d0010, NULL, NULL, ARM_EXT_XSCALE, do_mia}, 724 {"miatb", 0x0e2e0010, NULL, NULL, ARM_EXT_XSCALE, do_mia}, 725 {"miatt", 0x0e2f0010, NULL, NULL, ARM_EXT_XSCALE, do_mia}, 726 {"mar", 0x0c400000, NULL, NULL, ARM_EXT_XSCALE, do_mar}, 727 {"mra", 0x0c500000, NULL, NULL, ARM_EXT_XSCALE, do_mra}, 728 {"pld", 0xf450f000, "", NULL, ARM_EXT_XSCALE, do_pld}, 729 {"ldr", 0x000000d0, NULL, ldr_flags, ARM_ANY, do_ldrd}, 730 {"str", 0x000000f0, NULL, str_flags, ARM_ANY, do_ldrd}, 731 732/* ARM Instructions. */ 733 {"and", 0x00000000, NULL, s_flag, ARM_ANY, do_arit}, 734 {"eor", 0x00200000, NULL, s_flag, ARM_ANY, do_arit}, 735 {"sub", 0x00400000, NULL, s_flag, ARM_ANY, do_arit}, 736 {"rsb", 0x00600000, NULL, s_flag, ARM_ANY, do_arit}, 737 {"add", 0x00800000, NULL, s_flag, ARM_ANY, do_arit}, 738 {"adc", 0x00a00000, NULL, s_flag, ARM_ANY, do_arit}, 739 {"sbc", 0x00c00000, NULL, s_flag, ARM_ANY, do_arit}, 740 {"rsc", 0x00e00000, NULL, s_flag, ARM_ANY, do_arit}, 741 {"orr", 0x01800000, NULL, s_flag, ARM_ANY, do_arit}, 742 {"bic", 0x01c00000, NULL, s_flag, ARM_ANY, do_arit}, 743 {"tst", 0x01000000, NULL, cmp_flags, ARM_ANY, do_cmp}, 744 {"teq", 0x01200000, NULL, cmp_flags, ARM_ANY, do_cmp}, 745 {"cmp", 0x01400000, NULL, cmp_flags, ARM_ANY, do_cmp}, 746 {"cmn", 0x01600000, NULL, cmp_flags, ARM_ANY, do_cmp}, 747 {"mov", 0x01a00000, NULL, s_flag, ARM_ANY, do_mov}, 748 {"mvn", 0x01e00000, NULL, s_flag, ARM_ANY, do_mov}, 749 {"str", 0x04000000, NULL, str_flags, ARM_ANY, do_ldst}, 750 {"ldr", 0x04100000, NULL, ldr_flags, ARM_ANY, do_ldst}, 751 {"stm", 0x08000000, NULL, stm_flags, ARM_ANY, do_ldmstm}, 752 {"ldm", 0x08100000, NULL, ldm_flags, ARM_ANY, do_ldmstm}, 753 {"swi", 0x0f000000, NULL, NULL, ARM_ANY, do_swi}, 754#ifdef TE_WINCE 755 {"bl", 0x0b000000, NULL, NULL, ARM_ANY, do_branch}, 756 {"b", 0x0a000000, NULL, NULL, ARM_ANY, do_branch}, 757#else 758 {"bl", 0x0bfffffe, NULL, NULL, ARM_ANY, do_branch}, 759 {"b", 0x0afffffe, NULL, NULL, ARM_ANY, do_branch}, 760#endif 761 762/* Pseudo ops. */ 763 {"adr", 0x028f0000, NULL, NULL, ARM_ANY, do_adr}, 764 {"adrl", 0x028f0000, NULL, NULL, ARM_ANY, do_adrl}, 765 {"nop", 0x01a00000, NULL, NULL, ARM_ANY, do_nop}, 766 767/* ARM 2 multiplies. */ 768 {"mul", 0x00000090, NULL, s_flag, ARM_2UP, do_mul}, 769 {"mla", 0x00200090, NULL, s_flag, ARM_2UP, do_mla}, 770 771/* ARM 3 - swp instructions. */ 772 {"swp", 0x01000090, NULL, byte_flag, ARM_3UP, do_swap}, 773 774/* ARM 6 Coprocessor instructions. */ 775 {"mrs", 0x010f0000, NULL, NULL, ARM_6UP, do_mrs}, 776 {"msr", 0x0120f000, NULL, NULL, ARM_6UP, do_msr}, 777/* ScottB: our code uses 0x0128f000 for msr. 778 NickC: but this is wrong because the bits 16 through 19 are 779 handled by the PSR_xxx defines above. */ 780 781/* ARM 7M long multiplies - need signed/unsigned flags! */ 782 {"smull", 0x00c00090, NULL, s_flag, ARM_EXT_LONGMUL, do_mull}, 783 {"umull", 0x00800090, NULL, s_flag, ARM_EXT_LONGMUL, do_mull}, 784 {"smlal", 0x00e00090, NULL, s_flag, ARM_EXT_LONGMUL, do_mull}, 785 {"umlal", 0x00a00090, NULL, s_flag, ARM_EXT_LONGMUL, do_mull}, 786 787/* ARM THUMB interworking. */ 788 {"bx", 0x012fff10, NULL, NULL, ARM_EXT_THUMB, do_bx}, 789 790/* Floating point instructions. */ 791 {"wfs", 0x0e200110, NULL, NULL, FPU_ALL, do_fp_ctrl}, 792 {"rfs", 0x0e300110, NULL, NULL, FPU_ALL, do_fp_ctrl}, 793 {"wfc", 0x0e400110, NULL, NULL, FPU_ALL, do_fp_ctrl}, 794 {"rfc", 0x0e500110, NULL, NULL, FPU_ALL, do_fp_ctrl}, 795 {"ldf", 0x0c100100, "sdep", NULL, FPU_ALL, do_fp_ldst}, 796 {"stf", 0x0c000100, "sdep", NULL, FPU_ALL, do_fp_ldst}, 797 {"lfm", 0x0c100200, NULL, lfm_flags, FPU_MEMMULTI, do_fp_ldmstm}, 798 {"sfm", 0x0c000200, NULL, sfm_flags, FPU_MEMMULTI, do_fp_ldmstm}, 799 {"mvf", 0x0e008100, "sde", round_flags, FPU_ALL, do_fp_monadic}, 800 {"mnf", 0x0e108100, "sde", round_flags, FPU_ALL, do_fp_monadic}, 801 {"abs", 0x0e208100, "sde", round_flags, FPU_ALL, do_fp_monadic}, 802 {"rnd", 0x0e308100, "sde", round_flags, FPU_ALL, do_fp_monadic}, 803 {"sqt", 0x0e408100, "sde", round_flags, FPU_ALL, do_fp_monadic}, 804 {"log", 0x0e508100, "sde", round_flags, FPU_ALL, do_fp_monadic}, 805 {"lgn", 0x0e608100, "sde", round_flags, FPU_ALL, do_fp_monadic}, 806 {"exp", 0x0e708100, "sde", round_flags, FPU_ALL, do_fp_monadic}, 807 {"sin", 0x0e808100, "sde", round_flags, FPU_ALL, do_fp_monadic}, 808 {"cos", 0x0e908100, "sde", round_flags, FPU_ALL, do_fp_monadic}, 809 {"tan", 0x0ea08100, "sde", round_flags, FPU_ALL, do_fp_monadic}, 810 {"asn", 0x0eb08100, "sde", round_flags, FPU_ALL, do_fp_monadic}, 811 {"acs", 0x0ec08100, "sde", round_flags, FPU_ALL, do_fp_monadic}, 812 {"atn", 0x0ed08100, "sde", round_flags, FPU_ALL, do_fp_monadic}, 813 {"urd", 0x0ee08100, "sde", round_flags, FPU_ALL, do_fp_monadic}, 814 {"nrm", 0x0ef08100, "sde", round_flags, FPU_ALL, do_fp_monadic}, 815 {"adf", 0x0e000100, "sde", round_flags, FPU_ALL, do_fp_dyadic}, 816 {"suf", 0x0e200100, "sde", round_flags, FPU_ALL, do_fp_dyadic}, 817 {"rsf", 0x0e300100, "sde", round_flags, FPU_ALL, do_fp_dyadic}, 818 {"muf", 0x0e100100, "sde", round_flags, FPU_ALL, do_fp_dyadic}, 819 {"dvf", 0x0e400100, "sde", round_flags, FPU_ALL, do_fp_dyadic}, 820 {"rdf", 0x0e500100, "sde", round_flags, FPU_ALL, do_fp_dyadic}, 821 {"pow", 0x0e600100, "sde", round_flags, FPU_ALL, do_fp_dyadic}, 822 {"rpw", 0x0e700100, "sde", round_flags, FPU_ALL, do_fp_dyadic}, 823 {"rmf", 0x0e800100, "sde", round_flags, FPU_ALL, do_fp_dyadic}, 824 {"fml", 0x0e900100, "sde", round_flags, FPU_ALL, do_fp_dyadic}, 825 {"fdv", 0x0ea00100, "sde", round_flags, FPU_ALL, do_fp_dyadic}, 826 {"frd", 0x0eb00100, "sde", round_flags, FPU_ALL, do_fp_dyadic}, 827 {"pol", 0x0ec00100, "sde", round_flags, FPU_ALL, do_fp_dyadic}, 828 {"cmf", 0x0e90f110, NULL, except_flag, FPU_ALL, do_fp_cmp}, 829 {"cnf", 0x0eb0f110, NULL, except_flag, FPU_ALL, do_fp_cmp}, 830/* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not 831 be an optional suffix, but part of the instruction. To be compatible, 832 we accept either. */ 833 {"cmfe", 0x0ed0f110, NULL, NULL, FPU_ALL, do_fp_cmp}, 834 {"cnfe", 0x0ef0f110, NULL, NULL, FPU_ALL, do_fp_cmp}, 835 {"flt", 0x0e000110, "sde", round_flags, FPU_ALL, do_fp_from_reg}, 836 {"fix", 0x0e100110, NULL, fix_flags, FPU_ALL, do_fp_to_reg}, 837 838/* Generic copressor instructions. */ 839 {"cdp", 0x0e000000, NULL, NULL, ARM_2UP, do_cdp}, 840 {"ldc", 0x0c100000, NULL, cplong_flag, ARM_2UP, do_lstc}, 841 {"stc", 0x0c000000, NULL, cplong_flag, ARM_2UP, do_lstc}, 842 {"mcr", 0x0e000010, NULL, NULL, ARM_2UP, do_co_reg}, 843 {"mrc", 0x0e100010, NULL, NULL, ARM_2UP, do_co_reg}, 844 845/* ARM ISA extension 5. */ 846/* Note: blx is actually 2 opcodes, so the .value is set dynamically. 847 And it's sometimes conditional and sometimes not. */ 848 {"blx", 0, NULL, NULL, ARM_EXT_V5, do_blx}, 849 {"clz", 0x016f0f10, NULL, NULL, ARM_EXT_V5, do_clz}, 850 {"bkpt", 0xe1200070, "", NULL, ARM_EXT_V5, do_bkpt}, 851 {"ldc2", 0xfc100000, "", cplong_flag, ARM_EXT_V5, do_lstc2}, 852 {"stc2", 0xfc000000, "", cplong_flag, ARM_EXT_V5, do_lstc2}, 853 {"cdp2", 0xfe000000, "", NULL, ARM_EXT_V5, do_cdp2}, 854 {"mcr2", 0xfe000010, "", NULL, ARM_EXT_V5, do_co_reg2}, 855 {"mrc2", 0xfe100010, "", NULL, ARM_EXT_V5, do_co_reg2}, 856 857/* ARM ISA extension 5E, El Segundo. */ 858 {"smlabb", 0x01000080, NULL, NULL, ARM_EXT_V5E, do_smla}, 859 {"smlatb", 0x010000a0, NULL, NULL, ARM_EXT_V5E, do_smla}, 860 {"smlabt", 0x010000c0, NULL, NULL, ARM_EXT_V5E, do_smla}, 861 {"smlatt", 0x010000e0, NULL, NULL, ARM_EXT_V5E, do_smla}, 862 863 {"smlawb", 0x01200080, NULL, NULL, ARM_EXT_V5E, do_smla}, 864 {"smlawt", 0x012000c0, NULL, NULL, ARM_EXT_V5E, do_smla}, 865 866 {"smlalbb",0x01400080, NULL, NULL, ARM_EXT_V5E, do_smlal}, 867 {"smlaltb",0x014000a0, NULL, NULL, ARM_EXT_V5E, do_smlal}, 868 {"smlalbt",0x014000c0, NULL, NULL, ARM_EXT_V5E, do_smlal}, 869 {"smlaltt",0x014000e0, NULL, NULL, ARM_EXT_V5E, do_smlal}, 870 871 {"smulbb", 0x01600080, NULL, NULL, ARM_EXT_V5E, do_smul}, 872 {"smultb", 0x016000a0, NULL, NULL, ARM_EXT_V5E, do_smul}, 873 {"smulbt", 0x016000c0, NULL, NULL, ARM_EXT_V5E, do_smul}, 874 {"smultt", 0x016000e0, NULL, NULL, ARM_EXT_V5E, do_smul}, 875 876 {"smulwb", 0x012000a0, NULL, NULL, ARM_EXT_V5E, do_smul}, 877 {"smulwt", 0x012000e0, NULL, NULL, ARM_EXT_V5E, do_smul}, 878 879 {"qadd", 0x01000050, NULL, NULL, ARM_EXT_V5E, do_qadd}, 880 {"qdadd", 0x01400050, NULL, NULL, ARM_EXT_V5E, do_qadd}, 881 {"qsub", 0x01200050, NULL, NULL, ARM_EXT_V5E, do_qadd}, 882 {"qdsub", 0x01600050, NULL, NULL, ARM_EXT_V5E, do_qadd}, 883 884 {"mcrr", 0x0c400000, NULL, NULL, ARM_EXT_V5E, do_co_reg2c}, 885 {"mrrc", 0x0c500000, NULL, NULL, ARM_EXT_V5E, do_co_reg2c}, 886}; 887 888/* Defines for various bits that we will want to toggle. */ 889#define INST_IMMEDIATE 0x02000000 890#define OFFSET_REG 0x02000000 891#define HWOFFSET_IMM 0x00400000 892#define SHIFT_BY_REG 0x00000010 893#define PRE_INDEX 0x01000000 894#define INDEX_UP 0x00800000 895#define WRITE_BACK 0x00200000 896#define LDM_TYPE_2_OR_3 0x00400000 897 898#define LITERAL_MASK 0xf000f000 899#define COND_MASK 0xf0000000 900#define OPCODE_MASK 0xfe1fffff 901#define DATA_OP_SHIFT 21 902 903/* Codes to distinguish the arithmetic instructions. */ 904#define OPCODE_AND 0 905#define OPCODE_EOR 1 906#define OPCODE_SUB 2 907#define OPCODE_RSB 3 908#define OPCODE_ADD 4 909#define OPCODE_ADC 5 910#define OPCODE_SBC 6 911#define OPCODE_RSC 7 912#define OPCODE_TST 8 913#define OPCODE_TEQ 9 914#define OPCODE_CMP 10 915#define OPCODE_CMN 11 916#define OPCODE_ORR 12 917#define OPCODE_MOV 13 918#define OPCODE_BIC 14 919#define OPCODE_MVN 15 920 921static void do_t_nop PARAMS ((char *)); 922static void do_t_arit PARAMS ((char *)); 923static void do_t_add PARAMS ((char *)); 924static void do_t_asr PARAMS ((char *)); 925static void do_t_branch9 PARAMS ((char *)); 926static void do_t_branch12 PARAMS ((char *)); 927static void do_t_branch23 PARAMS ((char *)); 928static void do_t_bx PARAMS ((char *)); 929static void do_t_compare PARAMS ((char *)); 930static void do_t_ldmstm PARAMS ((char *)); 931static void do_t_ldr PARAMS ((char *)); 932static void do_t_ldrb PARAMS ((char *)); 933static void do_t_ldrh PARAMS ((char *)); 934static void do_t_lds PARAMS ((char *)); 935static void do_t_lsl PARAMS ((char *)); 936static void do_t_lsr PARAMS ((char *)); 937static void do_t_mov PARAMS ((char *)); 938static void do_t_push_pop PARAMS ((char *)); 939static void do_t_str PARAMS ((char *)); 940static void do_t_strb PARAMS ((char *)); 941static void do_t_strh PARAMS ((char *)); 942static void do_t_sub PARAMS ((char *)); 943static void do_t_swi PARAMS ((char *)); 944static void do_t_adr PARAMS ((char *)); 945 946#define T_OPCODE_MUL 0x4340 947#define T_OPCODE_TST 0x4200 948#define T_OPCODE_CMN 0x42c0 949#define T_OPCODE_NEG 0x4240 950#define T_OPCODE_MVN 0x43c0 951 952#define T_OPCODE_ADD_R3 0x1800 953#define T_OPCODE_SUB_R3 0x1a00 954#define T_OPCODE_ADD_HI 0x4400 955#define T_OPCODE_ADD_ST 0xb000 956#define T_OPCODE_SUB_ST 0xb080 957#define T_OPCODE_ADD_SP 0xa800 958#define T_OPCODE_ADD_PC 0xa000 959#define T_OPCODE_ADD_I8 0x3000 960#define T_OPCODE_SUB_I8 0x3800 961#define T_OPCODE_ADD_I3 0x1c00 962#define T_OPCODE_SUB_I3 0x1e00 963 964#define T_OPCODE_ASR_R 0x4100 965#define T_OPCODE_LSL_R 0x4080 966#define T_OPCODE_LSR_R 0x40c0 967#define T_OPCODE_ASR_I 0x1000 968#define T_OPCODE_LSL_I 0x0000 969#define T_OPCODE_LSR_I 0x0800 970 971#define T_OPCODE_MOV_I8 0x2000 972#define T_OPCODE_CMP_I8 0x2800 973#define T_OPCODE_CMP_LR 0x4280 974#define T_OPCODE_MOV_HR 0x4600 975#define T_OPCODE_CMP_HR 0x4500 976 977#define T_OPCODE_LDR_PC 0x4800 978#define T_OPCODE_LDR_SP 0x9800 979#define T_OPCODE_STR_SP 0x9000 980#define T_OPCODE_LDR_IW 0x6800 981#define T_OPCODE_STR_IW 0x6000 982#define T_OPCODE_LDR_IH 0x8800 983#define T_OPCODE_STR_IH 0x8000 984#define T_OPCODE_LDR_IB 0x7800 985#define T_OPCODE_STR_IB 0x7000 986#define T_OPCODE_LDR_RW 0x5800 987#define T_OPCODE_STR_RW 0x5000 988#define T_OPCODE_LDR_RH 0x5a00 989#define T_OPCODE_STR_RH 0x5200 990#define T_OPCODE_LDR_RB 0x5c00 991#define T_OPCODE_STR_RB 0x5400 992 993#define T_OPCODE_PUSH 0xb400 994#define T_OPCODE_POP 0xbc00 995 996#define T_OPCODE_BRANCH 0xe7fe 997 998static int thumb_reg PARAMS ((char ** str, int hi_lo)); 999 1000#define THUMB_SIZE 2 /* Size of thumb instruction. */ 1001#define THUMB_REG_LO 0x1 1002#define THUMB_REG_HI 0x2 1003#define THUMB_REG_ANY 0x3 1004 1005#define THUMB_H1 0x0080 1006#define THUMB_H2 0x0040 1007 1008#define THUMB_ASR 0 1009#define THUMB_LSL 1 1010#define THUMB_LSR 2 1011 1012#define THUMB_MOVE 0 1013#define THUMB_COMPARE 1 1014 1015#define THUMB_LOAD 0 1016#define THUMB_STORE 1 1017 1018#define THUMB_PP_PC_LR 0x0100 1019 1020/* These three are used for immediate shifts, do not alter. */ 1021#define THUMB_WORD 2 1022#define THUMB_HALFWORD 1 1023#define THUMB_BYTE 0 1024 1025struct thumb_opcode 1026{ 1027 /* Basic string to match. */ 1028 CONST char * template; 1029 1030 /* Basic instruction code. */ 1031 unsigned long value; 1032 1033 int size; 1034 1035 /* Which CPU variants this exists for. */ 1036 unsigned long variants; 1037 1038 /* Function to call to parse args. */ 1039 void (* parms) PARAMS ((char *)); 1040}; 1041 1042static CONST struct thumb_opcode tinsns[] = 1043{ 1044 {"adc", 0x4140, 2, ARM_EXT_THUMB, do_t_arit}, 1045 {"add", 0x0000, 2, ARM_EXT_THUMB, do_t_add}, 1046 {"and", 0x4000, 2, ARM_EXT_THUMB, do_t_arit}, 1047 {"asr", 0x0000, 2, ARM_EXT_THUMB, do_t_asr}, 1048 {"b", T_OPCODE_BRANCH, 2, ARM_EXT_THUMB, do_t_branch12}, 1049 {"beq", 0xd0fe, 2, ARM_EXT_THUMB, do_t_branch9}, 1050 {"bne", 0xd1fe, 2, ARM_EXT_THUMB, do_t_branch9}, 1051 {"bcs", 0xd2fe, 2, ARM_EXT_THUMB, do_t_branch9}, 1052 {"bhs", 0xd2fe, 2, ARM_EXT_THUMB, do_t_branch9}, 1053 {"bcc", 0xd3fe, 2, ARM_EXT_THUMB, do_t_branch9}, 1054 {"bul", 0xd3fe, 2, ARM_EXT_THUMB, do_t_branch9}, 1055 {"blo", 0xd3fe, 2, ARM_EXT_THUMB, do_t_branch9}, 1056 {"bmi", 0xd4fe, 2, ARM_EXT_THUMB, do_t_branch9}, 1057 {"bpl", 0xd5fe, 2, ARM_EXT_THUMB, do_t_branch9}, 1058 {"bvs", 0xd6fe, 2, ARM_EXT_THUMB, do_t_branch9}, 1059 {"bvc", 0xd7fe, 2, ARM_EXT_THUMB, do_t_branch9}, 1060 {"bhi", 0xd8fe, 2, ARM_EXT_THUMB, do_t_branch9}, 1061 {"bls", 0xd9fe, 2, ARM_EXT_THUMB, do_t_branch9}, 1062 {"bge", 0xdafe, 2, ARM_EXT_THUMB, do_t_branch9}, 1063 {"blt", 0xdbfe, 2, ARM_EXT_THUMB, do_t_branch9}, 1064 {"bgt", 0xdcfe, 2, ARM_EXT_THUMB, do_t_branch9}, 1065 {"ble", 0xddfe, 2, ARM_EXT_THUMB, do_t_branch9}, 1066 {"bal", 0xdefe, 2, ARM_EXT_THUMB, do_t_branch9}, 1067 {"bic", 0x4380, 2, ARM_EXT_THUMB, do_t_arit}, 1068 {"bl", 0xf7fffffe, 4, ARM_EXT_THUMB, do_t_branch23}, 1069 {"blx", 0, 0, ARM_EXT_V5, do_t_blx}, 1070 {"bkpt", 0xbe00, 2, ARM_EXT_V5, do_t_bkpt}, 1071 {"bx", 0x4700, 2, ARM_EXT_THUMB, do_t_bx}, 1072 {"cmn", T_OPCODE_CMN, 2, ARM_EXT_THUMB, do_t_arit}, 1073 {"cmp", 0x0000, 2, ARM_EXT_THUMB, do_t_compare}, 1074 {"eor", 0x4040, 2, ARM_EXT_THUMB, do_t_arit}, 1075 {"ldmia", 0xc800, 2, ARM_EXT_THUMB, do_t_ldmstm}, 1076 {"ldr", 0x0000, 2, ARM_EXT_THUMB, do_t_ldr}, 1077 {"ldrb", 0x0000, 2, ARM_EXT_THUMB, do_t_ldrb}, 1078 {"ldrh", 0x0000, 2, ARM_EXT_THUMB, do_t_ldrh}, 1079 {"ldrsb", 0x5600, 2, ARM_EXT_THUMB, do_t_lds}, 1080 {"ldrsh", 0x5e00, 2, ARM_EXT_THUMB, do_t_lds}, 1081 {"ldsb", 0x5600, 2, ARM_EXT_THUMB, do_t_lds}, 1082 {"ldsh", 0x5e00, 2, ARM_EXT_THUMB, do_t_lds}, 1083 {"lsl", 0x0000, 2, ARM_EXT_THUMB, do_t_lsl}, 1084 {"lsr", 0x0000, 2, ARM_EXT_THUMB, do_t_lsr}, 1085 {"mov", 0x0000, 2, ARM_EXT_THUMB, do_t_mov}, 1086 {"mul", T_OPCODE_MUL, 2, ARM_EXT_THUMB, do_t_arit}, 1087 {"mvn", T_OPCODE_MVN, 2, ARM_EXT_THUMB, do_t_arit}, 1088 {"neg", T_OPCODE_NEG, 2, ARM_EXT_THUMB, do_t_arit}, 1089 {"orr", 0x4300, 2, ARM_EXT_THUMB, do_t_arit}, 1090 {"pop", 0xbc00, 2, ARM_EXT_THUMB, do_t_push_pop}, 1091 {"push", 0xb400, 2, ARM_EXT_THUMB, do_t_push_pop}, 1092 {"ror", 0x41c0, 2, ARM_EXT_THUMB, do_t_arit}, 1093 {"sbc", 0x4180, 2, ARM_EXT_THUMB, do_t_arit}, 1094 {"stmia", 0xc000, 2, ARM_EXT_THUMB, do_t_ldmstm}, 1095 {"str", 0x0000, 2, ARM_EXT_THUMB, do_t_str}, 1096 {"strb", 0x0000, 2, ARM_EXT_THUMB, do_t_strb}, 1097 {"strh", 0x0000, 2, ARM_EXT_THUMB, do_t_strh}, 1098 {"swi", 0xdf00, 2, ARM_EXT_THUMB, do_t_swi}, 1099 {"sub", 0x0000, 2, ARM_EXT_THUMB, do_t_sub}, 1100 {"tst", T_OPCODE_TST, 2, ARM_EXT_THUMB, do_t_arit}, 1101 /* Pseudo ops: */ 1102 {"adr", 0x0000, 2, ARM_EXT_THUMB, do_t_adr}, 1103 {"nop", 0x46C0, 2, ARM_EXT_THUMB, do_t_nop}, /* mov r8,r8 */ 1104}; 1105 1106struct reg_entry 1107{ 1108 CONST char * name; 1109 int number; 1110}; 1111 1112#define int_register(reg) ((reg) >= 0 && (reg) <= 15) 1113#define cp_register(reg) ((reg) >= 32 && (reg) <= 47) 1114#define fp_register(reg) ((reg) >= 16 && (reg) <= 23) 1115 1116#define REG_PC 15 1117#define REG_LR 14 1118#define REG_SP 13 1119 1120/* These are the standard names. Users can add aliases with .req. */ 1121static CONST struct reg_entry reg_table[] = 1122{ 1123 /* Processor Register Numbers. */ 1124 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3}, 1125 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7}, 1126 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11}, 1127 {"r12", 12}, {"r13", REG_SP},{"r14", REG_LR},{"r15", REG_PC}, 1128 /* APCS conventions. */ 1129 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3}, 1130 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8}, 1131 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10}, 1132 {"fp", 11}, {"ip", 12}, {"sp", REG_SP},{"lr", REG_LR},{"pc", REG_PC}, 1133 /* ATPCS additions to APCS conventions. */ 1134 {"wr", 7}, {"v8", 11}, 1135 /* FP Registers. */ 1136 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19}, 1137 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23}, 1138 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35}, 1139 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39}, 1140 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43}, 1141 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47}, 1142 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35}, 1143 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39}, 1144 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43}, 1145 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47}, 1146 /* ATPCS additions to float register names. */ 1147 {"s0",16}, {"s1",17}, {"s2",18}, {"s3",19}, 1148 {"s4",20}, {"s5",21}, {"s6",22}, {"s7",23}, 1149 {"d0",16}, {"d1",17}, {"d2",18}, {"d3",19}, 1150 {"d4",20}, {"d5",21}, {"d6",22}, {"d7",23}, 1151 /* FIXME: At some point we need to add VFP register names. */ 1152 /* Array terminator. */ 1153 {NULL, 0} 1154}; 1155 1156#define BAD_ARGS _("Bad arguments to instruction") 1157#define BAD_PC _("r15 not allowed here") 1158#define BAD_FLAGS _("Instruction should not have flags") 1159#define BAD_COND _("Instruction is not conditional") 1160#define ERR_NO_ACCUM _("acc0 expected") 1161 1162static struct hash_control * arm_ops_hsh = NULL; 1163static struct hash_control * arm_tops_hsh = NULL; 1164static struct hash_control * arm_cond_hsh = NULL; 1165static struct hash_control * arm_shift_hsh = NULL; 1166static struct hash_control * arm_reg_hsh = NULL; 1167static struct hash_control * arm_psr_hsh = NULL; 1168 1169/* This table describes all the machine specific pseudo-ops the assembler 1170 has to support. The fields are: 1171 pseudo-op name without dot 1172 function to call to execute this pseudo-op 1173 Integer arg to pass to the function. */ 1174 1175static void s_req PARAMS ((int)); 1176static void s_align PARAMS ((int)); 1177static void s_bss PARAMS ((int)); 1178static void s_even PARAMS ((int)); 1179static void s_ltorg PARAMS ((int)); 1180static void s_arm PARAMS ((int)); 1181static void s_thumb PARAMS ((int)); 1182static void s_code PARAMS ((int)); 1183static void s_force_thumb PARAMS ((int)); 1184static void s_thumb_func PARAMS ((int)); 1185static void s_thumb_set PARAMS ((int)); 1186static void arm_s_text PARAMS ((int)); 1187static void arm_s_data PARAMS ((int)); 1188#ifdef OBJ_ELF 1189static void arm_s_section PARAMS ((int)); 1190static void s_arm_elf_cons PARAMS ((int)); 1191#endif 1192 1193static int my_get_expression PARAMS ((expressionS *, char **)); 1194 1195CONST pseudo_typeS md_pseudo_table[] = 1196{ 1197 /* Never called becasue '.req' does not start line. */ 1198 { "req", s_req, 0 }, 1199 { "bss", s_bss, 0 }, 1200 { "align", s_align, 0 }, 1201 { "arm", s_arm, 0 }, 1202 { "thumb", s_thumb, 0 }, 1203 { "code", s_code, 0 }, 1204 { "force_thumb", s_force_thumb, 0 }, 1205 { "thumb_func", s_thumb_func, 0 }, 1206 { "thumb_set", s_thumb_set, 0 }, 1207 { "even", s_even, 0 }, 1208 { "ltorg", s_ltorg, 0 }, 1209 { "pool", s_ltorg, 0 }, 1210 /* Allow for the effect of section changes. */ 1211 { "text", arm_s_text, 0 }, 1212 { "data", arm_s_data, 0 }, 1213#ifdef OBJ_ELF 1214 { "section", arm_s_section, 0 }, 1215 { "section.s", arm_s_section, 0 }, 1216 { "sect", arm_s_section, 0 }, 1217 { "sect.s", arm_s_section, 0 }, 1218 { "word", s_arm_elf_cons, 4 }, 1219 { "long", s_arm_elf_cons, 4 }, 1220 { "file", dwarf2_directive_file, 0 }, 1221 { "loc", dwarf2_directive_loc, 0 }, 1222#else 1223 { "word", cons, 4}, 1224#endif 1225 { "extend", float_cons, 'x' }, 1226 { "ldouble", float_cons, 'x' }, 1227 { "packed", float_cons, 'p' }, 1228 { 0, 0, 0 } 1229}; 1230 1231/* Stuff needed to resolve the label ambiguity 1232 As: 1233 ... 1234 label: <insn> 1235 may differ from: 1236 ... 1237 label: 1238 <insn> 1239*/ 1240 1241symbolS * last_label_seen; 1242static int label_is_thumb_function_name = false; 1243 1244/* Literal stuff. */ 1245 1246#define MAX_LITERAL_POOL_SIZE 1024 1247 1248typedef struct literalS 1249{ 1250 struct expressionS exp; 1251 struct arm_it * inst; 1252} literalT; 1253 1254literalT literals[MAX_LITERAL_POOL_SIZE]; 1255 1256/* Next free entry in the pool. */ 1257int next_literal_pool_place = 0; 1258 1259/* Next literal pool number. */ 1260int lit_pool_num = 1; 1261 1262symbolS * current_poolP = NULL; 1263 1264static int 1265add_to_lit_pool () 1266{ 1267 int lit_count = 0; 1268 1269 if (current_poolP == NULL) 1270 current_poolP = symbol_create (FAKE_LABEL_NAME, undefined_section, 1271 (valueT) 0, &zero_address_frag); 1272 1273 /* Check if this literal value is already in the pool: */ 1274 while (lit_count < next_literal_pool_place) 1275 { 1276 if (literals[lit_count].exp.X_op == inst.reloc.exp.X_op 1277 && inst.reloc.exp.X_op == O_constant 1278 && (literals[lit_count].exp.X_add_number 1279 == inst.reloc.exp.X_add_number) 1280 && literals[lit_count].exp.X_unsigned == inst.reloc.exp.X_unsigned) 1281 break; 1282 lit_count++; 1283 } 1284 1285 if (lit_count == next_literal_pool_place) /* New entry. */ 1286 { 1287 if (next_literal_pool_place > MAX_LITERAL_POOL_SIZE) 1288 { 1289 inst.error = _("Literal Pool Overflow"); 1290 return FAIL; 1291 } 1292 1293 literals[next_literal_pool_place].exp = inst.reloc.exp; 1294 lit_count = next_literal_pool_place++; 1295 } 1296 1297 inst.reloc.exp.X_op = O_symbol; 1298 inst.reloc.exp.X_add_number = (lit_count) * 4 - 8; 1299 inst.reloc.exp.X_add_symbol = current_poolP; 1300 1301 return SUCCESS; 1302} 1303 1304/* Can't use symbol_new here, so have to create a symbol and then at 1305 a later date assign it a value. Thats what these functions do. */ 1306 1307static void 1308symbol_locate (symbolP, name, segment, valu, frag) 1309 symbolS * symbolP; 1310 CONST char * name; /* It is copied, the caller can modify. */ 1311 segT segment; /* Segment identifier (SEG_<something>). */ 1312 valueT valu; /* Symbol value. */ 1313 fragS * frag; /* Associated fragment. */ 1314{ 1315 unsigned int name_length; 1316 char * preserved_copy_of_name; 1317 1318 name_length = strlen (name) + 1; /* +1 for \0. */ 1319 obstack_grow (¬es, name, name_length); 1320 preserved_copy_of_name = obstack_finish (¬es); 1321#ifdef STRIP_UNDERSCORE 1322 if (preserved_copy_of_name[0] == '_') 1323 preserved_copy_of_name++; 1324#endif 1325 1326#ifdef tc_canonicalize_symbol_name 1327 preserved_copy_of_name = 1328 tc_canonicalize_symbol_name (preserved_copy_of_name); 1329#endif 1330 1331 S_SET_NAME (symbolP, preserved_copy_of_name); 1332 1333 S_SET_SEGMENT (symbolP, segment); 1334 S_SET_VALUE (symbolP, valu); 1335 symbol_clear_list_pointers(symbolP); 1336 1337 symbol_set_frag (symbolP, frag); 1338 1339 /* Link to end of symbol chain. */ 1340 { 1341 extern int symbol_table_frozen; 1342 if (symbol_table_frozen) 1343 abort (); 1344 } 1345 1346 symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP); 1347 1348 obj_symbol_new_hook (symbolP); 1349 1350#ifdef tc_symbol_new_hook 1351 tc_symbol_new_hook (symbolP); 1352#endif 1353 1354#ifdef DEBUG_SYMS 1355 verify_symbol_chain (symbol_rootP, symbol_lastP); 1356#endif /* DEBUG_SYMS */ 1357} 1358 1359/* Check that an immediate is valid. 1360 If so, convert it to the right format. */ 1361 1362static unsigned int 1363validate_immediate (val) 1364 unsigned int val; 1365{ 1366 unsigned int a; 1367 unsigned int i; 1368 1369#define rotate_left(v, n) (v << n | v >> (32 - n)) 1370 1371 for (i = 0; i < 32; i += 2) 1372 if ((a = rotate_left (val, i)) <= 0xff) 1373 return a | (i << 7); /* 12-bit pack: [shift-cnt,const]. */ 1374 1375 return FAIL; 1376} 1377 1378/* Check to see if an immediate can be computed as two seperate immediate 1379 values, added together. We already know that this value cannot be 1380 computed by just one ARM instruction. */ 1381 1382static unsigned int 1383validate_immediate_twopart (val, highpart) 1384 unsigned int val; 1385 unsigned int * highpart; 1386{ 1387 unsigned int a; 1388 unsigned int i; 1389 1390 for (i = 0; i < 32; i += 2) 1391 if (((a = rotate_left (val, i)) & 0xff) != 0) 1392 { 1393 if (a & 0xff00) 1394 { 1395 if (a & ~ 0xffff) 1396 continue; 1397 * highpart = (a >> 8) | ((i + 24) << 7); 1398 } 1399 else if (a & 0xff0000) 1400 { 1401 if (a & 0xff000000) 1402 continue; 1403 * highpart = (a >> 16) | ((i + 16) << 7); 1404 } 1405 else 1406 { 1407 assert (a & 0xff000000); 1408 * highpart = (a >> 24) | ((i + 8) << 7); 1409 } 1410 1411 return (a & 0xff) | (i << 7); 1412 } 1413 1414 return FAIL; 1415} 1416 1417static int 1418validate_offset_imm (val, hwse) 1419 unsigned int val; 1420 int hwse; 1421{ 1422 if ((hwse && val > 255) || val > 4095) 1423 return FAIL; 1424 return val; 1425} 1426 1427static void 1428s_req (a) 1429 int a ATTRIBUTE_UNUSED; 1430{ 1431 as_bad (_("Invalid syntax for .req directive.")); 1432} 1433 1434static void 1435s_bss (ignore) 1436 int ignore ATTRIBUTE_UNUSED; 1437{ 1438 /* We don't support putting frags in the BSS segment, we fake it by 1439 marking in_bss, then looking at s_skip for clues. */ 1440 subseg_set (bss_section, 0); 1441 demand_empty_rest_of_line (); 1442} 1443 1444static void 1445s_even (ignore) 1446 int ignore ATTRIBUTE_UNUSED; 1447{ 1448 /* Never make frag if expect extra pass. */ 1449 if (!need_pass_2) 1450 frag_align (1, 0, 0); 1451 1452 record_alignment (now_seg, 1); 1453 1454 demand_empty_rest_of_line (); 1455} 1456 1457static void 1458s_ltorg (ignored) 1459 int ignored ATTRIBUTE_UNUSED; 1460{ 1461 int lit_count = 0; 1462 char sym_name[20]; 1463 1464 if (current_poolP == NULL) 1465 return; 1466 1467 /* Align pool as you have word accesses. 1468 Only make a frag if we have to. */ 1469 if (!need_pass_2) 1470 frag_align (2, 0, 0); 1471 1472 record_alignment (now_seg, 2); 1473 1474 sprintf (sym_name, "$$lit_\002%x", lit_pool_num++); 1475 1476 symbol_locate (current_poolP, sym_name, now_seg, 1477 (valueT) frag_now_fix (), frag_now); 1478 symbol_table_insert (current_poolP); 1479 1480 ARM_SET_THUMB (current_poolP, thumb_mode); 1481 1482#if defined OBJ_COFF || defined OBJ_ELF 1483 ARM_SET_INTERWORK (current_poolP, support_interwork); 1484#endif 1485 1486 while (lit_count < next_literal_pool_place) 1487 /* First output the expression in the instruction to the pool. */ 1488 emit_expr (&(literals[lit_count++].exp), 4); /* .word */ 1489 1490 next_literal_pool_place = 0; 1491 current_poolP = NULL; 1492} 1493 1494/* Same as s_align_ptwo but align 0 => align 2. */ 1495 1496static void 1497s_align (unused) 1498 int unused ATTRIBUTE_UNUSED; 1499{ 1500 register int temp; 1501 register long temp_fill; 1502 long max_alignment = 15; 1503 1504 temp = get_absolute_expression (); 1505 if (temp > max_alignment) 1506 as_bad (_("Alignment too large: %d. assumed."), temp = max_alignment); 1507 else if (temp < 0) 1508 { 1509 as_bad (_("Alignment negative. 0 assumed.")); 1510 temp = 0; 1511 } 1512 1513 if (*input_line_pointer == ',') 1514 { 1515 input_line_pointer++; 1516 temp_fill = get_absolute_expression (); 1517 } 1518 else 1519 temp_fill = 0; 1520 1521 if (!temp) 1522 temp = 2; 1523 1524 /* Only make a frag if we HAVE to. */ 1525 if (temp && !need_pass_2) 1526 frag_align (temp, (int) temp_fill, 0); 1527 demand_empty_rest_of_line (); 1528 1529 record_alignment (now_seg, temp); 1530} 1531 1532static void 1533s_force_thumb (ignore) 1534 int ignore ATTRIBUTE_UNUSED; 1535{ 1536 /* If we are not already in thumb mode go into it, EVEN if 1537 the target processor does not support thumb instructions. 1538 This is used by gcc/config/arm/lib1funcs.asm for example 1539 to compile interworking support functions even if the 1540 target processor should not support interworking. */ 1541 if (! thumb_mode) 1542 { 1543 thumb_mode = 2; 1544 1545 record_alignment (now_seg, 1); 1546 } 1547 1548 demand_empty_rest_of_line (); 1549} 1550 1551static void 1552s_thumb_func (ignore) 1553 int ignore ATTRIBUTE_UNUSED; 1554{ 1555 if (! thumb_mode) 1556 opcode_select (16); 1557 1558 /* The following label is the name/address of the start of a Thumb function. 1559 We need to know this for the interworking support. */ 1560 label_is_thumb_function_name = true; 1561 1562 demand_empty_rest_of_line (); 1563} 1564 1565/* Perform a .set directive, but also mark the alias as 1566 being a thumb function. */ 1567 1568static void 1569s_thumb_set (equiv) 1570 int equiv; 1571{ 1572 /* XXX the following is a duplicate of the code for s_set() in read.c 1573 We cannot just call that code as we need to get at the symbol that 1574 is created. */ 1575 register char * name; 1576 register char delim; 1577 register char * end_name; 1578 register symbolS * symbolP; 1579 1580 /* Especial apologies for the random logic: 1581 This just grew, and could be parsed much more simply! 1582 Dean - in haste. */ 1583 name = input_line_pointer; 1584 delim = get_symbol_end (); 1585 end_name = input_line_pointer; 1586 *end_name = delim; 1587 1588 SKIP_WHITESPACE (); 1589 1590 if (*input_line_pointer != ',') 1591 { 1592 *end_name = 0; 1593 as_bad (_("Expected comma after name \"%s\""), name); 1594 *end_name = delim; 1595 ignore_rest_of_line (); 1596 return; 1597 } 1598 1599 input_line_pointer++; 1600 *end_name = 0; 1601 1602 if (name[0] == '.' && name[1] == '\0') 1603 { 1604 /* XXX - this should not happen to .thumb_set. */ 1605 abort (); 1606 } 1607 1608 if ((symbolP = symbol_find (name)) == NULL 1609 && (symbolP = md_undefined_symbol (name)) == NULL) 1610 { 1611#ifndef NO_LISTING 1612 /* When doing symbol listings, play games with dummy fragments living 1613 outside the normal fragment chain to record the file and line info 1614 for this symbol. */ 1615 if (listing & LISTING_SYMBOLS) 1616 { 1617 extern struct list_info_struct * listing_tail; 1618 fragS * dummy_frag = (fragS *) xmalloc (sizeof (fragS)); 1619 1620 memset (dummy_frag, 0, sizeof (fragS)); 1621 dummy_frag->fr_type = rs_fill; 1622 dummy_frag->line = listing_tail; 1623 symbolP = symbol_new (name, undefined_section, 0, dummy_frag); 1624 dummy_frag->fr_symbol = symbolP; 1625 } 1626 else 1627#endif 1628 symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag); 1629 1630#ifdef OBJ_COFF 1631 /* "set" symbols are local unless otherwise specified. */ 1632 SF_SET_LOCAL (symbolP); 1633#endif /* OBJ_COFF */ 1634 } /* Make a new symbol. */ 1635 1636 symbol_table_insert (symbolP); 1637 1638 * end_name = delim; 1639 1640 if (equiv 1641 && S_IS_DEFINED (symbolP) 1642 && S_GET_SEGMENT (symbolP) != reg_section) 1643 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP)); 1644 1645 pseudo_set (symbolP); 1646 1647 demand_empty_rest_of_line (); 1648 1649 /* XXX Now we come to the Thumb specific bit of code. */ 1650 1651 THUMB_SET_FUNC (symbolP, 1); 1652 ARM_SET_THUMB (symbolP, 1); 1653#if defined OBJ_ELF || defined OBJ_COFF 1654 ARM_SET_INTERWORK (symbolP, support_interwork); 1655#endif 1656} 1657 1658/* If we change section we must dump the literal pool first. */ 1659 1660static void 1661arm_s_text (ignore) 1662 int ignore; 1663{ 1664 if (now_seg != text_section) 1665 s_ltorg (0); 1666 1667#ifdef OBJ_ELF 1668 obj_elf_text (ignore); 1669#else 1670 s_text (ignore); 1671#endif 1672} 1673 1674static void 1675arm_s_data (ignore) 1676 int ignore; 1677{ 1678 if (flag_readonly_data_in_text) 1679 { 1680 if (now_seg != text_section) 1681 s_ltorg (0); 1682 } 1683 else if (now_seg != data_section) 1684 s_ltorg (0); 1685 1686#ifdef OBJ_ELF 1687 obj_elf_data (ignore); 1688#else 1689 s_data (ignore); 1690#endif 1691} 1692 1693#ifdef OBJ_ELF 1694static void 1695arm_s_section (ignore) 1696 int ignore; 1697{ 1698 s_ltorg (0); 1699 1700 obj_elf_section (ignore); 1701} 1702#endif 1703 1704static void 1705opcode_select (width) 1706 int width; 1707{ 1708 switch (width) 1709 { 1710 case 16: 1711 if (! thumb_mode) 1712 { 1713 if (! (cpu_variant & ARM_EXT_THUMB)) 1714 as_bad (_("selected processor does not support THUMB opcodes")); 1715 1716 thumb_mode = 1; 1717 /* No need to force the alignment, since we will have been 1718 coming from ARM mode, which is word-aligned. */ 1719 record_alignment (now_seg, 1); 1720 } 1721 break; 1722 1723 case 32: 1724 if (thumb_mode) 1725 { 1726 if ((cpu_variant & ARM_ANY) == ARM_EXT_THUMB) 1727 as_bad (_("selected processor does not support ARM opcodes")); 1728 1729 thumb_mode = 0; 1730 1731 if (!need_pass_2) 1732 frag_align (2, 0, 0); 1733 1734 record_alignment (now_seg, 1); 1735 } 1736 break; 1737 1738 default: 1739 as_bad (_("invalid instruction size selected (%d)"), width); 1740 } 1741} 1742 1743static void 1744s_arm (ignore) 1745 int ignore ATTRIBUTE_UNUSED; 1746{ 1747 opcode_select (32); 1748 demand_empty_rest_of_line (); 1749} 1750 1751static void 1752s_thumb (ignore) 1753 int ignore ATTRIBUTE_UNUSED; 1754{ 1755 opcode_select (16); 1756 demand_empty_rest_of_line (); 1757} 1758 1759static void 1760s_code (unused) 1761 int unused ATTRIBUTE_UNUSED; 1762{ 1763 register int temp; 1764 1765 temp = get_absolute_expression (); 1766 switch (temp) 1767 { 1768 case 16: 1769 case 32: 1770 opcode_select (temp); 1771 break; 1772 1773 default: 1774 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp); 1775 } 1776} 1777 1778static void 1779end_of_line (str) 1780 char * str; 1781{ 1782 skip_whitespace (str); 1783 1784 if (* str != '\0') 1785 inst.error = _("Garbage following instruction"); 1786} 1787 1788static int 1789skip_past_comma (str) 1790 char ** str; 1791{ 1792 char * p = * str, c; 1793 int comma = 0; 1794 1795 while ((c = *p) == ' ' || c == ',') 1796 { 1797 p++; 1798 if (c == ',' && comma++) 1799 return FAIL; 1800 } 1801 1802 if (c == '\0') 1803 return FAIL; 1804 1805 *str = p; 1806 return comma ? SUCCESS : FAIL; 1807} 1808 1809/* A standard register must be given at this point. 1810 SHIFT is the place to put it in inst.instruction. 1811 Restores input start point on error. 1812 Returns the reg#, or FAIL. */ 1813 1814static int 1815reg_required_here (str, shift) 1816 char ** str; 1817 int shift; 1818{ 1819 static char buff [128]; /* XXX */ 1820 int reg; 1821 char * start = * str; 1822 1823 if ((reg = arm_reg_parse (str)) != FAIL && int_register (reg)) 1824 { 1825 if (shift >= 0) 1826 inst.instruction |= reg << shift; 1827 return reg; 1828 } 1829 1830 /* Restore the start point, we may have got a reg of the wrong class. */ 1831 *str = start; 1832 1833 /* In the few cases where we might be able to accept something else 1834 this error can be overridden. */ 1835 sprintf (buff, _("Register expected, not '%.100s'"), start); 1836 inst.error = buff; 1837 1838 return FAIL; 1839} 1840 1841static CONST struct asm_psr * 1842arm_psr_parse (ccp) 1843 register char ** ccp; 1844{ 1845 char * start = * ccp; 1846 char c; 1847 char * p; 1848 CONST struct asm_psr * psr; 1849 1850 p = start; 1851 1852 /* Skip to the end of the next word in the input stream. */ 1853 do 1854 { 1855 c = *p++; 1856 } 1857 while (isalpha (c) || c == '_'); 1858 1859 /* Terminate the word. */ 1860 *--p = 0; 1861 1862 /* CPSR's and SPSR's can now be lowercase. This is just a convenience 1863 feature for ease of use and backwards compatibility. */ 1864 if (!strncmp (start, "cpsr", 4)) 1865 strncpy (start, "CPSR", 4); 1866 else if (!strncmp (start, "spsr", 4)) 1867 strncpy (start, "SPSR", 4); 1868 1869 /* Now locate the word in the psr hash table. */ 1870 psr = (CONST struct asm_psr *) hash_find (arm_psr_hsh, start); 1871 1872 /* Restore the input stream. */ 1873 *p = c; 1874 1875 /* If we found a valid match, advance the 1876 stream pointer past the end of the word. */ 1877 *ccp = p; 1878 1879 return psr; 1880} 1881 1882/* Parse the input looking for a PSR flag. */ 1883 1884static int 1885psr_required_here (str) 1886 char ** str; 1887{ 1888 char * start = * str; 1889 CONST struct asm_psr * psr; 1890 1891 psr = arm_psr_parse (str); 1892 1893 if (psr) 1894 { 1895 /* If this is the SPSR that is being modified, set the R bit. */ 1896 if (! psr->cpsr) 1897 inst.instruction |= SPSR_BIT; 1898 1899 /* Set the psr flags in the MSR instruction. */ 1900 inst.instruction |= psr->field << PSR_SHIFT; 1901 1902 return SUCCESS; 1903 } 1904 1905 /* In the few cases where we might be able to accept 1906 something else this error can be overridden. */ 1907 inst.error = _("flag for {c}psr instruction expected"); 1908 1909 /* Restore the start point. */ 1910 *str = start; 1911 return FAIL; 1912} 1913 1914static int 1915co_proc_number (str) 1916 char ** str; 1917{ 1918 int processor, pchar; 1919 1920 skip_whitespace (* str); 1921 1922 /* The data sheet seems to imply that just a number on its own is valid 1923 here, but the RISC iX assembler seems to accept a prefix 'p'. We will 1924 accept either. */ 1925 if (**str == 'p' || **str == 'P') 1926 (*str)++; 1927 1928 pchar = *(*str)++; 1929 if (pchar >= '0' && pchar <= '9') 1930 { 1931 processor = pchar - '0'; 1932 if (**str >= '0' && **str <= '9') 1933 { 1934 processor = processor * 10 + *(*str)++ - '0'; 1935 if (processor > 15) 1936 { 1937 inst.error = _("Illegal co-processor number"); 1938 return FAIL; 1939 } 1940 } 1941 } 1942 else 1943 { 1944 inst.error = _("Bad or missing co-processor number"); 1945 return FAIL; 1946 } 1947 1948 inst.instruction |= processor << 8; 1949 return SUCCESS; 1950} 1951 1952static int 1953cp_opc_expr (str, where, length) 1954 char ** str; 1955 int where; 1956 int length; 1957{ 1958 expressionS expr; 1959 1960 skip_whitespace (* str); 1961 1962 memset (&expr, '\0', sizeof (expr)); 1963 1964 if (my_get_expression (&expr, str)) 1965 return FAIL; 1966 if (expr.X_op != O_constant) 1967 { 1968 inst.error = _("bad or missing expression"); 1969 return FAIL; 1970 } 1971 1972 if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number) 1973 { 1974 inst.error = _("immediate co-processor expression too large"); 1975 return FAIL; 1976 } 1977 1978 inst.instruction |= expr.X_add_number << where; 1979 return SUCCESS; 1980} 1981 1982static int 1983cp_reg_required_here (str, where) 1984 char ** str; 1985 int where; 1986{ 1987 int reg; 1988 char * start = *str; 1989 1990 if ((reg = arm_reg_parse (str)) != FAIL && cp_register (reg)) 1991 { 1992 reg &= 15; 1993 inst.instruction |= reg << where; 1994 return reg; 1995 } 1996 1997 /* In the few cases where we might be able to accept something else 1998 this error can be overridden. */ 1999 inst.error = _("Co-processor register expected"); 2000 2001 /* Restore the start point. */ 2002 *str = start; 2003 return FAIL; 2004} 2005 2006static int 2007fp_reg_required_here (str, where) 2008 char ** str; 2009 int where; 2010{ 2011 int reg; 2012 char * start = * str; 2013 2014 if ((reg = arm_reg_parse (str)) != FAIL && fp_register (reg)) 2015 { 2016 reg &= 7; 2017 inst.instruction |= reg << where; 2018 return reg; 2019 } 2020 2021 /* In the few cases where we might be able to accept something else 2022 this error can be overridden. */ 2023 inst.error = _("Floating point register expected"); 2024 2025 /* Restore the start point. */ 2026 *str = start; 2027 return FAIL; 2028} 2029 2030static int 2031cp_address_offset (str) 2032 char ** str; 2033{ 2034 int offset; 2035 2036 skip_whitespace (* str); 2037 2038 if (! is_immediate_prefix (**str)) 2039 { 2040 inst.error = _("immediate expression expected"); 2041 return FAIL; 2042 } 2043 2044 (*str)++; 2045 2046 if (my_get_expression (& inst.reloc.exp, str)) 2047 return FAIL; 2048 2049 if (inst.reloc.exp.X_op == O_constant) 2050 { 2051 offset = inst.reloc.exp.X_add_number; 2052 2053 if (offset & 3) 2054 { 2055 inst.error = _("co-processor address must be word aligned"); 2056 return FAIL; 2057 } 2058 2059 if (offset > 1023 || offset < -1023) 2060 { 2061 inst.error = _("offset too large"); 2062 return FAIL; 2063 } 2064 2065 if (offset >= 0) 2066 inst.instruction |= INDEX_UP; 2067 else 2068 offset = -offset; 2069 2070 inst.instruction |= offset >> 2; 2071 } 2072 else 2073 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM; 2074 2075 return SUCCESS; 2076} 2077 2078static int 2079cp_address_required_here (str) 2080 char ** str; 2081{ 2082 char * p = * str; 2083 int pre_inc = 0; 2084 int write_back = 0; 2085 2086 if (*p == '[') 2087 { 2088 int reg; 2089 2090 p++; 2091 skip_whitespace (p); 2092 2093 if ((reg = reg_required_here (& p, 16)) == FAIL) 2094 return FAIL; 2095 2096 skip_whitespace (p); 2097 2098 if (*p == ']') 2099 { 2100 p++; 2101 2102 if (skip_past_comma (& p) == SUCCESS) 2103 { 2104 /* [Rn], #expr */ 2105 write_back = WRITE_BACK; 2106 2107 if (reg == REG_PC) 2108 { 2109 inst.error = _("pc may not be used in post-increment"); 2110 return FAIL; 2111 } 2112 2113 if (cp_address_offset (& p) == FAIL) 2114 return FAIL; 2115 } 2116 else 2117 pre_inc = PRE_INDEX | INDEX_UP; 2118 } 2119 else 2120 { 2121 /* '['Rn, #expr']'[!] */ 2122 2123 if (skip_past_comma (& p) == FAIL) 2124 { 2125 inst.error = _("pre-indexed expression expected"); 2126 return FAIL; 2127 } 2128 2129 pre_inc = PRE_INDEX; 2130 2131 if (cp_address_offset (& p) == FAIL) 2132 return FAIL; 2133 2134 skip_whitespace (p); 2135 2136 if (*p++ != ']') 2137 { 2138 inst.error = _("missing ]"); 2139 return FAIL; 2140 } 2141 2142 skip_whitespace (p); 2143 2144 if (*p == '!') 2145 { 2146 if (reg == REG_PC) 2147 { 2148 inst.error = _("pc may not be used with write-back"); 2149 return FAIL; 2150 } 2151 2152 p++; 2153 write_back = WRITE_BACK; 2154 } 2155 } 2156 } 2157 else 2158 { 2159 if (my_get_expression (&inst.reloc.exp, &p)) 2160 return FAIL; 2161 2162 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM; 2163 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */ 2164 inst.reloc.pc_rel = 1; 2165 inst.instruction |= (REG_PC << 16); 2166 pre_inc = PRE_INDEX; 2167 } 2168 2169 inst.instruction |= write_back | pre_inc; 2170 *str = p; 2171 return SUCCESS; 2172} 2173 2174static void 2175do_nop (str, flags) 2176 char * str; 2177 unsigned long flags; 2178{ 2179 /* Do nothing really. */ 2180 inst.instruction |= flags; /* This is pointless. */ 2181 end_of_line (str); 2182 return; 2183} 2184 2185static void 2186do_mrs (str, flags) 2187 char *str; 2188 unsigned long flags; 2189{ 2190 int skip = 0; 2191 2192 /* Only one syntax. */ 2193 skip_whitespace (str); 2194 2195 if (reg_required_here (&str, 12) == FAIL) 2196 { 2197 inst.error = BAD_ARGS; 2198 return; 2199 } 2200 2201 if (skip_past_comma (&str) == FAIL) 2202 { 2203 inst.error = _("comma expected after register name"); 2204 return; 2205 } 2206 2207 skip_whitespace (str); 2208 2209 if ( strcmp (str, "CPSR") == 0 2210 || strcmp (str, "SPSR") == 0 2211 /* Lower case versions for backwards compatability. */ 2212 || strcmp (str, "cpsr") == 0 2213 || strcmp (str, "spsr") == 0) 2214 skip = 4; 2215 2216 /* This is for backwards compatability with older toolchains. */ 2217 else if ( strcmp (str, "cpsr_all") == 0 2218 || strcmp (str, "spsr_all") == 0) 2219 skip = 8; 2220 else 2221 { 2222 inst.error = _("{C|S}PSR expected"); 2223 return; 2224 } 2225 2226 if (* str == 's' || * str == 'S') 2227 inst.instruction |= SPSR_BIT; 2228 str += skip; 2229 2230 inst.instruction |= flags; 2231 end_of_line (str); 2232} 2233 2234/* Two possible forms: 2235 "{C|S}PSR_<field>, Rm", 2236 "{C|S}PSR_f, #expression". */ 2237 2238static void 2239do_msr (str, flags) 2240 char * str; 2241 unsigned long flags; 2242{ 2243 skip_whitespace (str); 2244 2245 if (psr_required_here (& str) == FAIL) 2246 return; 2247 2248 if (skip_past_comma (& str) == FAIL) 2249 { 2250 inst.error = _("comma missing after psr flags"); 2251 return; 2252 } 2253 2254 skip_whitespace (str); 2255 2256 if (reg_required_here (& str, 0) != FAIL) 2257 { 2258 inst.error = NULL; 2259 inst.instruction |= flags; 2260 end_of_line (str); 2261 return; 2262 } 2263 2264 if (! is_immediate_prefix (* str)) 2265 { 2266 inst.error = 2267 _("only a register or immediate value can follow a psr flag"); 2268 return; 2269 } 2270 2271 str ++; 2272 inst.error = NULL; 2273 2274 if (my_get_expression (& inst.reloc.exp, & str)) 2275 { 2276 inst.error = 2277 _("only a register or immediate value can follow a psr flag"); 2278 return; 2279 } 2280 2281 if ((cpu_variant & ARM_EXT_V5) != ARM_EXT_V5 2282 && inst.instruction & ((PSR_c | PSR_x | PSR_s) << PSR_SHIFT)) 2283 { 2284 inst.error = _("immediate value cannot be used to set this field"); 2285 return; 2286 } 2287 2288 flags |= INST_IMMEDIATE; 2289 2290 if (inst.reloc.exp.X_add_symbol) 2291 { 2292 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE; 2293 inst.reloc.pc_rel = 0; 2294 } 2295 else 2296 { 2297 unsigned value = validate_immediate (inst.reloc.exp.X_add_number); 2298 2299 if (value == (unsigned) FAIL) 2300 { 2301 inst.error = _("Invalid constant"); 2302 return; 2303 } 2304 2305 inst.instruction |= value; 2306 } 2307 2308 inst.error = NULL; 2309 inst.instruction |= flags; 2310 end_of_line (str); 2311} 2312 2313/* Long Multiply Parser 2314 UMULL RdLo, RdHi, Rm, Rs 2315 SMULL RdLo, RdHi, Rm, Rs 2316 UMLAL RdLo, RdHi, Rm, Rs 2317 SMLAL RdLo, RdHi, Rm, Rs. */ 2318 2319static void 2320do_mull (str, flags) 2321 char * str; 2322 unsigned long flags; 2323{ 2324 int rdlo, rdhi, rm, rs; 2325 2326 /* Only one format "rdlo, rdhi, rm, rs". */ 2327 skip_whitespace (str); 2328 2329 if ((rdlo = reg_required_here (&str, 12)) == FAIL) 2330 { 2331 inst.error = BAD_ARGS; 2332 return; 2333 } 2334 2335 if (skip_past_comma (&str) == FAIL 2336 || (rdhi = reg_required_here (&str, 16)) == FAIL) 2337 { 2338 inst.error = BAD_ARGS; 2339 return; 2340 } 2341 2342 if (skip_past_comma (&str) == FAIL 2343 || (rm = reg_required_here (&str, 0)) == FAIL) 2344 { 2345 inst.error = BAD_ARGS; 2346 return; 2347 } 2348 2349 /* rdhi, rdlo and rm must all be different. */ 2350 if (rdlo == rdhi || rdlo == rm || rdhi == rm) 2351 as_tsktsk (_("rdhi, rdlo and rm must all be different")); 2352 2353 if (skip_past_comma (&str) == FAIL 2354 || (rs = reg_required_here (&str, 8)) == FAIL) 2355 { 2356 inst.error = BAD_ARGS; 2357 return; 2358 } 2359 2360 if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC) 2361 { 2362 inst.error = BAD_PC; 2363 return; 2364 } 2365 2366 inst.instruction |= flags; 2367 end_of_line (str); 2368 return; 2369} 2370 2371static void 2372do_mul (str, flags) 2373 char * str; 2374 unsigned long flags; 2375{ 2376 int rd, rm; 2377 2378 /* Only one format "rd, rm, rs". */ 2379 skip_whitespace (str); 2380 2381 if ((rd = reg_required_here (&str, 16)) == FAIL) 2382 { 2383 inst.error = BAD_ARGS; 2384 return; 2385 } 2386 2387 if (rd == REG_PC) 2388 { 2389 inst.error = BAD_PC; 2390 return; 2391 } 2392 2393 if (skip_past_comma (&str) == FAIL 2394 || (rm = reg_required_here (&str, 0)) == FAIL) 2395 { 2396 inst.error = BAD_ARGS; 2397 return; 2398 } 2399 2400 if (rm == REG_PC) 2401 { 2402 inst.error = BAD_PC; 2403 return; 2404 } 2405 2406 if (rm == rd) 2407 as_tsktsk (_("rd and rm should be different in mul")); 2408 2409 if (skip_past_comma (&str) == FAIL 2410 || (rm = reg_required_here (&str, 8)) == FAIL) 2411 { 2412 inst.error = BAD_ARGS; 2413 return; 2414 } 2415 2416 if (rm == REG_PC) 2417 { 2418 inst.error = BAD_PC; 2419 return; 2420 } 2421 2422 inst.instruction |= flags; 2423 end_of_line (str); 2424 return; 2425} 2426 2427static void 2428do_mla (str, flags) 2429 char * str; 2430 unsigned long flags; 2431{ 2432 int rd, rm; 2433 2434 /* Only one format "rd, rm, rs, rn". */ 2435 skip_whitespace (str); 2436 2437 if ((rd = reg_required_here (&str, 16)) == FAIL) 2438 { 2439 inst.error = BAD_ARGS; 2440 return; 2441 } 2442 2443 if (rd == REG_PC) 2444 { 2445 inst.error = BAD_PC; 2446 return; 2447 } 2448 2449 if (skip_past_comma (&str) == FAIL 2450 || (rm = reg_required_here (&str, 0)) == FAIL) 2451 { 2452 inst.error = BAD_ARGS; 2453 return; 2454 } 2455 2456 if (rm == REG_PC) 2457 { 2458 inst.error = BAD_PC; 2459 return; 2460 } 2461 2462 if (rm == rd) 2463 as_tsktsk (_("rd and rm should be different in mla")); 2464 2465 if (skip_past_comma (&str) == FAIL 2466 || (rd = reg_required_here (&str, 8)) == FAIL 2467 || skip_past_comma (&str) == FAIL 2468 || (rm = reg_required_here (&str, 12)) == FAIL) 2469 { 2470 inst.error = BAD_ARGS; 2471 return; 2472 } 2473 2474 if (rd == REG_PC || rm == REG_PC) 2475 { 2476 inst.error = BAD_PC; 2477 return; 2478 } 2479 2480 inst.instruction |= flags; 2481 end_of_line (str); 2482 return; 2483} 2484 2485/* Expects *str -> the characters "acc0", possibly with leading blanks. 2486 Advances *str to the next non-alphanumeric. 2487 Returns 0, or else FAIL (in which case sets inst.error). 2488 2489 (In a future XScale, there may be accumulators other than zero. 2490 At that time this routine and its callers can be upgraded to suit.) */ 2491 2492static int 2493accum0_required_here (str) 2494 char ** str; 2495{ 2496 static char buff [128]; /* Note the address is taken. Hence, static. */ 2497 char * p = * str; 2498 char c; 2499 int result = 0; /* The accum number. */ 2500 2501 skip_whitespace (p); 2502 2503 *str = p; /* Advance caller's string pointer too. */ 2504 c = *p++; 2505 while (isalnum (c)) 2506 c = *p++; 2507 2508 *--p = 0; /* Aap nul into input buffer at non-alnum. */ 2509 2510 if (! ( streq (*str, "acc0") || streq (*str, "ACC0"))) 2511 { 2512 sprintf (buff, _("acc0 expected, not '%.100s'"), *str); 2513 inst.error = buff; 2514 result = FAIL; 2515 } 2516 2517 *p = c; /* Unzap. */ 2518 *str = p; /* Caller's string pointer to after match. */ 2519 return result; 2520} 2521 2522/* Expects **str -> after a comma. May be leading blanks. 2523 Advances *str, recognizing a load mode, and setting inst.instruction. 2524 Returns rn, or else FAIL (in which case may set inst.error 2525 and not advance str) 2526 2527 Note: doesn't know Rd, so no err checks that require such knowledge. */ 2528 2529static int 2530ld_mode_required_here (string) 2531 char ** string; 2532{ 2533 char * str = * string; 2534 int rn; 2535 int pre_inc = 0; 2536 2537 skip_whitespace (str); 2538 2539 if (* str == '[') 2540 { 2541 str++; 2542 2543 skip_whitespace (str); 2544 2545 if ((rn = reg_required_here (& str, 16)) == FAIL) 2546 return FAIL; 2547 2548 skip_whitespace (str); 2549 2550 if (* str == ']') 2551 { 2552 str ++; 2553 2554 if (skip_past_comma (& str) == SUCCESS) 2555 { 2556 /* [Rn],... (post inc) */ 2557 if (ldst_extend (& str, 1) == FAIL) 2558 return FAIL; 2559 } 2560 else /* [Rn] */ 2561 { 2562 skip_whitespace (str); 2563 2564 if (* str == '!') 2565 { 2566 str ++; 2567 inst.instruction |= WRITE_BACK; 2568 } 2569 2570 inst.instruction |= INDEX_UP | HWOFFSET_IMM; 2571 pre_inc = 1; 2572 } 2573 } 2574 else /* [Rn,...] */ 2575 { 2576 if (skip_past_comma (& str) == FAIL) 2577 { 2578 inst.error = _("pre-indexed expression expected"); 2579 return FAIL; 2580 } 2581 2582 pre_inc = 1; 2583 2584 if (ldst_extend (& str, 1) == FAIL) 2585 return FAIL; 2586 2587 skip_whitespace (str); 2588 2589 if (* str ++ != ']') 2590 { 2591 inst.error = _("missing ]"); 2592 return FAIL; 2593 } 2594 2595 skip_whitespace (str); 2596 2597 if (* str == '!') 2598 { 2599 str ++; 2600 inst.instruction |= WRITE_BACK; 2601 } 2602 } 2603 } 2604 else if (* str == '=') /* ldr's "r,=label" syntax */ 2605 /* We should never reach here, because <text> = <expression> is 2606 caught gas/read.c read_a_source_file() as a .set operation. */ 2607 return FAIL; 2608 else /* PC +- 8 bit immediate offset. */ 2609 { 2610 if (my_get_expression (& inst.reloc.exp, & str)) 2611 return FAIL; 2612 2613 inst.instruction |= HWOFFSET_IMM; /* The I bit. */ 2614 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8; 2615 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */ 2616 inst.reloc.pc_rel = 1; 2617 inst.instruction |= (REG_PC << 16); 2618 2619 rn = REG_PC; 2620 pre_inc = 1; 2621 } 2622 2623 inst.instruction |= (pre_inc ? PRE_INDEX : 0); 2624 * string = str; 2625 2626 return rn; 2627} 2628 2629/* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse) 2630 SMLAxy{cond} Rd,Rm,Rs,Rn 2631 SMLAWy{cond} Rd,Rm,Rs,Rn 2632 Error if any register is R15. */ 2633 2634static void 2635do_smla (str, flags) 2636 char * str; 2637 unsigned long flags; 2638{ 2639 int rd, rm, rs, rn; 2640 2641 skip_whitespace (str); 2642 2643 if ((rd = reg_required_here (& str, 16)) == FAIL 2644 || skip_past_comma (& str) == FAIL 2645 || (rm = reg_required_here (& str, 0)) == FAIL 2646 || skip_past_comma (& str) == FAIL 2647 || (rs = reg_required_here (& str, 8)) == FAIL 2648 || skip_past_comma (& str) == FAIL 2649 || (rn = reg_required_here (& str, 12)) == FAIL) 2650 inst.error = BAD_ARGS; 2651 2652 else if (rd == REG_PC || rm == REG_PC || rs == REG_PC || rn == REG_PC) 2653 inst.error = BAD_PC; 2654 2655 else if (flags) 2656 inst.error = BAD_FLAGS; 2657 2658 else 2659 end_of_line (str); 2660} 2661 2662/* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse) 2663 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs 2664 Error if any register is R15. 2665 Warning if Rdlo == Rdhi. */ 2666 2667static void 2668do_smlal (str, flags) 2669 char * str; 2670 unsigned long flags; 2671{ 2672 int rdlo, rdhi, rm, rs; 2673 2674 skip_whitespace (str); 2675 2676 if ((rdlo = reg_required_here (& str, 12)) == FAIL 2677 || skip_past_comma (& str) == FAIL 2678 || (rdhi = reg_required_here (& str, 16)) == FAIL 2679 || skip_past_comma (& str) == FAIL 2680 || (rm = reg_required_here (& str, 0)) == FAIL 2681 || skip_past_comma (& str) == FAIL 2682 || (rs = reg_required_here (& str, 8)) == FAIL) 2683 { 2684 inst.error = BAD_ARGS; 2685 return; 2686 } 2687 2688 if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC) 2689 { 2690 inst.error = BAD_PC; 2691 return; 2692 } 2693 2694 if (rdlo == rdhi) 2695 as_tsktsk (_("rdhi and rdlo must be different")); 2696 2697 if (flags) 2698 inst.error = BAD_FLAGS; 2699 else 2700 end_of_line (str); 2701} 2702 2703/* ARM V5E (El Segundo) signed-multiply (argument parse) 2704 SMULxy{cond} Rd,Rm,Rs 2705 Error if any register is R15. */ 2706 2707static void 2708do_smul (str, flags) 2709 char * str; 2710 unsigned long flags; 2711{ 2712 int rd, rm, rs; 2713 2714 skip_whitespace (str); 2715 2716 if ((rd = reg_required_here (& str, 16)) == FAIL 2717 || skip_past_comma (& str) == FAIL 2718 || (rm = reg_required_here (& str, 0)) == FAIL 2719 || skip_past_comma (& str) == FAIL 2720 || (rs = reg_required_here (& str, 8)) == FAIL) 2721 inst.error = BAD_ARGS; 2722 2723 else if (rd == REG_PC || rm == REG_PC || rs == REG_PC) 2724 inst.error = BAD_PC; 2725 2726 else if (flags) 2727 inst.error = BAD_FLAGS; 2728 2729 else 2730 end_of_line (str); 2731} 2732 2733/* ARM V5E (El Segundo) saturating-add/subtract (argument parse) 2734 Q[D]{ADD,SUB}{cond} Rd,Rm,Rn 2735 Error if any register is R15. */ 2736 2737static void 2738do_qadd (str, flags) 2739 char * str; 2740 unsigned long flags; 2741{ 2742 int rd, rm, rn; 2743 2744 skip_whitespace (str); 2745 2746 if ((rd = reg_required_here (& str, 12)) == FAIL 2747 || skip_past_comma (& str) == FAIL 2748 || (rm = reg_required_here (& str, 0)) == FAIL 2749 || skip_past_comma (& str) == FAIL 2750 || (rn = reg_required_here (& str, 16)) == FAIL) 2751 inst.error = BAD_ARGS; 2752 2753 else if (rd == REG_PC || rm == REG_PC || rn == REG_PC) 2754 inst.error = BAD_PC; 2755 2756 else if (flags) 2757 inst.error = BAD_FLAGS; 2758 2759 else 2760 end_of_line (str); 2761} 2762 2763/* ARM V5E (el Segundo) 2764 MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>. 2765 MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>. 2766 2767 These are equivalent to the XScale instructions MAR and MRA, 2768 respectively, when coproc == 0, opcode == 0, and CRm == 0. 2769 2770 Result unpredicatable if Rd or Rn is R15. */ 2771 2772static void 2773do_co_reg2c (str, flags) 2774 char * str; 2775 unsigned long flags; 2776{ 2777 int rd, rn; 2778 2779 skip_whitespace (str); 2780 2781 if (co_proc_number (& str) == FAIL) 2782 { 2783 if (!inst.error) 2784 inst.error = BAD_ARGS; 2785 return; 2786 } 2787 2788 if (skip_past_comma (& str) == FAIL 2789 || cp_opc_expr (& str, 4, 4) == FAIL) 2790 { 2791 if (!inst.error) 2792 inst.error = BAD_ARGS; 2793 return; 2794 } 2795 2796 if (skip_past_comma (& str) == FAIL 2797 || (rd = reg_required_here (& str, 12)) == FAIL) 2798 { 2799 if (!inst.error) 2800 inst.error = BAD_ARGS; 2801 return; 2802 } 2803 2804 if (skip_past_comma (& str) == FAIL 2805 || (rn = reg_required_here (& str, 16)) == FAIL) 2806 { 2807 if (!inst.error) 2808 inst.error = BAD_ARGS; 2809 return; 2810 } 2811 2812 /* Unpredictable result if rd or rn is R15. */ 2813 if (rd == REG_PC || rn == REG_PC) 2814 as_tsktsk 2815 (_("Warning: Instruction unpredictable when using r15")); 2816 2817 if (skip_past_comma (& str) == FAIL 2818 || cp_reg_required_here (& str, 0) == FAIL) 2819 { 2820 if (!inst.error) 2821 inst.error = BAD_ARGS; 2822 return; 2823 } 2824 2825 if (flags) 2826 inst.error = BAD_COND; 2827 2828 end_of_line (str); 2829} 2830 2831/* ARM V5 count-leading-zeroes instruction (argument parse) 2832 CLZ{<cond>} <Rd>, <Rm> 2833 Condition defaults to COND_ALWAYS. 2834 Error if Rd or Rm are R15. */ 2835 2836static void 2837do_clz (str, flags) 2838 char * str; 2839 unsigned long flags; 2840{ 2841 int rd, rm; 2842 2843 if (flags) 2844 { 2845 as_bad (BAD_FLAGS); 2846 return; 2847 } 2848 2849 skip_whitespace (str); 2850 2851 if (((rd = reg_required_here (& str, 12)) == FAIL) 2852 || (skip_past_comma (& str) == FAIL) 2853 || ((rm = reg_required_here (& str, 0)) == FAIL)) 2854 inst.error = BAD_ARGS; 2855 2856 else if (rd == REG_PC || rm == REG_PC ) 2857 inst.error = BAD_PC; 2858 2859 else 2860 end_of_line (str); 2861} 2862 2863/* ARM V5 (argument parse) 2864 LDC2{L} <coproc>, <CRd>, <addressing mode> 2865 STC2{L} <coproc>, <CRd>, <addressing mode> 2866 Instruction is not conditional, and has 0xf in the codition field. 2867 Otherwise, it's the same as LDC/STC. */ 2868 2869static void 2870do_lstc2 (str, flags) 2871 char * str; 2872 unsigned long flags; 2873{ 2874 if (flags) 2875 inst.error = BAD_COND; 2876 2877 skip_whitespace (str); 2878 2879 if (co_proc_number (& str) == FAIL) 2880 { 2881 if (!inst.error) 2882 inst.error = BAD_ARGS; 2883 } 2884 else if (skip_past_comma (& str) == FAIL 2885 || cp_reg_required_here (& str, 12) == FAIL) 2886 { 2887 if (!inst.error) 2888 inst.error = BAD_ARGS; 2889 } 2890 else if (skip_past_comma (& str) == FAIL 2891 || cp_address_required_here (& str) == FAIL) 2892 { 2893 if (! inst.error) 2894 inst.error = BAD_ARGS; 2895 } 2896 else 2897 end_of_line (str); 2898} 2899 2900/* ARM V5 (argument parse) 2901 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2> 2902 Instruction is not conditional, and has 0xf in the condition field. 2903 Otherwise, it's the same as CDP. */ 2904 2905static void 2906do_cdp2 (str, flags) 2907 char * str; 2908 unsigned long flags; 2909{ 2910 skip_whitespace (str); 2911 2912 if (co_proc_number (& str) == FAIL) 2913 { 2914 if (!inst.error) 2915 inst.error = BAD_ARGS; 2916 return; 2917 } 2918 2919 if (skip_past_comma (& str) == FAIL 2920 || cp_opc_expr (& str, 20,4) == FAIL) 2921 { 2922 if (!inst.error) 2923 inst.error = BAD_ARGS; 2924 return; 2925 } 2926 2927 if (skip_past_comma (& str) == FAIL 2928 || cp_reg_required_here (& str, 12) == FAIL) 2929 { 2930 if (!inst.error) 2931 inst.error = BAD_ARGS; 2932 return; 2933 } 2934 2935 if (skip_past_comma (& str) == FAIL 2936 || cp_reg_required_here (& str, 16) == FAIL) 2937 { 2938 if (!inst.error) 2939 inst.error = BAD_ARGS; 2940 return; 2941 } 2942 2943 if (skip_past_comma (& str) == FAIL 2944 || cp_reg_required_here (& str, 0) == FAIL) 2945 { 2946 if (!inst.error) 2947 inst.error = BAD_ARGS; 2948 return; 2949 } 2950 2951 if (skip_past_comma (& str) == SUCCESS) 2952 { 2953 if (cp_opc_expr (& str, 5, 3) == FAIL) 2954 { 2955 if (!inst.error) 2956 inst.error = BAD_ARGS; 2957 return; 2958 } 2959 } 2960 2961 if (flags) 2962 inst.error = BAD_FLAGS; 2963 2964 end_of_line (str); 2965} 2966 2967/* ARM V5 (argument parse) 2968 MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2> 2969 MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2> 2970 Instruction is not conditional, and has 0xf in the condition field. 2971 Otherwise, it's the same as MCR/MRC. */ 2972 2973static void 2974do_co_reg2 (str, flags) 2975 char * str; 2976 unsigned long flags; 2977{ 2978 skip_whitespace (str); 2979 2980 if (co_proc_number (& str) == FAIL) 2981 { 2982 if (!inst.error) 2983 inst.error = BAD_ARGS; 2984 return; 2985 } 2986 2987 if (skip_past_comma (& str) == FAIL 2988 || cp_opc_expr (& str, 21, 3) == FAIL) 2989 { 2990 if (!inst.error) 2991 inst.error = BAD_ARGS; 2992 return; 2993 } 2994 2995 if (skip_past_comma (& str) == FAIL 2996 || reg_required_here (& str, 12) == FAIL) 2997 { 2998 if (!inst.error) 2999 inst.error = BAD_ARGS; 3000 return; 3001 } 3002 3003 if (skip_past_comma (& str) == FAIL 3004 || cp_reg_required_here (& str, 16) == FAIL) 3005 { 3006 if (!inst.error) 3007 inst.error = BAD_ARGS; 3008 return; 3009 } 3010 3011 if (skip_past_comma (& str) == FAIL 3012 || cp_reg_required_here (& str, 0) == FAIL) 3013 { 3014 if (!inst.error) 3015 inst.error = BAD_ARGS; 3016 return; 3017 } 3018 3019 if (skip_past_comma (& str) == SUCCESS) 3020 { 3021 if (cp_opc_expr (& str, 5, 3) == FAIL) 3022 { 3023 if (!inst.error) 3024 inst.error = BAD_ARGS; 3025 return; 3026 } 3027 } 3028 3029 if (flags) 3030 inst.error = BAD_COND; 3031 3032 end_of_line (str); 3033} 3034 3035/* THUMB V5 breakpoint instruction (argument parse) 3036 BKPT <immed_8>. */ 3037 3038static void 3039do_t_bkpt (str) 3040 char * str; 3041{ 3042 expressionS expr; 3043 unsigned long number; 3044 3045 skip_whitespace (str); 3046 3047 /* Allow optional leading '#'. */ 3048 if (is_immediate_prefix (*str)) 3049 str ++; 3050 3051 memset (& expr, '\0', sizeof (expr)); 3052 if (my_get_expression (& expr, & str) || (expr.X_op != O_constant)) 3053 { 3054 inst.error = _("bad or missing expression"); 3055 return; 3056 } 3057 3058 number = expr.X_add_number; 3059 3060 /* Check it fits an 8 bit unsigned. */ 3061 if (number != (number & 0xff)) 3062 { 3063 inst.error = _("immediate value out of range"); 3064 return; 3065 } 3066 3067 inst.instruction |= number; 3068 3069 end_of_line (str); 3070} 3071 3072/* ARM V5 branch-link-exchange (argument parse) for BLX(1) only. 3073 Expects inst.instruction is set for BLX(1). 3074 Note: this is cloned from do_branch, and the reloc changed to be a 3075 new one that can cope with setting one extra bit (the H bit). */ 3076 3077static void 3078do_branch25 (str, flags) 3079 char * str; 3080 unsigned long flags ATTRIBUTE_UNUSED; 3081{ 3082 if (my_get_expression (& inst.reloc.exp, & str)) 3083 return; 3084 3085#ifdef OBJ_ELF 3086 { 3087 char * save_in; 3088 3089 /* ScottB: February 5, 1998 */ 3090 /* Check to see of PLT32 reloc required for the instruction. */ 3091 3092 /* arm_parse_reloc() works on input_line_pointer. 3093 We actually want to parse the operands to the branch instruction 3094 passed in 'str'. Save the input pointer and restore it later. */ 3095 save_in = input_line_pointer; 3096 input_line_pointer = str; 3097 3098 if (inst.reloc.exp.X_op == O_symbol 3099 && *str == '(' 3100 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32) 3101 { 3102 inst.reloc.type = BFD_RELOC_ARM_PLT32; 3103 inst.reloc.pc_rel = 0; 3104 /* Modify str to point to after parsed operands, otherwise 3105 end_of_line() will complain about the (PLT) left in str. */ 3106 str = input_line_pointer; 3107 } 3108 else 3109 { 3110 inst.reloc.type = BFD_RELOC_ARM_PCREL_BLX; 3111 inst.reloc.pc_rel = 1; 3112 } 3113 3114 input_line_pointer = save_in; 3115 } 3116#else 3117 inst.reloc.type = BFD_RELOC_ARM_PCREL_BLX; 3118 inst.reloc.pc_rel = 1; 3119#endif /* OBJ_ELF */ 3120 3121 end_of_line (str); 3122} 3123 3124/* ARM V5 branch-link-exchange instruction (argument parse) 3125 BLX <target_addr> ie BLX(1) 3126 BLX{<condition>} <Rm> ie BLX(2) 3127 Unfortunately, there are two different opcodes for this mnemonic. 3128 So, the insns[].value is not used, and the code here zaps values 3129 into inst.instruction. 3130 Also, the <target_addr> can be 25 bits, hence has its own reloc. */ 3131 3132static void 3133do_blx (str, flags) 3134 char * str; 3135 unsigned long flags; 3136{ 3137 char * mystr = str; 3138 int rm; 3139 3140 if (flags) 3141 { 3142 as_bad (BAD_FLAGS); 3143 return; 3144 } 3145 3146 skip_whitespace (mystr); 3147 rm = reg_required_here (& mystr, 0); 3148 3149 /* The above may set inst.error. Ignore his opinion. */ 3150 inst.error = 0; 3151 3152 if (rm != FAIL) 3153 { 3154 /* Arg is a register. 3155 Use the condition code our caller put in inst.instruction. 3156 Pass ourselves off as a BX with a funny opcode. */ 3157 inst.instruction |= 0x012fff30; 3158 do_bx (str, flags); 3159 } 3160 else 3161 { 3162 /* This must be is BLX <target address>, no condition allowed. */ 3163 if (inst.instruction != COND_ALWAYS) 3164 { 3165 inst.error = BAD_COND; 3166 return; 3167 } 3168 3169 inst.instruction = 0xfafffffe; 3170 3171 /* Process like a B/BL, but with a different reloc. 3172 Note that B/BL expecte fffffe, not 0, offset in the opcode table. */ 3173 do_branch25 (str, flags); 3174 } 3175} 3176 3177/* ARM V5 Thumb BLX (argument parse) 3178 BLX <target_addr> which is BLX(1) 3179 BLX <Rm> which is BLX(2) 3180 Unfortunately, there are two different opcodes for this mnemonic. 3181 So, the tinsns[].value is not used, and the code here zaps values 3182 into inst.instruction. */ 3183 3184static void 3185do_t_blx (str) 3186 char * str; 3187{ 3188 char * mystr = str; 3189 int rm; 3190 3191 skip_whitespace (mystr); 3192 inst.instruction = 0x4780; 3193 3194 /* Note that this call is to the ARM register recognizer. BLX(2) 3195 uses the ARM register space, not the Thumb one, so a call to 3196 thumb_reg() would be wrong. */ 3197 rm = reg_required_here (& mystr, 3); 3198 inst.error = 0; 3199 3200 if (rm != FAIL) 3201 { 3202 /* It's BLX(2). The .instruction was zapped with rm & is final. */ 3203 inst.size = 2; 3204 } 3205 else 3206 { 3207 /* No ARM register. This must be BLX(1). Change the .instruction. */ 3208 inst.instruction = 0xf7ffeffe; 3209 inst.size = 4; 3210 3211 if (my_get_expression (& inst.reloc.exp, & mystr)) 3212 return; 3213 3214 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BLX; 3215 inst.reloc.pc_rel = 1; 3216 } 3217 3218 end_of_line (mystr); 3219} 3220 3221/* ARM V5 breakpoint instruction (argument parse) 3222 BKPT <16 bit unsigned immediate> 3223 Instruction is not conditional. 3224 The bit pattern given in insns[] has the COND_ALWAYS condition, 3225 and it is an error if the caller tried to override that. 3226 Note "flags" is nonzero if a flag was supplied (which is an error). */ 3227 3228static void 3229do_bkpt (str, flags) 3230 char * str; 3231 unsigned long flags; 3232{ 3233 expressionS expr; 3234 unsigned long number; 3235 3236 skip_whitespace (str); 3237 3238 /* Allow optional leading '#'. */ 3239 if (is_immediate_prefix (* str)) 3240 str++; 3241 3242 memset (& expr, '\0', sizeof (expr)); 3243 3244 if (my_get_expression (& expr, & str) || (expr.X_op != O_constant)) 3245 { 3246 inst.error = _("bad or missing expression"); 3247 return; 3248 } 3249 3250 number = expr.X_add_number; 3251 3252 /* Check it fits a 16 bit unsigned. */ 3253 if (number != (number & 0xffff)) 3254 { 3255 inst.error = _("immediate value out of range"); 3256 return; 3257 } 3258 3259 /* Top 12 of 16 bits to bits 19:8. */ 3260 inst.instruction |= (number & 0xfff0) << 4; 3261 3262 /* Bottom 4 of 16 bits to bits 3:0. */ 3263 inst.instruction |= number & 0xf; 3264 3265 end_of_line (str); 3266 3267 if (flags) 3268 inst.error = BAD_FLAGS; 3269} 3270 3271/* Xscale multiply-accumulate (argument parse) 3272 MIAcc acc0,Rm,Rs 3273 MIAPHcc acc0,Rm,Rs 3274 MIAxycc acc0,Rm,Rs. */ 3275 3276static void 3277do_mia (str, flags) 3278 char * str; 3279 unsigned long flags; 3280{ 3281 int rs; 3282 int rm; 3283 3284 if (flags) 3285 as_bad (BAD_FLAGS); 3286 3287 else if (accum0_required_here (& str) == FAIL) 3288 inst.error = ERR_NO_ACCUM; 3289 3290 else if (skip_past_comma (& str) == FAIL 3291 || (rm = reg_required_here (& str, 0)) == FAIL) 3292 inst.error = BAD_ARGS; 3293 3294 else if (skip_past_comma (& str) == FAIL 3295 || (rs = reg_required_here (& str, 12)) == FAIL) 3296 inst.error = BAD_ARGS; 3297 3298 /* inst.instruction has now been zapped with both rm and rs. */ 3299 else if (rm == REG_PC || rs == REG_PC) 3300 inst.error = BAD_PC; /* Undefined result if rm or rs is R15. */ 3301 3302 else 3303 end_of_line (str); 3304} 3305 3306/* Xscale move-accumulator-register (argument parse) 3307 3308 MARcc acc0,RdLo,RdHi. */ 3309 3310static void 3311do_mar (str, flags) 3312 char * str; 3313 unsigned long flags; 3314{ 3315 int rdlo, rdhi; 3316 3317 if (flags) 3318 as_bad (BAD_FLAGS); 3319 3320 else if (accum0_required_here (& str) == FAIL) 3321 inst.error = ERR_NO_ACCUM; 3322 3323 else if (skip_past_comma (& str) == FAIL 3324 || (rdlo = reg_required_here (& str, 12)) == FAIL) 3325 inst.error = BAD_ARGS; 3326 3327 else if (skip_past_comma (& str) == FAIL 3328 || (rdhi = reg_required_here (& str, 16)) == FAIL) 3329 inst.error = BAD_ARGS; 3330 3331 /* inst.instruction has now been zapped with both rdlo and rdhi. */ 3332 else if (rdlo == REG_PC || rdhi == REG_PC) 3333 inst.error = BAD_PC; /* Undefined result if rdlo or rdhi is R15. */ 3334 3335 else 3336 end_of_line (str); 3337} 3338 3339/* Xscale move-register-accumulator (argument parse) 3340 3341 MRAcc RdLo,RdHi,acc0. */ 3342 3343static void 3344do_mra (str, flags) 3345 char * str; 3346 unsigned long flags; 3347{ 3348 int rdlo; 3349 int rdhi; 3350 3351 if (flags) 3352 { 3353 as_bad (BAD_FLAGS); 3354 return; 3355 } 3356 3357 skip_whitespace (str); 3358 3359 if ((rdlo = reg_required_here (& str, 12)) == FAIL) 3360 inst.error = BAD_ARGS; 3361 3362 else if (skip_past_comma (& str) == FAIL 3363 || (rdhi = reg_required_here (& str, 16)) == FAIL) 3364 inst.error = BAD_ARGS; 3365 3366 else if (skip_past_comma (& str) == FAIL 3367 || accum0_required_here (& str) == FAIL) 3368 inst.error = ERR_NO_ACCUM; 3369 3370 /* inst.instruction has now been zapped with both rdlo and rdhi. */ 3371 else if (rdlo == rdhi) 3372 inst.error = BAD_ARGS; /* Undefined result if 2 writes to same reg. */ 3373 3374 else if (rdlo == REG_PC || rdhi == REG_PC) 3375 inst.error = BAD_PC; /* Undefined result if rdlo or rdhi is R15. */ 3376 else 3377 end_of_line (str); 3378} 3379 3380/* Xscale: Preload-Cache 3381 3382 PLD <addr_mode> 3383 3384 Syntactically, like LDR with B=1, W=0, L=1. */ 3385 3386static void 3387do_pld (str, flags) 3388 char * str; 3389 unsigned long flags; 3390{ 3391 int rd; 3392 3393 if (flags) 3394 { 3395 as_bad (BAD_FLAGS); 3396 return; 3397 } 3398 3399 skip_whitespace (str); 3400 3401 if (* str != '[') 3402 { 3403 inst.error = _("'[' expected after PLD mnemonic"); 3404 return; 3405 } 3406 3407 ++ str; 3408 skip_whitespace (str); 3409 3410 if ((rd = reg_required_here (& str, 16)) == FAIL) 3411 return; 3412 3413 skip_whitespace (str); 3414 3415 if (* str == ']') 3416 { 3417 /* [Rn], ... ? */ 3418 ++ str; 3419 skip_whitespace (str); 3420 3421 if (skip_past_comma (& str) == SUCCESS) 3422 { 3423 if (ldst_extend (& str, 0) == FAIL) 3424 return; 3425 } 3426 else if (* str == '!') /* [Rn]! */ 3427 { 3428 inst.error = _("writeback used in preload instruction"); 3429 ++ str; 3430 } 3431 else /* [Rn] */ 3432 inst.instruction |= INDEX_UP | PRE_INDEX; 3433 } 3434 else /* [Rn, ...] */ 3435 { 3436 if (skip_past_comma (& str) == FAIL) 3437 { 3438 inst.error = _("pre-indexed expression expected"); 3439 return; 3440 } 3441 3442 if (ldst_extend (& str, 0) == FAIL) 3443 return; 3444 3445 skip_whitespace (str); 3446 3447 if (* str != ']') 3448 { 3449 inst.error = _("missing ]"); 3450 return; 3451 } 3452 3453 ++ str; 3454 skip_whitespace (str); 3455 3456 if (* str == '!') /* [Rn]! */ 3457 { 3458 inst.error = _("writeback used in preload instruction"); 3459 ++ str; 3460 } 3461 3462 inst.instruction |= PRE_INDEX; 3463 } 3464 3465 end_of_line (str); 3466} 3467 3468/* Xscale load-consecutive (argument parse) 3469 Mode is like LDRH. 3470 3471 LDRccD R, mode 3472 STRccD R, mode. */ 3473 3474static void 3475do_ldrd (str, flags) 3476 char * str; 3477 unsigned long flags; 3478{ 3479 int rd; 3480 int rn; 3481 3482 if (flags != DOUBLE_LOAD_FLAG) 3483 { 3484 /* Change instruction pattern to normal ldr/str. */ 3485 if (inst.instruction & 0x20) 3486 inst.instruction = (inst.instruction & COND_MASK) | 0x04000000; /* str */ 3487 else 3488 inst.instruction = (inst.instruction & COND_MASK) | 0x04100000; /* ldr */ 3489 3490 /* Perform a normal load/store instruction parse. */ 3491 do_ldst (str, flags); 3492 3493 return; 3494 } 3495 3496 if ((cpu_variant & ARM_EXT_XSCALE) != ARM_EXT_XSCALE) 3497 { 3498 static char buff[128]; 3499 3500 --str; 3501 while (isspace (*str)) 3502 --str; 3503 str -= 4; 3504 3505 /* Deny all knowledge. */ 3506 sprintf (buff, _("bad instruction '%.100s'"), str); 3507 inst.error = buff; 3508 return; 3509 } 3510 3511 skip_whitespace (str); 3512 3513 if ((rd = reg_required_here (& str, 12)) == FAIL) 3514 { 3515 inst.error = BAD_ARGS; 3516 return; 3517 } 3518 3519 if (skip_past_comma (& str) == FAIL 3520 || (rn = ld_mode_required_here (& str)) == FAIL) 3521 { 3522 if (!inst.error) 3523 inst.error = BAD_ARGS; 3524 return; 3525 } 3526 3527 /* inst.instruction has now been zapped with Rd and the addressing mode. */ 3528 if (rd & 1) /* Unpredictable result if Rd is odd. */ 3529 { 3530 inst.error = _("Destination register must be even"); 3531 return; 3532 } 3533 3534 if (rd == REG_LR || rd == 12) 3535 { 3536 inst.error = _("r12 or r14 not allowed here"); 3537 return; 3538 } 3539 3540 if (((rd == rn) || (rd + 1 == rn)) 3541 && 3542 ((inst.instruction & WRITE_BACK) 3543 || (!(inst.instruction & PRE_INDEX)))) 3544 as_warn (_("pre/post-indexing used when modified address register is destination")); 3545 3546 end_of_line (str); 3547} 3548 3549/* Returns the index into fp_values of a floating point number, 3550 or -1 if not in the table. */ 3551 3552static int 3553my_get_float_expression (str) 3554 char ** str; 3555{ 3556 LITTLENUM_TYPE words[MAX_LITTLENUMS]; 3557 char * save_in; 3558 expressionS exp; 3559 int i; 3560 int j; 3561 3562 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE)); 3563 3564 /* Look for a raw floating point number. */ 3565 if ((save_in = atof_ieee (*str, 'x', words)) != NULL 3566 && is_end_of_line[(unsigned char) *save_in]) 3567 { 3568 for (i = 0; i < NUM_FLOAT_VALS; i++) 3569 { 3570 for (j = 0; j < MAX_LITTLENUMS; j++) 3571 { 3572 if (words[j] != fp_values[i][j]) 3573 break; 3574 } 3575 3576 if (j == MAX_LITTLENUMS) 3577 { 3578 *str = save_in; 3579 return i; 3580 } 3581 } 3582 } 3583 3584 /* Try and parse a more complex expression, this will probably fail 3585 unless the code uses a floating point prefix (eg "0f"). */ 3586 save_in = input_line_pointer; 3587 input_line_pointer = *str; 3588 if (expression (&exp) == absolute_section 3589 && exp.X_op == O_big 3590 && exp.X_add_number < 0) 3591 { 3592 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it. 3593 Ditto for 15. */ 3594 if (gen_to_words (words, 5, (long) 15) == 0) 3595 { 3596 for (i = 0; i < NUM_FLOAT_VALS; i++) 3597 { 3598 for (j = 0; j < MAX_LITTLENUMS; j++) 3599 { 3600 if (words[j] != fp_values[i][j]) 3601 break; 3602 } 3603 3604 if (j == MAX_LITTLENUMS) 3605 { 3606 *str = input_line_pointer; 3607 input_line_pointer = save_in; 3608 return i; 3609 } 3610 } 3611 } 3612 } 3613 3614 *str = input_line_pointer; 3615 input_line_pointer = save_in; 3616 return -1; 3617} 3618 3619/* Return true if anything in the expression is a bignum. */ 3620 3621static int 3622walk_no_bignums (sp) 3623 symbolS * sp; 3624{ 3625 if (symbol_get_value_expression (sp)->X_op == O_big) 3626 return 1; 3627 3628 if (symbol_get_value_expression (sp)->X_add_symbol) 3629 { 3630 return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol) 3631 || (symbol_get_value_expression (sp)->X_op_symbol 3632 && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol))); 3633 } 3634 3635 return 0; 3636} 3637 3638static int 3639my_get_expression (ep, str) 3640 expressionS * ep; 3641 char ** str; 3642{ 3643 char * save_in; 3644 segT seg; 3645 3646 save_in = input_line_pointer; 3647 input_line_pointer = *str; 3648 seg = expression (ep); 3649 3650#ifdef OBJ_AOUT 3651 if (seg != absolute_section 3652 && seg != text_section 3653 && seg != data_section 3654 && seg != bss_section 3655 && seg != undefined_section) 3656 { 3657 inst.error = _("bad_segment"); 3658 *str = input_line_pointer; 3659 input_line_pointer = save_in; 3660 return 1; 3661 } 3662#endif 3663 3664 /* Get rid of any bignums now, so that we don't generate an error for which 3665 we can't establish a line number later on. Big numbers are never valid 3666 in instructions, which is where this routine is always called. */ 3667 if (ep->X_op == O_big 3668 || (ep->X_add_symbol 3669 && (walk_no_bignums (ep->X_add_symbol) 3670 || (ep->X_op_symbol 3671 && walk_no_bignums (ep->X_op_symbol))))) 3672 { 3673 inst.error = _("Invalid constant"); 3674 *str = input_line_pointer; 3675 input_line_pointer = save_in; 3676 return 1; 3677 } 3678 3679 *str = input_line_pointer; 3680 input_line_pointer = save_in; 3681 return 0; 3682} 3683 3684/* UNRESTRICT should be one if <shift> <register> is permitted for this 3685 instruction. */ 3686 3687static int 3688decode_shift (str, unrestrict) 3689 char ** str; 3690 int unrestrict; 3691{ 3692 const struct asm_shift_name * shift; 3693 char * p; 3694 char c; 3695 3696 skip_whitespace (* str); 3697 3698 for (p = * str; isalpha (* p); p ++) 3699 ; 3700 3701 if (p == * str) 3702 { 3703 inst.error = _("Shift expression expected"); 3704 return FAIL; 3705 } 3706 3707 c = * p; 3708 * p = '\0'; 3709 shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str); 3710 * p = c; 3711 3712 if (shift == NULL) 3713 { 3714 inst.error = _("Shift expression expected"); 3715 return FAIL; 3716 } 3717 3718 assert (shift->properties->index == shift_properties[shift->properties->index].index); 3719 3720 if (shift->properties->index == SHIFT_RRX) 3721 { 3722 * str = p; 3723 inst.instruction |= shift->properties->bit_field; 3724 return SUCCESS; 3725 } 3726 3727 skip_whitespace (p); 3728 3729 if (unrestrict && reg_required_here (& p, 8) != FAIL) 3730 { 3731 inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG; 3732 * str = p; 3733 return SUCCESS; 3734 } 3735 else if (! is_immediate_prefix (* p)) 3736 { 3737 inst.error = (unrestrict 3738 ? _("shift requires register or #expression") 3739 : _("shift requires #expression")); 3740 * str = p; 3741 return FAIL; 3742 } 3743 3744 inst.error = NULL; 3745 p ++; 3746 3747 if (my_get_expression (& inst.reloc.exp, & p)) 3748 return FAIL; 3749 3750 /* Validate some simple #expressions. */ 3751 if (inst.reloc.exp.X_op == O_constant) 3752 { 3753 unsigned num = inst.reloc.exp.X_add_number; 3754 3755 /* Reject operations greater than 32. */ 3756 if (num > 32 3757 /* Reject a shift of 0 unless the mode allows it. */ 3758 || (num == 0 && shift->properties->allows_0 == 0) 3759 /* Reject a shift of 32 unless the mode allows it. */ 3760 || (num == 32 && shift->properties->allows_32 == 0) 3761 ) 3762 { 3763 /* As a special case we allow a shift of zero for 3764 modes that do not support it to be recoded as an 3765 logical shift left of zero (ie nothing). We warn 3766 about this though. */ 3767 if (num == 0) 3768 { 3769 as_warn (_("Shift of 0 ignored.")); 3770 shift = & shift_names[0]; 3771 assert (shift->properties->index == SHIFT_LSL); 3772 } 3773 else 3774 { 3775 inst.error = _("Invalid immediate shift"); 3776 return FAIL; 3777 } 3778 } 3779 3780 /* Shifts of 32 are encoded as 0, for those shifts that 3781 support it. */ 3782 if (num == 32) 3783 num = 0; 3784 3785 inst.instruction |= (num << 7) | shift->properties->bit_field; 3786 } 3787 else 3788 { 3789 inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM; 3790 inst.reloc.pc_rel = 0; 3791 inst.instruction |= shift->properties->bit_field; 3792 } 3793 3794 * str = p; 3795 return SUCCESS; 3796} 3797 3798/* Do those data_ops which can take a negative immediate constant 3799 by altering the instuction. A bit of a hack really. 3800 MOV <-> MVN 3801 AND <-> BIC 3802 ADC <-> SBC 3803 by inverting the second operand, and 3804 ADD <-> SUB 3805 CMP <-> CMN 3806 by negating the second operand. */ 3807 3808static int 3809negate_data_op (instruction, value) 3810 unsigned long * instruction; 3811 unsigned long value; 3812{ 3813 int op, new_inst; 3814 unsigned long negated, inverted; 3815 3816 negated = validate_immediate (-value); 3817 inverted = validate_immediate (~value); 3818 3819 op = (*instruction >> DATA_OP_SHIFT) & 0xf; 3820 switch (op) 3821 { 3822 /* First negates. */ 3823 case OPCODE_SUB: /* ADD <-> SUB */ 3824 new_inst = OPCODE_ADD; 3825 value = negated; 3826 break; 3827 3828 case OPCODE_ADD: 3829 new_inst = OPCODE_SUB; 3830 value = negated; 3831 break; 3832 3833 case OPCODE_CMP: /* CMP <-> CMN */ 3834 new_inst = OPCODE_CMN; 3835 value = negated; 3836 break; 3837 3838 case OPCODE_CMN: 3839 new_inst = OPCODE_CMP; 3840 value = negated; 3841 break; 3842 3843 /* Now Inverted ops. */ 3844 case OPCODE_MOV: /* MOV <-> MVN */ 3845 new_inst = OPCODE_MVN; 3846 value = inverted; 3847 break; 3848 3849 case OPCODE_MVN: 3850 new_inst = OPCODE_MOV; 3851 value = inverted; 3852 break; 3853 3854 case OPCODE_AND: /* AND <-> BIC */ 3855 new_inst = OPCODE_BIC; 3856 value = inverted; 3857 break; 3858 3859 case OPCODE_BIC: 3860 new_inst = OPCODE_AND; 3861 value = inverted; 3862 break; 3863 3864 case OPCODE_ADC: /* ADC <-> SBC */ 3865 new_inst = OPCODE_SBC; 3866 value = inverted; 3867 break; 3868 3869 case OPCODE_SBC: 3870 new_inst = OPCODE_ADC; 3871 value = inverted; 3872 break; 3873 3874 /* We cannot do anything. */ 3875 default: 3876 return FAIL; 3877 } 3878 3879 if (value == (unsigned) FAIL) 3880 return FAIL; 3881 3882 *instruction &= OPCODE_MASK; 3883 *instruction |= new_inst << DATA_OP_SHIFT; 3884 return value; 3885} 3886 3887static int 3888data_op2 (str) 3889 char ** str; 3890{ 3891 int value; 3892 expressionS expr; 3893 3894 skip_whitespace (* str); 3895 3896 if (reg_required_here (str, 0) != FAIL) 3897 { 3898 if (skip_past_comma (str) == SUCCESS) 3899 /* Shift operation on register. */ 3900 return decode_shift (str, NO_SHIFT_RESTRICT); 3901 3902 return SUCCESS; 3903 } 3904 else 3905 { 3906 /* Immediate expression. */ 3907 if (is_immediate_prefix (**str)) 3908 { 3909 (*str)++; 3910 inst.error = NULL; 3911 3912 if (my_get_expression (&inst.reloc.exp, str)) 3913 return FAIL; 3914 3915 if (inst.reloc.exp.X_add_symbol) 3916 { 3917 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE; 3918 inst.reloc.pc_rel = 0; 3919 } 3920 else 3921 { 3922 if (skip_past_comma (str) == SUCCESS) 3923 { 3924 /* #x, y -- ie explicit rotation by Y. */ 3925 if (my_get_expression (&expr, str)) 3926 return FAIL; 3927 3928 if (expr.X_op != O_constant) 3929 { 3930 inst.error = _("Constant expression expected"); 3931 return FAIL; 3932 } 3933 3934 /* Rotate must be a multiple of 2. */ 3935 if (((unsigned) expr.X_add_number) > 30 3936 || (expr.X_add_number & 1) != 0 3937 || ((unsigned) inst.reloc.exp.X_add_number) > 255) 3938 { 3939 inst.error = _("Invalid constant"); 3940 return FAIL; 3941 } 3942 inst.instruction |= INST_IMMEDIATE; 3943 inst.instruction |= inst.reloc.exp.X_add_number; 3944 inst.instruction |= expr.X_add_number << 7; 3945 return SUCCESS; 3946 } 3947 3948 /* Implicit rotation, select a suitable one. */ 3949 value = validate_immediate (inst.reloc.exp.X_add_number); 3950 3951 if (value == FAIL) 3952 { 3953 /* Can't be done. Perhaps the code reads something like 3954 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */ 3955 if ((value = negate_data_op (&inst.instruction, 3956 inst.reloc.exp.X_add_number)) 3957 == FAIL) 3958 { 3959 inst.error = _("Invalid constant"); 3960 return FAIL; 3961 } 3962 } 3963 3964 inst.instruction |= value; 3965 } 3966 3967 inst.instruction |= INST_IMMEDIATE; 3968 return SUCCESS; 3969 } 3970 3971 (*str)++; 3972 inst.error = _("Register or shift expression expected"); 3973 return FAIL; 3974 } 3975} 3976 3977static int 3978fp_op2 (str) 3979 char ** str; 3980{ 3981 skip_whitespace (* str); 3982 3983 if (fp_reg_required_here (str, 0) != FAIL) 3984 return SUCCESS; 3985 else 3986 { 3987 /* Immediate expression. */ 3988 if (*((*str)++) == '#') 3989 { 3990 int i; 3991 3992 inst.error = NULL; 3993 3994 skip_whitespace (* str); 3995 3996 /* First try and match exact strings, this is to guarantee 3997 that some formats will work even for cross assembly. */ 3998 3999 for (i = 0; fp_const[i]; i++) 4000 { 4001 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0) 4002 { 4003 char *start = *str; 4004 4005 *str += strlen (fp_const[i]); 4006 if (is_end_of_line[(unsigned char) **str]) 4007 { 4008 inst.instruction |= i + 8; 4009 return SUCCESS; 4010 } 4011 *str = start; 4012 } 4013 } 4014 4015 /* Just because we didn't get a match doesn't mean that the 4016 constant isn't valid, just that it is in a format that we 4017 don't automatically recognize. Try parsing it with 4018 the standard expression routines. */ 4019 if ((i = my_get_float_expression (str)) >= 0) 4020 { 4021 inst.instruction |= i + 8; 4022 return SUCCESS; 4023 } 4024 4025 inst.error = _("Invalid floating point immediate expression"); 4026 return FAIL; 4027 } 4028 inst.error = 4029 _("Floating point register or immediate expression expected"); 4030 return FAIL; 4031 } 4032} 4033 4034static void 4035do_arit (str, flags) 4036 char * str; 4037 unsigned long flags; 4038{ 4039 skip_whitespace (str); 4040 4041 if (reg_required_here (&str, 12) == FAIL 4042 || skip_past_comma (&str) == FAIL 4043 || reg_required_here (&str, 16) == FAIL 4044 || skip_past_comma (&str) == FAIL 4045 || data_op2 (&str) == FAIL) 4046 { 4047 if (!inst.error) 4048 inst.error = BAD_ARGS; 4049 return; 4050 } 4051 4052 inst.instruction |= flags; 4053 end_of_line (str); 4054 return; 4055} 4056 4057static void 4058do_adr (str, flags) 4059 char * str; 4060 unsigned long flags; 4061{ 4062 /* This is a pseudo-op of the form "adr rd, label" to be converted 4063 into a relative address of the form "add rd, pc, #label-.-8". */ 4064 skip_whitespace (str); 4065 4066 if (reg_required_here (&str, 12) == FAIL 4067 || skip_past_comma (&str) == FAIL 4068 || my_get_expression (&inst.reloc.exp, &str)) 4069 { 4070 if (!inst.error) 4071 inst.error = BAD_ARGS; 4072 return; 4073 } 4074 4075 /* Frag hacking will turn this into a sub instruction if the offset turns 4076 out to be negative. */ 4077 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE; 4078 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust. */ 4079 inst.reloc.pc_rel = 1; 4080 inst.instruction |= flags; 4081 4082 end_of_line (str); 4083} 4084 4085static void 4086do_adrl (str, flags) 4087 char * str; 4088 unsigned long flags; 4089{ 4090 /* This is a pseudo-op of the form "adrl rd, label" to be converted 4091 into a relative address of the form: 4092 add rd, pc, #low(label-.-8)" 4093 add rd, rd, #high(label-.-8)" */ 4094 4095 skip_whitespace (str); 4096 4097 if (reg_required_here (& str, 12) == FAIL 4098 || skip_past_comma (& str) == FAIL 4099 || my_get_expression (& inst.reloc.exp, & str)) 4100 { 4101 if (!inst.error) 4102 inst.error = BAD_ARGS; 4103 return; 4104 } 4105 4106 end_of_line (str); 4107 4108 /* Frag hacking will turn this into a sub instruction if the offset turns 4109 out to be negative. */ 4110 inst.reloc.type = BFD_RELOC_ARM_ADRL_IMMEDIATE; 4111 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */ 4112 inst.reloc.pc_rel = 1; 4113 inst.instruction |= flags; 4114 inst.size = INSN_SIZE * 2; 4115 4116 return; 4117} 4118 4119static void 4120do_cmp (str, flags) 4121 char * str; 4122 unsigned long flags; 4123{ 4124 skip_whitespace (str); 4125 4126 if (reg_required_here (&str, 16) == FAIL) 4127 { 4128 if (!inst.error) 4129 inst.error = BAD_ARGS; 4130 return; 4131 } 4132 4133 if (skip_past_comma (&str) == FAIL 4134 || data_op2 (&str) == FAIL) 4135 { 4136 if (!inst.error) 4137 inst.error = BAD_ARGS; 4138 return; 4139 } 4140 4141 inst.instruction |= flags; 4142 if ((flags & 0x0000f000) == 0) 4143 inst.instruction |= CONDS_BIT; 4144 4145 end_of_line (str); 4146 return; 4147} 4148 4149static void 4150do_mov (str, flags) 4151 char * str; 4152 unsigned long flags; 4153{ 4154 skip_whitespace (str); 4155 4156 if (reg_required_here (&str, 12) == FAIL) 4157 { 4158 if (!inst.error) 4159 inst.error = BAD_ARGS; 4160 return; 4161 } 4162 4163 if (skip_past_comma (&str) == FAIL 4164 || data_op2 (&str) == FAIL) 4165 { 4166 if (!inst.error) 4167 inst.error = BAD_ARGS; 4168 return; 4169 } 4170 4171 inst.instruction |= flags; 4172 end_of_line (str); 4173 return; 4174} 4175 4176static int 4177ldst_extend (str, hwse) 4178 char ** str; 4179 int hwse; 4180{ 4181 int add = INDEX_UP; 4182 4183 switch (**str) 4184 { 4185 case '#': 4186 case '$': 4187 (*str)++; 4188 if (my_get_expression (& inst.reloc.exp, str)) 4189 return FAIL; 4190 4191 if (inst.reloc.exp.X_op == O_constant) 4192 { 4193 int value = inst.reloc.exp.X_add_number; 4194 4195 if ((hwse && (value < -255 || value > 255)) 4196 || (value < -4095 || value > 4095)) 4197 { 4198 inst.error = _("address offset too large"); 4199 return FAIL; 4200 } 4201 4202 if (value < 0) 4203 { 4204 value = -value; 4205 add = 0; 4206 } 4207 4208 /* Halfword and signextension instructions have the 4209 immediate value split across bits 11..8 and bits 3..0. */ 4210 if (hwse) 4211 inst.instruction |= (add | HWOFFSET_IMM 4212 | ((value >> 4) << 8) | (value & 0xF)); 4213 else 4214 inst.instruction |= add | value; 4215 } 4216 else 4217 { 4218 if (hwse) 4219 { 4220 inst.instruction |= HWOFFSET_IMM; 4221 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8; 4222 } 4223 else 4224 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM; 4225 inst.reloc.pc_rel = 0; 4226 } 4227 return SUCCESS; 4228 4229 case '-': 4230 add = 0; 4231 /* Fall through. */ 4232 4233 case '+': 4234 (*str)++; 4235 /* Fall through. */ 4236 4237 default: 4238 if (reg_required_here (str, 0) == FAIL) 4239 return FAIL; 4240 4241 if (hwse) 4242 inst.instruction |= add; 4243 else 4244 { 4245 inst.instruction |= add | OFFSET_REG; 4246 if (skip_past_comma (str) == SUCCESS) 4247 return decode_shift (str, SHIFT_RESTRICT); 4248 } 4249 4250 return SUCCESS; 4251 } 4252} 4253 4254static void 4255do_ldst (str, flags) 4256 char * str; 4257 unsigned long flags; 4258{ 4259 int halfword = 0; 4260 int pre_inc = 0; 4261 int conflict_reg; 4262 int value; 4263 4264 /* This is not ideal, but it is the simplest way of dealing with the 4265 ARM7T halfword instructions (since they use a different 4266 encoding, but the same mnemonic): */ 4267 halfword = (flags & 0x80000000) != 0; 4268 if (halfword) 4269 { 4270 /* This is actually a load/store of a halfword, or a 4271 signed-extension load. */ 4272 if ((cpu_variant & ARM_EXT_HALFWORD) == 0) 4273 { 4274 inst.error 4275 = _("Processor does not support halfwords or signed bytes"); 4276 return; 4277 } 4278 4279 inst.instruction = ((inst.instruction & COND_MASK) 4280 | (flags & ~COND_MASK)); 4281 4282 flags = 0; 4283 } 4284 4285 skip_whitespace (str); 4286 4287 if ((conflict_reg = reg_required_here (& str, 12)) == FAIL) 4288 { 4289 if (!inst.error) 4290 inst.error = BAD_ARGS; 4291 return; 4292 } 4293 4294 if (skip_past_comma (& str) == FAIL) 4295 { 4296 inst.error = _("Address expected"); 4297 return; 4298 } 4299 4300 if (*str == '[') 4301 { 4302 int reg; 4303 4304 str++; 4305 4306 skip_whitespace (str); 4307 4308 if ((reg = reg_required_here (&str, 16)) == FAIL) 4309 return; 4310 4311 /* Conflicts can occur on stores as well as loads. */ 4312 conflict_reg = (conflict_reg == reg); 4313 4314 skip_whitespace (str); 4315 4316 if (*str == ']') 4317 { 4318 str ++; 4319 4320 if (skip_past_comma (&str) == SUCCESS) 4321 { 4322 /* [Rn],... (post inc) */ 4323 if (ldst_extend (&str, halfword) == FAIL) 4324 return; 4325 if (conflict_reg) 4326 { 4327 if (flags & TRANS_BIT) 4328 as_warn (_("Rn and Rd must be different in %s"), 4329 ((inst.instruction & LOAD_BIT) 4330 ? "LDRT" : "STRT")); 4331 else 4332 as_warn (_("%s register same as write-back base"), 4333 ((inst.instruction & LOAD_BIT) 4334 ? _("destination") : _("source"))); 4335 } 4336 } 4337 else 4338 { 4339 /* [Rn] */ 4340 if (halfword) 4341 inst.instruction |= HWOFFSET_IMM; 4342 4343 skip_whitespace (str); 4344 4345 if (*str == '!') 4346 { 4347 if (conflict_reg) 4348 as_warn (_("%s register same as write-back base"), 4349 ((inst.instruction & LOAD_BIT) 4350 ? _("destination") : _("source"))); 4351 str++; 4352 inst.instruction |= WRITE_BACK; 4353 } 4354 4355 flags |= INDEX_UP; 4356 if (flags & TRANS_BIT) 4357 { 4358 if (conflict_reg) 4359 as_warn (_("Rn and Rd must be different in %s"), 4360 ((inst.instruction & LOAD_BIT) 4361 ? "LDRT" : "STRT")); 4362 } 4363 else 4364 pre_inc = 1; 4365 } 4366 } 4367 else 4368 { 4369 /* [Rn,...] */ 4370 if (skip_past_comma (&str) == FAIL) 4371 { 4372 inst.error = _("pre-indexed expression expected"); 4373 return; 4374 } 4375 4376 pre_inc = 1; 4377 if (ldst_extend (&str, halfword) == FAIL) 4378 return; 4379 4380 skip_whitespace (str); 4381 4382 if (*str++ != ']') 4383 { 4384 inst.error = _("missing ]"); 4385 return; 4386 } 4387 4388 skip_whitespace (str); 4389 4390 if (*str == '!') 4391 { 4392 if (conflict_reg) 4393 as_warn (_("%s register same as write-back base"), 4394 ((inst.instruction & LOAD_BIT) 4395 ? _("destination") : _("source"))); 4396 str++; 4397 inst.instruction |= WRITE_BACK; 4398 } 4399 } 4400 } 4401 else if (*str == '=') 4402 { 4403 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */ 4404 str++; 4405 4406 skip_whitespace (str); 4407 4408 if (my_get_expression (&inst.reloc.exp, &str)) 4409 return; 4410 4411 if (inst.reloc.exp.X_op != O_constant 4412 && inst.reloc.exp.X_op != O_symbol) 4413 { 4414 inst.error = _("Constant expression expected"); 4415 return; 4416 } 4417 4418 if (inst.reloc.exp.X_op == O_constant 4419 && (value = validate_immediate (inst.reloc.exp.X_add_number)) != FAIL) 4420 { 4421 /* This can be done with a mov instruction. */ 4422 inst.instruction &= LITERAL_MASK; 4423 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT); 4424 inst.instruction |= (flags & COND_MASK) | (value & 0xfff); 4425 end_of_line (str); 4426 return; 4427 } 4428 else 4429 { 4430 /* Insert into literal pool. */ 4431 if (add_to_lit_pool () == FAIL) 4432 { 4433 if (!inst.error) 4434 inst.error = _("literal pool insertion failed"); 4435 return; 4436 } 4437 4438 /* Change the instruction exp to point to the pool. */ 4439 if (halfword) 4440 { 4441 inst.instruction |= HWOFFSET_IMM; 4442 inst.reloc.type = BFD_RELOC_ARM_HWLITERAL; 4443 } 4444 else 4445 inst.reloc.type = BFD_RELOC_ARM_LITERAL; 4446 inst.reloc.pc_rel = 1; 4447 inst.instruction |= (REG_PC << 16); 4448 pre_inc = 1; 4449 } 4450 } 4451 else 4452 { 4453 if (my_get_expression (&inst.reloc.exp, &str)) 4454 return; 4455 4456 if (halfword) 4457 { 4458 inst.instruction |= HWOFFSET_IMM; 4459 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8; 4460 } 4461 else 4462 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM; 4463#ifndef TE_WINCE 4464 /* PC rel adjust. */ 4465 inst.reloc.exp.X_add_number -= 8; 4466#endif 4467 inst.reloc.pc_rel = 1; 4468 inst.instruction |= (REG_PC << 16); 4469 pre_inc = 1; 4470 } 4471 4472 if (pre_inc && (flags & TRANS_BIT)) 4473 inst.error = _("Pre-increment instruction with translate"); 4474 4475 inst.instruction |= flags | (pre_inc ? PRE_INDEX : 0); 4476 end_of_line (str); 4477 return; 4478} 4479 4480static long 4481reg_list (strp) 4482 char ** strp; 4483{ 4484 char * str = * strp; 4485 long range = 0; 4486 int another_range; 4487 4488 /* We come back here if we get ranges concatenated by '+' or '|'. */ 4489 do 4490 { 4491 another_range = 0; 4492 4493 if (*str == '{') 4494 { 4495 int in_range = 0; 4496 int cur_reg = -1; 4497 4498 str++; 4499 do 4500 { 4501 int reg; 4502 4503 skip_whitespace (str); 4504 4505 if ((reg = reg_required_here (& str, -1)) == FAIL) 4506 return FAIL; 4507 4508 if (in_range) 4509 { 4510 int i; 4511 4512 if (reg <= cur_reg) 4513 { 4514 inst.error = _("Bad range in register list"); 4515 return FAIL; 4516 } 4517 4518 for (i = cur_reg + 1; i < reg; i++) 4519 { 4520 if (range & (1 << i)) 4521 as_tsktsk 4522 (_("Warning: Duplicated register (r%d) in register list"), 4523 i); 4524 else 4525 range |= 1 << i; 4526 } 4527 in_range = 0; 4528 } 4529 4530 if (range & (1 << reg)) 4531 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"), 4532 reg); 4533 else if (reg <= cur_reg) 4534 as_tsktsk (_("Warning: Register range not in ascending order")); 4535 4536 range |= 1 << reg; 4537 cur_reg = reg; 4538 } 4539 while (skip_past_comma (&str) != FAIL 4540 || (in_range = 1, *str++ == '-')); 4541 str--; 4542 skip_whitespace (str); 4543 4544 if (*str++ != '}') 4545 { 4546 inst.error = _("Missing `}'"); 4547 return FAIL; 4548 } 4549 } 4550 else 4551 { 4552 expressionS expr; 4553 4554 if (my_get_expression (&expr, &str)) 4555 return FAIL; 4556 4557 if (expr.X_op == O_constant) 4558 { 4559 if (expr.X_add_number 4560 != (expr.X_add_number & 0x0000ffff)) 4561 { 4562 inst.error = _("invalid register mask"); 4563 return FAIL; 4564 } 4565 4566 if ((range & expr.X_add_number) != 0) 4567 { 4568 int regno = range & expr.X_add_number; 4569 4570 regno &= -regno; 4571 regno = (1 << regno) - 1; 4572 as_tsktsk 4573 (_("Warning: Duplicated register (r%d) in register list"), 4574 regno); 4575 } 4576 4577 range |= expr.X_add_number; 4578 } 4579 else 4580 { 4581 if (inst.reloc.type != 0) 4582 { 4583 inst.error = _("expression too complex"); 4584 return FAIL; 4585 } 4586 4587 memcpy (&inst.reloc.exp, &expr, sizeof (expressionS)); 4588 inst.reloc.type = BFD_RELOC_ARM_MULTI; 4589 inst.reloc.pc_rel = 0; 4590 } 4591 } 4592 4593 skip_whitespace (str); 4594 4595 if (*str == '|' || *str == '+') 4596 { 4597 str++; 4598 another_range = 1; 4599 } 4600 } 4601 while (another_range); 4602 4603 *strp = str; 4604 return range; 4605} 4606 4607static void 4608do_ldmstm (str, flags) 4609 char * str; 4610 unsigned long flags; 4611{ 4612 int base_reg; 4613 long range; 4614 4615 skip_whitespace (str); 4616 4617 if ((base_reg = reg_required_here (&str, 16)) == FAIL) 4618 return; 4619 4620 if (base_reg == REG_PC) 4621 { 4622 inst.error = _("r15 not allowed as base register"); 4623 return; 4624 } 4625 4626 skip_whitespace (str); 4627 4628 if (*str == '!') 4629 { 4630 flags |= WRITE_BACK; 4631 str++; 4632 } 4633 4634 if (skip_past_comma (&str) == FAIL 4635 || (range = reg_list (&str)) == FAIL) 4636 { 4637 if (! inst.error) 4638 inst.error = BAD_ARGS; 4639 return; 4640 } 4641 4642 if (*str == '^') 4643 { 4644 str++; 4645 flags |= LDM_TYPE_2_OR_3; 4646 } 4647 4648 inst.instruction |= flags | range; 4649 end_of_line (str); 4650 return; 4651} 4652 4653static void 4654do_swi (str, flags) 4655 char * str; 4656 unsigned long flags; 4657{ 4658 skip_whitespace (str); 4659 4660 /* Allow optional leading '#'. */ 4661 if (is_immediate_prefix (*str)) 4662 str++; 4663 4664 if (my_get_expression (& inst.reloc.exp, & str)) 4665 return; 4666 4667 inst.reloc.type = BFD_RELOC_ARM_SWI; 4668 inst.reloc.pc_rel = 0; 4669 inst.instruction |= flags; 4670 4671 end_of_line (str); 4672 4673 return; 4674} 4675 4676static void 4677do_swap (str, flags) 4678 char * str; 4679 unsigned long flags; 4680{ 4681 int reg; 4682 4683 skip_whitespace (str); 4684 4685 if ((reg = reg_required_here (&str, 12)) == FAIL) 4686 return; 4687 4688 if (reg == REG_PC) 4689 { 4690 inst.error = _("r15 not allowed in swap"); 4691 return; 4692 } 4693 4694 if (skip_past_comma (&str) == FAIL 4695 || (reg = reg_required_here (&str, 0)) == FAIL) 4696 { 4697 if (!inst.error) 4698 inst.error = BAD_ARGS; 4699 return; 4700 } 4701 4702 if (reg == REG_PC) 4703 { 4704 inst.error = _("r15 not allowed in swap"); 4705 return; 4706 } 4707 4708 if (skip_past_comma (&str) == FAIL 4709 || *str++ != '[') 4710 { 4711 inst.error = BAD_ARGS; 4712 return; 4713 } 4714 4715 skip_whitespace (str); 4716 4717 if ((reg = reg_required_here (&str, 16)) == FAIL) 4718 return; 4719 4720 if (reg == REG_PC) 4721 { 4722 inst.error = BAD_PC; 4723 return; 4724 } 4725 4726 skip_whitespace (str); 4727 4728 if (*str++ != ']') 4729 { 4730 inst.error = _("missing ]"); 4731 return; 4732 } 4733 4734 inst.instruction |= flags; 4735 end_of_line (str); 4736 return; 4737} 4738 4739static void 4740do_branch (str, flags) 4741 char * str; 4742 unsigned long flags ATTRIBUTE_UNUSED; 4743{ 4744 if (my_get_expression (&inst.reloc.exp, &str)) 4745 return; 4746 4747#ifdef OBJ_ELF 4748 { 4749 char * save_in; 4750 4751 /* ScottB: February 5, 1998 - Check to see of PLT32 reloc 4752 required for the instruction. */ 4753 4754 /* arm_parse_reloc () works on input_line_pointer. 4755 We actually want to parse the operands to the branch instruction 4756 passed in 'str'. Save the input pointer and restore it later. */ 4757 save_in = input_line_pointer; 4758 input_line_pointer = str; 4759 if (inst.reloc.exp.X_op == O_symbol 4760 && *str == '(' 4761 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32) 4762 { 4763 inst.reloc.type = BFD_RELOC_ARM_PLT32; 4764 inst.reloc.pc_rel = 0; 4765 /* Modify str to point to after parsed operands, otherwise 4766 end_of_line() will complain about the (PLT) left in str. */ 4767 str = input_line_pointer; 4768 } 4769 else 4770 { 4771 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH; 4772 inst.reloc.pc_rel = 1; 4773 } 4774 input_line_pointer = save_in; 4775 } 4776#else 4777 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH; 4778 inst.reloc.pc_rel = 1; 4779#endif /* OBJ_ELF */ 4780 4781 end_of_line (str); 4782 return; 4783} 4784 4785static void 4786do_bx (str, flags) 4787 char * str; 4788 unsigned long flags ATTRIBUTE_UNUSED; 4789{ 4790 int reg; 4791 4792 skip_whitespace (str); 4793 4794 if ((reg = reg_required_here (&str, 0)) == FAIL) 4795 { 4796 inst.error = BAD_ARGS; 4797 return; 4798 } 4799 4800 /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */ 4801 if (reg == REG_PC) 4802 as_tsktsk (_("Use of r15 in bx in ARM mode is not really useful")); 4803 4804 end_of_line (str); 4805} 4806 4807static void 4808do_cdp (str, flags) 4809 char * str; 4810 unsigned long flags ATTRIBUTE_UNUSED; 4811{ 4812 /* Co-processor data operation. 4813 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */ 4814 skip_whitespace (str); 4815 4816 if (co_proc_number (&str) == FAIL) 4817 { 4818 if (!inst.error) 4819 inst.error = BAD_ARGS; 4820 return; 4821 } 4822 4823 if (skip_past_comma (&str) == FAIL 4824 || cp_opc_expr (&str, 20,4) == FAIL) 4825 { 4826 if (!inst.error) 4827 inst.error = BAD_ARGS; 4828 return; 4829 } 4830 4831 if (skip_past_comma (&str) == FAIL 4832 || cp_reg_required_here (&str, 12) == FAIL) 4833 { 4834 if (!inst.error) 4835 inst.error = BAD_ARGS; 4836 return; 4837 } 4838 4839 if (skip_past_comma (&str) == FAIL 4840 || cp_reg_required_here (&str, 16) == FAIL) 4841 { 4842 if (!inst.error) 4843 inst.error = BAD_ARGS; 4844 return; 4845 } 4846 4847 if (skip_past_comma (&str) == FAIL 4848 || cp_reg_required_here (&str, 0) == FAIL) 4849 { 4850 if (!inst.error) 4851 inst.error = BAD_ARGS; 4852 return; 4853 } 4854 4855 if (skip_past_comma (&str) == SUCCESS) 4856 { 4857 if (cp_opc_expr (&str, 5, 3) == FAIL) 4858 { 4859 if (!inst.error) 4860 inst.error = BAD_ARGS; 4861 return; 4862 } 4863 } 4864 4865 end_of_line (str); 4866 return; 4867} 4868 4869static void 4870do_lstc (str, flags) 4871 char * str; 4872 unsigned long flags; 4873{ 4874 /* Co-processor register load/store. 4875 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */ 4876 4877 skip_whitespace (str); 4878 4879 if (co_proc_number (&str) == FAIL) 4880 { 4881 if (!inst.error) 4882 inst.error = BAD_ARGS; 4883 return; 4884 } 4885 4886 if (skip_past_comma (&str) == FAIL 4887 || cp_reg_required_here (&str, 12) == FAIL) 4888 { 4889 if (!inst.error) 4890 inst.error = BAD_ARGS; 4891 return; 4892 } 4893 4894 if (skip_past_comma (&str) == FAIL 4895 || cp_address_required_here (&str) == FAIL) 4896 { 4897 if (! inst.error) 4898 inst.error = BAD_ARGS; 4899 return; 4900 } 4901 4902 inst.instruction |= flags; 4903 end_of_line (str); 4904 return; 4905} 4906 4907static void 4908do_co_reg (str, flags) 4909 char * str; 4910 unsigned long flags; 4911{ 4912 /* Co-processor register transfer. 4913 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */ 4914 4915 skip_whitespace (str); 4916 4917 if (co_proc_number (&str) == FAIL) 4918 { 4919 if (!inst.error) 4920 inst.error = BAD_ARGS; 4921 return; 4922 } 4923 4924 if (skip_past_comma (&str) == FAIL 4925 || cp_opc_expr (&str, 21, 3) == FAIL) 4926 { 4927 if (!inst.error) 4928 inst.error = BAD_ARGS; 4929 return; 4930 } 4931 4932 if (skip_past_comma (&str) == FAIL 4933 || reg_required_here (&str, 12) == FAIL) 4934 { 4935 if (!inst.error) 4936 inst.error = BAD_ARGS; 4937 return; 4938 } 4939 4940 if (skip_past_comma (&str) == FAIL 4941 || cp_reg_required_here (&str, 16) == FAIL) 4942 { 4943 if (!inst.error) 4944 inst.error = BAD_ARGS; 4945 return; 4946 } 4947 4948 if (skip_past_comma (&str) == FAIL 4949 || cp_reg_required_here (&str, 0) == FAIL) 4950 { 4951 if (!inst.error) 4952 inst.error = BAD_ARGS; 4953 return; 4954 } 4955 4956 if (skip_past_comma (&str) == SUCCESS) 4957 { 4958 if (cp_opc_expr (&str, 5, 3) == FAIL) 4959 { 4960 if (!inst.error) 4961 inst.error = BAD_ARGS; 4962 return; 4963 } 4964 } 4965 if (flags) 4966 { 4967 inst.error = BAD_COND; 4968 } 4969 4970 end_of_line (str); 4971 return; 4972} 4973 4974static void 4975do_fp_ctrl (str, flags) 4976 char * str; 4977 unsigned long flags ATTRIBUTE_UNUSED; 4978{ 4979 /* FP control registers. 4980 Format: <WFS|RFS|WFC|RFC>{cond} Rn */ 4981 4982 skip_whitespace (str); 4983 4984 if (reg_required_here (&str, 12) == FAIL) 4985 { 4986 if (!inst.error) 4987 inst.error = BAD_ARGS; 4988 return; 4989 } 4990 4991 end_of_line (str); 4992 return; 4993} 4994 4995static void 4996do_fp_ldst (str, flags) 4997 char * str; 4998 unsigned long flags ATTRIBUTE_UNUSED; 4999{ 5000 skip_whitespace (str); 5001 5002 switch (inst.suffix) 5003 { 5004 case SUFF_S: 5005 break; 5006 case SUFF_D: 5007 inst.instruction |= CP_T_X; 5008 break; 5009 case SUFF_E: 5010 inst.instruction |= CP_T_Y; 5011 break; 5012 case SUFF_P: 5013 inst.instruction |= CP_T_X | CP_T_Y; 5014 break; 5015 default: 5016 abort (); 5017 } 5018 5019 if (fp_reg_required_here (&str, 12) == FAIL) 5020 { 5021 if (!inst.error) 5022 inst.error = BAD_ARGS; 5023 return; 5024 } 5025 5026 if (skip_past_comma (&str) == FAIL 5027 || cp_address_required_here (&str) == FAIL) 5028 { 5029 if (!inst.error) 5030 inst.error = BAD_ARGS; 5031 return; 5032 } 5033 5034 end_of_line (str); 5035} 5036 5037static void 5038do_fp_ldmstm (str, flags) 5039 char * str; 5040 unsigned long flags; 5041{ 5042 int num_regs; 5043 5044 skip_whitespace (str); 5045 5046 if (fp_reg_required_here (&str, 12) == FAIL) 5047 { 5048 if (! inst.error) 5049 inst.error = BAD_ARGS; 5050 return; 5051 } 5052 5053 /* Get Number of registers to transfer. */ 5054 if (skip_past_comma (&str) == FAIL 5055 || my_get_expression (&inst.reloc.exp, &str)) 5056 { 5057 if (! inst.error) 5058 inst.error = _("constant expression expected"); 5059 return; 5060 } 5061 5062 if (inst.reloc.exp.X_op != O_constant) 5063 { 5064 inst.error = _("Constant value required for number of registers"); 5065 return; 5066 } 5067 5068 num_regs = inst.reloc.exp.X_add_number; 5069 5070 if (num_regs < 1 || num_regs > 4) 5071 { 5072 inst.error = _("number of registers must be in the range [1:4]"); 5073 return; 5074 } 5075 5076 switch (num_regs) 5077 { 5078 case 1: 5079 inst.instruction |= CP_T_X; 5080 break; 5081 case 2: 5082 inst.instruction |= CP_T_Y; 5083 break; 5084 case 3: 5085 inst.instruction |= CP_T_Y | CP_T_X; 5086 break; 5087 case 4: 5088 break; 5089 default: 5090 abort (); 5091 } 5092 5093 if (flags) 5094 { 5095 int reg; 5096 int write_back; 5097 int offset; 5098 5099 /* The instruction specified "ea" or "fd", so we can only accept 5100 [Rn]{!}. The instruction does not really support stacking or 5101 unstacking, so we have to emulate these by setting appropriate 5102 bits and offsets. */ 5103 if (skip_past_comma (&str) == FAIL 5104 || *str != '[') 5105 { 5106 if (! inst.error) 5107 inst.error = BAD_ARGS; 5108 return; 5109 } 5110 5111 str++; 5112 skip_whitespace (str); 5113 5114 if ((reg = reg_required_here (&str, 16)) == FAIL) 5115 return; 5116 5117 skip_whitespace (str); 5118 5119 if (*str != ']') 5120 { 5121 inst.error = BAD_ARGS; 5122 return; 5123 } 5124 5125 str++; 5126 if (*str == '!') 5127 { 5128 write_back = 1; 5129 str++; 5130 if (reg == REG_PC) 5131 { 5132 inst.error = 5133 _("R15 not allowed as base register with write-back"); 5134 return; 5135 } 5136 } 5137 else 5138 write_back = 0; 5139 5140 if (flags & CP_T_Pre) 5141 { 5142 /* Pre-decrement. */ 5143 offset = 3 * num_regs; 5144 if (write_back) 5145 flags |= CP_T_WB; 5146 } 5147 else 5148 { 5149 /* Post-increment. */ 5150 if (write_back) 5151 { 5152 flags |= CP_T_WB; 5153 offset = 3 * num_regs; 5154 } 5155 else 5156 { 5157 /* No write-back, so convert this into a standard pre-increment 5158 instruction -- aesthetically more pleasing. */ 5159 flags = CP_T_Pre | CP_T_UD; 5160 offset = 0; 5161 } 5162 } 5163 5164 inst.instruction |= flags | offset; 5165 } 5166 else if (skip_past_comma (&str) == FAIL 5167 || cp_address_required_here (&str) == FAIL) 5168 { 5169 if (! inst.error) 5170 inst.error = BAD_ARGS; 5171 return; 5172 } 5173 5174 end_of_line (str); 5175} 5176 5177static void 5178do_fp_dyadic (str, flags) 5179 char * str; 5180 unsigned long flags; 5181{ 5182 skip_whitespace (str); 5183 5184 switch (inst.suffix) 5185 { 5186 case SUFF_S: 5187 break; 5188 case SUFF_D: 5189 inst.instruction |= 0x00000080; 5190 break; 5191 case SUFF_E: 5192 inst.instruction |= 0x00080000; 5193 break; 5194 default: 5195 abort (); 5196 } 5197 5198 if (fp_reg_required_here (&str, 12) == FAIL) 5199 { 5200 if (! inst.error) 5201 inst.error = BAD_ARGS; 5202 return; 5203 } 5204 5205 if (skip_past_comma (&str) == FAIL 5206 || fp_reg_required_here (&str, 16) == FAIL) 5207 { 5208 if (! inst.error) 5209 inst.error = BAD_ARGS; 5210 return; 5211 } 5212 5213 if (skip_past_comma (&str) == FAIL 5214 || fp_op2 (&str) == FAIL) 5215 { 5216 if (! inst.error) 5217 inst.error = BAD_ARGS; 5218 return; 5219 } 5220 5221 inst.instruction |= flags; 5222 end_of_line (str); 5223 return; 5224} 5225 5226static void 5227do_fp_monadic (str, flags) 5228 char * str; 5229 unsigned long flags; 5230{ 5231 skip_whitespace (str); 5232 5233 switch (inst.suffix) 5234 { 5235 case SUFF_S: 5236 break; 5237 case SUFF_D: 5238 inst.instruction |= 0x00000080; 5239 break; 5240 case SUFF_E: 5241 inst.instruction |= 0x00080000; 5242 break; 5243 default: 5244 abort (); 5245 } 5246 5247 if (fp_reg_required_here (&str, 12) == FAIL) 5248 { 5249 if (! inst.error) 5250 inst.error = BAD_ARGS; 5251 return; 5252 } 5253 5254 if (skip_past_comma (&str) == FAIL 5255 || fp_op2 (&str) == FAIL) 5256 { 5257 if (! inst.error) 5258 inst.error = BAD_ARGS; 5259 return; 5260 } 5261 5262 inst.instruction |= flags; 5263 end_of_line (str); 5264 return; 5265} 5266 5267static void 5268do_fp_cmp (str, flags) 5269 char * str; 5270 unsigned long flags; 5271{ 5272 skip_whitespace (str); 5273 5274 if (fp_reg_required_here (&str, 16) == FAIL) 5275 { 5276 if (! inst.error) 5277 inst.error = BAD_ARGS; 5278 return; 5279 } 5280 5281 if (skip_past_comma (&str) == FAIL 5282 || fp_op2 (&str) == FAIL) 5283 { 5284 if (! inst.error) 5285 inst.error = BAD_ARGS; 5286 return; 5287 } 5288 5289 inst.instruction |= flags; 5290 end_of_line (str); 5291 return; 5292} 5293 5294static void 5295do_fp_from_reg (str, flags) 5296 char * str; 5297 unsigned long flags; 5298{ 5299 skip_whitespace (str); 5300 5301 switch (inst.suffix) 5302 { 5303 case SUFF_S: 5304 break; 5305 case SUFF_D: 5306 inst.instruction |= 0x00000080; 5307 break; 5308 case SUFF_E: 5309 inst.instruction |= 0x00080000; 5310 break; 5311 default: 5312 abort (); 5313 } 5314 5315 if (fp_reg_required_here (&str, 16) == FAIL) 5316 { 5317 if (! inst.error) 5318 inst.error = BAD_ARGS; 5319 return; 5320 } 5321 5322 if (skip_past_comma (&str) == FAIL 5323 || reg_required_here (&str, 12) == FAIL) 5324 { 5325 if (! inst.error) 5326 inst.error = BAD_ARGS; 5327 return; 5328 } 5329 5330 inst.instruction |= flags; 5331 end_of_line (str); 5332 return; 5333} 5334 5335static void 5336do_fp_to_reg (str, flags) 5337 char * str; 5338 unsigned long flags; 5339{ 5340 skip_whitespace (str); 5341 5342 if (reg_required_here (&str, 12) == FAIL) 5343 return; 5344 5345 if (skip_past_comma (&str) == FAIL 5346 || fp_reg_required_here (&str, 0) == FAIL) 5347 { 5348 if (! inst.error) 5349 inst.error = BAD_ARGS; 5350 return; 5351 } 5352 5353 inst.instruction |= flags; 5354 end_of_line (str); 5355 return; 5356} 5357 5358/* Thumb specific routines. */ 5359 5360/* Parse and validate that a register is of the right form, this saves 5361 repeated checking of this information in many similar cases. 5362 Unlike the 32-bit case we do not insert the register into the opcode 5363 here, since the position is often unknown until the full instruction 5364 has been parsed. */ 5365 5366static int 5367thumb_reg (strp, hi_lo) 5368 char ** strp; 5369 int hi_lo; 5370{ 5371 int reg; 5372 5373 if ((reg = reg_required_here (strp, -1)) == FAIL) 5374 return FAIL; 5375 5376 switch (hi_lo) 5377 { 5378 case THUMB_REG_LO: 5379 if (reg > 7) 5380 { 5381 inst.error = _("lo register required"); 5382 return FAIL; 5383 } 5384 break; 5385 5386 case THUMB_REG_HI: 5387 if (reg < 8) 5388 { 5389 inst.error = _("hi register required"); 5390 return FAIL; 5391 } 5392 break; 5393 5394 default: 5395 break; 5396 } 5397 5398 return reg; 5399} 5400 5401/* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode 5402 was SUB. */ 5403 5404static void 5405thumb_add_sub (str, subtract) 5406 char * str; 5407 int subtract; 5408{ 5409 int Rd, Rs, Rn = FAIL; 5410 5411 skip_whitespace (str); 5412 5413 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL 5414 || skip_past_comma (&str) == FAIL) 5415 { 5416 if (! inst.error) 5417 inst.error = BAD_ARGS; 5418 return; 5419 } 5420 5421 if (is_immediate_prefix (*str)) 5422 { 5423 Rs = Rd; 5424 str++; 5425 if (my_get_expression (&inst.reloc.exp, &str)) 5426 return; 5427 } 5428 else 5429 { 5430 if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL) 5431 return; 5432 5433 if (skip_past_comma (&str) == FAIL) 5434 { 5435 /* Two operand format, shuffle the registers 5436 and pretend there are 3. */ 5437 Rn = Rs; 5438 Rs = Rd; 5439 } 5440 else if (is_immediate_prefix (*str)) 5441 { 5442 str++; 5443 if (my_get_expression (&inst.reloc.exp, &str)) 5444 return; 5445 } 5446 else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL) 5447 return; 5448 } 5449 5450 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL; 5451 for the latter case, EXPR contains the immediate that was found. */ 5452 if (Rn != FAIL) 5453 { 5454 /* All register format. */ 5455 if (Rd > 7 || Rs > 7 || Rn > 7) 5456 { 5457 if (Rs != Rd) 5458 { 5459 inst.error = _("dest and source1 must be the same register"); 5460 return; 5461 } 5462 5463 /* Can't do this for SUB. */ 5464 if (subtract) 5465 { 5466 inst.error = _("subtract valid only on lo regs"); 5467 return; 5468 } 5469 5470 inst.instruction = (T_OPCODE_ADD_HI 5471 | (Rd > 7 ? THUMB_H1 : 0) 5472 | (Rn > 7 ? THUMB_H2 : 0)); 5473 inst.instruction |= (Rd & 7) | ((Rn & 7) << 3); 5474 } 5475 else 5476 { 5477 inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3; 5478 inst.instruction |= Rd | (Rs << 3) | (Rn << 6); 5479 } 5480 } 5481 else 5482 { 5483 /* Immediate expression, now things start to get nasty. */ 5484 5485 /* First deal with HI regs, only very restricted cases allowed: 5486 Adjusting SP, and using PC or SP to get an address. */ 5487 if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP)) 5488 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC)) 5489 { 5490 inst.error = _("invalid Hi register with immediate"); 5491 return; 5492 } 5493 5494 if (inst.reloc.exp.X_op != O_constant) 5495 { 5496 /* Value isn't known yet, all we can do is store all the fragments 5497 we know about in the instruction and let the reloc hacking 5498 work it all out. */ 5499 inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs; 5500 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD; 5501 } 5502 else 5503 { 5504 int offset = inst.reloc.exp.X_add_number; 5505 5506 if (subtract) 5507 offset = -offset; 5508 5509 if (offset < 0) 5510 { 5511 offset = -offset; 5512 subtract = 1; 5513 5514 /* Quick check, in case offset is MIN_INT. */ 5515 if (offset < 0) 5516 { 5517 inst.error = _("immediate value out of range"); 5518 return; 5519 } 5520 } 5521 else 5522 subtract = 0; 5523 5524 if (Rd == REG_SP) 5525 { 5526 if (offset & ~0x1fc) 5527 { 5528 inst.error = _("invalid immediate value for stack adjust"); 5529 return; 5530 } 5531 inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST; 5532 inst.instruction |= offset >> 2; 5533 } 5534 else if (Rs == REG_PC || Rs == REG_SP) 5535 { 5536 if (subtract 5537 || (offset & ~0x3fc)) 5538 { 5539 inst.error = _("invalid immediate for address calculation"); 5540 return; 5541 } 5542 inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC 5543 : T_OPCODE_ADD_SP); 5544 inst.instruction |= (Rd << 8) | (offset >> 2); 5545 } 5546 else if (Rs == Rd) 5547 { 5548 if (offset & ~0xff) 5549 { 5550 inst.error = _("immediate value out of range"); 5551 return; 5552 } 5553 inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8; 5554 inst.instruction |= (Rd << 8) | offset; 5555 } 5556 else 5557 { 5558 if (offset & ~0x7) 5559 { 5560 inst.error = _("immediate value out of range"); 5561 return; 5562 } 5563 inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3; 5564 inst.instruction |= Rd | (Rs << 3) | (offset << 6); 5565 } 5566 } 5567 } 5568 5569 end_of_line (str); 5570} 5571 5572static void 5573thumb_shift (str, shift) 5574 char * str; 5575 int shift; 5576{ 5577 int Rd, Rs, Rn = FAIL; 5578 5579 skip_whitespace (str); 5580 5581 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL 5582 || skip_past_comma (&str) == FAIL) 5583 { 5584 if (! inst.error) 5585 inst.error = BAD_ARGS; 5586 return; 5587 } 5588 5589 if (is_immediate_prefix (*str)) 5590 { 5591 /* Two operand immediate format, set Rs to Rd. */ 5592 Rs = Rd; 5593 str ++; 5594 if (my_get_expression (&inst.reloc.exp, &str)) 5595 return; 5596 } 5597 else 5598 { 5599 if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL) 5600 return; 5601 5602 if (skip_past_comma (&str) == FAIL) 5603 { 5604 /* Two operand format, shuffle the registers 5605 and pretend there are 3. */ 5606 Rn = Rs; 5607 Rs = Rd; 5608 } 5609 else if (is_immediate_prefix (*str)) 5610 { 5611 str++; 5612 if (my_get_expression (&inst.reloc.exp, &str)) 5613 return; 5614 } 5615 else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL) 5616 return; 5617 } 5618 5619 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL; 5620 for the latter case, EXPR contains the immediate that was found. */ 5621 5622 if (Rn != FAIL) 5623 { 5624 if (Rs != Rd) 5625 { 5626 inst.error = _("source1 and dest must be same register"); 5627 return; 5628 } 5629 5630 switch (shift) 5631 { 5632 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break; 5633 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break; 5634 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break; 5635 } 5636 5637 inst.instruction |= Rd | (Rn << 3); 5638 } 5639 else 5640 { 5641 switch (shift) 5642 { 5643 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break; 5644 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break; 5645 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break; 5646 } 5647 5648 if (inst.reloc.exp.X_op != O_constant) 5649 { 5650 /* Value isn't known yet, create a dummy reloc and let reloc 5651 hacking fix it up. */ 5652 inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT; 5653 } 5654 else 5655 { 5656 unsigned shift_value = inst.reloc.exp.X_add_number; 5657 5658 if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL)) 5659 { 5660 inst.error = _("Invalid immediate for shift"); 5661 return; 5662 } 5663 5664 /* Shifts of zero are handled by converting to LSL. */ 5665 if (shift_value == 0) 5666 inst.instruction = T_OPCODE_LSL_I; 5667 5668 /* Shifts of 32 are encoded as a shift of zero. */ 5669 if (shift_value == 32) 5670 shift_value = 0; 5671 5672 inst.instruction |= shift_value << 6; 5673 } 5674 5675 inst.instruction |= Rd | (Rs << 3); 5676 } 5677 5678 end_of_line (str); 5679} 5680 5681static void 5682thumb_mov_compare (str, move) 5683 char * str; 5684 int move; 5685{ 5686 int Rd, Rs = FAIL; 5687 5688 skip_whitespace (str); 5689 5690 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL 5691 || skip_past_comma (&str) == FAIL) 5692 { 5693 if (! inst.error) 5694 inst.error = BAD_ARGS; 5695 return; 5696 } 5697 5698 if (is_immediate_prefix (*str)) 5699 { 5700 str++; 5701 if (my_get_expression (&inst.reloc.exp, &str)) 5702 return; 5703 } 5704 else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL) 5705 return; 5706 5707 if (Rs != FAIL) 5708 { 5709 if (Rs < 8 && Rd < 8) 5710 { 5711 if (move == THUMB_MOVE) 5712 /* A move of two lowregs is encoded as ADD Rd, Rs, #0 5713 since a MOV instruction produces unpredictable results. */ 5714 inst.instruction = T_OPCODE_ADD_I3; 5715 else 5716 inst.instruction = T_OPCODE_CMP_LR; 5717 inst.instruction |= Rd | (Rs << 3); 5718 } 5719 else 5720 { 5721 if (move == THUMB_MOVE) 5722 inst.instruction = T_OPCODE_MOV_HR; 5723 else 5724 inst.instruction = T_OPCODE_CMP_HR; 5725 5726 if (Rd > 7) 5727 inst.instruction |= THUMB_H1; 5728 5729 if (Rs > 7) 5730 inst.instruction |= THUMB_H2; 5731 5732 inst.instruction |= (Rd & 7) | ((Rs & 7) << 3); 5733 } 5734 } 5735 else 5736 { 5737 if (Rd > 7) 5738 { 5739 inst.error = _("only lo regs allowed with immediate"); 5740 return; 5741 } 5742 5743 if (move == THUMB_MOVE) 5744 inst.instruction = T_OPCODE_MOV_I8; 5745 else 5746 inst.instruction = T_OPCODE_CMP_I8; 5747 5748 inst.instruction |= Rd << 8; 5749 5750 if (inst.reloc.exp.X_op != O_constant) 5751 inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM; 5752 else 5753 { 5754 unsigned value = inst.reloc.exp.X_add_number; 5755 5756 if (value > 255) 5757 { 5758 inst.error = _("invalid immediate"); 5759 return; 5760 } 5761 5762 inst.instruction |= value; 5763 } 5764 } 5765 5766 end_of_line (str); 5767} 5768 5769static void 5770thumb_load_store (str, load_store, size) 5771 char * str; 5772 int load_store; 5773 int size; 5774{ 5775 int Rd, Rb, Ro = FAIL; 5776 5777 skip_whitespace (str); 5778 5779 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL 5780 || skip_past_comma (&str) == FAIL) 5781 { 5782 if (! inst.error) 5783 inst.error = BAD_ARGS; 5784 return; 5785 } 5786 5787 if (*str == '[') 5788 { 5789 str++; 5790 if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL) 5791 return; 5792 5793 if (skip_past_comma (&str) != FAIL) 5794 { 5795 if (is_immediate_prefix (*str)) 5796 { 5797 str++; 5798 if (my_get_expression (&inst.reloc.exp, &str)) 5799 return; 5800 } 5801 else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL) 5802 return; 5803 } 5804 else 5805 { 5806 inst.reloc.exp.X_op = O_constant; 5807 inst.reloc.exp.X_add_number = 0; 5808 } 5809 5810 if (*str != ']') 5811 { 5812 inst.error = _("expected ']'"); 5813 return; 5814 } 5815 str++; 5816 } 5817 else if (*str == '=') 5818 { 5819 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */ 5820 str++; 5821 5822 skip_whitespace (str); 5823 5824 if (my_get_expression (& inst.reloc.exp, & str)) 5825 return; 5826 5827 end_of_line (str); 5828 5829 if ( inst.reloc.exp.X_op != O_constant 5830 && inst.reloc.exp.X_op != O_symbol) 5831 { 5832 inst.error = "Constant expression expected"; 5833 return; 5834 } 5835 5836 if (inst.reloc.exp.X_op == O_constant 5837 && ((inst.reloc.exp.X_add_number & ~0xFF) == 0)) 5838 { 5839 /* This can be done with a mov instruction. */ 5840 5841 inst.instruction = T_OPCODE_MOV_I8 | (Rd << 8); 5842 inst.instruction |= inst.reloc.exp.X_add_number; 5843 return; 5844 } 5845 5846 /* Insert into literal pool. */ 5847 if (add_to_lit_pool () == FAIL) 5848 { 5849 if (!inst.error) 5850 inst.error = "literal pool insertion failed"; 5851 return; 5852 } 5853 5854 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET; 5855 inst.reloc.pc_rel = 1; 5856 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8); 5857 /* Adjust ARM pipeline offset to Thumb. */ 5858 inst.reloc.exp.X_add_number += 4; 5859 5860 return; 5861 } 5862 else 5863 { 5864 if (my_get_expression (&inst.reloc.exp, &str)) 5865 return; 5866 5867 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8); 5868 inst.reloc.pc_rel = 1; 5869 inst.reloc.exp.X_add_number -= 4; /* Pipeline offset. */ 5870 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET; 5871 end_of_line (str); 5872 return; 5873 } 5874 5875 if (Rb == REG_PC || Rb == REG_SP) 5876 { 5877 if (size != THUMB_WORD) 5878 { 5879 inst.error = _("byte or halfword not valid for base register"); 5880 return; 5881 } 5882 else if (Rb == REG_PC && load_store != THUMB_LOAD) 5883 { 5884 inst.error = _("R15 based store not allowed"); 5885 return; 5886 } 5887 else if (Ro != FAIL) 5888 { 5889 inst.error = _("Invalid base register for register offset"); 5890 return; 5891 } 5892 5893 if (Rb == REG_PC) 5894 inst.instruction = T_OPCODE_LDR_PC; 5895 else if (load_store == THUMB_LOAD) 5896 inst.instruction = T_OPCODE_LDR_SP; 5897 else 5898 inst.instruction = T_OPCODE_STR_SP; 5899 5900 inst.instruction |= Rd << 8; 5901 if (inst.reloc.exp.X_op == O_constant) 5902 { 5903 unsigned offset = inst.reloc.exp.X_add_number; 5904 5905 if (offset & ~0x3fc) 5906 { 5907 inst.error = _("invalid offset"); 5908 return; 5909 } 5910 5911 inst.instruction |= offset >> 2; 5912 } 5913 else 5914 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET; 5915 } 5916 else if (Rb > 7) 5917 { 5918 inst.error = _("invalid base register in load/store"); 5919 return; 5920 } 5921 else if (Ro == FAIL) 5922 { 5923 /* Immediate offset. */ 5924 if (size == THUMB_WORD) 5925 inst.instruction = (load_store == THUMB_LOAD 5926 ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW); 5927 else if (size == THUMB_HALFWORD) 5928 inst.instruction = (load_store == THUMB_LOAD 5929 ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH); 5930 else 5931 inst.instruction = (load_store == THUMB_LOAD 5932 ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB); 5933 5934 inst.instruction |= Rd | (Rb << 3); 5935 5936 if (inst.reloc.exp.X_op == O_constant) 5937 { 5938 unsigned offset = inst.reloc.exp.X_add_number; 5939 5940 if (offset & ~(0x1f << size)) 5941 { 5942 inst.error = _("Invalid offset"); 5943 return; 5944 } 5945 inst.instruction |= (offset >> size) << 6; 5946 } 5947 else 5948 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET; 5949 } 5950 else 5951 { 5952 /* Register offset. */ 5953 if (size == THUMB_WORD) 5954 inst.instruction = (load_store == THUMB_LOAD 5955 ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW); 5956 else if (size == THUMB_HALFWORD) 5957 inst.instruction = (load_store == THUMB_LOAD 5958 ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH); 5959 else 5960 inst.instruction = (load_store == THUMB_LOAD 5961 ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB); 5962 5963 inst.instruction |= Rd | (Rb << 3) | (Ro << 6); 5964 } 5965 5966 end_of_line (str); 5967} 5968 5969static void 5970do_t_nop (str) 5971 char * str; 5972{ 5973 /* Do nothing. */ 5974 end_of_line (str); 5975 return; 5976} 5977 5978/* Handle the Format 4 instructions that do not have equivalents in other 5979 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL, 5980 BIC and MVN. */ 5981 5982static void 5983do_t_arit (str) 5984 char * str; 5985{ 5986 int Rd, Rs, Rn; 5987 5988 skip_whitespace (str); 5989 5990 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL 5991 || skip_past_comma (&str) == FAIL 5992 || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL) 5993 { 5994 inst.error = BAD_ARGS; 5995 return; 5996 } 5997 5998 if (skip_past_comma (&str) != FAIL) 5999 { 6000 /* Three operand format not allowed for TST, CMN, NEG and MVN. 6001 (It isn't allowed for CMP either, but that isn't handled by this 6002 function.) */ 6003 if (inst.instruction == T_OPCODE_TST 6004 || inst.instruction == T_OPCODE_CMN 6005 || inst.instruction == T_OPCODE_NEG 6006 || inst.instruction == T_OPCODE_MVN) 6007 { 6008 inst.error = BAD_ARGS; 6009 return; 6010 } 6011 6012 if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL) 6013 return; 6014 6015 if (Rs != Rd) 6016 { 6017 inst.error = _("dest and source1 one must be the same register"); 6018 return; 6019 } 6020 Rs = Rn; 6021 } 6022 6023 if (inst.instruction == T_OPCODE_MUL 6024 && Rs == Rd) 6025 as_tsktsk (_("Rs and Rd must be different in MUL")); 6026 6027 inst.instruction |= Rd | (Rs << 3); 6028 end_of_line (str); 6029} 6030 6031static void 6032do_t_add (str) 6033 char * str; 6034{ 6035 thumb_add_sub (str, 0); 6036} 6037 6038static void 6039do_t_asr (str) 6040 char * str; 6041{ 6042 thumb_shift (str, THUMB_ASR); 6043} 6044 6045static void 6046do_t_branch9 (str) 6047 char * str; 6048{ 6049 if (my_get_expression (&inst.reloc.exp, &str)) 6050 return; 6051 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9; 6052 inst.reloc.pc_rel = 1; 6053 end_of_line (str); 6054} 6055 6056static void 6057do_t_branch12 (str) 6058 char * str; 6059{ 6060 if (my_get_expression (&inst.reloc.exp, &str)) 6061 return; 6062 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12; 6063 inst.reloc.pc_rel = 1; 6064 end_of_line (str); 6065} 6066 6067/* Find the real, Thumb encoded start of a Thumb function. */ 6068 6069static symbolS * 6070find_real_start (symbolP) 6071 symbolS * symbolP; 6072{ 6073 char * real_start; 6074 const char * name = S_GET_NAME (symbolP); 6075 symbolS * new_target; 6076 6077 /* This definiton must agree with the one in gcc/config/arm/thumb.c. */ 6078#define STUB_NAME ".real_start_of" 6079 6080 if (name == NULL) 6081 abort (); 6082 6083 /* Names that start with '.' are local labels, not function entry points. 6084 The compiler may generate BL instructions to these labels because it 6085 needs to perform a branch to a far away location. */ 6086 if (name[0] == '.') 6087 return symbolP; 6088 6089 real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1); 6090 sprintf (real_start, "%s%s", STUB_NAME, name); 6091 6092 new_target = symbol_find (real_start); 6093 6094 if (new_target == NULL) 6095 { 6096 as_warn ("Failed to find real start of function: %s\n", name); 6097 new_target = symbolP; 6098 } 6099 6100 free (real_start); 6101 6102 return new_target; 6103} 6104 6105static void 6106do_t_branch23 (str) 6107 char * str; 6108{ 6109 if (my_get_expression (& inst.reloc.exp, & str)) 6110 return; 6111 6112 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23; 6113 inst.reloc.pc_rel = 1; 6114 end_of_line (str); 6115 6116 /* If the destination of the branch is a defined symbol which does not have 6117 the THUMB_FUNC attribute, then we must be calling a function which has 6118 the (interfacearm) attribute. We look for the Thumb entry point to that 6119 function and change the branch to refer to that function instead. */ 6120 if ( inst.reloc.exp.X_op == O_symbol 6121 && inst.reloc.exp.X_add_symbol != NULL 6122 && S_IS_DEFINED (inst.reloc.exp.X_add_symbol) 6123 && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol)) 6124 inst.reloc.exp.X_add_symbol = 6125 find_real_start (inst.reloc.exp.X_add_symbol); 6126} 6127 6128static void 6129do_t_bx (str) 6130 char * str; 6131{ 6132 int reg; 6133 6134 skip_whitespace (str); 6135 6136 if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL) 6137 return; 6138 6139 /* This sets THUMB_H2 from the top bit of reg. */ 6140 inst.instruction |= reg << 3; 6141 6142 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc 6143 should cause the alignment to be checked once it is known. This is 6144 because BX PC only works if the instruction is word aligned. */ 6145 6146 end_of_line (str); 6147} 6148 6149static void 6150do_t_compare (str) 6151 char * str; 6152{ 6153 thumb_mov_compare (str, THUMB_COMPARE); 6154} 6155 6156static void 6157do_t_ldmstm (str) 6158 char * str; 6159{ 6160 int Rb; 6161 long range; 6162 6163 skip_whitespace (str); 6164 6165 if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL) 6166 return; 6167 6168 if (*str != '!') 6169 as_warn (_("Inserted missing '!': load/store multiple always writes back base register")); 6170 else 6171 str++; 6172 6173 if (skip_past_comma (&str) == FAIL 6174 || (range = reg_list (&str)) == FAIL) 6175 { 6176 if (! inst.error) 6177 inst.error = BAD_ARGS; 6178 return; 6179 } 6180 6181 if (inst.reloc.type != BFD_RELOC_NONE) 6182 { 6183 /* This really doesn't seem worth it. */ 6184 inst.reloc.type = BFD_RELOC_NONE; 6185 inst.error = _("Expression too complex"); 6186 return; 6187 } 6188 6189 if (range & ~0xff) 6190 { 6191 inst.error = _("only lo-regs valid in load/store multiple"); 6192 return; 6193 } 6194 6195 inst.instruction |= (Rb << 8) | range; 6196 end_of_line (str); 6197} 6198 6199static void 6200do_t_ldr (str) 6201 char * str; 6202{ 6203 thumb_load_store (str, THUMB_LOAD, THUMB_WORD); 6204} 6205 6206static void 6207do_t_ldrb (str) 6208 char * str; 6209{ 6210 thumb_load_store (str, THUMB_LOAD, THUMB_BYTE); 6211} 6212 6213static void 6214do_t_ldrh (str) 6215 char * str; 6216{ 6217 thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD); 6218} 6219 6220static void 6221do_t_lds (str) 6222 char * str; 6223{ 6224 int Rd, Rb, Ro; 6225 6226 skip_whitespace (str); 6227 6228 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL 6229 || skip_past_comma (&str) == FAIL 6230 || *str++ != '[' 6231 || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL 6232 || skip_past_comma (&str) == FAIL 6233 || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL 6234 || *str++ != ']') 6235 { 6236 if (! inst.error) 6237 inst.error = _("Syntax: ldrs[b] Rd, [Rb, Ro]"); 6238 return; 6239 } 6240 6241 inst.instruction |= Rd | (Rb << 3) | (Ro << 6); 6242 end_of_line (str); 6243} 6244 6245static void 6246do_t_lsl (str) 6247 char * str; 6248{ 6249 thumb_shift (str, THUMB_LSL); 6250} 6251 6252static void 6253do_t_lsr (str) 6254 char * str; 6255{ 6256 thumb_shift (str, THUMB_LSR); 6257} 6258 6259static void 6260do_t_mov (str) 6261 char * str; 6262{ 6263 thumb_mov_compare (str, THUMB_MOVE); 6264} 6265 6266static void 6267do_t_push_pop (str) 6268 char * str; 6269{ 6270 long range; 6271 6272 skip_whitespace (str); 6273 6274 if ((range = reg_list (&str)) == FAIL) 6275 { 6276 if (! inst.error) 6277 inst.error = BAD_ARGS; 6278 return; 6279 } 6280 6281 if (inst.reloc.type != BFD_RELOC_NONE) 6282 { 6283 /* This really doesn't seem worth it. */ 6284 inst.reloc.type = BFD_RELOC_NONE; 6285 inst.error = _("Expression too complex"); 6286 return; 6287 } 6288 6289 if (range & ~0xff) 6290 { 6291 if ((inst.instruction == T_OPCODE_PUSH 6292 && (range & ~0xff) == 1 << REG_LR) 6293 || (inst.instruction == T_OPCODE_POP 6294 && (range & ~0xff) == 1 << REG_PC)) 6295 { 6296 inst.instruction |= THUMB_PP_PC_LR; 6297 range &= 0xff; 6298 } 6299 else 6300 { 6301 inst.error = _("invalid register list to push/pop instruction"); 6302 return; 6303 } 6304 } 6305 6306 inst.instruction |= range; 6307 end_of_line (str); 6308} 6309 6310static void 6311do_t_str (str) 6312 char * str; 6313{ 6314 thumb_load_store (str, THUMB_STORE, THUMB_WORD); 6315} 6316 6317static void 6318do_t_strb (str) 6319 char * str; 6320{ 6321 thumb_load_store (str, THUMB_STORE, THUMB_BYTE); 6322} 6323 6324static void 6325do_t_strh (str) 6326 char * str; 6327{ 6328 thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD); 6329} 6330 6331static void 6332do_t_sub (str) 6333 char * str; 6334{ 6335 thumb_add_sub (str, 1); 6336} 6337 6338static void 6339do_t_swi (str) 6340 char * str; 6341{ 6342 skip_whitespace (str); 6343 6344 if (my_get_expression (&inst.reloc.exp, &str)) 6345 return; 6346 6347 inst.reloc.type = BFD_RELOC_ARM_SWI; 6348 end_of_line (str); 6349 return; 6350} 6351 6352static void 6353do_t_adr (str) 6354 char * str; 6355{ 6356 int reg; 6357 6358 /* This is a pseudo-op of the form "adr rd, label" to be converted 6359 into a relative address of the form "add rd, pc, #label-.-4". */ 6360 skip_whitespace (str); 6361 6362 /* Store Rd in temporary location inside instruction. */ 6363 if ((reg = reg_required_here (&str, 4)) == FAIL 6364 || (reg > 7) /* For Thumb reg must be r0..r7. */ 6365 || skip_past_comma (&str) == FAIL 6366 || my_get_expression (&inst.reloc.exp, &str)) 6367 { 6368 if (!inst.error) 6369 inst.error = BAD_ARGS; 6370 return; 6371 } 6372 6373 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD; 6374 inst.reloc.exp.X_add_number -= 4; /* PC relative adjust. */ 6375 inst.reloc.pc_rel = 1; 6376 inst.instruction |= REG_PC; /* Rd is already placed into the instruction. */ 6377 6378 end_of_line (str); 6379} 6380 6381static void 6382insert_reg (entry) 6383 int entry; 6384{ 6385 int len = strlen (reg_table[entry].name) + 2; 6386 char * buf = (char *) xmalloc (len); 6387 char * buf2 = (char *) xmalloc (len); 6388 int i = 0; 6389 6390#ifdef REGISTER_PREFIX 6391 buf[i++] = REGISTER_PREFIX; 6392#endif 6393 6394 strcpy (buf + i, reg_table[entry].name); 6395 6396 for (i = 0; buf[i]; i++) 6397 buf2[i] = islower (buf[i]) ? toupper (buf[i]) : buf[i]; 6398 6399 buf2[i] = '\0'; 6400 6401 hash_insert (arm_reg_hsh, buf, (PTR) & reg_table[entry]); 6402 hash_insert (arm_reg_hsh, buf2, (PTR) & reg_table[entry]); 6403} 6404 6405static void 6406insert_reg_alias (str, regnum) 6407 char *str; 6408 int regnum; 6409{ 6410 struct reg_entry *new = 6411 (struct reg_entry *) xmalloc (sizeof (struct reg_entry)); 6412 char *name = xmalloc (strlen (str) + 1); 6413 strcpy (name, str); 6414 6415 new->name = name; 6416 new->number = regnum; 6417 6418 hash_insert (arm_reg_hsh, name, (PTR) new); 6419} 6420 6421static void 6422set_constant_flonums () 6423{ 6424 int i; 6425 6426 for (i = 0; i < NUM_FLOAT_VALS; i++) 6427 if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL) 6428 abort (); 6429} 6430 6431void 6432md_begin () 6433{ 6434 unsigned mach; 6435 unsigned int i; 6436 6437 if ( (arm_ops_hsh = hash_new ()) == NULL 6438 || (arm_tops_hsh = hash_new ()) == NULL 6439 || (arm_cond_hsh = hash_new ()) == NULL 6440 || (arm_shift_hsh = hash_new ()) == NULL 6441 || (arm_reg_hsh = hash_new ()) == NULL 6442 || (arm_psr_hsh = hash_new ()) == NULL) 6443 as_fatal (_("Virtual memory exhausted")); 6444 6445 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++) 6446 hash_insert (arm_ops_hsh, insns[i].template, (PTR) (insns + i)); 6447 for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++) 6448 hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i)); 6449 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++) 6450 hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i)); 6451 for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++) 6452 hash_insert (arm_shift_hsh, shift_names[i].name, (PTR) (shift_names + i)); 6453 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++) 6454 hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i)); 6455 6456 for (i = 0; reg_table[i].name; i++) 6457 insert_reg (i); 6458 6459 set_constant_flonums (); 6460 6461#if defined OBJ_COFF || defined OBJ_ELF 6462 { 6463 unsigned int flags = 0; 6464 6465 /* Set the flags in the private structure. */ 6466 if (uses_apcs_26) flags |= F_APCS26; 6467 if (support_interwork) flags |= F_INTERWORK; 6468 if (uses_apcs_float) flags |= F_APCS_FLOAT; 6469 if (pic_code) flags |= F_PIC; 6470 if ((cpu_variant & FPU_ALL) == FPU_NONE) flags |= F_SOFT_FLOAT; 6471 6472 bfd_set_private_flags (stdoutput, flags); 6473 6474 /* We have run out flags in the COFF header to encode the 6475 status of ATPCS support, so instead we create a dummy, 6476 empty, debug section called .arm.atpcs. */ 6477 if (atpcs) 6478 { 6479 asection * sec; 6480 6481 sec = bfd_make_section (stdoutput, ".arm.atpcs"); 6482 6483 if (sec != NULL) 6484 { 6485 bfd_set_section_flags 6486 (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */); 6487 bfd_set_section_size (stdoutput, sec, 0); 6488 bfd_set_section_contents (stdoutput, sec, NULL, 0, 0); 6489 } 6490 } 6491 } 6492#endif 6493 6494 /* Record the CPU type as well. */ 6495 switch (cpu_variant & ARM_CPU_MASK) 6496 { 6497 case ARM_2: 6498 mach = bfd_mach_arm_2; 6499 break; 6500 6501 case ARM_3: /* Also ARM_250. */ 6502 mach = bfd_mach_arm_2a; 6503 break; 6504 6505 default: 6506 case ARM_6 | ARM_3 | ARM_2: /* Actually no CPU type defined. */ 6507 mach = bfd_mach_arm_4; 6508 break; 6509 6510 case ARM_7: /* Also ARM_6. */ 6511 mach = bfd_mach_arm_3; 6512 break; 6513 } 6514 6515 /* Catch special cases. */ 6516 if (cpu_variant != (FPU_DEFAULT | CPU_DEFAULT)) 6517 { 6518 if (cpu_variant & ARM_EXT_XSCALE) 6519 mach = bfd_mach_arm_XScale; 6520 else if (cpu_variant & ARM_EXT_V5E) 6521 mach = bfd_mach_arm_5TE; 6522 else if (cpu_variant & ARM_EXT_V5) 6523 { 6524 if (cpu_variant & ARM_EXT_THUMB) 6525 mach = bfd_mach_arm_5T; 6526 else 6527 mach = bfd_mach_arm_5; 6528 } 6529 else if (cpu_variant & ARM_EXT_HALFWORD) 6530 { 6531 if (cpu_variant & ARM_EXT_THUMB) 6532 mach = bfd_mach_arm_4T; 6533 else 6534 mach = bfd_mach_arm_4; 6535 } 6536 else if (cpu_variant & ARM_EXT_LONGMUL) 6537 mach = bfd_mach_arm_3M; 6538 } 6539 6540 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach); 6541} 6542 6543/* Turn an integer of n bytes (in val) into a stream of bytes appropriate 6544 for use in the a.out file, and stores them in the array pointed to by buf. 6545 This knows about the endian-ness of the target machine and does 6546 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte) 6547 2 (short) and 4 (long) Floating numbers are put out as a series of 6548 LITTLENUMS (shorts, here at least). */ 6549 6550void 6551md_number_to_chars (buf, val, n) 6552 char * buf; 6553 valueT val; 6554 int n; 6555{ 6556 if (target_big_endian) 6557 number_to_chars_bigendian (buf, val, n); 6558 else 6559 number_to_chars_littleendian (buf, val, n); 6560} 6561 6562static valueT 6563md_chars_to_number (buf, n) 6564 char * buf; 6565 int n; 6566{ 6567 valueT result = 0; 6568 unsigned char * where = (unsigned char *) buf; 6569 6570 if (target_big_endian) 6571 { 6572 while (n--) 6573 { 6574 result <<= 8; 6575 result |= (*where++ & 255); 6576 } 6577 } 6578 else 6579 { 6580 while (n--) 6581 { 6582 result <<= 8; 6583 result |= (where[n] & 255); 6584 } 6585 } 6586 6587 return result; 6588} 6589 6590/* Turn a string in input_line_pointer into a floating point constant 6591 of type TYPE, and store the appropriate bytes in *LITP. The number 6592 of LITTLENUMS emitted is stored in *SIZEP. An error message is 6593 returned, or NULL on OK. 6594 6595 Note that fp constants aren't represent in the normal way on the ARM. 6596 In big endian mode, things are as expected. However, in little endian 6597 mode fp constants are big-endian word-wise, and little-endian byte-wise 6598 within the words. For example, (double) 1.1 in big endian mode is 6599 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is 6600 the byte sequence 99 99 f1 3f 9a 99 99 99. 6601 6602 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */ 6603 6604char * 6605md_atof (type, litP, sizeP) 6606 char type; 6607 char * litP; 6608 int * sizeP; 6609{ 6610 int prec; 6611 LITTLENUM_TYPE words[MAX_LITTLENUMS]; 6612 char *t; 6613 int i; 6614 6615 switch (type) 6616 { 6617 case 'f': 6618 case 'F': 6619 case 's': 6620 case 'S': 6621 prec = 2; 6622 break; 6623 6624 case 'd': 6625 case 'D': 6626 case 'r': 6627 case 'R': 6628 prec = 4; 6629 break; 6630 6631 case 'x': 6632 case 'X': 6633 prec = 6; 6634 break; 6635 6636 case 'p': 6637 case 'P': 6638 prec = 6; 6639 break; 6640 6641 default: 6642 *sizeP = 0; 6643 return _("Bad call to MD_ATOF()"); 6644 } 6645 6646 t = atof_ieee (input_line_pointer, type, words); 6647 if (t) 6648 input_line_pointer = t; 6649 *sizeP = prec * 2; 6650 6651 if (target_big_endian) 6652 { 6653 for (i = 0; i < prec; i++) 6654 { 6655 md_number_to_chars (litP, (valueT) words[i], 2); 6656 litP += 2; 6657 } 6658 } 6659 else 6660 { 6661 /* For a 4 byte float the order of elements in `words' is 1 0. For an 6662 8 byte float the order is 1 0 3 2. */ 6663 for (i = 0; i < prec; i += 2) 6664 { 6665 md_number_to_chars (litP, (valueT) words[i + 1], 2); 6666 md_number_to_chars (litP + 2, (valueT) words[i], 2); 6667 litP += 4; 6668 } 6669 } 6670 6671 return 0; 6672} 6673 6674/* The knowledge of the PC's pipeline offset is built into the insns 6675 themselves. */ 6676 6677long 6678md_pcrel_from (fixP) 6679 fixS * fixP; 6680{ 6681 if (fixP->fx_addsy 6682 && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section 6683 && fixP->fx_subsy == NULL) 6684 return 0; 6685 6686 if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD)) 6687 { 6688 /* PC relative addressing on the Thumb is slightly odd 6689 as the bottom two bits of the PC are forced to zero 6690 for the calculation. */ 6691 return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3; 6692 } 6693 6694#ifdef TE_WINCE 6695 /* The pattern was adjusted to accomodate CE's off-by-one fixups, 6696 so we un-adjust here to compensate for the accomodation. */ 6697 return fixP->fx_where + fixP->fx_frag->fr_address + 8; 6698#else 6699 return fixP->fx_where + fixP->fx_frag->fr_address; 6700#endif 6701} 6702 6703/* Round up a section size to the appropriate boundary. */ 6704 6705valueT 6706md_section_align (segment, size) 6707 segT segment ATTRIBUTE_UNUSED; 6708 valueT size; 6709{ 6710#ifdef OBJ_ELF 6711 return size; 6712#else 6713 /* Round all sects to multiple of 4. */ 6714 return (size + 3) & ~3; 6715#endif 6716} 6717 6718/* Under ELF we need to default _GLOBAL_OFFSET_TABLE. 6719 Otherwise we have no need to default values of symbols. */ 6720 6721symbolS * 6722md_undefined_symbol (name) 6723 char * name ATTRIBUTE_UNUSED; 6724{ 6725#ifdef OBJ_ELF 6726 if (name[0] == '_' && name[1] == 'G' 6727 && streq (name, GLOBAL_OFFSET_TABLE_NAME)) 6728 { 6729 if (!GOT_symbol) 6730 { 6731 if (symbol_find (name)) 6732 as_bad ("GOT already in the symbol table"); 6733 6734 GOT_symbol = symbol_new (name, undefined_section, 6735 (valueT) 0, & zero_address_frag); 6736 } 6737 6738 return GOT_symbol; 6739 } 6740#endif 6741 6742 return 0; 6743} 6744 6745/* arm_reg_parse () := if it looks like a register, return its token and 6746 advance the pointer. */ 6747 6748static int 6749arm_reg_parse (ccp) 6750 register char ** ccp; 6751{ 6752 char * start = * ccp; 6753 char c; 6754 char * p; 6755 struct reg_entry * reg; 6756 6757#ifdef REGISTER_PREFIX 6758 if (*start != REGISTER_PREFIX) 6759 return FAIL; 6760 p = start + 1; 6761#else 6762 p = start; 6763#ifdef OPTIONAL_REGISTER_PREFIX 6764 if (*p == OPTIONAL_REGISTER_PREFIX) 6765 p++, start++; 6766#endif 6767#endif 6768 if (!isalpha (*p) || !is_name_beginner (*p)) 6769 return FAIL; 6770 6771 c = *p++; 6772 while (isalpha (c) || isdigit (c) || c == '_') 6773 c = *p++; 6774 6775 *--p = 0; 6776 reg = (struct reg_entry *) hash_find (arm_reg_hsh, start); 6777 *p = c; 6778 6779 if (reg) 6780 { 6781 *ccp = p; 6782 return reg->number; 6783 } 6784 6785 return FAIL; 6786} 6787 6788int 6789md_apply_fix3 (fixP, val, seg) 6790 fixS * fixP; 6791 valueT * val; 6792 segT seg; 6793{ 6794 offsetT value = * val; 6795 offsetT newval; 6796 unsigned int newimm; 6797 unsigned long temp; 6798 int sign; 6799 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal; 6800 arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data; 6801 6802 assert (fixP->fx_r_type < BFD_RELOC_UNUSED); 6803 6804 /* Note whether this will delete the relocation. */ 6805#if 0 6806 /* Patch from REarnshaw to JDavis (disabled for the moment, since it 6807 doesn't work fully.) */ 6808 if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy)) 6809 && !fixP->fx_pcrel) 6810#else 6811 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel) 6812#endif 6813 fixP->fx_done = 1; 6814 6815 /* If this symbol is in a different section then we need to leave it for 6816 the linker to deal with. Unfortunately, md_pcrel_from can't tell, 6817 so we have to undo it's effects here. */ 6818 if (fixP->fx_pcrel) 6819 { 6820 if (fixP->fx_addsy != NULL 6821 && S_IS_DEFINED (fixP->fx_addsy) 6822 && S_GET_SEGMENT (fixP->fx_addsy) != seg) 6823 { 6824 if (target_oabi 6825 && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH 6826 || fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BLX 6827 )) 6828 value = 0; 6829 else 6830 value += md_pcrel_from (fixP); 6831 } 6832 } 6833 6834 /* Remember value for emit_reloc. */ 6835 fixP->fx_addnumber = value; 6836 6837 switch (fixP->fx_r_type) 6838 { 6839 case BFD_RELOC_ARM_IMMEDIATE: 6840 newimm = validate_immediate (value); 6841 temp = md_chars_to_number (buf, INSN_SIZE); 6842 6843 /* If the instruction will fail, see if we can fix things up by 6844 changing the opcode. */ 6845 if (newimm == (unsigned int) FAIL 6846 && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL) 6847 { 6848 as_bad_where (fixP->fx_file, fixP->fx_line, 6849 _("invalid constant (%lx) after fixup"), 6850 (unsigned long) value); 6851 break; 6852 } 6853 6854 newimm |= (temp & 0xfffff000); 6855 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE); 6856 break; 6857 6858 case BFD_RELOC_ARM_ADRL_IMMEDIATE: 6859 { 6860 unsigned int highpart = 0; 6861 unsigned int newinsn = 0xe1a00000; /* nop. */ 6862 newimm = validate_immediate (value); 6863 temp = md_chars_to_number (buf, INSN_SIZE); 6864 6865 /* If the instruction will fail, see if we can fix things up by 6866 changing the opcode. */ 6867 if (newimm == (unsigned int) FAIL 6868 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL) 6869 { 6870 /* No ? OK - try using two ADD instructions to generate 6871 the value. */ 6872 newimm = validate_immediate_twopart (value, & highpart); 6873 6874 /* Yes - then make sure that the second instruction is 6875 also an add. */ 6876 if (newimm != (unsigned int) FAIL) 6877 newinsn = temp; 6878 /* Still No ? Try using a negated value. */ 6879 else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL) 6880 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT; 6881 /* Otherwise - give up. */ 6882 else 6883 { 6884 as_bad_where (fixP->fx_file, fixP->fx_line, 6885 _("Unable to compute ADRL instructions for PC offset of 0x%lx"), 6886 value); 6887 break; 6888 } 6889 6890 /* Replace the first operand in the 2nd instruction (which 6891 is the PC) with the destination register. We have 6892 already added in the PC in the first instruction and we 6893 do not want to do it again. */ 6894 newinsn &= ~ 0xf0000; 6895 newinsn |= ((newinsn & 0x0f000) << 4); 6896 } 6897 6898 newimm |= (temp & 0xfffff000); 6899 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE); 6900 6901 highpart |= (newinsn & 0xfffff000); 6902 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE); 6903 } 6904 break; 6905 6906 case BFD_RELOC_ARM_OFFSET_IMM: 6907 sign = value >= 0; 6908 6909 if (value < 0) 6910 value = - value; 6911 6912 if (validate_offset_imm (value, 0) == FAIL) 6913 { 6914 as_bad_where (fixP->fx_file, fixP->fx_line, 6915 _("bad immediate value for offset (%ld)"), 6916 (long) value); 6917 break; 6918 } 6919 6920 newval = md_chars_to_number (buf, INSN_SIZE); 6921 newval &= 0xff7ff000; 6922 newval |= value | (sign ? INDEX_UP : 0); 6923 md_number_to_chars (buf, newval, INSN_SIZE); 6924 break; 6925 6926 case BFD_RELOC_ARM_OFFSET_IMM8: 6927 case BFD_RELOC_ARM_HWLITERAL: 6928 sign = value >= 0; 6929 6930 if (value < 0) 6931 value = - value; 6932 6933 if (validate_offset_imm (value, 1) == FAIL) 6934 { 6935 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL) 6936 as_bad_where (fixP->fx_file, fixP->fx_line, 6937 _("invalid literal constant: pool needs to be closer")); 6938 else 6939 as_bad (_("bad immediate value for half-word offset (%ld)"), 6940 (long) value); 6941 break; 6942 } 6943 6944 newval = md_chars_to_number (buf, INSN_SIZE); 6945 newval &= 0xff7ff0f0; 6946 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0); 6947 md_number_to_chars (buf, newval, INSN_SIZE); 6948 break; 6949 6950 case BFD_RELOC_ARM_LITERAL: 6951 sign = value >= 0; 6952 6953 if (value < 0) 6954 value = - value; 6955 6956 if (validate_offset_imm (value, 0) == FAIL) 6957 { 6958 as_bad_where (fixP->fx_file, fixP->fx_line, 6959 _("invalid literal constant: pool needs to be closer")); 6960 break; 6961 } 6962 6963 newval = md_chars_to_number (buf, INSN_SIZE); 6964 newval &= 0xff7ff000; 6965 newval |= value | (sign ? INDEX_UP : 0); 6966 md_number_to_chars (buf, newval, INSN_SIZE); 6967 break; 6968 6969 case BFD_RELOC_ARM_SHIFT_IMM: 6970 newval = md_chars_to_number (buf, INSN_SIZE); 6971 if (((unsigned long) value) > 32 6972 || (value == 32 6973 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60))) 6974 { 6975 as_bad_where (fixP->fx_file, fixP->fx_line, 6976 _("shift expression is too large")); 6977 break; 6978 } 6979 6980 if (value == 0) 6981 /* Shifts of zero must be done as lsl. */ 6982 newval &= ~0x60; 6983 else if (value == 32) 6984 value = 0; 6985 newval &= 0xfffff07f; 6986 newval |= (value & 0x1f) << 7; 6987 md_number_to_chars (buf, newval, INSN_SIZE); 6988 break; 6989 6990 case BFD_RELOC_ARM_SWI: 6991 if (arm_data->thumb_mode) 6992 { 6993 if (((unsigned long) value) > 0xff) 6994 as_bad_where (fixP->fx_file, fixP->fx_line, 6995 _("Invalid swi expression")); 6996 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00; 6997 newval |= value; 6998 md_number_to_chars (buf, newval, THUMB_SIZE); 6999 } 7000 else 7001 { 7002 if (((unsigned long) value) > 0x00ffffff) 7003 as_bad_where (fixP->fx_file, fixP->fx_line, 7004 _("Invalid swi expression")); 7005 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000; 7006 newval |= value; 7007 md_number_to_chars (buf, newval, INSN_SIZE); 7008 } 7009 break; 7010 7011 case BFD_RELOC_ARM_MULTI: 7012 if (((unsigned long) value) > 0xffff) 7013 as_bad_where (fixP->fx_file, fixP->fx_line, 7014 _("Invalid expression in load/store multiple")); 7015 newval = value | md_chars_to_number (buf, INSN_SIZE); 7016 md_number_to_chars (buf, newval, INSN_SIZE); 7017 break; 7018 7019 case BFD_RELOC_ARM_PCREL_BRANCH: 7020 newval = md_chars_to_number (buf, INSN_SIZE); 7021 7022 /* Sign-extend a 24-bit number. */ 7023#define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000) 7024 7025#ifdef OBJ_ELF 7026 if (! target_oabi) 7027 value = fixP->fx_offset; 7028#endif 7029 7030 /* We are going to store value (shifted right by two) in the 7031 instruction, in a 24 bit, signed field. Thus we need to check 7032 that none of the top 8 bits of the shifted value (top 7 bits of 7033 the unshifted, unsigned value) are set, or that they are all set. */ 7034 if ((value & ~ ((offsetT) 0x1ffffff)) != 0 7035 && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff))) 7036 { 7037#ifdef OBJ_ELF 7038 /* Normally we would be stuck at this point, since we cannot store 7039 the absolute address that is the destination of the branch in the 7040 24 bits of the branch instruction. If however, we happen to know 7041 that the destination of the branch is in the same section as the 7042 branch instruciton itself, then we can compute the relocation for 7043 ourselves and not have to bother the linker with it. 7044 7045 FIXME: The tests for OBJ_ELF and ! target_oabi are only here 7046 because I have not worked out how to do this for OBJ_COFF or 7047 target_oabi. */ 7048 if (! target_oabi 7049 && fixP->fx_addsy != NULL 7050 && S_IS_DEFINED (fixP->fx_addsy) 7051 && S_GET_SEGMENT (fixP->fx_addsy) == seg) 7052 { 7053 /* Get pc relative value to go into the branch. */ 7054 value = * val; 7055 7056 /* Permit a backward branch provided that enough bits 7057 are set. Allow a forwards branch, provided that 7058 enough bits are clear. */ 7059 if ( (value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff) 7060 || (value & ~ ((offsetT) 0x1ffffff)) == 0) 7061 fixP->fx_done = 1; 7062 } 7063 7064 if (! fixP->fx_done) 7065#endif 7066 as_bad_where (fixP->fx_file, fixP->fx_line, 7067 _("gas can't handle same-section branch dest >= 0x04000000")); 7068 } 7069 7070 value >>= 2; 7071 value += SEXT24 (newval); 7072 7073 if ( (value & ~ ((offsetT) 0xffffff)) != 0 7074 && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff))) 7075 as_bad_where (fixP->fx_file, fixP->fx_line, 7076 _("out of range branch")); 7077 7078 newval = (value & 0x00ffffff) | (newval & 0xff000000); 7079 md_number_to_chars (buf, newval, INSN_SIZE); 7080 break; 7081 7082 case BFD_RELOC_ARM_PCREL_BLX: 7083 { 7084 offsetT hbit; 7085 newval = md_chars_to_number (buf, INSN_SIZE); 7086 7087#ifdef OBJ_ELF 7088 if (! target_oabi) 7089 value = fixP->fx_offset; 7090#endif 7091 hbit = (value >> 1) & 1; 7092 value = (value >> 2) & 0x00ffffff; 7093 value = (value + (newval & 0x00ffffff)) & 0x00ffffff; 7094 newval = value | (newval & 0xfe000000) | (hbit << 24); 7095 md_number_to_chars (buf, newval, INSN_SIZE); 7096 } 7097 break; 7098 7099 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch. */ 7100 newval = md_chars_to_number (buf, THUMB_SIZE); 7101 { 7102 addressT diff = (newval & 0xff) << 1; 7103 if (diff & 0x100) 7104 diff |= ~0xff; 7105 7106 value += diff; 7107 if ((value & ~0xff) && ((value & ~0xff) != ~0xff)) 7108 as_bad_where (fixP->fx_file, fixP->fx_line, 7109 _("Branch out of range")); 7110 newval = (newval & 0xff00) | ((value & 0x1ff) >> 1); 7111 } 7112 md_number_to_chars (buf, newval, THUMB_SIZE); 7113 break; 7114 7115 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch. */ 7116 newval = md_chars_to_number (buf, THUMB_SIZE); 7117 { 7118 addressT diff = (newval & 0x7ff) << 1; 7119 if (diff & 0x800) 7120 diff |= ~0x7ff; 7121 7122 value += diff; 7123 if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff)) 7124 as_bad_where (fixP->fx_file, fixP->fx_line, 7125 _("Branch out of range")); 7126 newval = (newval & 0xf800) | ((value & 0xfff) >> 1); 7127 } 7128 md_number_to_chars (buf, newval, THUMB_SIZE); 7129 break; 7130 7131 case BFD_RELOC_THUMB_PCREL_BLX: 7132 case BFD_RELOC_THUMB_PCREL_BRANCH23: 7133 { 7134 offsetT newval2; 7135 addressT diff; 7136 7137 newval = md_chars_to_number (buf, THUMB_SIZE); 7138 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE); 7139 diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1); 7140 if (diff & 0x400000) 7141 diff |= ~0x3fffff; 7142#ifdef OBJ_ELF 7143 value = fixP->fx_offset; 7144#endif 7145 value += diff; 7146 if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff)) 7147 as_bad_where (fixP->fx_file, fixP->fx_line, 7148 _("Branch with link out of range")); 7149 7150 newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12); 7151 newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1); 7152 md_number_to_chars (buf, newval, THUMB_SIZE); 7153 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE); 7154 } 7155 break; 7156 7157 case BFD_RELOC_8: 7158 if (fixP->fx_done || fixP->fx_pcrel) 7159 md_number_to_chars (buf, value, 1); 7160#ifdef OBJ_ELF 7161 else if (!target_oabi) 7162 { 7163 value = fixP->fx_offset; 7164 md_number_to_chars (buf, value, 1); 7165 } 7166#endif 7167 break; 7168 7169 case BFD_RELOC_16: 7170 if (fixP->fx_done || fixP->fx_pcrel) 7171 md_number_to_chars (buf, value, 2); 7172#ifdef OBJ_ELF 7173 else if (!target_oabi) 7174 { 7175 value = fixP->fx_offset; 7176 md_number_to_chars (buf, value, 2); 7177 } 7178#endif 7179 break; 7180 7181#ifdef OBJ_ELF 7182 case BFD_RELOC_ARM_GOT32: 7183 case BFD_RELOC_ARM_GOTOFF: 7184 md_number_to_chars (buf, 0, 4); 7185 break; 7186#endif 7187 7188 case BFD_RELOC_RVA: 7189 case BFD_RELOC_32: 7190 if (fixP->fx_done || fixP->fx_pcrel) 7191 md_number_to_chars (buf, value, 4); 7192#ifdef OBJ_ELF 7193 else if (!target_oabi) 7194 { 7195 value = fixP->fx_offset; 7196 md_number_to_chars (buf, value, 4); 7197 } 7198#endif 7199 break; 7200 7201#ifdef OBJ_ELF 7202 case BFD_RELOC_ARM_PLT32: 7203 /* It appears the instruction is fully prepared at this point. */ 7204 break; 7205#endif 7206 7207 case BFD_RELOC_ARM_GOTPC: 7208 md_number_to_chars (buf, value, 4); 7209 break; 7210 7211 case BFD_RELOC_ARM_CP_OFF_IMM: 7212 sign = value >= 0; 7213 if (value < -1023 || value > 1023 || (value & 3)) 7214 as_bad_where (fixP->fx_file, fixP->fx_line, 7215 _("Illegal value for co-processor offset")); 7216 if (value < 0) 7217 value = -value; 7218 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00; 7219 newval |= (value >> 2) | (sign ? INDEX_UP : 0); 7220 md_number_to_chars (buf, newval, INSN_SIZE); 7221 break; 7222 7223 case BFD_RELOC_ARM_THUMB_OFFSET: 7224 newval = md_chars_to_number (buf, THUMB_SIZE); 7225 /* Exactly what ranges, and where the offset is inserted depends 7226 on the type of instruction, we can establish this from the 7227 top 4 bits. */ 7228 switch (newval >> 12) 7229 { 7230 case 4: /* PC load. */ 7231 /* Thumb PC loads are somewhat odd, bit 1 of the PC is 7232 forced to zero for these loads, so we will need to round 7233 up the offset if the instruction address is not word 7234 aligned (since the final address produced must be, and 7235 we can only describe word-aligned immediate offsets). */ 7236 7237 if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3) 7238 as_bad_where (fixP->fx_file, fixP->fx_line, 7239 _("Invalid offset, target not word aligned (0x%08X)"), 7240 (unsigned int) (fixP->fx_frag->fr_address 7241 + fixP->fx_where + value)); 7242 7243 if ((value + 2) & ~0x3fe) 7244 as_bad_where (fixP->fx_file, fixP->fx_line, 7245 _("Invalid offset, value too big (0x%08lX)"), value); 7246 7247 /* Round up, since pc will be rounded down. */ 7248 newval |= (value + 2) >> 2; 7249 break; 7250 7251 case 9: /* SP load/store. */ 7252 if (value & ~0x3fc) 7253 as_bad_where (fixP->fx_file, fixP->fx_line, 7254 _("Invalid offset, value too big (0x%08lX)"), value); 7255 newval |= value >> 2; 7256 break; 7257 7258 case 6: /* Word load/store. */ 7259 if (value & ~0x7c) 7260 as_bad_where (fixP->fx_file, fixP->fx_line, 7261 _("Invalid offset, value too big (0x%08lX)"), value); 7262 newval |= value << 4; /* 6 - 2. */ 7263 break; 7264 7265 case 7: /* Byte load/store. */ 7266 if (value & ~0x1f) 7267 as_bad_where (fixP->fx_file, fixP->fx_line, 7268 _("Invalid offset, value too big (0x%08lX)"), value); 7269 newval |= value << 6; 7270 break; 7271 7272 case 8: /* Halfword load/store. */ 7273 if (value & ~0x3e) 7274 as_bad_where (fixP->fx_file, fixP->fx_line, 7275 _("Invalid offset, value too big (0x%08lX)"), value); 7276 newval |= value << 5; /* 6 - 1. */ 7277 break; 7278 7279 default: 7280 as_bad_where (fixP->fx_file, fixP->fx_line, 7281 "Unable to process relocation for thumb opcode: %lx", 7282 (unsigned long) newval); 7283 break; 7284 } 7285 md_number_to_chars (buf, newval, THUMB_SIZE); 7286 break; 7287 7288 case BFD_RELOC_ARM_THUMB_ADD: 7289 /* This is a complicated relocation, since we use it for all of 7290 the following immediate relocations: 7291 7292 3bit ADD/SUB 7293 8bit ADD/SUB 7294 9bit ADD/SUB SP word-aligned 7295 10bit ADD PC/SP word-aligned 7296 7297 The type of instruction being processed is encoded in the 7298 instruction field: 7299 7300 0x8000 SUB 7301 0x00F0 Rd 7302 0x000F Rs 7303 */ 7304 newval = md_chars_to_number (buf, THUMB_SIZE); 7305 { 7306 int rd = (newval >> 4) & 0xf; 7307 int rs = newval & 0xf; 7308 int subtract = newval & 0x8000; 7309 7310 if (rd == REG_SP) 7311 { 7312 if (value & ~0x1fc) 7313 as_bad_where (fixP->fx_file, fixP->fx_line, 7314 _("Invalid immediate for stack address calculation")); 7315 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST; 7316 newval |= value >> 2; 7317 } 7318 else if (rs == REG_PC || rs == REG_SP) 7319 { 7320 if (subtract || 7321 value & ~0x3fc) 7322 as_bad_where (fixP->fx_file, fixP->fx_line, 7323 _("Invalid immediate for address calculation (value = 0x%08lX)"), 7324 (unsigned long) value); 7325 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP); 7326 newval |= rd << 8; 7327 newval |= value >> 2; 7328 } 7329 else if (rs == rd) 7330 { 7331 if (value & ~0xff) 7332 as_bad_where (fixP->fx_file, fixP->fx_line, 7333 _("Invalid 8bit immediate")); 7334 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8; 7335 newval |= (rd << 8) | value; 7336 } 7337 else 7338 { 7339 if (value & ~0x7) 7340 as_bad_where (fixP->fx_file, fixP->fx_line, 7341 _("Invalid 3bit immediate")); 7342 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3; 7343 newval |= rd | (rs << 3) | (value << 6); 7344 } 7345 } 7346 md_number_to_chars (buf, newval, THUMB_SIZE); 7347 break; 7348 7349 case BFD_RELOC_ARM_THUMB_IMM: 7350 newval = md_chars_to_number (buf, THUMB_SIZE); 7351 switch (newval >> 11) 7352 { 7353 case 0x04: /* 8bit immediate MOV. */ 7354 case 0x05: /* 8bit immediate CMP. */ 7355 if (value < 0 || value > 255) 7356 as_bad_where (fixP->fx_file, fixP->fx_line, 7357 _("Invalid immediate: %ld is too large"), 7358 (long) value); 7359 newval |= value; 7360 break; 7361 7362 default: 7363 abort (); 7364 } 7365 md_number_to_chars (buf, newval, THUMB_SIZE); 7366 break; 7367 7368 case BFD_RELOC_ARM_THUMB_SHIFT: 7369 /* 5bit shift value (0..31). */ 7370 if (value < 0 || value > 31) 7371 as_bad_where (fixP->fx_file, fixP->fx_line, 7372 _("Illegal Thumb shift value: %ld"), (long) value); 7373 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f; 7374 newval |= value << 6; 7375 md_number_to_chars (buf, newval, THUMB_SIZE); 7376 break; 7377 7378 case BFD_RELOC_VTABLE_INHERIT: 7379 case BFD_RELOC_VTABLE_ENTRY: 7380 fixP->fx_done = 0; 7381 return 1; 7382 7383 case BFD_RELOC_NONE: 7384 default: 7385 as_bad_where (fixP->fx_file, fixP->fx_line, 7386 _("Bad relocation fixup type (%d)"), fixP->fx_r_type); 7387 } 7388 7389 return 1; 7390} 7391 7392/* Translate internal representation of relocation info to BFD target 7393 format. */ 7394 7395arelent * 7396tc_gen_reloc (section, fixp) 7397 asection * section ATTRIBUTE_UNUSED; 7398 fixS * fixp; 7399{ 7400 arelent * reloc; 7401 bfd_reloc_code_real_type code; 7402 7403 reloc = (arelent *) xmalloc (sizeof (arelent)); 7404 7405 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); 7406 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); 7407 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; 7408 7409 /* @@ Why fx_addnumber sometimes and fx_offset other times? */ 7410#ifndef OBJ_ELF 7411 if (fixp->fx_pcrel == 0) 7412 reloc->addend = fixp->fx_offset; 7413 else 7414 reloc->addend = fixp->fx_offset = reloc->address; 7415#else /* OBJ_ELF */ 7416 reloc->addend = fixp->fx_offset; 7417#endif 7418 7419 switch (fixp->fx_r_type) 7420 { 7421 case BFD_RELOC_8: 7422 if (fixp->fx_pcrel) 7423 { 7424 code = BFD_RELOC_8_PCREL; 7425 break; 7426 } 7427 7428 case BFD_RELOC_16: 7429 if (fixp->fx_pcrel) 7430 { 7431 code = BFD_RELOC_16_PCREL; 7432 break; 7433 } 7434 7435 case BFD_RELOC_32: 7436 if (fixp->fx_pcrel) 7437 { 7438 code = BFD_RELOC_32_PCREL; 7439 break; 7440 } 7441 7442 case BFD_RELOC_ARM_PCREL_BRANCH: 7443 case BFD_RELOC_ARM_PCREL_BLX: 7444 case BFD_RELOC_RVA: 7445 case BFD_RELOC_THUMB_PCREL_BRANCH9: 7446 case BFD_RELOC_THUMB_PCREL_BRANCH12: 7447 case BFD_RELOC_THUMB_PCREL_BRANCH23: 7448 case BFD_RELOC_THUMB_PCREL_BLX: 7449 case BFD_RELOC_VTABLE_ENTRY: 7450 case BFD_RELOC_VTABLE_INHERIT: 7451 code = fixp->fx_r_type; 7452 break; 7453 7454 case BFD_RELOC_ARM_LITERAL: 7455 case BFD_RELOC_ARM_HWLITERAL: 7456 /* If this is called then the a literal has been referenced across 7457 a section boundary - possibly due to an implicit dump. */ 7458 as_bad_where (fixp->fx_file, fixp->fx_line, 7459 _("Literal referenced across section boundary (Implicit dump?)")); 7460 return NULL; 7461 7462#ifdef OBJ_ELF 7463 case BFD_RELOC_ARM_GOT32: 7464 case BFD_RELOC_ARM_GOTOFF: 7465 case BFD_RELOC_ARM_PLT32: 7466 code = fixp->fx_r_type; 7467 break; 7468#endif 7469 7470 case BFD_RELOC_ARM_IMMEDIATE: 7471 as_bad_where (fixp->fx_file, fixp->fx_line, 7472 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"), 7473 fixp->fx_r_type); 7474 return NULL; 7475 7476 case BFD_RELOC_ARM_ADRL_IMMEDIATE: 7477 as_bad_where (fixp->fx_file, fixp->fx_line, 7478 _("ADRL used for a symbol not defined in the same file")); 7479 return NULL; 7480 7481 case BFD_RELOC_ARM_OFFSET_IMM: 7482 as_bad_where (fixp->fx_file, fixp->fx_line, 7483 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"), 7484 fixp->fx_r_type); 7485 return NULL; 7486 7487 default: 7488 { 7489 char * type; 7490 7491 switch (fixp->fx_r_type) 7492 { 7493 case BFD_RELOC_ARM_IMMEDIATE: type = "IMMEDIATE"; break; 7494 case BFD_RELOC_ARM_OFFSET_IMM: type = "OFFSET_IMM"; break; 7495 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break; 7496 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break; 7497 case BFD_RELOC_ARM_SWI: type = "SWI"; break; 7498 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break; 7499 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break; 7500 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break; 7501 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break; 7502 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break; 7503 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break; 7504 default: type = _("<unknown>"); break; 7505 } 7506 as_bad_where (fixp->fx_file, fixp->fx_line, 7507 _("Cannot represent %s relocation in this object file format"), 7508 type); 7509 return NULL; 7510 } 7511 } 7512 7513#ifdef OBJ_ELF 7514 if (code == BFD_RELOC_32_PCREL 7515 && GOT_symbol 7516 && fixp->fx_addsy == GOT_symbol) 7517 { 7518 code = BFD_RELOC_ARM_GOTPC; 7519 reloc->addend = fixp->fx_offset = reloc->address; 7520 } 7521#endif 7522 7523 reloc->howto = bfd_reloc_type_lookup (stdoutput, code); 7524 7525 if (reloc->howto == NULL) 7526 { 7527 as_bad_where (fixp->fx_file, fixp->fx_line, 7528 _("Can not represent %s relocation in this object file format"), 7529 bfd_get_reloc_code_name (code)); 7530 return NULL; 7531 } 7532 7533 /* HACK: Since arm ELF uses Rel instead of Rela, encode the 7534 vtable entry to be used in the relocation's section offset. */ 7535 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY) 7536 reloc->address = fixp->fx_offset; 7537 7538 return reloc; 7539} 7540 7541int 7542md_estimate_size_before_relax (fragP, segtype) 7543 fragS * fragP ATTRIBUTE_UNUSED; 7544 segT segtype ATTRIBUTE_UNUSED; 7545{ 7546 as_fatal (_("md_estimate_size_before_relax\n")); 7547 return 1; 7548} 7549 7550static void 7551output_inst PARAMS ((void)) 7552{ 7553 char * to = NULL; 7554 7555 if (inst.error) 7556 { 7557 as_bad (inst.error); 7558 return; 7559 } 7560 7561 to = frag_more (inst.size); 7562 7563 if (thumb_mode && (inst.size > THUMB_SIZE)) 7564 { 7565 assert (inst.size == (2 * THUMB_SIZE)); 7566 md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE); 7567 md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE); 7568 } 7569 else if (inst.size > INSN_SIZE) 7570 { 7571 assert (inst.size == (2 * INSN_SIZE)); 7572 md_number_to_chars (to, inst.instruction, INSN_SIZE); 7573 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE); 7574 } 7575 else 7576 md_number_to_chars (to, inst.instruction, inst.size); 7577 7578 if (inst.reloc.type != BFD_RELOC_NONE) 7579 fix_new_arm (frag_now, to - frag_now->fr_literal, 7580 inst.size, & inst.reloc.exp, inst.reloc.pc_rel, 7581 inst.reloc.type); 7582 7583#ifdef OBJ_ELF 7584 dwarf2_emit_insn (inst.size); 7585#endif 7586} 7587 7588void 7589md_assemble (str) 7590 char * str; 7591{ 7592 char c; 7593 char * p; 7594 char * q; 7595 char * start; 7596 7597 /* Align the instruction. 7598 This may not be the right thing to do but ... */ 7599#if 0 7600 arm_align (2, 0); 7601#endif 7602 listing_prev_line (); /* Defined in listing.h. */ 7603 7604 /* Align the previous label if needed. */ 7605 if (last_label_seen != NULL) 7606 { 7607 symbol_set_frag (last_label_seen, frag_now); 7608 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ()); 7609 S_SET_SEGMENT (last_label_seen, now_seg); 7610 } 7611 7612 memset (&inst, '\0', sizeof (inst)); 7613 inst.reloc.type = BFD_RELOC_NONE; 7614 7615 skip_whitespace (str); 7616 7617 /* Scan up to the end of the op-code, which must end in white space or 7618 end of string. */ 7619 for (start = p = str; *p != '\0'; p++) 7620 if (*p == ' ') 7621 break; 7622 7623 if (p == str) 7624 { 7625 as_bad (_("No operator -- statement `%s'\n"), str); 7626 return; 7627 } 7628 7629 if (thumb_mode) 7630 { 7631 CONST struct thumb_opcode * opcode; 7632 7633 c = *p; 7634 *p = '\0'; 7635 opcode = (CONST struct thumb_opcode *) hash_find (arm_tops_hsh, str); 7636 *p = c; 7637 7638 if (opcode) 7639 { 7640 /* Check that this instruction is supported for this CPU. */ 7641 if (thumb_mode == 1 && (opcode->variants & cpu_variant) == 0) 7642 { 7643 as_bad (_("selected processor does not support this opcode")); 7644 return; 7645 } 7646 7647 inst.instruction = opcode->value; 7648 inst.size = opcode->size; 7649 (*opcode->parms) (p); 7650 output_inst (); 7651 return; 7652 } 7653 } 7654 else 7655 { 7656 CONST struct asm_opcode * opcode; 7657 unsigned long cond_code; 7658 7659 inst.size = INSN_SIZE; 7660 /* P now points to the end of the opcode, probably white space, but we 7661 have to break the opcode up in case it contains condionals and flags; 7662 keep trying with progressively smaller basic instructions until one 7663 matches, or we run out of opcode. */ 7664 q = (p - str > LONGEST_INST) ? str + LONGEST_INST : p; 7665 7666 for (; q != str; q--) 7667 { 7668 c = *q; 7669 *q = '\0'; 7670 7671 opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str); 7672 *q = c; 7673 7674 if (opcode && opcode->template) 7675 { 7676 unsigned long flag_bits = 0; 7677 char * r; 7678 7679 /* Check that this instruction is supported for this CPU. */ 7680 if ((opcode->variants & cpu_variant) == 0) 7681 goto try_shorter; 7682 7683 inst.instruction = opcode->value; 7684 if (q == p) /* Just a simple opcode. */ 7685 { 7686 if (opcode->comp_suffix) 7687 { 7688 if (*opcode->comp_suffix != '\0') 7689 as_bad (_("Opcode `%s' must have suffix from list: <%s>"), 7690 str, opcode->comp_suffix); 7691 else 7692 /* Not a conditional instruction. */ 7693 (*opcode->parms) (q, 0); 7694 } 7695 else 7696 { 7697 /* A conditional instruction with default condition. */ 7698 inst.instruction |= COND_ALWAYS; 7699 (*opcode->parms) (q, 0); 7700 } 7701 output_inst (); 7702 return; 7703 } 7704 7705 /* Not just a simple opcode. Check if extra is a 7706 conditional. */ 7707 r = q; 7708 if (p - r >= 2) 7709 { 7710 CONST struct asm_cond *cond; 7711 char d = *(r + 2); 7712 7713 *(r + 2) = '\0'; 7714 cond = (CONST struct asm_cond *) hash_find (arm_cond_hsh, r); 7715 *(r + 2) = d; 7716 if (cond) 7717 { 7718 if (cond->value == 0xf0000000) 7719 as_tsktsk ( 7720_("Warning: Use of the 'nv' conditional is deprecated\n")); 7721 7722 cond_code = cond->value; 7723 r += 2; 7724 } 7725 else 7726 cond_code = COND_ALWAYS; 7727 } 7728 else 7729 cond_code = COND_ALWAYS; 7730 7731 /* Apply the conditional, or complain it's not allowed. */ 7732 if (opcode->comp_suffix && *opcode->comp_suffix == '\0') 7733 { 7734 /* Instruction isn't conditional. */ 7735 if (cond_code != COND_ALWAYS) 7736 { 7737 as_bad (_("Opcode `%s' is unconditional\n"), str); 7738 return; 7739 } 7740 } 7741 else 7742 /* Instruction is conditional: set the condition into it. */ 7743 inst.instruction |= cond_code; 7744 7745 /* If there is a compulsory suffix, it should come here 7746 before any optional flags. */ 7747 if (opcode->comp_suffix && *opcode->comp_suffix != '\0') 7748 { 7749 CONST char *s = opcode->comp_suffix; 7750 7751 while (*s) 7752 { 7753 inst.suffix++; 7754 if (*r == *s) 7755 break; 7756 s++; 7757 } 7758 7759 if (*s == '\0') 7760 { 7761 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), 7762 str, opcode->comp_suffix); 7763 return; 7764 } 7765 7766 r++; 7767 } 7768 7769 /* The remainder, if any should now be flags for the instruction; 7770 Scan these checking each one found with the opcode. */ 7771 if (r != p) 7772 { 7773 char d; 7774 CONST struct asm_flg *flag = opcode->flags; 7775 7776 if (flag) 7777 { 7778 int flagno; 7779 7780 d = *p; 7781 *p = '\0'; 7782 7783 for (flagno = 0; flag[flagno].template; flagno++) 7784 { 7785 if (streq (r, flag[flagno].template)) 7786 { 7787 flag_bits |= flag[flagno].set_bits; 7788 break; 7789 } 7790 } 7791 7792 *p = d; 7793 if (! flag[flagno].template) 7794 goto try_shorter; 7795 } 7796 else 7797 goto try_shorter; 7798 } 7799 7800 (*opcode->parms) (p, flag_bits); 7801 output_inst (); 7802 return; 7803 } 7804 7805 try_shorter: 7806 ; 7807 } 7808 } 7809 7810 /* It wasn't an instruction, but it might be a register alias of the form 7811 alias .req reg. */ 7812 q = p; 7813 skip_whitespace (q); 7814 7815 c = *p; 7816 *p = '\0'; 7817 7818 if (*q && !strncmp (q, ".req ", 4)) 7819 { 7820 int reg; 7821 char * copy_of_str; 7822 char * r; 7823 7824#ifdef IGNORE_OPCODE_CASE 7825 str = original_case_string; 7826#endif 7827 copy_of_str = str; 7828 7829 q += 4; 7830 skip_whitespace (q); 7831 7832 for (r = q; *r != '\0'; r++) 7833 if (*r == ' ') 7834 break; 7835 7836 if (r != q) 7837 { 7838 int regnum; 7839 char d = *r; 7840 7841 *r = '\0'; 7842 regnum = arm_reg_parse (& q); 7843 *r = d; 7844 7845 reg = arm_reg_parse (& str); 7846 7847 if (reg == FAIL) 7848 { 7849 if (regnum != FAIL) 7850 insert_reg_alias (str, regnum); 7851 else 7852 as_warn (_("register '%s' does not exist\n"), q); 7853 } 7854 else if (regnum != FAIL) 7855 { 7856 if (reg != regnum) 7857 as_warn (_("ignoring redefinition of register alias '%s'"), 7858 copy_of_str); 7859 7860 /* Do not warn about redefinitions to the same alias. */ 7861 } 7862 else 7863 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"), 7864 copy_of_str, q); 7865 } 7866 else 7867 as_warn (_("ignoring incomplete .req pseuso op")); 7868 7869 *p = c; 7870 return; 7871 } 7872 7873 *p = c; 7874 as_bad (_("bad instruction `%s'"), start); 7875} 7876 7877/* md_parse_option 7878 Invocation line includes a switch not recognized by the base assembler. 7879 See if it's a processor-specific option. These are: 7880 Cpu variants, the arm part is optional: 7881 -m[arm]1 Currently not supported. 7882 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor 7883 -m[arm]3 Arm 3 processor 7884 -m[arm]6[xx], Arm 6 processors 7885 -m[arm]7[xx][t][[d]m] Arm 7 processors 7886 -m[arm]8[10] Arm 8 processors 7887 -m[arm]9[20][tdmi] Arm 9 processors 7888 -mstrongarm[110[0]] StrongARM processors 7889 -mxscale XScale processors 7890 -m[arm]v[2345[t[e]]] Arm architectures 7891 -mall All (except the ARM1) 7892 FP variants: 7893 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions 7894 -mfpe-old (No float load/store multiples) 7895 -mno-fpu Disable all floating point instructions 7896 Run-time endian selection: 7897 -EB big endian cpu 7898 -EL little endian cpu 7899 ARM Procedure Calling Standard: 7900 -mapcs-32 32 bit APCS 7901 -mapcs-26 26 bit APCS 7902 -mapcs-float Pass floats in float regs 7903 -mapcs-reentrant Position independent code 7904 -mthumb-interwork Code supports Arm/Thumb interworking 7905 -matpcs ARM/Thumb Procedure Call Standard 7906 -moabi Old ELF ABI */ 7907 7908CONST char * md_shortopts = "m:k"; 7909 7910struct option md_longopts[] = 7911{ 7912#ifdef ARM_BI_ENDIAN 7913#define OPTION_EB (OPTION_MD_BASE + 0) 7914 {"EB", no_argument, NULL, OPTION_EB}, 7915#define OPTION_EL (OPTION_MD_BASE + 1) 7916 {"EL", no_argument, NULL, OPTION_EL}, 7917#ifdef OBJ_ELF 7918#define OPTION_OABI (OPTION_MD_BASE +2) 7919 {"oabi", no_argument, NULL, OPTION_OABI}, 7920#endif 7921#endif 7922 {NULL, no_argument, NULL, 0} 7923}; 7924 7925size_t md_longopts_size = sizeof (md_longopts); 7926 7927int 7928md_parse_option (c, arg) 7929 int c; 7930 char * arg; 7931{ 7932 char * str = arg; 7933 7934 switch (c) 7935 { 7936#ifdef ARM_BI_ENDIAN 7937 case OPTION_EB: 7938 target_big_endian = 1; 7939 break; 7940 case OPTION_EL: 7941 target_big_endian = 0; 7942 break; 7943#endif 7944 7945 case 'm': 7946 switch (*str) 7947 { 7948 case 'f': 7949 if (streq (str, "fpa10")) 7950 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA10; 7951 else if (streq (str, "fpa11")) 7952 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA11; 7953 else if (streq (str, "fpe-old")) 7954 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_CORE; 7955 else 7956 goto bad; 7957 break; 7958 7959 case 'n': 7960 if (streq (str, "no-fpu")) 7961 cpu_variant &= ~FPU_ALL; 7962 break; 7963 7964#ifdef OBJ_ELF 7965 case 'o': 7966 if (streq (str, "oabi")) 7967 target_oabi = true; 7968 break; 7969#endif 7970 7971 case 't': 7972 /* Limit assembler to generating only Thumb instructions: */ 7973 if (streq (str, "thumb")) 7974 { 7975 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_EXT_THUMB; 7976 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_NONE; 7977 thumb_mode = 1; 7978 } 7979 else if (streq (str, "thumb-interwork")) 7980 { 7981 if ((cpu_variant & ARM_EXT_THUMB) == 0) 7982 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V4T; 7983#if defined OBJ_COFF || defined OBJ_ELF 7984 support_interwork = true; 7985#endif 7986 } 7987 else 7988 goto bad; 7989 break; 7990 7991 default: 7992 if (streq (str, "all")) 7993 { 7994 cpu_variant = ARM_ALL | FPU_ALL; 7995 return 1; 7996 } 7997#if defined OBJ_COFF || defined OBJ_ELF 7998 if (! strncmp (str, "apcs-", 5)) 7999 { 8000 /* GCC passes on all command line options starting "-mapcs-..." 8001 to us, so we must parse them here. */ 8002 8003 str += 5; 8004 8005 if (streq (str, "32")) 8006 { 8007 uses_apcs_26 = false; 8008 return 1; 8009 } 8010 else if (streq (str, "26")) 8011 { 8012 uses_apcs_26 = true; 8013 return 1; 8014 } 8015 else if (streq (str, "frame")) 8016 { 8017 /* Stack frames are being generated - does not affect 8018 linkage of code. */ 8019 return 1; 8020 } 8021 else if (streq (str, "stack-check")) 8022 { 8023 /* Stack checking is being performed - does not affect 8024 linkage, but does require that the functions 8025 __rt_stkovf_split_small and __rt_stkovf_split_big be 8026 present in the final link. */ 8027 8028 return 1; 8029 } 8030 else if (streq (str, "float")) 8031 { 8032 /* Floating point arguments are being passed in the floating 8033 point registers. This does affect linking, since this 8034 version of the APCS is incompatible with the version that 8035 passes floating points in the integer registers. */ 8036 8037 uses_apcs_float = true; 8038 return 1; 8039 } 8040 else if (streq (str, "reentrant")) 8041 { 8042 /* Reentrant code has been generated. This does affect 8043 linking, since there is no point in linking reentrant/ 8044 position independent code with absolute position code. */ 8045 pic_code = true; 8046 return 1; 8047 } 8048 8049 as_bad (_("Unrecognised APCS switch -m%s"), arg); 8050 return 0; 8051 } 8052 8053 if (! strcmp (str, "atpcs")) 8054 { 8055 atpcs = true; 8056 return 1; 8057 } 8058#endif 8059 /* Strip off optional "arm". */ 8060 if (! strncmp (str, "arm", 3)) 8061 str += 3; 8062 8063 switch (*str) 8064 { 8065 case '1': 8066 if (streq (str, "1")) 8067 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_1; 8068 else 8069 goto bad; 8070 break; 8071 8072 case '2': 8073 if (streq (str, "2")) 8074 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2; 8075 else if (streq (str, "250")) 8076 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_250; 8077 else 8078 goto bad; 8079 break; 8080 8081 case '3': 8082 if (streq (str, "3")) 8083 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3; 8084 else 8085 goto bad; 8086 break; 8087 8088 case '6': 8089 switch (strtol (str, NULL, 10)) 8090 { 8091 case 6: 8092 case 60: 8093 case 600: 8094 case 610: 8095 case 620: 8096 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_6; 8097 break; 8098 default: 8099 goto bad; 8100 } 8101 break; 8102 8103 case '7': 8104 /* Eat the processor name. */ 8105 switch (strtol (str, & str, 10)) 8106 { 8107 case 7: 8108 case 70: 8109 case 700: 8110 case 710: 8111 case 720: 8112 case 7100: 8113 case 7500: 8114 break; 8115 default: 8116 goto bad; 8117 } 8118 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7; 8119 for (; *str; str++) 8120 { 8121 switch (*str) 8122 { 8123 case 't': 8124 cpu_variant |= ARM_ARCH_V4T; 8125 break; 8126 8127 case 'm': 8128 cpu_variant |= ARM_EXT_LONGMUL; 8129 break; 8130 8131 case 'f': /* fe => fp enabled cpu. */ 8132 if (str[1] == 'e') 8133 ++ str; 8134 else 8135 goto bad; 8136 8137 case 'c': /* Left over from 710c processor name. */ 8138 case 'd': /* Debug. */ 8139 case 'i': /* Embedded ICE. */ 8140 /* Included for completeness in ARM processor naming. */ 8141 break; 8142 8143 default: 8144 goto bad; 8145 } 8146 } 8147 break; 8148 8149 case '8': 8150 if (streq (str, "8") || streq (str, "810")) 8151 cpu_variant = (cpu_variant & ~ARM_ANY) 8152 | ARM_8 | ARM_ARCH_V4; 8153 else 8154 goto bad; 8155 break; 8156 8157 case '9': 8158 if (streq (str, "9")) 8159 cpu_variant = (cpu_variant & ~ARM_ANY) 8160 | ARM_9 | ARM_ARCH_V4T; 8161 else if (streq (str, "920")) 8162 cpu_variant = (cpu_variant & ~ARM_ANY) 8163 | ARM_9 | ARM_ARCH_V4; 8164 else if (streq (str, "920t")) 8165 cpu_variant = (cpu_variant & ~ARM_ANY) 8166 | ARM_9 | ARM_ARCH_V4T; 8167 else if (streq (str, "9tdmi")) 8168 cpu_variant = (cpu_variant & ~ARM_ANY) 8169 | ARM_9 | ARM_ARCH_V4T; 8170 else 8171 goto bad; 8172 break; 8173 8174 case 's': 8175 if (streq (str, "strongarm") 8176 || streq (str, "strongarm110") 8177 || streq (str, "strongarm1100")) 8178 cpu_variant = (cpu_variant & ~ARM_ANY) 8179 | ARM_8 | ARM_ARCH_V4; 8180 else 8181 goto bad; 8182 break; 8183 8184 case 'x': 8185 if (streq (str, "xscale")) 8186 cpu_variant = ARM_9 | ARM_ARCH_XSCALE; 8187 else 8188 goto bad; 8189 break; 8190 8191 case 'v': 8192 /* Select variant based on architecture rather than 8193 processor. */ 8194 switch (*++str) 8195 { 8196 case '2': 8197 switch (*++str) 8198 { 8199 case 'a': 8200 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3; 8201 break; 8202 case 0: 8203 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2; 8204 break; 8205 default: 8206 as_bad (_("Invalid architecture variant -m%s"), arg); 8207 break; 8208 } 8209 break; 8210 8211 case '3': 8212 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7; 8213 8214 switch (*++str) 8215 { 8216 case 'm': cpu_variant |= ARM_EXT_LONGMUL; break; 8217 case 0: break; 8218 default: 8219 as_bad (_("Invalid architecture variant -m%s"), arg); 8220 break; 8221 } 8222 break; 8223 8224 case '4': 8225 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7 | ARM_ARCH_V4; 8226 8227 switch (*++str) 8228 { 8229 case 't': cpu_variant |= ARM_EXT_THUMB; break; 8230 case 0: break; 8231 default: 8232 as_bad (_("Invalid architecture variant -m%s"), arg); 8233 break; 8234 } 8235 break; 8236 8237 case '5': 8238 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V5; 8239 switch (*++str) 8240 { 8241 case 't': cpu_variant |= ARM_EXT_THUMB; break; 8242 case 'e': cpu_variant |= ARM_EXT_V5E; break; 8243 case 0: break; 8244 default: 8245 as_bad (_("Invalid architecture variant -m%s"), arg); 8246 break; 8247 } 8248 break; 8249 8250 default: 8251 as_bad (_("Invalid architecture variant -m%s"), arg); 8252 break; 8253 } 8254 break; 8255 8256 default: 8257 bad: 8258 as_bad (_("Invalid processor variant -m%s"), arg); 8259 return 0; 8260 } 8261 } 8262 break; 8263 8264#if defined OBJ_ELF || defined OBJ_COFF 8265 case 'k': 8266 pic_code = 1; 8267 break; 8268#endif 8269 8270 default: 8271 return 0; 8272 } 8273 8274 return 1; 8275} 8276 8277void 8278md_show_usage (fp) 8279 FILE * fp; 8280{ 8281 fprintf (fp, _("\ 8282 ARM Specific Assembler Options:\n\ 8283 -m[arm][<processor name>] select processor variant\n\ 8284 -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\ 8285 -mthumb only allow Thumb instructions\n\ 8286 -mthumb-interwork mark the assembled code as supporting interworking\n\ 8287 -mall allow any instruction\n\ 8288 -mfpa10, -mfpa11 select floating point architecture\n\ 8289 -mfpe-old don't allow floating-point multiple instructions\n\ 8290 -mno-fpu don't allow any floating-point instructions.\n\ 8291 -k generate PIC code.\n")); 8292#if defined OBJ_COFF || defined OBJ_ELF 8293 fprintf (fp, _("\ 8294 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n\ 8295 -matpcs use ARM/Thumb Procedure Calling Standard\n\ 8296 -mapcs-float floating point args are passed in FP regs\n\ 8297 -mapcs-reentrant the code is position independent/reentrant\n")); 8298#endif 8299#ifdef OBJ_ELF 8300 fprintf (fp, _("\ 8301 -moabi support the old ELF ABI\n")); 8302#endif 8303#ifdef ARM_BI_ENDIAN 8304 fprintf (fp, _("\ 8305 -EB assemble code for a big endian cpu\n\ 8306 -EL assemble code for a little endian cpu\n")); 8307#endif 8308} 8309 8310/* We need to be able to fix up arbitrary expressions in some statements. 8311 This is so that we can handle symbols that are an arbitrary distance from 8312 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask), 8313 which returns part of an address in a form which will be valid for 8314 a data instruction. We do this by pushing the expression into a symbol 8315 in the expr_section, and creating a fix for that. */ 8316 8317static void 8318fix_new_arm (frag, where, size, exp, pc_rel, reloc) 8319 fragS * frag; 8320 int where; 8321 short int size; 8322 expressionS * exp; 8323 int pc_rel; 8324 int reloc; 8325{ 8326 fixS * new_fix; 8327 arm_fix_data * arm_data; 8328 8329 switch (exp->X_op) 8330 { 8331 case O_constant: 8332 case O_symbol: 8333 case O_add: 8334 case O_subtract: 8335 new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc); 8336 break; 8337 8338 default: 8339 new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0, 8340 pc_rel, reloc); 8341 break; 8342 } 8343 8344 /* Mark whether the fix is to a THUMB instruction, or an ARM 8345 instruction. */ 8346 arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data)); 8347 new_fix->tc_fix_data = (PTR) arm_data; 8348 arm_data->thumb_mode = thumb_mode; 8349 8350 return; 8351} 8352 8353/* This fix_new is called by cons via TC_CONS_FIX_NEW. */ 8354 8355void 8356cons_fix_new_arm (frag, where, size, exp) 8357 fragS * frag; 8358 int where; 8359 int size; 8360 expressionS * exp; 8361{ 8362 bfd_reloc_code_real_type type; 8363 int pcrel = 0; 8364 8365 /* Pick a reloc. 8366 FIXME: @@ Should look at CPU word size. */ 8367 switch (size) 8368 { 8369 case 1: 8370 type = BFD_RELOC_8; 8371 break; 8372 case 2: 8373 type = BFD_RELOC_16; 8374 break; 8375 case 4: 8376 default: 8377 type = BFD_RELOC_32; 8378 break; 8379 case 8: 8380 type = BFD_RELOC_64; 8381 break; 8382 } 8383 8384 fix_new_exp (frag, where, (int) size, exp, pcrel, type); 8385} 8386 8387/* A good place to do this, although this was probably not intended 8388 for this kind of use. We need to dump the literal pool before 8389 references are made to a null symbol pointer. */ 8390 8391void 8392arm_cleanup () 8393{ 8394 if (current_poolP == NULL) 8395 return; 8396 8397 /* Put it at the end of text section. */ 8398 subseg_set (text_section, 0); 8399 s_ltorg (0); 8400 listing_prev_line (); 8401} 8402 8403void 8404arm_start_line_hook () 8405{ 8406 last_label_seen = NULL; 8407} 8408 8409void 8410arm_frob_label (sym) 8411 symbolS * sym; 8412{ 8413 last_label_seen = sym; 8414 8415 ARM_SET_THUMB (sym, thumb_mode); 8416 8417#if defined OBJ_COFF || defined OBJ_ELF 8418 ARM_SET_INTERWORK (sym, support_interwork); 8419#endif 8420 8421 if (label_is_thumb_function_name) 8422 { 8423 /* When the address of a Thumb function is taken the bottom 8424 bit of that address should be set. This will allow 8425 interworking between Arm and Thumb functions to work 8426 correctly. */ 8427 8428 THUMB_SET_FUNC (sym, 1); 8429 8430 label_is_thumb_function_name = false; 8431 } 8432} 8433 8434/* Adjust the symbol table. This marks Thumb symbols as distinct from 8435 ARM ones. */ 8436 8437void 8438arm_adjust_symtab () 8439{ 8440#ifdef OBJ_COFF 8441 symbolS * sym; 8442 8443 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym)) 8444 { 8445 if (ARM_IS_THUMB (sym)) 8446 { 8447 if (THUMB_IS_FUNC (sym)) 8448 { 8449 /* Mark the symbol as a Thumb function. */ 8450 if ( S_GET_STORAGE_CLASS (sym) == C_STAT 8451 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */ 8452 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC); 8453 8454 else if (S_GET_STORAGE_CLASS (sym) == C_EXT) 8455 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC); 8456 else 8457 as_bad (_("%s: unexpected function type: %d"), 8458 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym)); 8459 } 8460 else switch (S_GET_STORAGE_CLASS (sym)) 8461 { 8462 case C_EXT: 8463 S_SET_STORAGE_CLASS (sym, C_THUMBEXT); 8464 break; 8465 case C_STAT: 8466 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT); 8467 break; 8468 case C_LABEL: 8469 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL); 8470 break; 8471 default: 8472 /* Do nothing. */ 8473 break; 8474 } 8475 } 8476 8477 if (ARM_IS_INTERWORK (sym)) 8478 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF; 8479 } 8480#endif 8481#ifdef OBJ_ELF 8482 symbolS * sym; 8483 char bind; 8484 8485 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym)) 8486 { 8487 if (ARM_IS_THUMB (sym)) 8488 { 8489 elf_symbol_type * elf_sym; 8490 8491 elf_sym = elf_symbol (symbol_get_bfdsym (sym)); 8492 bind = ELF_ST_BIND (elf_sym); 8493 8494 /* If it's a .thumb_func, declare it as so, 8495 otherwise tag label as .code 16. */ 8496 if (THUMB_IS_FUNC (sym)) 8497 elf_sym->internal_elf_sym.st_info = 8498 ELF_ST_INFO (bind, STT_ARM_TFUNC); 8499 else 8500 elf_sym->internal_elf_sym.st_info = 8501 ELF_ST_INFO (bind, STT_ARM_16BIT); 8502 } 8503 } 8504#endif 8505} 8506 8507int 8508arm_data_in_code () 8509{ 8510 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5)) 8511 { 8512 *input_line_pointer = '/'; 8513 input_line_pointer += 5; 8514 *input_line_pointer = 0; 8515 return 1; 8516 } 8517 8518 return 0; 8519} 8520 8521char * 8522arm_canonicalize_symbol_name (name) 8523 char * name; 8524{ 8525 int len; 8526 8527 if (thumb_mode && (len = strlen (name)) > 5 8528 && streq (name + len - 5, "/data")) 8529 *(name + len - 5) = 0; 8530 8531 return name; 8532} 8533 8534boolean 8535arm_validate_fix (fixP) 8536 fixS * fixP; 8537{ 8538 /* If the destination of the branch is a defined symbol which does not have 8539 the THUMB_FUNC attribute, then we must be calling a function which has 8540 the (interfacearm) attribute. We look for the Thumb entry point to that 8541 function and change the branch to refer to that function instead. */ 8542 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23 8543 && fixP->fx_addsy != NULL 8544 && S_IS_DEFINED (fixP->fx_addsy) 8545 && ! THUMB_IS_FUNC (fixP->fx_addsy)) 8546 { 8547 fixP->fx_addsy = find_real_start (fixP->fx_addsy); 8548 return true; 8549 } 8550 8551 return false; 8552} 8553 8554#ifdef OBJ_COFF 8555/* This is a little hack to help the gas/arm/adrl.s test. It prevents 8556 local labels from being added to the output symbol table when they 8557 are used with the ADRL pseudo op. The ADRL relocation should always 8558 be resolved before the binbary is emitted, so it is safe to say that 8559 it is adjustable. */ 8560 8561boolean 8562arm_fix_adjustable (fixP) 8563 fixS * fixP; 8564{ 8565 if (fixP->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE) 8566 return 1; 8567 return 0; 8568} 8569#endif 8570#ifdef OBJ_ELF 8571/* Relocations against Thumb function names must be left unadjusted, 8572 so that the linker can use this information to correctly set the 8573 bottom bit of their addresses. The MIPS version of this function 8574 also prevents relocations that are mips-16 specific, but I do not 8575 know why it does this. 8576 8577 FIXME: 8578 There is one other problem that ought to be addressed here, but 8579 which currently is not: Taking the address of a label (rather 8580 than a function) and then later jumping to that address. Such 8581 addresses also ought to have their bottom bit set (assuming that 8582 they reside in Thumb code), but at the moment they will not. */ 8583 8584boolean 8585arm_fix_adjustable (fixP) 8586 fixS * fixP; 8587{ 8588 if (fixP->fx_addsy == NULL) 8589 return 1; 8590 8591 /* Prevent all adjustments to global symbols. */ 8592 if (S_IS_EXTERN (fixP->fx_addsy)) 8593 return 0; 8594 8595 if (S_IS_WEAK (fixP->fx_addsy)) 8596 return 0; 8597 8598 if (THUMB_IS_FUNC (fixP->fx_addsy) 8599 && fixP->fx_subsy == NULL) 8600 return 0; 8601 8602 /* We need the symbol name for the VTABLE entries. */ 8603 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT 8604 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY) 8605 return 0; 8606 8607 return 1; 8608} 8609 8610const char * 8611elf32_arm_target_format () 8612{ 8613 if (target_big_endian) 8614 { 8615 if (target_oabi) 8616 return "elf32-bigarm-oabi"; 8617 else 8618 return "elf32-bigarm"; 8619 } 8620 else 8621 { 8622 if (target_oabi) 8623 return "elf32-littlearm-oabi"; 8624 else 8625 return "elf32-littlearm"; 8626 } 8627} 8628 8629void 8630armelf_frob_symbol (symp, puntp) 8631 symbolS * symp; 8632 int * puntp; 8633{ 8634 elf_frob_symbol (symp, puntp); 8635} 8636 8637int 8638arm_force_relocation (fixp) 8639 struct fix * fixp; 8640{ 8641 if ( fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT 8642 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY 8643 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH 8644 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX 8645 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX 8646 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23) 8647 return 1; 8648 8649 return 0; 8650} 8651 8652static bfd_reloc_code_real_type 8653arm_parse_reloc () 8654{ 8655 char id [16]; 8656 char * ip; 8657 unsigned int i; 8658 static struct 8659 { 8660 char * str; 8661 int len; 8662 bfd_reloc_code_real_type reloc; 8663 } 8664 reloc_map[] = 8665 { 8666#define MAP(str,reloc) { str, sizeof (str) - 1, reloc } 8667 MAP ("(got)", BFD_RELOC_ARM_GOT32), 8668 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF), 8669 /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)" 8670 branch instructions generated by GCC for PLT relocs. */ 8671 MAP ("(plt)", BFD_RELOC_ARM_PLT32), 8672 { NULL, 0, BFD_RELOC_UNUSED } 8673#undef MAP 8674 }; 8675 8676 for (i = 0, ip = input_line_pointer; 8677 i < sizeof (id) && (isalnum (*ip) || ispunct (*ip)); 8678 i++, ip++) 8679 id[i] = tolower (*ip); 8680 8681 for (i = 0; reloc_map[i].str; i++) 8682 if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0) 8683 break; 8684 8685 input_line_pointer += reloc_map[i].len; 8686 8687 return reloc_map[i].reloc; 8688} 8689 8690static void 8691s_arm_elf_cons (nbytes) 8692 int nbytes; 8693{ 8694 expressionS exp; 8695 8696#ifdef md_flush_pending_output 8697 md_flush_pending_output (); 8698#endif 8699 8700 if (is_it_end_of_statement ()) 8701 { 8702 demand_empty_rest_of_line (); 8703 return; 8704 } 8705 8706#ifdef md_cons_align 8707 md_cons_align (nbytes); 8708#endif 8709 8710 do 8711 { 8712 bfd_reloc_code_real_type reloc; 8713 8714 expression (& exp); 8715 8716 if (exp.X_op == O_symbol 8717 && * input_line_pointer == '(' 8718 && (reloc = arm_parse_reloc ()) != BFD_RELOC_UNUSED) 8719 { 8720 reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, reloc); 8721 int size = bfd_get_reloc_size (howto); 8722 8723 if (size > nbytes) 8724 as_bad ("%s relocations do not fit in %d bytes", 8725 howto->name, nbytes); 8726 else 8727 { 8728 register char *p = frag_more ((int) nbytes); 8729 int offset = nbytes - size; 8730 8731 fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size, 8732 &exp, 0, reloc); 8733 } 8734 } 8735 else 8736 emit_expr (&exp, (unsigned int) nbytes); 8737 } 8738 while (*input_line_pointer++ == ','); 8739 8740 /* Put terminator back into stream. */ 8741 input_line_pointer --; 8742 demand_empty_rest_of_line (); 8743} 8744 8745#endif /* OBJ_ELF */ 8746