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