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