From 077b8428ab2abe6e4c66216151c518c03467323c Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Sat, 25 Nov 2000 00:21:40 +0000 Subject: Add ARM v5t, v5te and XScale support --- ChangeLog | 6 + bfd/ChangeLog | 18 + bfd/archures.c | 2 + bfd/bfd-in2.h | 2 + bfd/coff-arm.c | 1 + bfd/coffcode.h | 5 +- bfd/config.bfd | 10 + bfd/cpu-arm.c | 5 +- binutils/ChangeLog | 4 + binutils/NEWS | 7 +- configure.in | 24 +- gas/ChangeLog | 42 + gas/config/tc-arm.c | 1729 ++++++++++++++++++++++++++++++++++------ gas/configure | 341 ++++---- gas/configure.in | 3 + gas/doc/c-arm.texi | 13 +- gas/testsuite/ChangeLog | 8 + gas/testsuite/gas/arm/arm.exp | 4 +- gas/testsuite/gas/arm/xscale.d | 38 + gas/testsuite/gas/arm/xscale.s | 40 + ld/ChangeLog | 5 + ld/configure.tgt | 2 + opcodes/ChangeLog | 10 + opcodes/arm-dis.c | 26 + opcodes/arm-opc.h | 73 +- 25 files changed, 1972 insertions(+), 446 deletions(-) create mode 100644 gas/testsuite/gas/arm/xscale.d create mode 100644 gas/testsuite/gas/arm/xscale.s diff --git a/ChangeLog b/ChangeLog index 55793fe..36e0305 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2000-11-24 Nick Clifton + + * configure.in (xscale-elf): Add target. + (xscale-coff): Add target. + (c4x, c5x, tic54x): Move after ARM targets. + 2000-11-23 Alexandre Oliva * ltcf-gcj.sh: Added file, required by 2000-11-18 merge. diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 188b62f..3229922 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,21 @@ +2000-11-24 Nick Clifton + + * archures.c (bfd_mach_arm_5TE): Define. + (bfd_mach_arm+XScale): Define. + * bfd-in2.h: Regenerate. + + * coff-arm.c (coff_arm_reloc_type_lookup): Accept + BFD_RELOC_ARM_PCREL_BLX. + + * coffcode.h (coff_set_flags): Set flags for 5t, 5te and + XScale machine numbers. + + * config.bfd (xscale-elf): Add target. + (xscale-coff): Add target. + + * cpu-arm.c: Add xscale machine name. + Add v5t, v5te and XScale machine numbers. + 2000-11-23 Kazu Hirata * aix386-core.c: Fix formatting. diff --git a/bfd/archures.c b/bfd/archures.c index 8cfc39e..f494d88 100644 --- a/bfd/archures.c +++ b/bfd/archures.c @@ -205,6 +205,8 @@ DESCRIPTION .#define bfd_mach_arm_4T 6 .#define bfd_mach_arm_5 7 .#define bfd_mach_arm_5T 8 +.#define bfd_mach_arm_5TE 9 +.#define bfd_mach_arm_XScale 10 . bfd_arch_ns32k, {* National Semiconductors ns32000 *} . bfd_arch_w65, {* WDC 65816 *} . bfd_arch_tic30, {* Texas Instruments TMS320C30 *} diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 20a0e4c..e13b3d1 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -1471,6 +1471,8 @@ enum bfd_architecture #define bfd_mach_arm_4T 6 #define bfd_mach_arm_5 7 #define bfd_mach_arm_5T 8 +#define bfd_mach_arm_5TE 9 +#define bfd_mach_arm_XScale 10 bfd_arch_ns32k, /* National Semiconductors ns32000 */ bfd_arch_w65, /* WDC 65816 */ bfd_arch_tic30, /* Texas Instruments TMS320C30 */ diff --git a/bfd/coff-arm.c b/bfd/coff-arm.c index 35297d9..95e65cd 100644 --- a/bfd/coff-arm.c +++ b/bfd/coff-arm.c @@ -845,6 +845,7 @@ coff_arm_reloc_type_lookup (abfd, code) ASTD (BFD_RELOC_16, ARM_16); ASTD (BFD_RELOC_32, ARM_32); ASTD (BFD_RELOC_ARM_PCREL_BRANCH, ARM_26); + ASTD (BFD_RELOC_ARM_PCREL_BLX, ARM_26); ASTD (BFD_RELOC_8_PCREL, ARM_DISP8); ASTD (BFD_RELOC_16_PCREL, ARM_DISP16); ASTD (BFD_RELOC_32_PCREL, ARM_DISP32); diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 3bdf307..c5025fb 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -2596,7 +2596,10 @@ coff_set_flags (abfd, magicp, flagsp) case bfd_mach_arm_4: * flagsp |= F_ARM_4; break; case bfd_mach_arm_4T: * flagsp |= F_ARM_4T; break; case bfd_mach_arm_5: * flagsp |= F_ARM_5; break; - case bfd_mach_arm_5T: * flagsp |= F_ARM_5; break; /* XXX - we do not have an F_ARM_5T */ + /* FIXME: we do not have F_ARM vaues greater than F_ARM_5. */ + case bfd_mach_arm_5T: * flagsp |= F_ARM_5; break; + case bfd_mach_arm_5TE: * flagsp |= F_ARM_5; break; + case bfd_mach_arm_XScale: * flagsp |= F_ARM_5; break; } return true; #endif diff --git a/bfd/config.bfd b/bfd/config.bfd index 6235079..5deb6cc 100644 --- a/bfd/config.bfd +++ b/bfd/config.bfd @@ -32,6 +32,7 @@ alpha*) targ_archs=bfd_alpha_arch ;; arm*) targ_archs=bfd_arm_arch ;; strongarm*) targ_archs=bfd_arm_arch ;; thumb*) targ_archs=bfd_arm_arch ;; +xscale*) targ_archs=bfd_arm_arch ;; c30*) targ_archs=bfd_tic30_arch ;; c54x*) targ_archs=bfd_tic54x_arch ;; hppa*) targ_archs=bfd_hppa_arch ;; @@ -182,6 +183,15 @@ case "${targ}" in targ_selvecs=armcoff_big_vec targ_underscore=yes ;; + xscale-*-elf) + targ_defvec=bfd_elf32_littlearm_vec + targ_selvecs=bfd_elf32_bigarm_vec + ;; + xscale-*-coff) + targ_defvec=armcoff_little_vec + targ_selvecs=armcoff_big_vec + targ_underscore=yes + ;; a29k-*-ebmon* | a29k-*-udi* | a29k-*-coff* | a29k-*-sym1* | \ a29k-*-vxworks* | a29k-*-sysv*) diff --git a/bfd/cpu-arm.c b/bfd/cpu-arm.c index 7b351f5..91507f8 100644 --- a/bfd/cpu-arm.c +++ b/bfd/cpu-arm.c @@ -93,6 +93,7 @@ processors[] = { bfd_mach_arm_4, "strongarm"}, { bfd_mach_arm_4, "strongarm110" }, { bfd_mach_arm_4, "strongarm1100" }, + { bfd_mach_arm_XScale, "xscale" } }; static boolean @@ -135,7 +136,9 @@ static const bfd_arch_info_type arch_info_struct[] = N( bfd_mach_arm_4, "armv4", false, & arch_info_struct[5] ), N( bfd_mach_arm_4T, "armv4t", false, & arch_info_struct[6] ), N( bfd_mach_arm_5, "armv5", false, & arch_info_struct[7] ), - N( bfd_mach_arm_5T, "armv5t", false, NULL ) + N( bfd_mach_arm_5T, "armv5t", false, & arch_info_struct[8] ), + N( bfd_mach_arm_5TE, "armv5te", false, & arch_info_struct[9] ), + N( bfd_mach_arm_XScale, "xscale", false, NULL ) }; const bfd_arch_info_type bfd_arm_arch = diff --git a/binutils/ChangeLog b/binutils/ChangeLog index a6b7728..8f4d625 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,7 @@ +2000-11-24 Nick Clifton + + * NEWS: Announce support for v5t, v5te and XScale. + 2000-11-22 Nick Clifton * readelf.c (get_machine_name): Add EM_JAVELIN, EM_FIREPATH, diff --git a/binutils/NEWS b/binutils/NEWS index 7e5e91f..62f858f 100644 --- a/binutils/NEWS +++ b/binutils/NEWS @@ -1,7 +1,10 @@ -*- text -*- -* Add --srec-len and --srec-forceS3 command line switch to objcopy. By Luciano - Gemme. +* Add support for ARM v5t and v5te architectures and Intel's XScale ARM + extenstions. + +* Add --srec-len and --srec-forceS3 command line switch to objcopy. + By Luciano Gemme. * Support for the MIPS32, by Anders Norlander. diff --git a/configure.in b/configure.in index 5bb8895..b9e1b71 100644 --- a/configure.in +++ b/configure.in @@ -628,12 +628,6 @@ case "${target}" in arm-*-oabi*) noconfigdirs="$noconfigdirs target-libgloss target-libffi" ;; - c4x-*-*) - noconfigdirs="$noconfigdirs ${libstdcxx_version} target-libgloss target-libffi" - ;; - c54x*-*-* | tic54x-*-*) - noconfigdirs="$noconfigdirs ${libstdcxx_version} target-libgloss target-libffi gcc gdb newlib" - ;; thumb-*-coff) noconfigdirs="$noconfigdirs target-libgloss target-libffi" ;; @@ -655,12 +649,30 @@ case "${target}" in target_configdirs="${target_configdirs} target-bsp target-cygmon" fi ;; + xscale-*-elf) + noconfigdirs="$noconfigdirs target-libgloss target-libffi" + if [ x${is_cross_compiler} != xno ] ; then + target_configdirs="${target_configdirs} target-bsp target-cygmon" + fi + ;; + xscale-*-coff) + noconfigdirs="$noconfigdirs target-libgloss target-libffi" + if [ x${is_cross_compiler} != xno ] ; then + target_configdirs="${target_configdirs} target-bsp target-cygmon" + fi + ;; thumb-*-pe) noconfigdirs="$noconfigdirs target-libgloss target-libffi" ;; arm-*-riscix*) noconfigdirs="$noconfigdirs ld target-libgloss target-libffi" ;; + c4x-*-*) + noconfigdirs="$noconfigdirs ${libstdcxx_version} target-libgloss target-libffi" + ;; + c54x*-*-* | tic54x-*-*) + noconfigdirs="$noconfigdirs ${libstdcxx_version} target-libgloss target-libffi gcc gdb newlib" + ;; d10v-*-*) noconfigdirs="$noconfigdirs ${libstdcxx_version} target-libgloss target-libffi" ;; diff --git a/gas/ChangeLog b/gas/ChangeLog index b402fb2..5ab54b2 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,45 @@ +2000-11-24 Nick Clifton + + * configure.in (xscale-elf): Add target. + (xscale-coff): Add target. + * configure: Regenerate. + + * config/tc-arm.c (ARM_EXT_V5E): New ARM architecture + extenstion. + (ARM_EXT_XSCALE): New ARM architecture extension. + (ARM_LONGMUL): Rename to ARM_EXT_LONGMUL. + (ARM_HALFWORD): Rename to ARM_EXT_HALFWORD. + (ARM_THUMB): Rename to ARM_EXT_THUMB. + (ARM_ARCH_V4): Remove processor from architecture. + (ARM_ARCH_3M): New architecutre definition. + (ARM_ARCH_V5TE): New architecutre definition. + (ARM_ARCH_XSCALE): New architecutre definition. + (CPU_DEFAULT): Allow to be defaulted to XScale. + (atpcs): New boolean variable. + (ldr_flags): Support 'd' flag for double word loads. + (str_flags): Support 'd' flag for double word stored. + (do_mia): New function. + (do_mar): New function. + (do_mra): New function. + (do_pld): New function. + (do_ldrd): New function. + (do_blx): New function. + (do_bkpt): New function. + (do_clz): New function. + (do_lstc2): New function. + (do_cdp2): New function. + (do_t_blx): New function. + (do_t_bkpt): New function. + (do_smla): New function. + (do_smlal): New function. + (do_smul): New function. + (do_qadd): New function. + (do_co_reg2c): New function. + (LONGEST_INSN): Redefine to 7. + + * doc/c-arm.texi: Document -mxscale, -mmarmv5te and -matpcs + command line switches. + 2000-11-22 Jim Wilson * config/tc-ia64.c (pseudo_func): Add missing initializers. diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index b6dd51d..4bab476 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -50,16 +50,21 @@ #define ARM_CPU_MASK 0x0000000f /* The following bitmasks control CPU extensions (ARM7 onwards): */ -#define ARM_LONGMUL 0x00000010 /* Allow long multiplies. */ -#define ARM_HALFWORD 0x00000020 /* Allow half word loads. */ -#define ARM_THUMB 0x00000040 /* Allow BX instruction. */ +#define ARM_EXT_LONGMUL 0x00000010 /* Allow long multiplies. */ +#define ARM_EXT_HALFWORD 0x00000020 /* Allow half word loads. */ +#define ARM_EXT_THUMB 0x00000040 /* Allow BX instruction. */ #define ARM_EXT_V5 0x00000080 /* Allow CLZ, etc. */ +#define ARM_EXT_V5E 0x00000100 /* "El Segundo". */ +#define ARM_EXT_XSCALE 0x00000200 /* Allow MIA etc. */ /* Architectures are the sum of the base and extensions. */ -#define ARM_ARCH_V4 (ARM_7 | ARM_LONGMUL | ARM_HALFWORD) -#define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_THUMB) +#define ARM_ARCH_V3M ARM_EXT_LONGMUL +#define ARM_ARCH_V4 (ARM_ARCH_V3M | ARM_EXT_HALFWORD) +#define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_EXT_THUMB) #define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5) -#define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_THUMB) +#define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_EXT_THUMB) +#define ARM_ARCH_V5TE (ARM_ARCH_V5T | ARM_EXT_V5E) +#define ARM_ARCH_XSCALE (ARM_ARCH_V5TE | ARM_EXT_XSCALE) /* Some useful combinations: */ #define ARM_ANY 0x00ffffff @@ -78,10 +83,14 @@ #define FPU_MEMMULTI 0x7f000000 /* Not fpu_core. */ #ifndef CPU_DEFAULT +#if defined __XSCALE__ +#define CPU_DEFAULT (ARM_9 | ARM_ARCH_XSCALE) +#else #if defined __thumb__ -#define CPU_DEFAULT (ARM_ARCH_V4 | ARM_THUMB) +#define CPU_DEFAULT (ARM_7 | ARM_ARCH_V4T) #else -#define CPU_DEFAULT ARM_ALL +#define CPU_DEFAULT ARM_ALL +#endif #endif #endif @@ -98,6 +107,7 @@ static int target_oabi = 0; #if defined OBJ_COFF || defined OBJ_ELF /* Flags stored in private area of BFD structure. */ static boolean uses_apcs_26 = false; +static boolean atpcs = false; static boolean support_interwork = false; static boolean uses_apcs_float = false; static boolean pic_code = false; @@ -244,9 +254,11 @@ LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS]; #define CP_T_UD 0x00800000 #define CP_T_WB 0x00200000 -#define CONDS_BIT (0x00100000) -#define LOAD_BIT (0x00100000) -#define TRANS_BIT (0x00200000) +#define CONDS_BIT 0x00100000 +#define LOAD_BIT 0x00100000 +#define TRANS_BIT 0x00200000 + +#define DOUBLE_LOAD_FLAG 0x00000001 struct asm_cond { @@ -294,6 +306,7 @@ static CONST struct asm_flg s_flag[] = static CONST struct asm_flg ldr_flags[] = { + {"d", DOUBLE_LOAD_FLAG}, {"b", 0x00400000}, {"t", TRANS_BIT}, {"bt", 0x00400000 | TRANS_BIT}, @@ -305,6 +318,7 @@ static CONST struct asm_flg ldr_flags[] = static CONST struct asm_flg str_flags[] = { + {"d", DOUBLE_LOAD_FLAG}, {"b", 0x00400000}, {"t", TRANS_BIT}, {"bt", 0x00400000 | TRANS_BIT}, @@ -591,6 +605,31 @@ static void do_mull PARAMS ((char *, unsigned long)); /* ARM THUMB. */ static void do_bx PARAMS ((char *, unsigned long)); +/* ARM_EXT_XScale. */ +static void do_mia PARAMS ((char *, unsigned long)); +static void do_mar PARAMS ((char *, unsigned long)); +static void do_mra PARAMS ((char *, unsigned long)); +static void do_pld PARAMS ((char *, unsigned long)); +static void do_ldrd PARAMS ((char *, unsigned long)); + +/* ARM_EXT_V5. */ +static void do_blx PARAMS ((char *, unsigned long)); +static void do_bkpt PARAMS ((char *, unsigned long)); +static void do_clz PARAMS ((char *, unsigned long)); +static void do_lstc2 PARAMS ((char *, unsigned long)); +static void do_cdp2 PARAMS ((char *, unsigned long)); +static void do_co_reg2 PARAMS ((char *, unsigned long)); + +static void do_t_blx PARAMS ((char *)); +static void do_t_bkpt PARAMS ((char *)); + +/* ARM_EXT_V5E. */ +static void do_smla PARAMS ((char *, unsigned long)); +static void do_smlal PARAMS ((char *, unsigned long)); +static void do_smul PARAMS ((char *, unsigned long)); +static void do_qadd PARAMS ((char *, unsigned long)); +static void do_co_reg2c PARAMS ((char *, unsigned long)); + /* Coprocessor Instructions. */ static void do_cdp PARAMS ((char *, unsigned long)); static void do_lstc PARAMS ((char *, unsigned long)); @@ -648,10 +687,10 @@ static bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void)); take 2: */ #define INSN_SIZE 4 -/* LONGEST_INST is the longest basic instruction name without conditions or - flags. ARM7M has 4 of length 5. */ - -#define LONGEST_INST 5 +/* LONGEST_INST is the longest basic instruction name without + conditions or flags. ARM7M has 4 of length 5. El Segundo + has one basic instruction name of length 7 (SMLALxy). */ +#define LONGEST_INST 7 struct asm_opcode { @@ -677,6 +716,19 @@ struct asm_opcode static CONST struct asm_opcode insns[] = { +/* Intel XScale extensions to ARM V5 ISA. */ + {"mia", 0x0e200010, NULL, NULL, ARM_EXT_XSCALE, do_mia}, + {"miaph", 0x0e280010, NULL, NULL, ARM_EXT_XSCALE, do_mia}, + {"miabb", 0x0e2c0010, NULL, NULL, ARM_EXT_XSCALE, do_mia}, + {"miabt", 0x0e2d0010, NULL, NULL, ARM_EXT_XSCALE, do_mia}, + {"miatb", 0x0e2e0010, NULL, NULL, ARM_EXT_XSCALE, do_mia}, + {"miatt", 0x0e2f0010, NULL, NULL, ARM_EXT_XSCALE, do_mia}, + {"mar", 0x0c400000, NULL, NULL, ARM_EXT_XSCALE, do_mar}, + {"mra", 0x0c500000, NULL, NULL, ARM_EXT_XSCALE, do_mra}, + {"pld", 0xf450f000, "", NULL, ARM_EXT_XSCALE, do_pld}, + {"ldr", 0x000000d0, NULL, ldr_flags, ARM_ANY, do_ldrd}, + {"str", 0x000000f0, NULL, str_flags, ARM_ANY, do_ldrd}, + /* ARM Instructions. */ {"and", 0x00000000, NULL, s_flag, ARM_ANY, do_arit}, {"eor", 0x00200000, NULL, s_flag, ARM_ANY, do_arit}, @@ -727,13 +779,13 @@ static CONST struct asm_opcode insns[] = handled by the PSR_xxx defines above. */ /* ARM 7M long multiplies - need signed/unsigned flags! */ - {"smull", 0x00c00090, NULL, s_flag, ARM_LONGMUL, do_mull}, - {"umull", 0x00800090, NULL, s_flag, ARM_LONGMUL, do_mull}, - {"smlal", 0x00e00090, NULL, s_flag, ARM_LONGMUL, do_mull}, - {"umlal", 0x00a00090, NULL, s_flag, ARM_LONGMUL, do_mull}, + {"smull", 0x00c00090, NULL, s_flag, ARM_EXT_LONGMUL, do_mull}, + {"umull", 0x00800090, NULL, s_flag, ARM_EXT_LONGMUL, do_mull}, + {"smlal", 0x00e00090, NULL, s_flag, ARM_EXT_LONGMUL, do_mull}, + {"umlal", 0x00a00090, NULL, s_flag, ARM_EXT_LONGMUL, do_mull}, /* ARM THUMB interworking. */ - {"bx", 0x012fff10, NULL, NULL, ARM_THUMB, do_bx}, + {"bx", 0x012fff10, NULL, NULL, ARM_EXT_THUMB, do_bx}, /* Floating point instructions. */ {"wfs", 0x0e200110, NULL, NULL, FPU_ALL, do_fp_ctrl}, @@ -789,6 +841,48 @@ static CONST struct asm_opcode insns[] = {"stc", 0x0c000000, NULL, cplong_flag, ARM_2UP, do_lstc}, {"mcr", 0x0e000010, NULL, NULL, ARM_2UP, do_co_reg}, {"mrc", 0x0e100010, NULL, NULL, ARM_2UP, do_co_reg}, + +/* ARM ISA extension 5. */ +/* Note: blx is actually 2 opcodes, so the .value is set dynamically. + And it's sometimes conditional and sometimes not. */ + {"blx", 0, NULL, NULL, ARM_EXT_V5, do_blx}, + {"clz", 0x016f0f10, NULL, NULL, ARM_EXT_V5, do_clz}, + {"bkpt", 0xe1200070, "", NULL, ARM_EXT_V5, do_bkpt}, + {"ldc2", 0xfc100000, "", cplong_flag, ARM_EXT_V5, do_lstc2}, + {"stc2", 0xfc000000, "", cplong_flag, ARM_EXT_V5, do_lstc2}, + {"cdp2", 0xfe000000, "", NULL, ARM_EXT_V5, do_cdp2}, + {"mcr2", 0xfe000010, "", NULL, ARM_EXT_V5, do_co_reg2}, + {"mrc2", 0xfe100010, "", NULL, ARM_EXT_V5, do_co_reg2}, + +/* ARM ISA extension 5E, El Segundo. */ + {"smlabb", 0x01000080, NULL, NULL, ARM_EXT_V5E, do_smla}, + {"smlatb", 0x010000a0, NULL, NULL, ARM_EXT_V5E, do_smla}, + {"smlabt", 0x010000c0, NULL, NULL, ARM_EXT_V5E, do_smla}, + {"smlatt", 0x010000e0, NULL, NULL, ARM_EXT_V5E, do_smla}, + + {"smlawb", 0x01200080, NULL, NULL, ARM_EXT_V5E, do_smla}, + {"smlawt", 0x012000c0, NULL, NULL, ARM_EXT_V5E, do_smla}, + + {"smlalbb",0x01400080, NULL, NULL, ARM_EXT_V5E, do_smlal}, + {"smlaltb",0x014000a0, NULL, NULL, ARM_EXT_V5E, do_smlal}, + {"smlalbt",0x014000c0, NULL, NULL, ARM_EXT_V5E, do_smlal}, + {"smlaltt",0x014000e0, NULL, NULL, ARM_EXT_V5E, do_smlal}, + + {"smulbb", 0x01600080, NULL, NULL, ARM_EXT_V5E, do_smul}, + {"smultb", 0x016000a0, NULL, NULL, ARM_EXT_V5E, do_smul}, + {"smulbt", 0x016000c0, NULL, NULL, ARM_EXT_V5E, do_smul}, + {"smultt", 0x016000e0, NULL, NULL, ARM_EXT_V5E, do_smul}, + + {"smulwb", 0x012000a0, NULL, NULL, ARM_EXT_V5E, do_smul}, + {"smulwt", 0x012000e0, NULL, NULL, ARM_EXT_V5E, do_smul}, + + {"qadd", 0x01000050, NULL, NULL, ARM_EXT_V5E, do_qadd}, + {"qdadd", 0x01400050, NULL, NULL, ARM_EXT_V5E, do_qadd}, + {"qsub", 0x01200050, NULL, NULL, ARM_EXT_V5E, do_qadd}, + {"qdsub", 0x01600050, NULL, NULL, ARM_EXT_V5E, do_qadd}, + + {"mcrr", 0x0c400000, NULL, NULL, ARM_EXT_V5E, do_co_reg2c}, + {"mrrc", 0x0c500000, NULL, NULL, ARM_EXT_V5E, do_co_reg2c}, }; /* Defines for various bits that we will want to toggle. */ @@ -947,64 +1041,66 @@ struct thumb_opcode static CONST struct thumb_opcode tinsns[] = { - {"adc", 0x4140, 2, ARM_THUMB, do_t_arit}, - {"add", 0x0000, 2, ARM_THUMB, do_t_add}, - {"and", 0x4000, 2, ARM_THUMB, do_t_arit}, - {"asr", 0x0000, 2, ARM_THUMB, do_t_asr}, - {"b", T_OPCODE_BRANCH, 2, ARM_THUMB, do_t_branch12}, - {"beq", 0xd0fe, 2, ARM_THUMB, do_t_branch9}, - {"bne", 0xd1fe, 2, ARM_THUMB, do_t_branch9}, - {"bcs", 0xd2fe, 2, ARM_THUMB, do_t_branch9}, - {"bhs", 0xd2fe, 2, ARM_THUMB, do_t_branch9}, - {"bcc", 0xd3fe, 2, ARM_THUMB, do_t_branch9}, - {"bul", 0xd3fe, 2, ARM_THUMB, do_t_branch9}, - {"blo", 0xd3fe, 2, ARM_THUMB, do_t_branch9}, - {"bmi", 0xd4fe, 2, ARM_THUMB, do_t_branch9}, - {"bpl", 0xd5fe, 2, ARM_THUMB, do_t_branch9}, - {"bvs", 0xd6fe, 2, ARM_THUMB, do_t_branch9}, - {"bvc", 0xd7fe, 2, ARM_THUMB, do_t_branch9}, - {"bhi", 0xd8fe, 2, ARM_THUMB, do_t_branch9}, - {"bls", 0xd9fe, 2, ARM_THUMB, do_t_branch9}, - {"bge", 0xdafe, 2, ARM_THUMB, do_t_branch9}, - {"blt", 0xdbfe, 2, ARM_THUMB, do_t_branch9}, - {"bgt", 0xdcfe, 2, ARM_THUMB, do_t_branch9}, - {"ble", 0xddfe, 2, ARM_THUMB, do_t_branch9}, - {"bal", 0xdefe, 2, ARM_THUMB, do_t_branch9}, - {"bic", 0x4380, 2, ARM_THUMB, do_t_arit}, - {"bl", 0xf7fffffe, 4, ARM_THUMB, do_t_branch23}, - {"bx", 0x4700, 2, ARM_THUMB, do_t_bx}, - {"cmn", T_OPCODE_CMN, 2, ARM_THUMB, do_t_arit}, - {"cmp", 0x0000, 2, ARM_THUMB, do_t_compare}, - {"eor", 0x4040, 2, ARM_THUMB, do_t_arit}, - {"ldmia", 0xc800, 2, ARM_THUMB, do_t_ldmstm}, - {"ldr", 0x0000, 2, ARM_THUMB, do_t_ldr}, - {"ldrb", 0x0000, 2, ARM_THUMB, do_t_ldrb}, - {"ldrh", 0x0000, 2, ARM_THUMB, do_t_ldrh}, - {"ldrsb", 0x5600, 2, ARM_THUMB, do_t_lds}, - {"ldrsh", 0x5e00, 2, ARM_THUMB, do_t_lds}, - {"ldsb", 0x5600, 2, ARM_THUMB, do_t_lds}, - {"ldsh", 0x5e00, 2, ARM_THUMB, do_t_lds}, - {"lsl", 0x0000, 2, ARM_THUMB, do_t_lsl}, - {"lsr", 0x0000, 2, ARM_THUMB, do_t_lsr}, - {"mov", 0x0000, 2, ARM_THUMB, do_t_mov}, - {"mul", T_OPCODE_MUL, 2, ARM_THUMB, do_t_arit}, - {"mvn", T_OPCODE_MVN, 2, ARM_THUMB, do_t_arit}, - {"neg", T_OPCODE_NEG, 2, ARM_THUMB, do_t_arit}, - {"orr", 0x4300, 2, ARM_THUMB, do_t_arit}, - {"pop", 0xbc00, 2, ARM_THUMB, do_t_push_pop}, - {"push", 0xb400, 2, ARM_THUMB, do_t_push_pop}, - {"ror", 0x41c0, 2, ARM_THUMB, do_t_arit}, - {"sbc", 0x4180, 2, ARM_THUMB, do_t_arit}, - {"stmia", 0xc000, 2, ARM_THUMB, do_t_ldmstm}, - {"str", 0x0000, 2, ARM_THUMB, do_t_str}, - {"strb", 0x0000, 2, ARM_THUMB, do_t_strb}, - {"strh", 0x0000, 2, ARM_THUMB, do_t_strh}, - {"swi", 0xdf00, 2, ARM_THUMB, do_t_swi}, - {"sub", 0x0000, 2, ARM_THUMB, do_t_sub}, - {"tst", T_OPCODE_TST, 2, ARM_THUMB, do_t_arit}, + {"adc", 0x4140, 2, ARM_EXT_THUMB, do_t_arit}, + {"add", 0x0000, 2, ARM_EXT_THUMB, do_t_add}, + {"and", 0x4000, 2, ARM_EXT_THUMB, do_t_arit}, + {"asr", 0x0000, 2, ARM_EXT_THUMB, do_t_asr}, + {"b", T_OPCODE_BRANCH, 2, ARM_EXT_THUMB, do_t_branch12}, + {"beq", 0xd0fe, 2, ARM_EXT_THUMB, do_t_branch9}, + {"bne", 0xd1fe, 2, ARM_EXT_THUMB, do_t_branch9}, + {"bcs", 0xd2fe, 2, ARM_EXT_THUMB, do_t_branch9}, + {"bhs", 0xd2fe, 2, ARM_EXT_THUMB, do_t_branch9}, + {"bcc", 0xd3fe, 2, ARM_EXT_THUMB, do_t_branch9}, + {"bul", 0xd3fe, 2, ARM_EXT_THUMB, do_t_branch9}, + {"blo", 0xd3fe, 2, ARM_EXT_THUMB, do_t_branch9}, + {"bmi", 0xd4fe, 2, ARM_EXT_THUMB, do_t_branch9}, + {"bpl", 0xd5fe, 2, ARM_EXT_THUMB, do_t_branch9}, + {"bvs", 0xd6fe, 2, ARM_EXT_THUMB, do_t_branch9}, + {"bvc", 0xd7fe, 2, ARM_EXT_THUMB, do_t_branch9}, + {"bhi", 0xd8fe, 2, ARM_EXT_THUMB, do_t_branch9}, + {"bls", 0xd9fe, 2, ARM_EXT_THUMB, do_t_branch9}, + {"bge", 0xdafe, 2, ARM_EXT_THUMB, do_t_branch9}, + {"blt", 0xdbfe, 2, ARM_EXT_THUMB, do_t_branch9}, + {"bgt", 0xdcfe, 2, ARM_EXT_THUMB, do_t_branch9}, + {"ble", 0xddfe, 2, ARM_EXT_THUMB, do_t_branch9}, + {"bal", 0xdefe, 2, ARM_EXT_THUMB, do_t_branch9}, + {"bic", 0x4380, 2, ARM_EXT_THUMB, do_t_arit}, + {"bl", 0xf7fffffe, 4, ARM_EXT_THUMB, do_t_branch23}, + {"blx", 0, 0, ARM_EXT_V5, do_t_blx}, + {"bkpt", 0xbe00, 2, ARM_EXT_V5, do_t_bkpt}, + {"bx", 0x4700, 2, ARM_EXT_THUMB, do_t_bx}, + {"cmn", T_OPCODE_CMN, 2, ARM_EXT_THUMB, do_t_arit}, + {"cmp", 0x0000, 2, ARM_EXT_THUMB, do_t_compare}, + {"eor", 0x4040, 2, ARM_EXT_THUMB, do_t_arit}, + {"ldmia", 0xc800, 2, ARM_EXT_THUMB, do_t_ldmstm}, + {"ldr", 0x0000, 2, ARM_EXT_THUMB, do_t_ldr}, + {"ldrb", 0x0000, 2, ARM_EXT_THUMB, do_t_ldrb}, + {"ldrh", 0x0000, 2, ARM_EXT_THUMB, do_t_ldrh}, + {"ldrsb", 0x5600, 2, ARM_EXT_THUMB, do_t_lds}, + {"ldrsh", 0x5e00, 2, ARM_EXT_THUMB, do_t_lds}, + {"ldsb", 0x5600, 2, ARM_EXT_THUMB, do_t_lds}, + {"ldsh", 0x5e00, 2, ARM_EXT_THUMB, do_t_lds}, + {"lsl", 0x0000, 2, ARM_EXT_THUMB, do_t_lsl}, + {"lsr", 0x0000, 2, ARM_EXT_THUMB, do_t_lsr}, + {"mov", 0x0000, 2, ARM_EXT_THUMB, do_t_mov}, + {"mul", T_OPCODE_MUL, 2, ARM_EXT_THUMB, do_t_arit}, + {"mvn", T_OPCODE_MVN, 2, ARM_EXT_THUMB, do_t_arit}, + {"neg", T_OPCODE_NEG, 2, ARM_EXT_THUMB, do_t_arit}, + {"orr", 0x4300, 2, ARM_EXT_THUMB, do_t_arit}, + {"pop", 0xbc00, 2, ARM_EXT_THUMB, do_t_push_pop}, + {"push", 0xb400, 2, ARM_EXT_THUMB, do_t_push_pop}, + {"ror", 0x41c0, 2, ARM_EXT_THUMB, do_t_arit}, + {"sbc", 0x4180, 2, ARM_EXT_THUMB, do_t_arit}, + {"stmia", 0xc000, 2, ARM_EXT_THUMB, do_t_ldmstm}, + {"str", 0x0000, 2, ARM_EXT_THUMB, do_t_str}, + {"strb", 0x0000, 2, ARM_EXT_THUMB, do_t_strb}, + {"strh", 0x0000, 2, ARM_EXT_THUMB, do_t_strh}, + {"swi", 0xdf00, 2, ARM_EXT_THUMB, do_t_swi}, + {"sub", 0x0000, 2, ARM_EXT_THUMB, do_t_sub}, + {"tst", T_OPCODE_TST, 2, ARM_EXT_THUMB, do_t_arit}, /* Pseudo ops: */ - {"adr", 0x0000, 2, ARM_THUMB, do_t_adr}, - {"nop", 0x46C0, 2, ARM_THUMB, do_t_nop}, /* mov r8,r8 */ + {"adr", 0x0000, 2, ARM_EXT_THUMB, do_t_adr}, + {"nop", 0x46C0, 2, ARM_EXT_THUMB, do_t_nop}, /* mov r8,r8 */ }; struct reg_entry @@ -1061,6 +1157,7 @@ static CONST struct reg_entry reg_table[] = #define BAD_PC _("r15 not allowed here") #define BAD_FLAGS _("Instruction should not have flags") #define BAD_COND _("Instruction is not conditional") +#define ERR_NO_ACCUM _("acc0 expected") static struct hash_control * arm_ops_hsh = NULL; static struct hash_control * arm_tops_hsh = NULL; @@ -1613,7 +1710,7 @@ opcode_select (width) case 16: if (! thumb_mode) { - if (! (cpu_variant & ARM_THUMB)) + if (! (cpu_variant & ARM_EXT_THUMB)) as_bad (_("selected processor does not support THUMB opcodes")); thumb_mode = 1; @@ -1626,7 +1723,7 @@ opcode_select (width) case 32: if (thumb_mode) { - if ((cpu_variant & ARM_ANY) == ARM_THUMB) + if ((cpu_variant & ARM_ANY) == ARM_EXT_THUMB) as_bad (_("selected processor does not support ARM opcodes")); thumb_mode = 0; @@ -2134,254 +2231,1320 @@ do_mrs (str, flags) end_of_line (str); } -/* Two possible forms: - "{C|S}PSR_, Rm", - "{C|S}PSR_f, #expression". */ +/* Two possible forms: + "{C|S}PSR_, Rm", + "{C|S}PSR_f, #expression". */ + +static void +do_msr (str, flags) + char * str; + unsigned long flags; +{ + skip_whitespace (str); + + if (psr_required_here (& str) == FAIL) + return; + + if (skip_past_comma (& str) == FAIL) + { + inst.error = _("comma missing after psr flags"); + return; + } + + skip_whitespace (str); + + if (reg_required_here (& str, 0) != FAIL) + { + inst.error = NULL; + inst.instruction |= flags; + end_of_line (str); + return; + } + + if (! is_immediate_prefix (* str)) + { + inst.error = + _("only a register or immediate value can follow a psr flag"); + return; + } + + str ++; + inst.error = NULL; + + if (my_get_expression (& inst.reloc.exp, & str)) + { + inst.error = + _("only a register or immediate value can follow a psr flag"); + return; + } + + if ((cpu_variant & ARM_EXT_V5) != ARM_EXT_V5 + && inst.instruction & ((PSR_c | PSR_x | PSR_s) << PSR_SHIFT)) + { + inst.error = _("immediate value cannot be used to set this field"); + return; + } + + flags |= INST_IMMEDIATE; + + if (inst.reloc.exp.X_add_symbol) + { + inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE; + inst.reloc.pc_rel = 0; + } + else + { + unsigned value = validate_immediate (inst.reloc.exp.X_add_number); + + if (value == (unsigned) FAIL) + { + inst.error = _("Invalid constant"); + return; + } + + inst.instruction |= value; + } + + inst.error = NULL; + inst.instruction |= flags; + end_of_line (str); +} + +/* Long Multiply Parser + UMULL RdLo, RdHi, Rm, Rs + SMULL RdLo, RdHi, Rm, Rs + UMLAL RdLo, RdHi, Rm, Rs + SMLAL RdLo, RdHi, Rm, Rs. */ + +static void +do_mull (str, flags) + char * str; + unsigned long flags; +{ + int rdlo, rdhi, rm, rs; + + /* Only one format "rdlo, rdhi, rm, rs". */ + skip_whitespace (str); + + if ((rdlo = reg_required_here (&str, 12)) == FAIL) + { + inst.error = BAD_ARGS; + return; + } + + if (skip_past_comma (&str) == FAIL + || (rdhi = reg_required_here (&str, 16)) == FAIL) + { + inst.error = BAD_ARGS; + return; + } + + if (skip_past_comma (&str) == FAIL + || (rm = reg_required_here (&str, 0)) == FAIL) + { + inst.error = BAD_ARGS; + return; + } + + /* rdhi, rdlo and rm must all be different. */ + if (rdlo == rdhi || rdlo == rm || rdhi == rm) + as_tsktsk (_("rdhi, rdlo and rm must all be different")); + + if (skip_past_comma (&str) == FAIL + || (rs = reg_required_here (&str, 8)) == FAIL) + { + inst.error = BAD_ARGS; + return; + } + + if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC) + { + inst.error = BAD_PC; + return; + } + + inst.instruction |= flags; + end_of_line (str); + return; +} + +static void +do_mul (str, flags) + char * str; + unsigned long flags; +{ + int rd, rm; + + /* Only one format "rd, rm, rs". */ + skip_whitespace (str); + + if ((rd = reg_required_here (&str, 16)) == FAIL) + { + inst.error = BAD_ARGS; + return; + } + + if (rd == REG_PC) + { + inst.error = BAD_PC; + return; + } + + if (skip_past_comma (&str) == FAIL + || (rm = reg_required_here (&str, 0)) == FAIL) + { + inst.error = BAD_ARGS; + return; + } + + if (rm == REG_PC) + { + inst.error = BAD_PC; + return; + } + + if (rm == rd) + as_tsktsk (_("rd and rm should be different in mul")); + + if (skip_past_comma (&str) == FAIL + || (rm = reg_required_here (&str, 8)) == FAIL) + { + inst.error = BAD_ARGS; + return; + } + + if (rm == REG_PC) + { + inst.error = BAD_PC; + return; + } + + inst.instruction |= flags; + end_of_line (str); + return; +} + +static void +do_mla (str, flags) + char * str; + unsigned long flags; +{ + int rd, rm; + + /* Only one format "rd, rm, rs, rn". */ + skip_whitespace (str); + + if ((rd = reg_required_here (&str, 16)) == FAIL) + { + inst.error = BAD_ARGS; + return; + } + + if (rd == REG_PC) + { + inst.error = BAD_PC; + return; + } + + if (skip_past_comma (&str) == FAIL + || (rm = reg_required_here (&str, 0)) == FAIL) + { + inst.error = BAD_ARGS; + return; + } + + if (rm == REG_PC) + { + inst.error = BAD_PC; + return; + } + + if (rm == rd) + as_tsktsk (_("rd and rm should be different in mla")); + + if (skip_past_comma (&str) == FAIL + || (rd = reg_required_here (&str, 8)) == FAIL + || skip_past_comma (&str) == FAIL + || (rm = reg_required_here (&str, 12)) == FAIL) + { + inst.error = BAD_ARGS; + return; + } + + if (rd == REG_PC || rm == REG_PC) + { + inst.error = BAD_PC; + return; + } + + inst.instruction |= flags; + end_of_line (str); + return; +} + +/* Expects *str -> the characters "acc0", possibly with leading blanks. + Advances *str to the next non-alphanumeric. + Returns 0, or else FAIL (in which case sets inst.error). + + (In a future XScale, there may be accumulators other than zero. + At that time this routine and its callers can be upgraded to suit.) */ + +static int +accum0_required_here (str) + char ** str; +{ + static char buff [128]; /* Note the address is taken. Hence, static. */ + char * p = * str; + char c; + int result = 0; /* The accum number. */ + + skip_whitespace (p); + + *str = p; /* Advance caller's string pointer too. */ + c = *p++; + while (isalnum (c)) + c = *p++; + + *--p = 0; /* Aap nul into input buffer at non-alnum. */ + + if (! ( streq (*str, "acc0") || streq (*str, "ACC0"))) + { + sprintf (buff, _("acc0 expected, not '%.100s'"), *str); + inst.error = buff; + result = FAIL; + } + + *p = c; /* Unzap. */ + *str = p; /* Caller's string pointer to after match. */ + return result; +} + +/* Expects **str -> after a comma. May be leading blanks. + Advances *str, recognizing a load mode, and setting inst.instruction. + Returns rn, or else FAIL (in which case may set inst.error + and not advance str) + + Note: doesn't know Rd, so no err checks that require such knowledge. */ + +static int +ld_mode_required_here (string) + char ** string; +{ + char * str = * string; + int rn; + int pre_inc = 0; + + skip_whitespace (str); + + if (* str == '[') + { + str++; + + skip_whitespace (str); + + if ((rn = reg_required_here (& str, 16)) == FAIL) + return FAIL; + + skip_whitespace (str); + + if (* str == ']') + { + str ++; + + if (skip_past_comma (& str) == SUCCESS) + { + /* [Rn],... (post inc) */ + if (ldst_extend (& str, 1) == FAIL) + return FAIL; + } + else /* [Rn] */ + { + skip_whitespace (str); + + if (* str == '!') + { + str ++; + inst.instruction |= WRITE_BACK; + } + + inst.instruction |= INDEX_UP | HWOFFSET_IMM; + pre_inc = 1; + } + } + else /* [Rn,...] */ + { + if (skip_past_comma (& str) == FAIL) + { + inst.error = _("pre-indexed expression expected"); + return FAIL; + } + + pre_inc = 1; + + if (ldst_extend (& str, 1) == FAIL) + return FAIL; + + skip_whitespace (str); + + if (* str ++ != ']') + { + inst.error = _("missing ]"); + return FAIL; + } + + skip_whitespace (str); + + if (* str == '!') + { + str ++; + inst.instruction |= WRITE_BACK; + } + } + } + else if (* str == '=') /* ldr's "r,=label" syntax */ + /* We should never reach here, because = is + caught gas/read.c read_a_source_file() as a .set operation. */ + return FAIL; + else /* PC +- 8 bit immediate offset. */ + { + if (my_get_expression (& inst.reloc.exp, & str)) + return FAIL; + + inst.instruction |= HWOFFSET_IMM; /* The I bit. */ + inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8; + inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */ + inst.reloc.pc_rel = 1; + inst.instruction |= (REG_PC << 16); + + rn = REG_PC; + pre_inc = 1; + } + + inst.instruction |= (pre_inc ? PRE_INDEX : 0); + * string = str; + + return rn; +} + +/* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse) + SMLAxy{cond} Rd,Rm,Rs,Rn + SMLAWy{cond} Rd,Rm,Rs,Rn + Error if any register is R15. */ + +static void +do_smla (str, flags) + char * str; + unsigned long flags; +{ + int rd, rm, rs, rn; + + skip_whitespace (str); + + if ((rd = reg_required_here (& str, 16)) == FAIL + || skip_past_comma (& str) == FAIL + || (rm = reg_required_here (& str, 0)) == FAIL + || skip_past_comma (& str) == FAIL + || (rs = reg_required_here (& str, 8)) == FAIL + || skip_past_comma (& str) == FAIL + || (rn = reg_required_here (& str, 12)) == FAIL) + inst.error = BAD_ARGS; + + else if (rd == REG_PC || rm == REG_PC || rs == REG_PC || rn == REG_PC) + inst.error = BAD_PC; + + else if (flags) + inst.error = BAD_FLAGS; + + else + end_of_line (str); +} + +/* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse) + SMLALxy{cond} Rdlo,Rdhi,Rm,Rs + Error if any register is R15. + Warning if Rdlo == Rdhi. */ + +static void +do_smlal (str, flags) + char * str; + unsigned long flags; +{ + int rdlo, rdhi, rm, rs; + + skip_whitespace (str); + + if ((rdlo = reg_required_here (& str, 12)) == FAIL + || skip_past_comma (& str) == FAIL + || (rdhi = reg_required_here (& str, 16)) == FAIL + || skip_past_comma (& str) == FAIL + || (rm = reg_required_here (& str, 0)) == FAIL + || skip_past_comma (& str) == FAIL + || (rs = reg_required_here (& str, 8)) == FAIL) + { + inst.error = BAD_ARGS; + return; + } + + if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC) + { + inst.error = BAD_PC; + return; + } + + if (rdlo == rdhi) + as_tsktsk (_("rdhi and rdlo must be different")); + + if (flags) + inst.error = BAD_FLAGS; + else + end_of_line (str); +} + +/* ARM V5E (El Segundo) signed-multiply (argument parse) + SMULxy{cond} Rd,Rm,Rs + Error if any register is R15. */ + +static void +do_smul (str, flags) + char * str; + unsigned long flags; +{ + int rd, rm, rs; + + skip_whitespace (str); + + if ((rd = reg_required_here (& str, 16)) == FAIL + || skip_past_comma (& str) == FAIL + || (rm = reg_required_here (& str, 0)) == FAIL + || skip_past_comma (& str) == FAIL + || (rs = reg_required_here (& str, 8)) == FAIL) + inst.error = BAD_ARGS; + + else if (rd == REG_PC || rm == REG_PC || rs == REG_PC) + inst.error = BAD_PC; + + else if (flags) + inst.error = BAD_FLAGS; + + else + end_of_line (str); +} + +/* ARM V5E (El Segundo) saturating-add/subtract (argument parse) + Q[D]{ADD,SUB}{cond} Rd,Rm,Rn + Error if any register is R15. */ + +static void +do_qadd (str, flags) + char * str; + unsigned long flags; +{ + int rd, rm, rn; + + skip_whitespace (str); + + if ((rd = reg_required_here (& str, 12)) == FAIL + || skip_past_comma (& str) == FAIL + || (rm = reg_required_here (& str, 0)) == FAIL + || skip_past_comma (& str) == FAIL + || (rn = reg_required_here (& str, 16)) == FAIL) + inst.error = BAD_ARGS; + + else if (rd == REG_PC || rm == REG_PC || rn == REG_PC) + inst.error = BAD_PC; + + else if (flags) + inst.error = BAD_FLAGS; + + else + end_of_line (str); +} + +/* ARM V5E (el Segundo) + MCRRcc , , , , . + MRRCcc , , , , . + + These are equivalent to the XScale instructions MAR and MRA, + respectively, when coproc == 0, opcode == 0, and CRm == 0. + + Result unpredicatable if Rd or Rn is R15. */ + +static void +do_co_reg2c (str, flags) + char * str; + unsigned long flags; +{ + int rd, rn; + + skip_whitespace (str); + + if (co_proc_number (& str) == FAIL) + { + if (!inst.error) + inst.error = BAD_ARGS; + return; + } + + if (skip_past_comma (& str) == FAIL + || cp_opc_expr (& str, 4, 4) == FAIL) + { + if (!inst.error) + inst.error = BAD_ARGS; + return; + } + + if (skip_past_comma (& str) == FAIL + || (rd = reg_required_here (& str, 12)) == FAIL) + { + if (!inst.error) + inst.error = BAD_ARGS; + return; + } + + if (skip_past_comma (& str) == FAIL + || (rn = reg_required_here (& str, 16)) == FAIL) + { + if (!inst.error) + inst.error = BAD_ARGS; + return; + } + + /* Unpredictable result if rd or rn is R15. */ + if (rd == REG_PC || rn == REG_PC) + as_tsktsk + (_("Warning: Instruction unpredictable when using r15")); + + if (skip_past_comma (& str) == FAIL + || cp_reg_required_here (& str, 0) == FAIL) + { + if (!inst.error) + inst.error = BAD_ARGS; + return; + } + + if (flags) + inst.error = BAD_COND; + + end_of_line (str); +} + + +/* ARM V5 count-leading-zeroes instruction (argument parse) + CLZ{} , + Condition defaults to COND_ALWAYS. + Error if Rd or Rm are R15. */ + +static void +do_clz (str, flags) + char * str; + unsigned long flags; +{ + int rd, rm; + + if (flags) + { + as_bad (BAD_FLAGS); + return; + } + + skip_whitespace (str); + + if (((rd = reg_required_here (& str, 12)) == FAIL) + || (skip_past_comma (& str) == FAIL) + || ((rm = reg_required_here (& str, 0)) == FAIL)) + inst.error = BAD_ARGS; + + else if (rd == REG_PC || rm == REG_PC ) + inst.error = BAD_PC; + + else + end_of_line (str); +} + +/* ARM V5 (argument parse) + LDC2{L} , , + STC2{L} , , + Instruction is not conditional, and has 0xf in the codition field. + Otherwise, it's the same as LDC/STC. */ + +static void +do_lstc2 (str, flags) + char * str; + unsigned long flags; +{ + if (flags) + inst.error = BAD_COND; + + skip_whitespace (str); + + if (co_proc_number (& str) == FAIL) + { + if (!inst.error) + inst.error = BAD_ARGS; + } + else if (skip_past_comma (& str) == FAIL + || cp_reg_required_here (& str, 12) == FAIL) + { + if (!inst.error) + inst.error = BAD_ARGS; + } + else if (skip_past_comma (& str) == FAIL + || cp_address_required_here (& str) == FAIL) + { + if (! inst.error) + inst.error = BAD_ARGS; + } + else + end_of_line (str); +} + +/* ARM V5 (argument parse) + CDP2 , , , , , + Instruction is not conditional, and has 0xf in the condition field. + Otherwise, it's the same as CDP. */ + +static void +do_cdp2 (str, flags) + char * str; + unsigned long flags; +{ + skip_whitespace (str); + + if (co_proc_number (& str) == FAIL) + { + if (!inst.error) + inst.error = BAD_ARGS; + return; + } + + if (skip_past_comma (& str) == FAIL + || cp_opc_expr (& str, 20,4) == FAIL) + { + if (!inst.error) + inst.error = BAD_ARGS; + return; + } + + if (skip_past_comma (& str) == FAIL + || cp_reg_required_here (& str, 12) == FAIL) + { + if (!inst.error) + inst.error = BAD_ARGS; + return; + } + + if (skip_past_comma (& str) == FAIL + || cp_reg_required_here (& str, 16) == FAIL) + { + if (!inst.error) + inst.error = BAD_ARGS; + return; + } + + if (skip_past_comma (& str) == FAIL + || cp_reg_required_here (& str, 0) == FAIL) + { + if (!inst.error) + inst.error = BAD_ARGS; + return; + } + + if (skip_past_comma (& str) == SUCCESS) + { + if (cp_opc_expr (& str, 5, 3) == FAIL) + { + if (!inst.error) + inst.error = BAD_ARGS; + return; + } + } + + if (flags) + inst.error = BAD_FLAGS; + + end_of_line (str); +} + +/* ARM V5 (argument parse) + MCR2 , , , , , + MRC2 , , , , , + Instruction is not conditional, and has 0xf in the condition field. + Otherwise, it's the same as MCR/MRC. */ + +static void +do_co_reg2 (str, flags) + char * str; + unsigned long flags; +{ + skip_whitespace (str); + + if (co_proc_number (& str) == FAIL) + { + if (!inst.error) + inst.error = BAD_ARGS; + return; + } + + if (skip_past_comma (& str) == FAIL + || cp_opc_expr (& str, 21, 3) == FAIL) + { + if (!inst.error) + inst.error = BAD_ARGS; + return; + } + + if (skip_past_comma (& str) == FAIL + || reg_required_here (& str, 12) == FAIL) + { + if (!inst.error) + inst.error = BAD_ARGS; + return; + } + + if (skip_past_comma (& str) == FAIL + || cp_reg_required_here (& str, 16) == FAIL) + { + if (!inst.error) + inst.error = BAD_ARGS; + return; + } + + if (skip_past_comma (& str) == FAIL + || cp_reg_required_here (& str, 0) == FAIL) + { + if (!inst.error) + inst.error = BAD_ARGS; + return; + } + + if (skip_past_comma (& str) == SUCCESS) + { + if (cp_opc_expr (& str, 5, 3) == FAIL) + { + if (!inst.error) + inst.error = BAD_ARGS; + return; + } + } + + if (flags) + inst.error = BAD_COND; + + end_of_line (str); +} + +/* THUMB V5 breakpoint instruction (argument parse) + BKPT . */ + +static void +do_t_bkpt (str) + char * str; +{ + expressionS expr; + unsigned long number; + + skip_whitespace (str); + + /* Allow optional leading '#'. */ + if (is_immediate_prefix (*str)) + str ++; + + memset (& expr, '\0', sizeof (expr)); + if (my_get_expression (& expr, & str) || (expr.X_op != O_constant)) + { + inst.error = _("bad or missing expression"); + return; + } + + number = expr.X_add_number; + + /* Check it fits an 8 bit unsigned. */ + if (number != (number & 0xff)) + { + inst.error = _("immediate value out of range"); + return; + } + + inst.instruction |= number; + + end_of_line (str); +} + +/* ARM V5 branch-link-exchange (argument parse) for BLX(1) only. + Expects inst.instruction is set for BLX(1). + Note: this is cloned from do_branch, and the reloc changed to be a + new one that can cope with setting one extra bit (the H bit). */ + +static void +do_branch25 (str, flags) + char * str; + unsigned long flags ATTRIBUTE_UNUSED; +{ + if (my_get_expression (& inst.reloc.exp, & str)) + return; + +#ifdef OBJ_ELF + { + char * save_in; + + /* ScottB: February 5, 1998 */ + /* Check to see of PLT32 reloc required for the instruction. */ + + /* arm_parse_reloc() works on input_line_pointer. + We actually want to parse the operands to the branch instruction + passed in 'str'. Save the input pointer and restore it later. */ + save_in = input_line_pointer; + input_line_pointer = str; + + if (inst.reloc.exp.X_op == O_symbol + && *str == '(' + && arm_parse_reloc () == BFD_RELOC_ARM_PLT32) + { + inst.reloc.type = BFD_RELOC_ARM_PLT32; + inst.reloc.pc_rel = 0; + /* Modify str to point to after parsed operands, otherwise + end_of_line() will complain about the (PLT) left in str. */ + str = input_line_pointer; + } + else + { + inst.reloc.type = BFD_RELOC_ARM_PCREL_BLX; + inst.reloc.pc_rel = 1; + } + + input_line_pointer = save_in; + } +#else + inst.reloc.type = BFD_RELOC_ARM_PCREL_BLX; + inst.reloc.pc_rel = 1; +#endif /* OBJ_ELF */ + + end_of_line (str); +} + +/* ARM V5 branch-link-exchange instruction (argument parse) + BLX ie BLX(1) + BLX{} ie BLX(2) + Unfortunately, there are two different opcodes for this mnemonic. + So, the insns[].value is not used, and the code here zaps values + into inst.instruction. + Also, the can be 25 bits, hence has its own reloc. */ static void -do_msr (str, flags) - char * str; +do_blx (str, flags) + char * str; unsigned long flags; { - skip_whitespace (str); - - if (psr_required_here (& str) == FAIL) - return; + char * mystr = str; + int rm; - if (skip_past_comma (& str) == FAIL) + if (flags) { - inst.error = _("comma missing after psr flags"); + as_bad (BAD_FLAGS); return; } - - skip_whitespace (str); - - if (reg_required_here (& str, 0) != FAIL) - { - inst.error = NULL; - inst.instruction |= flags; - end_of_line (str); - return; + + skip_whitespace (mystr); + rm = reg_required_here (& mystr, 0); + + /* The above may set inst.error. Ignore his opinion. */ + inst.error = 0; + + if (rm != FAIL) + { + /* Arg is a register. + Use the condition code our caller put in inst.instruction. + Pass ourselves off as a BX with a funny opcode. */ + inst.instruction |= 0x012fff30; + do_bx (str, flags); } - - if (! is_immediate_prefix (* str)) + else { - inst.error = - _("only a register or immediate value can follow a psr flag"); - return; + /* This must be is BLX , no condition allowed. */ + if (inst.instruction != COND_ALWAYS) + { + inst.error = BAD_COND; + return; + } + + inst.instruction = 0xfafffffe; + + /* Process like a B/BL, but with a different reloc. + Note that B/BL expecte fffffe, not 0, offset in the opcode table. */ + do_branch25 (str, flags); } +} - str ++; - inst.error = NULL; - - if (my_get_expression (& inst.reloc.exp, & str)) - { - inst.error = - _("only a register or immediate value can follow a psr flag"); - return; - } +/* ARM V5 Thumb BLX (argument parse) + BLX which is BLX(1) + BLX which is BLX(2) + Unfortunately, there are two different opcodes for this mnemonic. + So, the tinsns[].value is not used, and the code here zaps values + into inst.instruction. */ - if (inst.instruction & ((PSR_c | PSR_x | PSR_s) << PSR_SHIFT)) - { - inst.error = _("only flag field of psr can be set with immediate value"); - return; - } +static void +do_t_blx (str) + char * str; +{ + char * mystr = str; + int rm; - flags |= INST_IMMEDIATE; + skip_whitespace (mystr); + inst.instruction = 0x4780; - if (inst.reloc.exp.X_add_symbol) + /* Note that this call is to the ARM register recognizer. BLX(2) + uses the ARM register space, not the Thumb one, so a call to + thumb_reg() would be wrong. */ + rm = reg_required_here (& mystr, 3); + inst.error = 0; + + if (rm != FAIL) { - inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE; - inst.reloc.pc_rel = 0; + /* It's BLX(2). The .instruction was zapped with rm & is final. */ + inst.size = 2; } else { - unsigned value = validate_immediate (inst.reloc.exp.X_add_number); - - if (value == (unsigned) FAIL) - { - inst.error = _("Invalid constant"); - return; - } + /* No ARM register. This must be BLX(1). Change the .instruction. */ + inst.instruction = 0xf7ffeffe; + inst.size = 4; - inst.instruction |= value; + if (my_get_expression (& inst.reloc.exp, & mystr)) + return; + + inst.reloc.type = BFD_RELOC_THUMB_PCREL_BLX; + inst.reloc.pc_rel = 1; } - - inst.error = NULL; - inst.instruction |= flags; - end_of_line (str); + + end_of_line (mystr); } -/* Long Multiply Parser - UMULL RdLo, RdHi, Rm, Rs - SMULL RdLo, RdHi, Rm, Rs - UMLAL RdLo, RdHi, Rm, Rs - SMLAL RdLo, RdHi, Rm, Rs. */ +/* ARM V5 breakpoint instruction (argument parse) + BKPT <16 bit unsigned immediate> + Instruction is not conditional. + The bit pattern given in insns[] has the COND_ALWAYS condition, + and it is an error if the caller tried to override that. + Note "flags" is nonzero if a flag was supplied (which is an error). */ static void -do_mull (str, flags) - char * str; +do_bkpt (str, flags) + char * str; unsigned long flags; { - int rdlo, rdhi, rm, rs; + expressionS expr; + unsigned long number; - /* Only one format "rdlo, rdhi, rm, rs". */ skip_whitespace (str); + + /* Allow optional leading '#'. */ + if (is_immediate_prefix (* str)) + str++; - if ((rdlo = reg_required_here (&str, 12)) == FAIL) + memset (& expr, '\0', sizeof (expr)); + + if (my_get_expression (& expr, & str) || (expr.X_op != O_constant)) { - inst.error = BAD_ARGS; + inst.error = _("bad or missing expression"); return; } - - if (skip_past_comma (&str) == FAIL - || (rdhi = reg_required_here (&str, 16)) == FAIL) + + number = expr.X_add_number; + + /* Check it fits a 16 bit unsigned. */ + if (number != (number & 0xffff)) { - inst.error = BAD_ARGS; + inst.error = _("immediate value out of range"); return; } + + /* Top 12 of 16 bits to bits 19:8. */ + inst.instruction |= (number & 0xfff0) << 4; + + /* Bottom 4 of 16 bits to bits 3:0. */ + inst.instruction |= number & 0xf; - if (skip_past_comma (&str) == FAIL - || (rm = reg_required_here (&str, 0)) == FAIL) - { - inst.error = BAD_ARGS; - return; - } + end_of_line (str); - /* rdhi, rdlo and rm must all be different. */ - if (rdlo == rdhi || rdlo == rm || rdhi == rm) - as_tsktsk (_("rdhi, rdlo and rm must all be different")); + if (flags) + inst.error = BAD_FLAGS; +} - if (skip_past_comma (&str) == FAIL - || (rs = reg_required_here (&str, 8)) == FAIL) - { - inst.error = BAD_ARGS; - return; - } +/* Xscale multiply-accumulate (argument parse) + MIAcc acc0,Rm,Rs + MIAPHcc acc0,Rm,Rs + MIAxycc acc0,Rm,Rs. */ - if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC) - { - inst.error = BAD_PC; - return; - } +static void +do_mia (str, flags) + char * str; + unsigned long flags; +{ + int rs; + int rm; - inst.instruction |= flags; - end_of_line (str); - return; + if (flags) + as_bad (BAD_FLAGS); + + else if (accum0_required_here (& str) == FAIL) + inst.error = ERR_NO_ACCUM; + + else if (skip_past_comma (& str) == FAIL + || (rm = reg_required_here (& str, 0)) == FAIL) + inst.error = BAD_ARGS; + + else if (skip_past_comma (& str) == FAIL + || (rs = reg_required_here (& str, 12)) == FAIL) + inst.error = BAD_ARGS; + + /* inst.instruction has now been zapped with both rm and rs. */ + else if (rm == REG_PC || rs == REG_PC) + inst.error = BAD_PC; /* Undefined result if rm or rs is R15. */ + + else + end_of_line (str); } +/* Xscale move-accumulator-register (argument parse) + + MARcc acc0,RdLo,RdHi. */ + static void -do_mul (str, flags) +do_mar (str, flags) char * str; unsigned long flags; { - int rd, rm; + int rdlo, rdhi; - /* Only one format "rd, rm, rs". */ - skip_whitespace (str); + if (flags) + as_bad (BAD_FLAGS); + + else if (accum0_required_here (& str) == FAIL) + inst.error = ERR_NO_ACCUM; + + else if (skip_past_comma (& str) == FAIL + || (rdlo = reg_required_here (& str, 12)) == FAIL) + inst.error = BAD_ARGS; + + else if (skip_past_comma (& str) == FAIL + || (rdhi = reg_required_here (& str, 16)) == FAIL) + inst.error = BAD_ARGS; + + /* inst.instruction has now been zapped with both rdlo and rdhi. */ + else if (rdlo == REG_PC || rdhi == REG_PC) + inst.error = BAD_PC; /* Undefined result if rdlo or rdhi is R15. */ + + else + end_of_line (str); +} - if ((rd = reg_required_here (&str, 16)) == FAIL) - { - inst.error = BAD_ARGS; - return; - } +/* Xscale move-register-accumulator (argument parse) - if (rd == REG_PC) + MRAcc RdLo,RdHi,acc0. */ + +static void +do_mra (str, flags) + char * str; + unsigned long flags; +{ + int rdlo; + int rdhi; + + if (flags) { - inst.error = BAD_PC; + as_bad (BAD_FLAGS); return; } - if (skip_past_comma (&str) == FAIL - || (rm = reg_required_here (&str, 0)) == FAIL) + skip_whitespace (str); + + if ((rdlo = reg_required_here (& str, 12)) == FAIL) + inst.error = BAD_ARGS; + + else if (skip_past_comma (& str) == FAIL + || (rdhi = reg_required_here (& str, 16)) == FAIL) + inst.error = BAD_ARGS; + + else if (skip_past_comma (& str) == FAIL + || accum0_required_here (& str) == FAIL) + inst.error = ERR_NO_ACCUM; + + /* inst.instruction has now been zapped with both rdlo and rdhi. */ + else if (rdlo == rdhi) + inst.error = BAD_ARGS; /* Undefined result if 2 writes to same reg. */ + + else if (rdlo == REG_PC || rdhi == REG_PC) + inst.error = BAD_PC; /* Undefined result if rdlo or rdhi is R15. */ + else + end_of_line (str); +} + +/* Xscale: Preload-Cache + + PLD + + Syntactically, like LDR with B=1, W=0, L=1. */ + +static void +do_pld (str, flags) + char * str; + unsigned long flags; +{ + int rd; + + if (flags) { - inst.error = BAD_ARGS; + as_bad (BAD_FLAGS); return; } - if (rm == REG_PC) + skip_whitespace (str); + + if (* str != '[') { - inst.error = BAD_PC; + inst.error = _("'[' expected after PLD mnemonic"); return; } - if (rm == rd) - as_tsktsk (_("rd and rm should be different in mul")); + ++ str; + skip_whitespace (str); - if (skip_past_comma (&str) == FAIL - || (rm = reg_required_here (&str, 8)) == FAIL) + if ((rd = reg_required_here (& str, 16)) == FAIL) + return; + + skip_whitespace (str); + + if (* str == ']') { - inst.error = BAD_ARGS; - return; - } + /* [Rn], ... ? */ + ++ str; + skip_whitespace (str); - if (rm == REG_PC) + if (skip_past_comma (& str) == SUCCESS) + { + if (ldst_extend (& str, 0) == FAIL) + return; + } + else if (* str == '!') /* [Rn]! */ + { + inst.error = _("writeback used in preload instruction"); + ++ str; + } + else /* [Rn] */ + inst.instruction |= INDEX_UP | PRE_INDEX; + } + else /* [Rn, ...] */ { - inst.error = BAD_PC; - return; + if (skip_past_comma (& str) == FAIL) + { + inst.error = _("pre-indexed expression expected"); + return; + } + + if (ldst_extend (& str, 0) == FAIL) + return; + + skip_whitespace (str); + + if (* str != ']') + { + inst.error = _("missing ]"); + return; + } + + ++ str; + skip_whitespace (str); + + if (* str == '!') /* [Rn]! */ + { + inst.error = _("writeback used in preload instruction"); + ++ str; + } + + inst.instruction |= PRE_INDEX; } - inst.instruction |= flags; end_of_line (str); - return; } +/* Xscale load-consecutive (argument parse) + Mode is like LDRH. + + LDRccD R, mode + STRccD R, mode. */ + static void -do_mla (str, flags) +do_ldrd (str, flags) char * str; unsigned long flags; { - int rd, rm; - - /* Only one format "rd, rm, rs, rn". */ - skip_whitespace (str); + int rd; + int rn; - if ((rd = reg_required_here (&str, 16)) == FAIL) + if (flags != DOUBLE_LOAD_FLAG) { - inst.error = BAD_ARGS; + /* Change instruction pattern to normal ldr/str. */ + if (inst.instruction & 0x20) + inst.instruction = (inst.instruction & COND_MASK) | 0x04000000; /* str */ + else + inst.instruction = (inst.instruction & COND_MASK) | 0x04100000; /* ldr */ + + /* Perform a normal load/store instruction parse. */ + do_ldst (str, flags); + return; } - - if (rd == REG_PC) + + if ((cpu_variant & ARM_EXT_XSCALE) != ARM_EXT_XSCALE) { - inst.error = BAD_PC; + static char buff[128]; + + --str; + while (isspace (*str)) + --str; + str -= 4; + + /* Deny all knowledge. */ + sprintf (buff, _("bad instruction '%.100s'"), str); + inst.error = buff; return; } - - if (skip_past_comma (&str) == FAIL - || (rm = reg_required_here (&str, 0)) == FAIL) + + skip_whitespace (str); + + if ((rd = reg_required_here (& str, 12)) == FAIL) { inst.error = BAD_ARGS; return; } - if (rm == REG_PC) + if (skip_past_comma (& str) == FAIL + || (rn = ld_mode_required_here (& str)) == FAIL) { - inst.error = BAD_PC; + if (!inst.error) + inst.error = BAD_ARGS; return; } - - if (rm == rd) - as_tsktsk (_("rd and rm should be different in mla")); - - if (skip_past_comma (&str) == FAIL - || (rd = reg_required_here (&str, 8)) == FAIL - || skip_past_comma (&str) == FAIL - || (rm = reg_required_here (&str, 12)) == FAIL) + + /* inst.instruction has now been zapped with Rd and the addressing mode. */ + if (rd & 1) /* Unpredictable result if Rd is odd. */ { - inst.error = BAD_ARGS; + inst.error = _("Destination register must be even"); return; } - if (rd == REG_PC || rm == REG_PC) + if (rd == REG_LR || rd == 12) { - inst.error = BAD_PC; + inst.error = _("r12 or r14 not allowed here"); return; } - inst.instruction |= flags; + if (((rd == rn) || (rd + 1 == rn)) + && + ((inst.instruction & WRITE_BACK) + || (!(inst.instruction & PRE_INDEX)))) + as_warn (_("pre/post-indexing used when modified address register is destination")); + end_of_line (str); - return; } /* Returns the index into fp_values of a floating point number, @@ -3107,7 +4270,7 @@ do_ldst (str, flags) { /* This is actually a load/store of a halfword, or a signed-extension load. */ - if ((cpu_variant & ARM_HALFWORD) == 0) + if ((cpu_variant & ARM_EXT_HALFWORD) == 0) { inst.error = _("Processor does not support halfwords or signed bytes"); @@ -5294,6 +6457,24 @@ md_begin () if ((cpu_variant & FPU_ALL) == FPU_NONE) flags |= F_SOFT_FLOAT; bfd_set_private_flags (stdoutput, flags); + + /* We have run out flags in the COFF header to encode the + status of ATPCS support, so instead we create a dummy, + empty, debug section called .arm.atpcs. */ + if (atpcs) + { + asection * sec; + + sec = bfd_make_section (stdoutput, ".arm.atpcs"); + + if (sec != NULL) + { + bfd_set_section_flags + (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */); + bfd_set_section_size (stdoutput, sec, 0); + bfd_set_section_contents (stdoutput, sec, NULL, 0, 0); + } + } } #endif @@ -5321,15 +6502,25 @@ md_begin () /* Catch special cases. */ if (cpu_variant != (FPU_DEFAULT | CPU_DEFAULT)) { - if (cpu_variant & (ARM_EXT_V5 & ARM_THUMB)) - mach = bfd_mach_arm_5T; + if (cpu_variant & ARM_EXT_XSCALE) + mach = bfd_mach_arm_XScale; + else if (cpu_variant & ARM_EXT_V5E) + mach = bfd_mach_arm_5TE; else if (cpu_variant & ARM_EXT_V5) - mach = bfd_mach_arm_5; - else if (cpu_variant & ARM_THUMB) - mach = bfd_mach_arm_4T; - else if ((cpu_variant & ARM_ARCH_V4) == ARM_ARCH_V4) - mach = bfd_mach_arm_4; - else if (cpu_variant & ARM_LONGMUL) + { + if (cpu_variant & ARM_EXT_THUMB) + mach = bfd_mach_arm_5T; + else + mach = bfd_mach_arm_5; + } + else if (cpu_variant & ARM_EXT_HALFWORD) + { + if (cpu_variant & ARM_EXT_THUMB) + mach = bfd_mach_arm_4T; + else + mach = bfd_mach_arm_4; + } + else if (cpu_variant & ARM_EXT_LONGMUL) mach = bfd_mach_arm_3M; } @@ -5678,7 +6869,7 @@ md_apply_fix3 (fixP, val, seg) else { as_bad_where (fixP->fx_file, fixP->fx_line, - _("Unable to compute ADRL instructions for PC offset of 0x%x"), + _("Unable to compute ADRL instructions for PC offset of 0x%lx"), value); break; } @@ -6038,7 +7229,7 @@ md_apply_fix3 (fixP, val, seg) if ((value + 2) & ~0x3fe) as_bad_where (fixP->fx_file, fixP->fx_line, - _("Invalid offset, value too big (0x%08X)"), value); + _("Invalid offset, value too big (0x%08lX)"), value); /* Round up, since pc will be rounded down. */ newval |= (value + 2) >> 2; @@ -6047,28 +7238,28 @@ md_apply_fix3 (fixP, val, seg) case 9: /* SP load/store. */ if (value & ~0x3fc) as_bad_where (fixP->fx_file, fixP->fx_line, - _("Invalid offset, value too big (0x%08X)"), value); + _("Invalid offset, value too big (0x%08lX)"), value); newval |= value >> 2; break; case 6: /* Word load/store. */ if (value & ~0x7c) as_bad_where (fixP->fx_file, fixP->fx_line, - _("Invalid offset, value too big (0x%08X)"), value); + _("Invalid offset, value too big (0x%08lX)"), value); newval |= value << 4; /* 6 - 2. */ break; case 7: /* Byte load/store. */ if (value & ~0x1f) as_bad_where (fixP->fx_file, fixP->fx_line, - _("Invalid offset, value too big (0x%08X)"), value); + _("Invalid offset, value too big (0x%08lX)"), value); newval |= value << 6; break; case 8: /* Halfword load/store. */ if (value & ~0x3e) as_bad_where (fixP->fx_file, fixP->fx_line, - _("Invalid offset, value too big (0x%08X)"), value); + _("Invalid offset, value too big (0x%08lX)"), value); newval |= value << 5; /* 6 - 1. */ break; @@ -6271,8 +7462,7 @@ tc_gen_reloc (section, fixp) case BFD_RELOC_ARM_ADRL_IMMEDIATE: as_bad_where (fixp->fx_file, fixp->fx_line, - _("ADRL used for a symbol not defined in the same file"), - fixp->fx_r_type); + _("ADRL used for a symbol not defined in the same file")); return NULL; case BFD_RELOC_ARM_OFFSET_IMM: @@ -6683,7 +7873,8 @@ _("Warning: Use of the 'nv' conditional is deprecated\n")); -m[arm]8[10] Arm 8 processors -m[arm]9[20][tdmi] Arm 9 processors -mstrongarm[110[0]] StrongARM processors - -m[arm]v[2345[t]] Arm architectures + -mxscale XScale processors + -m[arm]v[2345[t[e]]] Arm architectures -mall All (except the ARM1) FP variants: -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions @@ -6698,6 +7889,7 @@ _("Warning: Use of the 'nv' conditional is deprecated\n")); -mapcs-float Pass floats in float regs -mapcs-reentrant Position independent code -mthumb-interwork Code supports Arm/Thumb interworking + -matpcs ARM/Thumb Procedure Call Standard -moabi Old ELF ABI */ CONST char * md_shortopts = "m:k"; @@ -6767,13 +7959,13 @@ md_parse_option (c, arg) /* Limit assembler to generating only Thumb instructions: */ if (streq (str, "thumb")) { - cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB; + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_EXT_THUMB; cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_NONE; thumb_mode = 1; } else if (streq (str, "thumb-interwork")) { - if ((cpu_variant & ARM_THUMB) == 0) + if ((cpu_variant & ARM_EXT_THUMB) == 0) cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V4T; #if defined OBJ_COFF || defined OBJ_ELF support_interwork = true; @@ -6844,6 +8036,12 @@ md_parse_option (c, arg) as_bad (_("Unrecognised APCS switch -m%s"), arg); return 0; } + + if (! strcmp (str, "atpcs")) + { + atpcs = true; + return 1; + } #endif /* Strip off optional "arm". */ if (! strncmp (str, "arm", 3)) @@ -6910,11 +8108,11 @@ md_parse_option (c, arg) switch (*str) { case 't': - cpu_variant |= (ARM_THUMB | ARM_ARCH_V4); + cpu_variant |= ARM_ARCH_V4T; break; case 'm': - cpu_variant |= ARM_LONGMUL; + cpu_variant |= ARM_EXT_LONGMUL; break; case 'f': /* fe => fp enabled cpu. */ @@ -6938,7 +8136,7 @@ md_parse_option (c, arg) case '8': if (streq (str, "8") || streq (str, "810")) cpu_variant = (cpu_variant & ~ARM_ANY) - | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL; + | ARM_8 | ARM_ARCH_V4; else goto bad; break; @@ -6946,16 +8144,16 @@ md_parse_option (c, arg) case '9': if (streq (str, "9")) cpu_variant = (cpu_variant & ~ARM_ANY) - | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB; + | ARM_9 | ARM_ARCH_V4T; else if (streq (str, "920")) cpu_variant = (cpu_variant & ~ARM_ANY) - | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL; + | ARM_9 | ARM_ARCH_V4; else if (streq (str, "920t")) cpu_variant = (cpu_variant & ~ARM_ANY) - | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB; + | ARM_9 | ARM_ARCH_V4T; else if (streq (str, "9tdmi")) cpu_variant = (cpu_variant & ~ARM_ANY) - | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB; + | ARM_9 | ARM_ARCH_V4T; else goto bad; break; @@ -6965,11 +8163,18 @@ md_parse_option (c, arg) || streq (str, "strongarm110") || streq (str, "strongarm1100")) cpu_variant = (cpu_variant & ~ARM_ANY) - | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL; + | ARM_8 | ARM_ARCH_V4; else goto bad; break; + case 'x': + if (streq (str, "xscale")) + cpu_variant = ARM_9 | ARM_ARCH_XSCALE; + else + goto bad; + break; + case 'v': /* Select variant based on architecture rather than processor. */ @@ -6995,7 +8200,7 @@ md_parse_option (c, arg) switch (*++str) { - case 'm': cpu_variant |= ARM_LONGMUL; break; + case 'm': cpu_variant |= ARM_EXT_LONGMUL; break; case 0: break; default: as_bad (_("Invalid architecture variant -m%s"), arg); @@ -7004,11 +8209,11 @@ md_parse_option (c, arg) break; case '4': - cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V4; + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7 | ARM_ARCH_V4; switch (*++str) { - case 't': cpu_variant |= ARM_THUMB; break; + case 't': cpu_variant |= ARM_EXT_THUMB; break; case 0: break; default: as_bad (_("Invalid architecture variant -m%s"), arg); @@ -7017,10 +8222,11 @@ md_parse_option (c, arg) break; case '5': - cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V5; + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V5; switch (*++str) { - case 't': cpu_variant |= ARM_THUMB; break; + case 't': cpu_variant |= ARM_EXT_THUMB; break; + case 'e': cpu_variant |= ARM_EXT_V5E; break; case 0: break; default: as_bad (_("Invalid architecture variant -m%s"), arg); @@ -7073,6 +8279,7 @@ md_show_usage (fp) #if defined OBJ_COFF || defined OBJ_ELF fprintf (fp, _("\ -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n\ + -matpcs use ARM/Thumb Procedure Calling Standard\n\ -mapcs-float floating point args are passed in FP regs\n\ -mapcs-reentrant the code is position independent/reentrant\n")); #endif diff --git a/gas/configure b/gas/configure index 576258e..229bf97 100755 --- a/gas/configure +++ b/gas/configure @@ -2237,6 +2237,7 @@ for this_target in $target $canon_targets ; do armb*) cpu_type=arm endian=little ;; armv*l) cpu_type=arm endian=little ;; armv*b) cpu_type=arm endian=big ;; + xscale*) cpu_type=arm endian=little ;; strongarm*) cpu_type=arm endian=little ;; thumb*) cpu_type=arm endian=little ;; hppa*) cpu_type=hppa ;; @@ -2531,6 +2532,8 @@ EOF strongarm-*-coff) fmt=coff ;; strongarm-*-elf) fmt=elf ;; + xscale-*-coff) fmt=coff ;; + xscale-*-elf) fmt=elf ;; tic30-*-*aout*) fmt=aout bfd_gas=yes ;; tic30-*-*coff*) fmt=coff bfd_gas=yes ;; @@ -3039,7 +3042,7 @@ EOF # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:3043: checking for $ac_word" >&5 +echo "configure:3046: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3069,7 +3072,7 @@ if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:3073: checking for $ac_word" >&5 +echo "configure:3076: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3120,7 +3123,7 @@ fi # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:3124: checking for $ac_word" >&5 +echo "configure:3127: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3152,7 +3155,7 @@ fi fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:3156: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 +echo "configure:3159: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. @@ -3163,12 +3166,12 @@ cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF -#line 3167 "configure" +#line 3170 "configure" #include "confdefs.h" main(){return(0);} EOF -if { (eval echo configure:3172: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3175: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -3194,12 +3197,12 @@ if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:3198: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:3201: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:3203: checking whether we are using GNU C" >&5 +echo "configure:3206: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3208,7 +3211,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:3212: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:3215: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -3227,7 +3230,7 @@ ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:3231: checking whether ${CC-cc} accepts -g" >&5 +echo "configure:3234: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3264,7 +3267,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:3268: checking for $ac_word" >&5 +echo "configure:3271: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3295,7 +3298,7 @@ done test -n "$YACC" || YACC="yacc" echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:3299: checking how to run the C preprocessor" >&5 +echo "configure:3302: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -3310,13 +3313,13 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3320: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3323: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -3327,13 +3330,13 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3337: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3340: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -3344,13 +3347,13 @@ else rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3354: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3357: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -3380,7 +3383,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:3384: checking for $ac_word" >&5 +echo "configure:3387: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3413,7 +3416,7 @@ test -n "$LEX" || LEX=""$missing_dir/missing flex"" # Extract the first word of "flex", so it can be a program name with args. set dummy flex; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:3417: checking for $ac_word" >&5 +echo "configure:3420: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3447,7 +3450,7 @@ then *) ac_lib=l ;; esac echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6 -echo "configure:3451: checking for yywrap in -l$ac_lib" >&5 +echo "configure:3454: checking for yywrap in -l$ac_lib" >&5 ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -3455,7 +3458,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$ac_lib $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3473: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -3489,7 +3492,7 @@ fi fi echo $ac_n "checking lex output file root""... $ac_c" 1>&6 -echo "configure:3493: checking lex output file root" >&5 +echo "configure:3496: checking lex output file root" >&5 if eval "test \"`echo '$''{'ac_cv_prog_lex_root'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3510,7 +3513,7 @@ echo "$ac_t""$ac_cv_prog_lex_root" 1>&6 LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root echo $ac_n "checking whether yytext is a pointer""... $ac_c" 1>&6 -echo "configure:3514: checking whether yytext is a pointer" >&5 +echo "configure:3517: checking whether yytext is a pointer" >&5 if eval "test \"`echo '$''{'ac_cv_prog_lex_yytext_pointer'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3522,14 +3525,14 @@ echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c ac_save_LIBS="$LIBS" LIBS="$LIBS $LEXLIB" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3536: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_prog_lex_yytext_pointer=yes else @@ -3555,7 +3558,7 @@ ALL_LINGUAS= # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:3559: checking for $ac_word" >&5 +echo "configure:3562: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3583,12 +3586,12 @@ else fi echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:3587: checking for ANSI C header files" >&5 +echo "configure:3590: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -3596,7 +3599,7 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3600: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3603: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3613,7 +3616,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -3631,7 +3634,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -3652,7 +3655,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -3663,7 +3666,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:3667: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:3670: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -3687,12 +3690,12 @@ EOF fi echo $ac_n "checking for working const""... $ac_c" 1>&6 -echo "configure:3691: checking for working const" >&5 +echo "configure:3694: checking for working const" >&5 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3748: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else @@ -3762,21 +3765,21 @@ EOF fi echo $ac_n "checking for inline""... $ac_c" 1>&6 -echo "configure:3766: checking for inline" >&5 +echo "configure:3769: checking for inline" >&5 if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3783: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_inline=$ac_kw; break else @@ -3802,12 +3805,12 @@ EOF esac echo $ac_n "checking for off_t""... $ac_c" 1>&6 -echo "configure:3806: checking for off_t" >&5 +echo "configure:3809: checking for off_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -3835,12 +3838,12 @@ EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 -echo "configure:3839: checking for size_t" >&5 +echo "configure:3842: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -3870,19 +3873,19 @@ fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 -echo "configure:3874: checking for working alloca.h" >&5 +echo "configure:3877: checking for working alloca.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { char *p = alloca(2 * sizeof(int)); ; return 0; } EOF -if { (eval echo configure:3886: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3889: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_header_alloca_h=yes else @@ -3903,12 +3906,12 @@ EOF fi echo $ac_n "checking for alloca""... $ac_c" 1>&6 -echo "configure:3907: checking for alloca" >&5 +echo "configure:3910: checking for alloca" >&5 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3943: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_alloca_works=yes else @@ -3968,12 +3971,12 @@ EOF echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 -echo "configure:3972: checking whether alloca needs Cray hooks" >&5 +echo "configure:3975: checking whether alloca needs Cray hooks" >&5 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&6 if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4002: checking for $ac_func" >&5 +echo "configure:4005: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4033: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -4053,7 +4056,7 @@ done fi echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 -echo "configure:4057: checking stack direction for C alloca" >&5 +echo "configure:4060: checking stack direction for C alloca" >&5 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4061,7 +4064,7 @@ else ac_cv_c_stack_direction=0 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:4087: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_stack_direction=1 else @@ -4105,17 +4108,17 @@ for ac_hdr in unistd.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4109: checking for $ac_hdr" >&5 +echo "configure:4112: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4119: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4122: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4144,12 +4147,12 @@ done for ac_func in getpagesize do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4148: checking for $ac_func" >&5 +echo "configure:4151: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4179: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -4197,7 +4200,7 @@ fi done echo $ac_n "checking for working mmap""... $ac_c" 1>&6 -echo "configure:4201: checking for working mmap" >&5 +echo "configure:4204: checking for working mmap" >&5 if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4205,7 +4208,7 @@ else ac_cv_func_mmap_fixed_mapped=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:4352: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_mmap_fixed_mapped=yes else @@ -4373,17 +4376,17 @@ unistd.h values.h sys/param.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4377: checking for $ac_hdr" >&5 +echo "configure:4380: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4387: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4390: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4413,12 +4416,12 @@ done __argz_count __argz_stringify __argz_next do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4417: checking for $ac_func" >&5 +echo "configure:4420: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4448: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -4470,12 +4473,12 @@ done for ac_func in stpcpy do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4474: checking for $ac_func" >&5 +echo "configure:4477: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4505: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -4532,19 +4535,19 @@ EOF if test $ac_cv_header_locale_h = yes; then echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6 -echo "configure:4536: checking for LC_MESSAGES" >&5 +echo "configure:4539: checking for LC_MESSAGES" >&5 if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { return LC_MESSAGES ; return 0; } EOF -if { (eval echo configure:4548: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4551: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* am_cv_val_LC_MESSAGES=yes else @@ -4565,7 +4568,7 @@ EOF fi fi echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6 -echo "configure:4569: checking whether NLS is requested" >&5 +echo "configure:4572: checking whether NLS is requested" >&5 # Check whether --enable-nls or --disable-nls was given. if test "${enable_nls+set}" = set; then enableval="$enable_nls" @@ -4585,7 +4588,7 @@ fi EOF echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6 -echo "configure:4589: checking whether included gettext is requested" >&5 +echo "configure:4592: checking whether included gettext is requested" >&5 # Check whether --with-included-gettext or --without-included-gettext was given. if test "${with_included_gettext+set}" = set; then withval="$with_included_gettext" @@ -4604,17 +4607,17 @@ fi ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for libintl.h""... $ac_c" 1>&6 -echo "configure:4608: checking for libintl.h" >&5 +echo "configure:4611: checking for libintl.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4618: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4621: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4631,19 +4634,19 @@ fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6 -echo "configure:4635: checking for gettext in libc" >&5 +echo "configure:4638: checking for gettext in libc" >&5 if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { return (int) gettext ("") ; return 0; } EOF -if { (eval echo configure:4647: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4650: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* gt_cv_func_gettext_libc=yes else @@ -4659,7 +4662,7 @@ echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6 if test "$gt_cv_func_gettext_libc" != "yes"; then echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6 -echo "configure:4663: checking for bindtextdomain in -lintl" >&5 +echo "configure:4666: checking for bindtextdomain in -lintl" >&5 ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4667,7 +4670,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lintl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4685: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4694,19 +4697,19 @@ fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6 -echo "configure:4698: checking for gettext in libintl" >&5 +echo "configure:4701: checking for gettext in libintl" >&5 if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4713: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* gt_cv_func_gettext_libintl=yes else @@ -4734,7 +4737,7 @@ EOF # Extract the first word of "msgfmt", so it can be a program name with args. set dummy msgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:4738: checking for $ac_word" >&5 +echo "configure:4741: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4768,12 +4771,12 @@ fi for ac_func in dcgettext do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4772: checking for $ac_func" >&5 +echo "configure:4775: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4803: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -4823,7 +4826,7 @@ done # Extract the first word of "gmsgfmt", so it can be a program name with args. set dummy gmsgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:4827: checking for $ac_word" >&5 +echo "configure:4830: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4859,7 +4862,7 @@ fi # Extract the first word of "xgettext", so it can be a program name with args. set dummy xgettext; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:4863: checking for $ac_word" >&5 +echo "configure:4866: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4891,7 +4894,7 @@ else fi cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4906: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* CATOBJEXT=.gmo DATADIRNAME=share @@ -4931,7 +4934,7 @@ fi # Extract the first word of "msgfmt", so it can be a program name with args. set dummy msgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:4935: checking for $ac_word" >&5 +echo "configure:4938: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4965,7 +4968,7 @@ fi # Extract the first word of "gmsgfmt", so it can be a program name with args. set dummy gmsgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:4969: checking for $ac_word" >&5 +echo "configure:4972: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5001,7 +5004,7 @@ fi # Extract the first word of "xgettext", so it can be a program name with args. set dummy xgettext; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:5005: checking for $ac_word" >&5 +echo "configure:5008: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5091,7 +5094,7 @@ fi LINGUAS= else echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6 -echo "configure:5095: checking for catalogs to be installed" >&5 +echo "configure:5098: checking for catalogs to be installed" >&5 NEW_LINGUAS= for lang in ${LINGUAS=$ALL_LINGUAS}; do case "$ALL_LINGUAS" in @@ -5119,17 +5122,17 @@ echo "configure:5095: checking for catalogs to be installed" >&5 if test "$CATOBJEXT" = ".cat"; then ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6 -echo "configure:5123: checking for linux/version.h" >&5 +echo "configure:5126: checking for linux/version.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5133: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5136: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -5192,7 +5195,7 @@ fi echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6 -echo "configure:5196: checking whether to enable maintainer-specific portions of Makefiles" >&5 +echo "configure:5199: checking whether to enable maintainer-specific portions of Makefiles" >&5 # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then enableval="$enable_maintainer_mode" @@ -5217,7 +5220,7 @@ fi echo $ac_n "checking for executable suffix""... $ac_c" 1>&6 -echo "configure:5221: checking for executable suffix" >&5 +echo "configure:5224: checking for executable suffix" >&5 if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5227,7 +5230,7 @@ else rm -f conftest* echo 'int main () { return 0; }' > conftest.$ac_ext ac_cv_exeext= - if { (eval echo configure:5231: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then + if { (eval echo configure:5234: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then for file in conftest.*; do case $file in *.c | *.o | *.obj | *.ilk | *.pdb) ;; @@ -5252,17 +5255,17 @@ for ac_hdr in string.h stdlib.h memory.h strings.h unistd.h stdarg.h varargs.h e do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:5256: checking for $ac_hdr" >&5 +echo "configure:5259: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5266: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5269: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -5292,7 +5295,7 @@ done # Put this here so that autoconf's "cross-compiling" message doesn't confuse # people who are not cross-compiling but are compiling cross-assemblers. echo $ac_n "checking whether compiling a cross-assembler""... $ac_c" 1>&6 -echo "configure:5296: checking whether compiling a cross-assembler" >&5 +echo "configure:5299: checking whether compiling a cross-assembler" >&5 if test "${host}" = "${target}"; then cross_gas=no else @@ -5307,19 +5310,19 @@ echo "$ac_t""$cross_gas" 1>&6 # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 -echo "configure:5311: checking for working alloca.h" >&5 +echo "configure:5314: checking for working alloca.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { char *p = alloca(2 * sizeof(int)); ; return 0; } EOF -if { (eval echo configure:5323: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5326: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_header_alloca_h=yes else @@ -5340,12 +5343,12 @@ EOF fi echo $ac_n "checking for alloca""... $ac_c" 1>&6 -echo "configure:5344: checking for alloca" >&5 +echo "configure:5347: checking for alloca" >&5 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5380: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_alloca_works=yes else @@ -5405,12 +5408,12 @@ EOF echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 -echo "configure:5409: checking whether alloca needs Cray hooks" >&5 +echo "configure:5412: checking whether alloca needs Cray hooks" >&5 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&6 if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5439: checking for $ac_func" >&5 +echo "configure:5442: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5470: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5490,7 +5493,7 @@ done fi echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 -echo "configure:5494: checking stack direction for C alloca" >&5 +echo "configure:5497: checking stack direction for C alloca" >&5 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5498,7 +5501,7 @@ else ac_cv_c_stack_direction=0 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:5524: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_stack_direction=1 else @@ -5539,21 +5542,21 @@ EOF fi echo $ac_n "checking for inline""... $ac_c" 1>&6 -echo "configure:5543: checking for inline" >&5 +echo "configure:5546: checking for inline" >&5 if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5560: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_inline=$ac_kw; break else @@ -5583,12 +5586,12 @@ esac for ac_func in unlink remove do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5587: checking for $ac_func" >&5 +echo "configure:5590: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5618: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5640,12 +5643,12 @@ done for ac_func in sbrk do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5644: checking for $ac_func" >&5 +echo "configure:5647: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5675: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5703,7 +5706,7 @@ case "$host" in ;; *-ncr-sysv4.3*) echo $ac_n "checking for _mwvalidcheckl in -lmw""... $ac_c" 1>&6 -echo "configure:5707: checking for _mwvalidcheckl in -lmw" >&5 +echo "configure:5710: checking for _mwvalidcheckl in -lmw" >&5 ac_lib_var=`echo mw'_'_mwvalidcheckl | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5711,7 +5714,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lmw $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5729: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5743,7 +5746,7 @@ else fi echo $ac_n "checking for main in -lm""... $ac_c" 1>&6 -echo "configure:5747: checking for main in -lm" >&5 +echo "configure:5750: checking for main in -lm" >&5 ac_lib_var=`echo m'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5751,14 +5754,14 @@ else ac_save_LIBS="$LIBS" LIBS="-lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5765: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5781,7 +5784,7 @@ fi ;; *) echo $ac_n "checking for main in -lm""... $ac_c" 1>&6 -echo "configure:5785: checking for main in -lm" >&5 +echo "configure:5788: checking for main in -lm" >&5 ac_lib_var=`echo m'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5789,14 +5792,14 @@ else ac_save_LIBS="$LIBS" LIBS="-lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5803: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5827,12 +5830,12 @@ esac # enough, but on some of those systems, the assert macro relies on requoting # working properly! echo $ac_n "checking for working assert macro""... $ac_c" 1>&6 -echo "configure:5831: checking for working assert macro" >&5 +echo "configure:5834: checking for working assert macro" >&5 if eval "test \"`echo '$''{'gas_cv_assert_ok'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -5848,7 +5851,7 @@ assert (a == b ; return 0; } EOF -if { (eval echo configure:5852: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5855: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* gas_cv_assert_ok=yes else @@ -5889,12 +5892,12 @@ gas_test_headers=" " echo $ac_n "checking whether declaration is required for strstr""... $ac_c" 1>&6 -echo "configure:5893: checking whether declaration is required for strstr" >&5 +echo "configure:5896: checking whether declaration is required for strstr" >&5 if eval "test \"`echo '$''{'gas_cv_decl_needed_strstr'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5912: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* gas_cv_decl_needed_strstr=no else @@ -5926,12 +5929,12 @@ fi echo $ac_n "checking whether declaration is required for malloc""... $ac_c" 1>&6 -echo "configure:5930: checking whether declaration is required for malloc" >&5 +echo "configure:5933: checking whether declaration is required for malloc" >&5 if eval "test \"`echo '$''{'gas_cv_decl_needed_malloc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5949: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* gas_cv_decl_needed_malloc=no else @@ -5963,12 +5966,12 @@ fi echo $ac_n "checking whether declaration is required for free""... $ac_c" 1>&6 -echo "configure:5967: checking whether declaration is required for free" >&5 +echo "configure:5970: checking whether declaration is required for free" >&5 if eval "test \"`echo '$''{'gas_cv_decl_needed_free'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5986: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* gas_cv_decl_needed_free=no else @@ -6000,12 +6003,12 @@ fi echo $ac_n "checking whether declaration is required for sbrk""... $ac_c" 1>&6 -echo "configure:6004: checking whether declaration is required for sbrk" >&5 +echo "configure:6007: checking whether declaration is required for sbrk" >&5 if eval "test \"`echo '$''{'gas_cv_decl_needed_sbrk'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6023: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* gas_cv_decl_needed_sbrk=no else @@ -6037,12 +6040,12 @@ fi echo $ac_n "checking whether declaration is required for environ""... $ac_c" 1>&6 -echo "configure:6041: checking whether declaration is required for environ" >&5 +echo "configure:6044: checking whether declaration is required for environ" >&5 if eval "test \"`echo '$''{'gas_cv_decl_needed_environ'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6060: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* gas_cv_decl_needed_environ=no else @@ -6077,12 +6080,12 @@ fi # for it? echo $ac_n "checking whether declaration is required for errno""... $ac_c" 1>&6 -echo "configure:6081: checking whether declaration is required for errno" >&5 +echo "configure:6084: checking whether declaration is required for errno" >&5 if eval "test \"`echo '$''{'gas_cv_decl_needed_errno'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6104: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* gas_cv_decl_needed_errno=no else diff --git a/gas/configure.in b/gas/configure.in index c5762e8..9531d2e 100644 --- a/gas/configure.in +++ b/gas/configure.in @@ -117,6 +117,7 @@ changequote([,])dnl armb*) cpu_type=arm endian=little ;; armv*l) cpu_type=arm endian=little ;; armv*b) cpu_type=arm endian=big ;; + xscale*) cpu_type=arm endian=little ;; strongarm*) cpu_type=arm endian=little ;; thumb*) cpu_type=arm endian=little ;; hppa*) cpu_type=hppa ;; @@ -406,6 +407,8 @@ changequote([,])dnl strongarm-*-coff) fmt=coff ;; strongarm-*-elf) fmt=elf ;; + xscale-*-coff) fmt=coff ;; + xscale-*-elf) fmt=elf ;; tic30-*-*aout*) fmt=aout bfd_gas=yes ;; tic30-*-*coff*) fmt=coff bfd_gas=yes ;; diff --git a/gas/doc/c-arm.texi b/gas/doc/c-arm.texi index 10c8042..0ace9a2 100644 --- a/gas/doc/c-arm.texi +++ b/gas/doc/c-arm.texi @@ -32,15 +32,18 @@ @cindex @code{-marm} command line option, ARM @item -marm@code{[2|250|3|6|60|600|610|620|7|7m|7d|7dm|7di|7dmi|70|700|700i|710|710c|7100|7500|7500fe|7tdmi|8|810|9|9tdmi|920|strongarm|strongarm110|strongarm1100]} +@itemx -mxscale This option specifies the target processor. The assembler will issue an error message if an attempt is made to assemble an instruction which will not execute on the target processor. @cindex @code{-marmv} command line option, ARM -@item -marmv@code{[2|2a|3|3m|4|4t|5|5t]} +@item -marmv@code{[2|2a|3|3m|4|4t|5|5t|5te]} This option specifies the target architecture. The assembler will issue an error message if an attempt is made to assemble an instruction which will not execute on the target architecture. +The option @code{-marmv5te} specifies that v5t architecture should be +used with the El Segundo extensions enabled. @cindex @code{-mthumb} command line option, ARM @item -mthumb @@ -74,6 +77,14 @@ This option specifies that the output generated by the assembler should be marked as supporting the indicated version of the Arm Procedure. Calling Standard. +@cindex @code{-matpcs} command line option, ARM +@item -matpcs +This option specifies that the output generated by the assembler should +be marked as supporting the Arm/Thumb Procedure Calling Standard. If +enabled this option will cause the assembler to create an empty +debugging section in the object file called .arm.atpcs. Debuggers can +use this to determine the ABI being used by. + @cindex @code{-mapcs-float} command line option, ARM @item -mapcs-float This indicates the the floating point variant of the APCS should be diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 729b1f3..e5527d5 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2000-11-24 Nick Clifton + + * arm.exp: Run tests for xscale as well as arm. + Run xscale tests. + + * xscale.s: New file: XScale instruction tests. + * xscale.d: New file: Expected XScale instruction results. + 2000-11-20 H.J. Lu * gas/i386/intel.d: Add 3 "nop"s for the a.out assembler. diff --git a/gas/testsuite/gas/arm/arm.exp b/gas/testsuite/gas/arm/arm.exp index d658eeb..1383306 100644 --- a/gas/testsuite/gas/arm/arm.exp +++ b/gas/testsuite/gas/arm/arm.exp @@ -1,7 +1,7 @@ # # Some ARM tests # -if [istarget *arm*-*-*] then { +if {[istarget *arm*-*-*] || [istarget "xscale-*-*"]} then { run_dump_test "inst" gas_test "arm3.s" "" $stdoptlist "Arm 3 instructions" @@ -21,6 +21,8 @@ if [istarget *arm*-*-*] then { gas_test "immed.s" "" $stdoptlist "immediate expressions" gas_test "float.s" "" $stdoptlist "Core floating point instructions" + + run_dump_test "xscale" } # Not all arm targets are bi-endian, so only run this test on ones diff --git a/gas/testsuite/gas/arm/xscale.d b/gas/testsuite/gas/arm/xscale.d new file mode 100644 index 0000000..38eb1ee --- /dev/null +++ b/gas/testsuite/gas/arm/xscale.d @@ -0,0 +1,38 @@ +#objdump: -dr --prefix-addresses --show-raw-insn +#name: XScale instructions +#as: -mxscale -EL + +# Test the XScale instructions: + +.*: +file format .*arm.* + +Disassembly of section .text: +00000000 ee201010 mia acc0, r0, r1 +00000004 <[^>]*> be20d01e mialt acc0, lr, sp +00000008 <[^>]*> ee284012 miaph acc0, r2, r4 +0000000c <[^>]*> 1e286015 miaphne acc0, r5, r6 +00000010 <[^>]*> ee2c8017 miaBB acc0, r7, r8 +00000014 <[^>]*> ee2da019 miaBT acc0, r9, sl +00000018 <[^>]*> ee2eb01c miaTB acc0, ip, fp +0000001c <[^>]*> ee2f0010 miaTT acc0, r0, r0 +00000020 <[^>]*> ec411000 mar acc0, r1, r1 +00000024 <[^>]*> cc4c2000 margt acc0, r2, ip +00000028 <[^>]*> ec543000 mra r3, r4, acc0 +0000002c <[^>]*> ec585000 mra r5, r8, acc0 +00000030 <[^>]*> f5d0f000 pld \[r0\] +00000034 <[^>]*> f5d1f789 pld \[r1, #1929\] +00000038 <[^>]*> f7d2f003 pld \[r2, r3\] +0000003c <[^>]*> f754f285 pld \[r4, -r5, lsl #5\] +00000040 <[^>]*> f456f456 pld \[r6\], -#1110 +00000044 <[^>]*> f6d7f008 pld \[r7\], r8 +00000048 <[^>]*> f659f06a pld \[r9\], -sl, rrx +0000004c <[^>]*> e1c100d0 ldrd r0, \[r1\] +00000050 <[^>]*> 01c327d8 ldreqd r2, \[r3, #120\] +00000054 <[^>]*> b10540d6 ldrltd r4, \[r5, -r6\] +00000058 <[^>]*> e16a88f9 strd r8, \[sl, -#137\]! +0000005c <[^>]*> e1ac00fd strd r0, \[ip, sp\]! +00000060 <[^>]*> 30ce21f0 strccd r2, \[lr\], #16 +00000064 <[^>]*> 708640f8 strvcd r4, \[r6\], r8 +00000068 <[^>]*> e5910000 ldr r0, \[r1\] +0000006c <[^>]*> e5832000 str r2, \[r3\] +00000070 <[^>]*> e321f011 msr CPSR_c, #17 ; 0x11 diff --git a/gas/testsuite/gas/arm/xscale.s b/gas/testsuite/gas/arm/xscale.s new file mode 100644 index 0000000..0ca3999 --- /dev/null +++ b/gas/testsuite/gas/arm/xscale.s @@ -0,0 +1,40 @@ + .text + .global foo +foo: + mia acc0, r0, r1 + mialt acc0, r14, r13 + + miaph acc0, r2, r4 + miaphne acc0, r5, r6 + + miaBB acc0, r7, r8 + miaBT acc0, r9, r10 + miaTB acc0, r12, r11 + miaTT acc0, r0, r0 + + mar acc0, r1, r1 + margt acc0, r2, r12 + + mra r3, r4, acc0 + mra r5, r8, acc0 + + pld [r0] + pld [r1, #0x789] + pld [r2, r3] + pld [r4, -r5, lsl #5] + pld [r6], #-0x456 + pld [r7], +r8 + pld [r9], -r10, RRX + + ldrd r0, [r1] + ldreqd r2, [r3, #0x78] + ldrltd r4, [r5, -r6] + strd r8, [r10,#-0x89]! + strald r0, [r12, +r13]! + strlod r2, [r14], #+0x010 + strvcd r4, [r6], r8 + + ldr r0, [r1] + str r2, [r3] + + msr cpsr_ctl, #0x11 diff --git a/ld/ChangeLog b/ld/ChangeLog index 7962379..90a4b90 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,8 @@ +2000-11-24 Nick Clifton + + * configure.tgt (xscale-coff): Add target. + (xscale-elf): Add target. + 2000-11-24 Fred Fish * ldmain.c (main): Remove redundant init of config.make_executable diff --git a/ld/configure.tgt b/ld/configure.tgt index fad940d..f8f366a 100644 --- a/ld/configure.tgt +++ b/ld/configure.tgt @@ -178,6 +178,8 @@ thumb-epoc-pe) targ_emul=arm_epoc_pe ; targ_extra_ofiles="deffilep.o pe-dll.o" ;; thumb-*-pe) targ_emul=armpe ; targ_extra_ofiles="deffilep.o pe-dll.o" ;; +xscale-*-coff) targ_emul=armcoff ;; +xscale-*-elf) targ_emul=armelf ;; h8300-*-hms* | h8300-*-coff*) targ_emul=h8300; targ_extra_emuls="h8300h h8300s" ;; diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 7c3ba0e..b323984 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,13 @@ +2000-11-24 Nick Clifton + + * arm-opc.h: Add new opcode formatting parameter 'B'. + (arm_opcodes): Add XScale, v5, and v5te instructions. + (thumb_opcodes): Add v5t instructions. + + * arm-dis.c (print_insn_arm): Handle new 'B' format + parameter. + (print_insn_thumb): Decode BLX(1) instruction. + 2000-11-21 Chris Demetriou * mips-opc.c: Fix file header comment. diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c index 0ddcffa..262406b 100644 --- a/opcodes/arm-dis.c +++ b/opcodes/arm-dis.c @@ -421,6 +421,29 @@ print_insn_arm (pc, info, given) } break; + case 'B': + /* Print ARM V5 BLX(1) address: pc+25 bits. */ + { + bfd_vma address; + bfd_vma offset = 0; + + if (given & 0x00800000) + /* Is signed, hi bits should be ones. */ + offset = (-1) ^ 0x00ffffff; + + /* Offset is (SignExtend(offset field)<<2). */ + offset += given & 0x00ffffff; + offset <<= 2; + address = offset + pc + 8; + + if (given & 0x01000000) + /* H bit allows addressing to 2-byte boundaries. */ + address += 2; + + info->print_address_func (address, info); + } + break; + case 'C': func (stream, "_"); if (given & 0x80000) @@ -648,6 +671,9 @@ print_insn_thumb (pc, info, given) info->bytes_per_chunk = 4; info->bytes_per_line = 4; + if ((given & 0x10000000) == 0) + func (stream, "blx\t"); + else func (stream, "bl\t"); info->print_address_func (BDISP23 (given) * 2 + pc + 4, info); diff --git a/opcodes/arm-opc.h b/opcodes/arm-opc.h index 5ecde4b..42ab954 100644 --- a/opcodes/arm-opc.h +++ b/opcodes/arm-opc.h @@ -51,6 +51,7 @@ struct thumb_opcode %a print address for ldr/str instruction %s print address for ldr/str halfword/signextend instruction %b print branch destination + %B print arm BLX(1) destination %A print address for ldc/stc/ldf/stf instruction %m print register mask for ldm/stm instruction %C print the PSR sub type. @@ -75,7 +76,7 @@ Thumb specific format options: static struct arm_opcode arm_opcodes[] = { - /* ARM instructions */ + /* ARM instructions. */ {0xe1a00000, 0xffffffff, "nop\t\t\t(mov r0,r0)"}, {0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"}, {0x00000090, 0x0fe000f0, "mul%c%20's\t%16-19r, %0-3r, %8-11r"}, @@ -83,6 +84,59 @@ static struct arm_opcode arm_opcodes[] = {0x01000090, 0x0fb00ff0, "swp%c%22'b\t%12-15r, %0-3r, [%16-19r]"}, {0x00800090, 0x0fa000f0, "%22?sumull%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"}, {0x00a00090, 0x0fa000f0, "%22?sumlal%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"}, + + /* XScale instructions. */ + {0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"}, + {0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"}, + {0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"}, + {0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"}, + {0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"}, + {0xf450f000, 0xfc70f000, "pld\t%a"}, + + /* V5 Instructions. */ + {0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"}, + {0xfa000000, 0xfe000000, "blx\t%B"}, + {0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"}, + {0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"}, + {0xfc100000, 0xfe100000, "ldc2%22'l\t%8-11d, cr%12-15d, %A"}, + {0xfc000000, 0xfe100000, "stc2%22'l\t%8-11d, cr%12-15d, %A"}, + {0xfe000000, 0xff000010, "cdp2\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"}, + {0xfe000010, 0xff100010, "mcr2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"}, + {0xfe100010, 0xff100010, "mrc2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"}, + + /* V5E "El Segundo" Instructions. */ + {0x000000d0, 0x0e1000f0, "ldr%cd\t%12-15r, %s"}, + {0x000000f0, 0x0e1000f0, "str%cd\t%12-15r, %s"}, + {0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, + {0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, + {0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, + {0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, + + {0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, + {0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, + + {0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, + {0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, + {0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, + {0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, + + {0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"}, + {0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"}, + {0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"}, + {0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"}, + + {0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"}, + {0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"}, + + {0x01000050, 0x0ff00ff0, "qadd%c\t%12-15r, %0-3r, %16-19r"}, + {0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"}, + {0x01200050, 0x0ff00ff0, "qsub%c\t%12-15r, %0-3r, %16-19r"}, + {0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"}, + + {0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"}, + {0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"}, + + /* ARM Instructions. */ {0x00000090, 0x0e100090, "str%c%6's%h\t%12-15r, %s"}, {0x00100090, 0x0e100090, "ldr%c%6's%h\t%12-15r, %s"}, {0x00000000, 0x0de00000, "and%c%20's\t%12-15r, %16-19r, %o"}, @@ -174,10 +228,21 @@ static struct arm_opcode arm_opcodes[] = static struct thumb_opcode thumb_opcodes[] = { - /* Thumb instructions */ - {0x46C0, 0xFFFF, "nop\t\t\t(mov r8,r8)"}, /* format 5 instructions do not update the PSR */ + /* Thumb instructions. */ + + /* ARM V5 ISA extends Thumb. */ + {0xbe00, 0xff00, "bkpt\t%0-7x"}, + {0x4780, 0xff87, "blx\t%3-6r"}, /* note: 4 bit register number. */ + /* Note: this is BLX(2). BLX(1) is done in arm-dis.c/print_insn_thumb() + as an extension of the special processing there for Thumb BL. + BL and BLX(1) involve 2 successive 16-bit instructions, which must + always appear together in the correct order. So, the empty + string is put in this table, and the string interpreter takes + to mean it has a pair of BL-ish instructions. */ + {0x46C0, 0xFFFF, "nop\t\t\t(mov r8, r8)"}, + /* Format 5 instructions do not update the PSR. */ {0x1C00, 0xFFC0, "mov\t%0-2r, %3-5r\t\t(add %0-2r, %3-5r, #%6-8d)"}, - /* format 4 */ + /* Format 4. */ {0x4000, 0xFFC0, "and\t%0-2r, %3-5r"}, {0x4040, 0xFFC0, "eor\t%0-2r, %3-5r"}, {0x4080, 0xFFC0, "lsl\t%0-2r, %3-5r"}, -- cgit v1.1