📄 tc-arm.c
字号:
/* tc-arm.c -- Assemble for the ARM Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org) Modified by David Taylor (dtaylor@armltd.co.uk) Cirrus coprocessor mods by Aldy Hernandez (aldyh@redhat.com) This file is part of GAS, the GNU Assembler. GAS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GAS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GAS; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <string.h>#define NO_RELOC 0#include "as.h"#include "safe-ctype.h"/* Need TARGET_CPU. */#include "config.h"#include "subsegs.h"#include "obstack.h"#include "symbols.h"#include "listing.h"#ifdef OBJ_ELF#include "elf/arm.h"#include "dwarf2dbg.h"#endif/* XXX Set this to 1 after the next binutils release */#define WARN_DEPRECATED 0/* The following bitmasks control CPU extensions: */#define ARM_EXT_V1 0x00000001 /* All processors (core set). */#define ARM_EXT_V2 0x00000002 /* Multiply instructions. */#define ARM_EXT_V2S 0x00000004 /* SWP instructions. */#define ARM_EXT_V3 0x00000008 /* MSR MRS. */#define ARM_EXT_V3M 0x00000010 /* Allow long multiplies. */#define ARM_EXT_V4 0x00000020 /* Allow half word loads. */#define ARM_EXT_V4T 0x00000040 /* Thumb v1. */#define ARM_EXT_V5 0x00000080 /* Allow CLZ, etc. */#define ARM_EXT_V5T 0x00000100 /* Thumb v2. */#define ARM_EXT_V5ExP 0x00000200 /* DSP core set. */#define ARM_EXT_V5E 0x00000400 /* DSP Double transfers. */#define ARM_EXT_V5J 0x00000800 /* Jazelle extension. *//* Co-processor space extensions. */#define ARM_CEXT_XSCALE 0x00800000 /* Allow MIA etc. */#define ARM_CEXT_MAVERICK 0x00400000 /* Use Cirrus/DSP coprocessor. *//* Architectures are the sum of the base and extensions. The ARM ARM (rev E) defines the following: ARMv3, ARMv3M, ARMv4xM, ARMv4, ARMv4TxM, ARMv4T, ARMv5xM, ARMv5, ARMv5TxM, ARMv5T, ARMv5TExP, ARMv5TE. To these we add three more to cover cores prior to ARM6. Finally, there are cores which implement further extensions in the co-processor space. */#define ARM_ARCH_V1 ARM_EXT_V1#define ARM_ARCH_V2 (ARM_ARCH_V1 | ARM_EXT_V2)#define ARM_ARCH_V2S (ARM_ARCH_V2 | ARM_EXT_V2S)#define ARM_ARCH_V3 (ARM_ARCH_V2S | ARM_EXT_V3)#define ARM_ARCH_V3M (ARM_ARCH_V3 | ARM_EXT_V3M)#define ARM_ARCH_V4xM (ARM_ARCH_V3 | ARM_EXT_V4)#define ARM_ARCH_V4 (ARM_ARCH_V3M | ARM_EXT_V4)#define ARM_ARCH_V4TxM (ARM_ARCH_V4xM | ARM_EXT_V4T)#define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_EXT_V4T)#define ARM_ARCH_V5xM (ARM_ARCH_V4xM | ARM_EXT_V5)#define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5)#define ARM_ARCH_V5TxM (ARM_ARCH_V5xM | ARM_EXT_V4T | ARM_EXT_V5T)#define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_EXT_V4T | ARM_EXT_V5T)#define ARM_ARCH_V5TExP (ARM_ARCH_V5T | ARM_EXT_V5ExP)#define ARM_ARCH_V5TE (ARM_ARCH_V5TExP | ARM_EXT_V5E)#define ARM_ARCH_V5TEJ (ARM_ARCH_V5TE | ARM_EXT_V5J)/* Processors with specific extensions in the co-processor space. */#define ARM_ARCH_XSCALE (ARM_ARCH_V5TE | ARM_CEXT_XSCALE)/* Some useful combinations: */#define ARM_ANY 0x0000ffff /* Any basic core. */#define ARM_ALL 0x00ffffff /* Any core + co-processor */#define CPROC_ANY 0x00ff0000 /* Any co-processor */#define FPU_ANY 0xff000000 /* Note this is ~ARM_ALL. */#define FPU_FPA_EXT_V1 0x80000000 /* Base FPA instruction set. */#define FPU_FPA_EXT_V2 0x40000000 /* LFM/SFM. */#define FPU_VFP_EXT_NONE 0x20000000 /* Use VFP word-ordering. */#define FPU_VFP_EXT_V1xD 0x10000000 /* Base VFP instruction set. */#define FPU_VFP_EXT_V1 0x08000000 /* Double-precision insns. */#define FPU_VFP_EXT_V2 0x04000000 /* ARM10E VFPr1. */#define FPU_NONE 0#define FPU_ARCH_FPE FPU_FPA_EXT_V1#define FPU_ARCH_FPA (FPU_ARCH_FPE | FPU_FPA_EXT_V2)#define FPU_ARCH_VFP FPU_VFP_EXT_NONE#define FPU_ARCH_VFP_V1xD (FPU_VFP_EXT_V1xD | FPU_VFP_EXT_NONE)#define FPU_ARCH_VFP_V1 (FPU_ARCH_VFP_V1xD | FPU_VFP_EXT_V1)#define FPU_ARCH_VFP_V2 (FPU_ARCH_VFP_V1 | FPU_VFP_EXT_V2)/* Types of processor to assemble for. */#define ARM_1 ARM_ARCH_V1#define ARM_2 ARM_ARCH_V2#define ARM_3 ARM_ARCH_V2S#define ARM_250 ARM_ARCH_V2S#define ARM_6 ARM_ARCH_V3#define ARM_7 ARM_ARCH_V3#define ARM_8 ARM_ARCH_V4#define ARM_9 ARM_ARCH_V4T#define ARM_STRONG ARM_ARCH_V4#define ARM_CPU_MASK 0x0000000f /* XXX? */#ifndef CPU_DEFAULT#if defined __XSCALE__#define CPU_DEFAULT (ARM_ARCH_XSCALE)#else#if defined __thumb__#define CPU_DEFAULT (ARM_ARCH_V5T)#else#define CPU_DEFAULT ARM_ANY#endif#endif#endif/* For backwards compatibility we default to the FPA. */#ifndef FPU_DEFAULT#define FPU_DEFAULT FPU_ARCH_FPA#endif#define streq(a, b) (strcmp (a, b) == 0)#define skip_whitespace(str) while (*(str) == ' ') ++(str)static unsigned long cpu_variant;static int target_oabi = 0;/* Flags stored in private area of BFD structure. */static int uses_apcs_26 = false;static int atpcs = false;static int support_interwork = false;static int uses_apcs_float = false;static int pic_code = false;/* Variables that we set while parsing command-line options. Once all options have been read we re-process these values to set the real assembly flags. */static int legacy_cpu = -1;static int legacy_fpu = -1;static int mcpu_cpu_opt = -1;static int mcpu_fpu_opt = -1;static int march_cpu_opt = -1;static int march_fpu_opt = -1;static int mfpu_opt = -1;/* This array holds the chars that always start a comment. If the pre-processor is disabled, these aren't very useful. */const char comment_chars[] = "@";/* This array holds the chars that only start a comment at the beginning of a line. If the line seems to have the form '# 123 filename' .line and .file directives will appear in the pre-processed output. *//* Note that input_file.c hand checks for '#' at the beginning of the first line of the input file. This is because the compiler outputs #NO_APP at the beginning of its output. *//* Also note that comments like this one will always work. */const char line_comment_chars[] = "#";const char line_separator_chars[] = ";";/* Chars that can be used to separate mant from exp in floating point numbers. */const char EXP_CHARS[] = "eE";/* Chars that mean this number is a floating point constant. *//* As in 0f12.456 *//* or 0d1.2345e12 */const char FLT_CHARS[] = "rRsSfFdDxXeEpP";/* Prefix characters that indicate the start of an immediate value. */#define is_immediate_prefix(C) ((C) == '#' || (C) == '$')#ifdef OBJ_ELF/* Pre-defined "_GLOBAL_OFFSET_TABLE_" */symbolS * GOT_symbol;#endif/* Size of relocation record. */const int md_reloc_size = 8;/* 0: assemble for ARM, 1: assemble for Thumb, 2: assemble for Thumb even though target CPU does not support thumb instructions. */static int thumb_mode = 0;typedef struct arm_fix{ int thumb_mode;} arm_fix_data;struct arm_it{ const char * error; unsigned long instruction; int size; struct { bfd_reloc_code_real_type type; expressionS exp; int pc_rel; } reloc;};struct arm_it inst;enum asm_shift_index{ SHIFT_LSL = 0, SHIFT_LSR, SHIFT_ASR, SHIFT_ROR, SHIFT_RRX};struct asm_shift_properties{ enum asm_shift_index index; unsigned long bit_field; unsigned int allows_0 : 1; unsigned int allows_32 : 1;};static const struct asm_shift_properties shift_properties [] ={ { SHIFT_LSL, 0, 1, 0}, { SHIFT_LSR, 0x20, 0, 1}, { SHIFT_ASR, 0x40, 0, 1}, { SHIFT_ROR, 0x60, 0, 0}, { SHIFT_RRX, 0x60, 0, 0}};struct asm_shift_name{ const char * name; const struct asm_shift_properties * properties;};static const struct asm_shift_name shift_names [] ={ { "asl", shift_properties + SHIFT_LSL }, { "lsl", shift_properties + SHIFT_LSL }, { "lsr", shift_properties + SHIFT_LSR }, { "asr", shift_properties + SHIFT_ASR }, { "ror", shift_properties + SHIFT_ROR }, { "rrx", shift_properties + SHIFT_RRX }, { "ASL", shift_properties + SHIFT_LSL }, { "LSL", shift_properties + SHIFT_LSL }, { "LSR", shift_properties + SHIFT_LSR }, { "ASR", shift_properties + SHIFT_ASR }, { "ROR", shift_properties + SHIFT_ROR }, { "RRX", shift_properties + SHIFT_RRX }};#define NO_SHIFT_RESTRICT 1#define SHIFT_RESTRICT 0#define NUM_FLOAT_VALS 8const char * fp_const[] ={ "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0};/* Number of littlenums required to hold an extended precision number. */#define MAX_LITTLENUMS 6LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];#define FAIL (-1)#define SUCCESS (0)/* Whether a Co-processor load/store operation accepts write-back forms. */#define CP_WB_OK 1#define CP_NO_WB 0#define SUFF_S 1#define SUFF_D 2#define SUFF_E 3#define SUFF_P 4#define CP_T_X 0x00008000#define CP_T_Y 0x00400000#define CP_T_Pre 0x01000000#define CP_T_UD 0x00800000
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -