/* tc-arm.c -- Assemble for the ARM
- Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
Modified by David Taylor (dtaylor@armltd.co.uk)
/* Co-processor space extensions. */
#define ARM_CEXT_XSCALE 0x00800000 /* Allow MIA etc. */
#define ARM_CEXT_MAVERICK 0x00400000 /* Use Cirrus/DSP coprocessor. */
+#define ARM_CEXT_IWMMXT 0x00200000 /* Intel Wireless MMX technology coprocessor. */
/* Architectures are the sum of the base and extensions. The ARM ARM (rev E)
defines the following: ARMv3, ARMv3M, ARMv4xM, ARMv4, ARMv4TxM, ARMv4T,
/* Processors with specific extensions in the co-processor space. */
#define ARM_ARCH_XSCALE (ARM_ARCH_V5TE | ARM_CEXT_XSCALE)
+#define ARM_ARCH_IWMMXT (ARM_ARCH_XSCALE | ARM_CEXT_IWMMXT)
/* Some useful combinations: */
#define ARM_ANY 0x0000ffff /* Any basic core. */
#endif
#endif
+#ifdef TE_LINUX
+#define FPU_DEFAULT FPU_ARCH_FPA
+#endif
+
+#ifdef TE_NetBSD
+#ifdef OBJ_ELF
+#define FPU_DEFAULT FPU_ARCH_VFP /* Soft-float, but VFP order. */
+#else
+/* Legacy a.out format. */
+#define FPU_DEFAULT FPU_ARCH_FPA /* Soft-float, but FPA order. */
+#endif
+#endif
+
/* For backwards compatibility we default to the FPA. */
#ifndef FPU_DEFAULT
#define FPU_DEFAULT FPU_ARCH_FPA
static int target_oabi = 0;
/* Flags stored in private area of BFD structure. */
-static int uses_apcs_26 = false;
-static int atpcs = false;
-static int support_interwork = false;
-static int uses_apcs_float = false;
-static int pic_code = false;
+static int uses_apcs_26 = FALSE;
+static int atpcs = FALSE;
+static int support_interwork = FALSE;
+static int uses_apcs_float = FALSE;
+static int pic_code = FALSE;
/* Variables that we set while parsing command-line options. Once all
options have been read we re-process these values to set the real
struct asm_psr
{
- const char * template;
- boolean cpsr;
+ const char *template;
+ bfd_boolean cpsr;
unsigned long field;
};
static const struct asm_psr psrs[] =
{
- {"CPSR", true, PSR_c | PSR_f},
- {"CPSR_all", true, PSR_c | PSR_f},
- {"SPSR", false, PSR_c | PSR_f},
- {"SPSR_all", false, PSR_c | PSR_f},
- {"CPSR_flg", true, PSR_f},
- {"CPSR_f", true, PSR_f},
- {"SPSR_flg", false, PSR_f},
- {"SPSR_f", false, PSR_f},
- {"CPSR_c", true, PSR_c},
- {"CPSR_ctl", true, PSR_c},
- {"SPSR_c", false, PSR_c},
- {"SPSR_ctl", false, PSR_c},
- {"CPSR_x", true, PSR_x},
- {"CPSR_s", true, PSR_s},
- {"SPSR_x", false, PSR_x},
- {"SPSR_s", false, PSR_s},
+ {"CPSR", TRUE, PSR_c | PSR_f},
+ {"CPSR_all", TRUE, PSR_c | PSR_f},
+ {"SPSR", FALSE, PSR_c | PSR_f},
+ {"SPSR_all", FALSE, PSR_c | PSR_f},
+ {"CPSR_flg", TRUE, PSR_f},
+ {"CPSR_f", TRUE, PSR_f},
+ {"SPSR_flg", FALSE, PSR_f},
+ {"SPSR_f", FALSE, PSR_f},
+ {"CPSR_c", TRUE, PSR_c},
+ {"CPSR_ctl", TRUE, PSR_c},
+ {"SPSR_c", FALSE, PSR_c},
+ {"SPSR_ctl", FALSE, PSR_c},
+ {"CPSR_x", TRUE, PSR_x},
+ {"CPSR_s", TRUE, PSR_s},
+ {"SPSR_x", FALSE, PSR_x},
+ {"SPSR_s", FALSE, PSR_s},
/* Combinations of flags. */
- {"CPSR_fs", true, PSR_f | PSR_s},
- {"CPSR_fx", true, PSR_f | PSR_x},
- {"CPSR_fc", true, PSR_f | PSR_c},
- {"CPSR_sf", true, PSR_s | PSR_f},
- {"CPSR_sx", true, PSR_s | PSR_x},
- {"CPSR_sc", true, PSR_s | PSR_c},
- {"CPSR_xf", true, PSR_x | PSR_f},
- {"CPSR_xs", true, PSR_x | PSR_s},
- {"CPSR_xc", true, PSR_x | PSR_c},
- {"CPSR_cf", true, PSR_c | PSR_f},
- {"CPSR_cs", true, PSR_c | PSR_s},
- {"CPSR_cx", true, PSR_c | PSR_x},
- {"CPSR_fsx", true, PSR_f | PSR_s | PSR_x},
- {"CPSR_fsc", true, PSR_f | PSR_s | PSR_c},
- {"CPSR_fxs", true, PSR_f | PSR_x | PSR_s},
- {"CPSR_fxc", true, PSR_f | PSR_x | PSR_c},
- {"CPSR_fcs", true, PSR_f | PSR_c | PSR_s},
- {"CPSR_fcx", true, PSR_f | PSR_c | PSR_x},
- {"CPSR_sfx", true, PSR_s | PSR_f | PSR_x},
- {"CPSR_sfc", true, PSR_s | PSR_f | PSR_c},
- {"CPSR_sxf", true, PSR_s | PSR_x | PSR_f},
- {"CPSR_sxc", true, PSR_s | PSR_x | PSR_c},
- {"CPSR_scf", true, PSR_s | PSR_c | PSR_f},
- {"CPSR_scx", true, PSR_s | PSR_c | PSR_x},
- {"CPSR_xfs", true, PSR_x | PSR_f | PSR_s},
- {"CPSR_xfc", true, PSR_x | PSR_f | PSR_c},
- {"CPSR_xsf", true, PSR_x | PSR_s | PSR_f},
- {"CPSR_xsc", true, PSR_x | PSR_s | PSR_c},
- {"CPSR_xcf", true, PSR_x | PSR_c | PSR_f},
- {"CPSR_xcs", true, PSR_x | PSR_c | PSR_s},
- {"CPSR_cfs", true, PSR_c | PSR_f | PSR_s},
- {"CPSR_cfx", true, PSR_c | PSR_f | PSR_x},
- {"CPSR_csf", true, PSR_c | PSR_s | PSR_f},
- {"CPSR_csx", true, PSR_c | PSR_s | PSR_x},
- {"CPSR_cxf", true, PSR_c | PSR_x | PSR_f},
- {"CPSR_cxs", true, PSR_c | PSR_x | PSR_s},
- {"CPSR_fsxc", true, PSR_f | PSR_s | PSR_x | PSR_c},
- {"CPSR_fscx", true, PSR_f | PSR_s | PSR_c | PSR_x},
- {"CPSR_fxsc", true, PSR_f | PSR_x | PSR_s | PSR_c},
- {"CPSR_fxcs", true, PSR_f | PSR_x | PSR_c | PSR_s},
- {"CPSR_fcsx", true, PSR_f | PSR_c | PSR_s | PSR_x},
- {"CPSR_fcxs", true, PSR_f | PSR_c | PSR_x | PSR_s},
- {"CPSR_sfxc", true, PSR_s | PSR_f | PSR_x | PSR_c},
- {"CPSR_sfcx", true, PSR_s | PSR_f | PSR_c | PSR_x},
- {"CPSR_sxfc", true, PSR_s | PSR_x | PSR_f | PSR_c},
- {"CPSR_sxcf", true, PSR_s | PSR_x | PSR_c | PSR_f},
- {"CPSR_scfx", true, PSR_s | PSR_c | PSR_f | PSR_x},
- {"CPSR_scxf", true, PSR_s | PSR_c | PSR_x | PSR_f},
- {"CPSR_xfsc", true, PSR_x | PSR_f | PSR_s | PSR_c},
- {"CPSR_xfcs", true, PSR_x | PSR_f | PSR_c | PSR_s},
- {"CPSR_xsfc", true, PSR_x | PSR_s | PSR_f | PSR_c},
- {"CPSR_xscf", true, PSR_x | PSR_s | PSR_c | PSR_f},
- {"CPSR_xcfs", true, PSR_x | PSR_c | PSR_f | PSR_s},
- {"CPSR_xcsf", true, PSR_x | PSR_c | PSR_s | PSR_f},
- {"CPSR_cfsx", true, PSR_c | PSR_f | PSR_s | PSR_x},
- {"CPSR_cfxs", true, PSR_c | PSR_f | PSR_x | PSR_s},
- {"CPSR_csfx", true, PSR_c | PSR_s | PSR_f | PSR_x},
- {"CPSR_csxf", true, PSR_c | PSR_s | PSR_x | PSR_f},
- {"CPSR_cxfs", true, PSR_c | PSR_x | PSR_f | PSR_s},
- {"CPSR_cxsf", true, PSR_c | PSR_x | PSR_s | PSR_f},
- {"SPSR_fs", false, PSR_f | PSR_s},
- {"SPSR_fx", false, PSR_f | PSR_x},
- {"SPSR_fc", false, PSR_f | PSR_c},
- {"SPSR_sf", false, PSR_s | PSR_f},
- {"SPSR_sx", false, PSR_s | PSR_x},
- {"SPSR_sc", false, PSR_s | PSR_c},
- {"SPSR_xf", false, PSR_x | PSR_f},
- {"SPSR_xs", false, PSR_x | PSR_s},
- {"SPSR_xc", false, PSR_x | PSR_c},
- {"SPSR_cf", false, PSR_c | PSR_f},
- {"SPSR_cs", false, PSR_c | PSR_s},
- {"SPSR_cx", false, PSR_c | PSR_x},
- {"SPSR_fsx", false, PSR_f | PSR_s | PSR_x},
- {"SPSR_fsc", false, PSR_f | PSR_s | PSR_c},
- {"SPSR_fxs", false, PSR_f | PSR_x | PSR_s},
- {"SPSR_fxc", false, PSR_f | PSR_x | PSR_c},
- {"SPSR_fcs", false, PSR_f | PSR_c | PSR_s},
- {"SPSR_fcx", false, PSR_f | PSR_c | PSR_x},
- {"SPSR_sfx", false, PSR_s | PSR_f | PSR_x},
- {"SPSR_sfc", false, PSR_s | PSR_f | PSR_c},
- {"SPSR_sxf", false, PSR_s | PSR_x | PSR_f},
- {"SPSR_sxc", false, PSR_s | PSR_x | PSR_c},
- {"SPSR_scf", false, PSR_s | PSR_c | PSR_f},
- {"SPSR_scx", false, PSR_s | PSR_c | PSR_x},
- {"SPSR_xfs", false, PSR_x | PSR_f | PSR_s},
- {"SPSR_xfc", false, PSR_x | PSR_f | PSR_c},
- {"SPSR_xsf", false, PSR_x | PSR_s | PSR_f},
- {"SPSR_xsc", false, PSR_x | PSR_s | PSR_c},
- {"SPSR_xcf", false, PSR_x | PSR_c | PSR_f},
- {"SPSR_xcs", false, PSR_x | PSR_c | PSR_s},
- {"SPSR_cfs", false, PSR_c | PSR_f | PSR_s},
- {"SPSR_cfx", false, PSR_c | PSR_f | PSR_x},
- {"SPSR_csf", false, PSR_c | PSR_s | PSR_f},
- {"SPSR_csx", false, PSR_c | PSR_s | PSR_x},
- {"SPSR_cxf", false, PSR_c | PSR_x | PSR_f},
- {"SPSR_cxs", false, PSR_c | PSR_x | PSR_s},
- {"SPSR_fsxc", false, PSR_f | PSR_s | PSR_x | PSR_c},
- {"SPSR_fscx", false, PSR_f | PSR_s | PSR_c | PSR_x},
- {"SPSR_fxsc", false, PSR_f | PSR_x | PSR_s | PSR_c},
- {"SPSR_fxcs", false, PSR_f | PSR_x | PSR_c | PSR_s},
- {"SPSR_fcsx", false, PSR_f | PSR_c | PSR_s | PSR_x},
- {"SPSR_fcxs", false, PSR_f | PSR_c | PSR_x | PSR_s},
- {"SPSR_sfxc", false, PSR_s | PSR_f | PSR_x | PSR_c},
- {"SPSR_sfcx", false, PSR_s | PSR_f | PSR_c | PSR_x},
- {"SPSR_sxfc", false, PSR_s | PSR_x | PSR_f | PSR_c},
- {"SPSR_sxcf", false, PSR_s | PSR_x | PSR_c | PSR_f},
- {"SPSR_scfx", false, PSR_s | PSR_c | PSR_f | PSR_x},
- {"SPSR_scxf", false, PSR_s | PSR_c | PSR_x | PSR_f},
- {"SPSR_xfsc", false, PSR_x | PSR_f | PSR_s | PSR_c},
- {"SPSR_xfcs", false, PSR_x | PSR_f | PSR_c | PSR_s},
- {"SPSR_xsfc", false, PSR_x | PSR_s | PSR_f | PSR_c},
- {"SPSR_xscf", false, PSR_x | PSR_s | PSR_c | PSR_f},
- {"SPSR_xcfs", false, PSR_x | PSR_c | PSR_f | PSR_s},
- {"SPSR_xcsf", false, PSR_x | PSR_c | PSR_s | PSR_f},
- {"SPSR_cfsx", false, PSR_c | PSR_f | PSR_s | PSR_x},
- {"SPSR_cfxs", false, PSR_c | PSR_f | PSR_x | PSR_s},
- {"SPSR_csfx", false, PSR_c | PSR_s | PSR_f | PSR_x},
- {"SPSR_csxf", false, PSR_c | PSR_s | PSR_x | PSR_f},
- {"SPSR_cxfs", false, PSR_c | PSR_x | PSR_f | PSR_s},
- {"SPSR_cxsf", false, PSR_c | PSR_x | PSR_s | PSR_f},
+ {"CPSR_fs", TRUE, PSR_f | PSR_s},
+ {"CPSR_fx", TRUE, PSR_f | PSR_x},
+ {"CPSR_fc", TRUE, PSR_f | PSR_c},
+ {"CPSR_sf", TRUE, PSR_s | PSR_f},
+ {"CPSR_sx", TRUE, PSR_s | PSR_x},
+ {"CPSR_sc", TRUE, PSR_s | PSR_c},
+ {"CPSR_xf", TRUE, PSR_x | PSR_f},
+ {"CPSR_xs", TRUE, PSR_x | PSR_s},
+ {"CPSR_xc", TRUE, PSR_x | PSR_c},
+ {"CPSR_cf", TRUE, PSR_c | PSR_f},
+ {"CPSR_cs", TRUE, PSR_c | PSR_s},
+ {"CPSR_cx", TRUE, PSR_c | PSR_x},
+ {"CPSR_fsx", TRUE, PSR_f | PSR_s | PSR_x},
+ {"CPSR_fsc", TRUE, PSR_f | PSR_s | PSR_c},
+ {"CPSR_fxs", TRUE, PSR_f | PSR_x | PSR_s},
+ {"CPSR_fxc", TRUE, PSR_f | PSR_x | PSR_c},
+ {"CPSR_fcs", TRUE, PSR_f | PSR_c | PSR_s},
+ {"CPSR_fcx", TRUE, PSR_f | PSR_c | PSR_x},
+ {"CPSR_sfx", TRUE, PSR_s | PSR_f | PSR_x},
+ {"CPSR_sfc", TRUE, PSR_s | PSR_f | PSR_c},
+ {"CPSR_sxf", TRUE, PSR_s | PSR_x | PSR_f},
+ {"CPSR_sxc", TRUE, PSR_s | PSR_x | PSR_c},
+ {"CPSR_scf", TRUE, PSR_s | PSR_c | PSR_f},
+ {"CPSR_scx", TRUE, PSR_s | PSR_c | PSR_x},
+ {"CPSR_xfs", TRUE, PSR_x | PSR_f | PSR_s},
+ {"CPSR_xfc", TRUE, PSR_x | PSR_f | PSR_c},
+ {"CPSR_xsf", TRUE, PSR_x | PSR_s | PSR_f},
+ {"CPSR_xsc", TRUE, PSR_x | PSR_s | PSR_c},
+ {"CPSR_xcf", TRUE, PSR_x | PSR_c | PSR_f},
+ {"CPSR_xcs", TRUE, PSR_x | PSR_c | PSR_s},
+ {"CPSR_cfs", TRUE, PSR_c | PSR_f | PSR_s},
+ {"CPSR_cfx", TRUE, PSR_c | PSR_f | PSR_x},
+ {"CPSR_csf", TRUE, PSR_c | PSR_s | PSR_f},
+ {"CPSR_csx", TRUE, PSR_c | PSR_s | PSR_x},
+ {"CPSR_cxf", TRUE, PSR_c | PSR_x | PSR_f},
+ {"CPSR_cxs", TRUE, PSR_c | PSR_x | PSR_s},
+ {"CPSR_fsxc", TRUE, PSR_f | PSR_s | PSR_x | PSR_c},
+ {"CPSR_fscx", TRUE, PSR_f | PSR_s | PSR_c | PSR_x},
+ {"CPSR_fxsc", TRUE, PSR_f | PSR_x | PSR_s | PSR_c},
+ {"CPSR_fxcs", TRUE, PSR_f | PSR_x | PSR_c | PSR_s},
+ {"CPSR_fcsx", TRUE, PSR_f | PSR_c | PSR_s | PSR_x},
+ {"CPSR_fcxs", TRUE, PSR_f | PSR_c | PSR_x | PSR_s},
+ {"CPSR_sfxc", TRUE, PSR_s | PSR_f | PSR_x | PSR_c},
+ {"CPSR_sfcx", TRUE, PSR_s | PSR_f | PSR_c | PSR_x},
+ {"CPSR_sxfc", TRUE, PSR_s | PSR_x | PSR_f | PSR_c},
+ {"CPSR_sxcf", TRUE, PSR_s | PSR_x | PSR_c | PSR_f},
+ {"CPSR_scfx", TRUE, PSR_s | PSR_c | PSR_f | PSR_x},
+ {"CPSR_scxf", TRUE, PSR_s | PSR_c | PSR_x | PSR_f},
+ {"CPSR_xfsc", TRUE, PSR_x | PSR_f | PSR_s | PSR_c},
+ {"CPSR_xfcs", TRUE, PSR_x | PSR_f | PSR_c | PSR_s},
+ {"CPSR_xsfc", TRUE, PSR_x | PSR_s | PSR_f | PSR_c},
+ {"CPSR_xscf", TRUE, PSR_x | PSR_s | PSR_c | PSR_f},
+ {"CPSR_xcfs", TRUE, PSR_x | PSR_c | PSR_f | PSR_s},
+ {"CPSR_xcsf", TRUE, PSR_x | PSR_c | PSR_s | PSR_f},
+ {"CPSR_cfsx", TRUE, PSR_c | PSR_f | PSR_s | PSR_x},
+ {"CPSR_cfxs", TRUE, PSR_c | PSR_f | PSR_x | PSR_s},
+ {"CPSR_csfx", TRUE, PSR_c | PSR_s | PSR_f | PSR_x},
+ {"CPSR_csxf", TRUE, PSR_c | PSR_s | PSR_x | PSR_f},
+ {"CPSR_cxfs", TRUE, PSR_c | PSR_x | PSR_f | PSR_s},
+ {"CPSR_cxsf", TRUE, PSR_c | PSR_x | PSR_s | PSR_f},
+ {"SPSR_fs", FALSE, PSR_f | PSR_s},
+ {"SPSR_fx", FALSE, PSR_f | PSR_x},
+ {"SPSR_fc", FALSE, PSR_f | PSR_c},
+ {"SPSR_sf", FALSE, PSR_s | PSR_f},
+ {"SPSR_sx", FALSE, PSR_s | PSR_x},
+ {"SPSR_sc", FALSE, PSR_s | PSR_c},
+ {"SPSR_xf", FALSE, PSR_x | PSR_f},
+ {"SPSR_xs", FALSE, PSR_x | PSR_s},
+ {"SPSR_xc", FALSE, PSR_x | PSR_c},
+ {"SPSR_cf", FALSE, PSR_c | PSR_f},
+ {"SPSR_cs", FALSE, PSR_c | PSR_s},
+ {"SPSR_cx", FALSE, PSR_c | PSR_x},
+ {"SPSR_fsx", FALSE, PSR_f | PSR_s | PSR_x},
+ {"SPSR_fsc", FALSE, PSR_f | PSR_s | PSR_c},
+ {"SPSR_fxs", FALSE, PSR_f | PSR_x | PSR_s},
+ {"SPSR_fxc", FALSE, PSR_f | PSR_x | PSR_c},
+ {"SPSR_fcs", FALSE, PSR_f | PSR_c | PSR_s},
+ {"SPSR_fcx", FALSE, PSR_f | PSR_c | PSR_x},
+ {"SPSR_sfx", FALSE, PSR_s | PSR_f | PSR_x},
+ {"SPSR_sfc", FALSE, PSR_s | PSR_f | PSR_c},
+ {"SPSR_sxf", FALSE, PSR_s | PSR_x | PSR_f},
+ {"SPSR_sxc", FALSE, PSR_s | PSR_x | PSR_c},
+ {"SPSR_scf", FALSE, PSR_s | PSR_c | PSR_f},
+ {"SPSR_scx", FALSE, PSR_s | PSR_c | PSR_x},
+ {"SPSR_xfs", FALSE, PSR_x | PSR_f | PSR_s},
+ {"SPSR_xfc", FALSE, PSR_x | PSR_f | PSR_c},
+ {"SPSR_xsf", FALSE, PSR_x | PSR_s | PSR_f},
+ {"SPSR_xsc", FALSE, PSR_x | PSR_s | PSR_c},
+ {"SPSR_xcf", FALSE, PSR_x | PSR_c | PSR_f},
+ {"SPSR_xcs", FALSE, PSR_x | PSR_c | PSR_s},
+ {"SPSR_cfs", FALSE, PSR_c | PSR_f | PSR_s},
+ {"SPSR_cfx", FALSE, PSR_c | PSR_f | PSR_x},
+ {"SPSR_csf", FALSE, PSR_c | PSR_s | PSR_f},
+ {"SPSR_csx", FALSE, PSR_c | PSR_s | PSR_x},
+ {"SPSR_cxf", FALSE, PSR_c | PSR_x | PSR_f},
+ {"SPSR_cxs", FALSE, PSR_c | PSR_x | PSR_s},
+ {"SPSR_fsxc", FALSE, PSR_f | PSR_s | PSR_x | PSR_c},
+ {"SPSR_fscx", FALSE, PSR_f | PSR_s | PSR_c | PSR_x},
+ {"SPSR_fxsc", FALSE, PSR_f | PSR_x | PSR_s | PSR_c},
+ {"SPSR_fxcs", FALSE, PSR_f | PSR_x | PSR_c | PSR_s},
+ {"SPSR_fcsx", FALSE, PSR_f | PSR_c | PSR_s | PSR_x},
+ {"SPSR_fcxs", FALSE, PSR_f | PSR_c | PSR_x | PSR_s},
+ {"SPSR_sfxc", FALSE, PSR_s | PSR_f | PSR_x | PSR_c},
+ {"SPSR_sfcx", FALSE, PSR_s | PSR_f | PSR_c | PSR_x},
+ {"SPSR_sxfc", FALSE, PSR_s | PSR_x | PSR_f | PSR_c},
+ {"SPSR_sxcf", FALSE, PSR_s | PSR_x | PSR_c | PSR_f},
+ {"SPSR_scfx", FALSE, PSR_s | PSR_c | PSR_f | PSR_x},
+ {"SPSR_scxf", FALSE, PSR_s | PSR_c | PSR_x | PSR_f},
+ {"SPSR_xfsc", FALSE, PSR_x | PSR_f | PSR_s | PSR_c},
+ {"SPSR_xfcs", FALSE, PSR_x | PSR_f | PSR_c | PSR_s},
+ {"SPSR_xsfc", FALSE, PSR_x | PSR_s | PSR_f | PSR_c},
+ {"SPSR_xscf", FALSE, PSR_x | PSR_s | PSR_c | PSR_f},
+ {"SPSR_xcfs", FALSE, PSR_x | PSR_c | PSR_f | PSR_s},
+ {"SPSR_xcsf", FALSE, PSR_x | PSR_c | PSR_s | PSR_f},
+ {"SPSR_cfsx", FALSE, PSR_c | PSR_f | PSR_s | PSR_x},
+ {"SPSR_cfxs", FALSE, PSR_c | PSR_f | PSR_x | PSR_s},
+ {"SPSR_csfx", FALSE, PSR_c | PSR_s | PSR_f | PSR_x},
+ {"SPSR_csxf", FALSE, PSR_c | PSR_s | PSR_x | PSR_f},
+ {"SPSR_cxfs", FALSE, PSR_c | PSR_x | PSR_f | PSR_s},
+ {"SPSR_cxsf", FALSE, PSR_c | PSR_x | PSR_s | PSR_f},
+};
+
+enum wreg_type
+ {
+ IWMMXT_REG_WR = 0,
+ IWMMXT_REG_WC = 1,
+ IWMMXT_REG_WR_OR_WC = 2,
+ IWMMXT_REG_WCG
+ };
+
+enum iwmmxt_insn_type
+{
+ check_rd,
+ check_wr,
+ check_wrwr,
+ check_wrwrwr,
+ check_wrwrwcg,
+ check_tbcst,
+ check_tmovmsk,
+ check_tmia,
+ check_tmcrr,
+ check_tmrrc,
+ check_tmcr,
+ check_tmrc,
+ check_tinsr,
+ check_textrc,
+ check_waligni,
+ check_textrm,
+ check_wshufh
};
enum vfp_dp_reg_pos
#define REG_LR 14
#define REG_PC 15
+#define wr_register(reg) ((reg ^ WR_PREFIX) >= 0 && (reg ^ WR_PREFIX) <= 15)
+#define wc_register(reg) ((reg ^ WC_PREFIX) >= 0 && (reg ^ WC_PREFIX) <= 15)
+#define wcg_register(reg) ((reg ^ WC_PREFIX) >= 8 && (reg ^ WC_PREFIX) <= 11)
+
/* These are the standard names. Users can add aliases with .req. */
/* Integer Register Numbers. */
static const struct reg_entry rn_table[] =
{NULL, 0}
};
+#define WR_PREFIX 0x200
+#define WC_PREFIX 0x400
+
+static const struct reg_entry iwmmxt_table[] =
+{
+ /* Intel Wireless MMX technology register names. */
+ { "wr0", 0x0 | WR_PREFIX}, {"wr1", 0x1 | WR_PREFIX},
+ { "wr2", 0x2 | WR_PREFIX}, {"wr3", 0x3 | WR_PREFIX},
+ { "wr4", 0x4 | WR_PREFIX}, {"wr5", 0x5 | WR_PREFIX},
+ { "wr6", 0x6 | WR_PREFIX}, {"wr7", 0x7 | WR_PREFIX},
+ { "wr8", 0x8 | WR_PREFIX}, {"wr9", 0x9 | WR_PREFIX},
+ { "wr10", 0xa | WR_PREFIX}, {"wr11", 0xb | WR_PREFIX},
+ { "wr12", 0xc | WR_PREFIX}, {"wr13", 0xd | WR_PREFIX},
+ { "wr14", 0xe | WR_PREFIX}, {"wr15", 0xf | WR_PREFIX},
+ { "wcid", 0x0 | WC_PREFIX}, {"wcon", 0x1 | WC_PREFIX},
+ {"wcssf", 0x2 | WC_PREFIX}, {"wcasf", 0x3 | WC_PREFIX},
+ {"wcgr0", 0x8 | WC_PREFIX}, {"wcgr1", 0x9 | WC_PREFIX},
+ {"wcgr2", 0xa | WC_PREFIX}, {"wcgr3", 0xb | WC_PREFIX},
+
+ { "wR0", 0x0 | WR_PREFIX}, {"wR1", 0x1 | WR_PREFIX},
+ { "wR2", 0x2 | WR_PREFIX}, {"wR3", 0x3 | WR_PREFIX},
+ { "wR4", 0x4 | WR_PREFIX}, {"wR5", 0x5 | WR_PREFIX},
+ { "wR6", 0x6 | WR_PREFIX}, {"wR7", 0x7 | WR_PREFIX},
+ { "wR8", 0x8 | WR_PREFIX}, {"wR9", 0x9 | WR_PREFIX},
+ { "wR10", 0xa | WR_PREFIX}, {"wR11", 0xb | WR_PREFIX},
+ { "wR12", 0xc | WR_PREFIX}, {"wR13", 0xd | WR_PREFIX},
+ { "wR14", 0xe | WR_PREFIX}, {"wR15", 0xf | WR_PREFIX},
+ { "wCID", 0x0 | WC_PREFIX}, {"wCon", 0x1 | WC_PREFIX},
+ {"wCSSF", 0x2 | WC_PREFIX}, {"wCASF", 0x3 | WC_PREFIX},
+ {"wCGR0", 0x8 | WC_PREFIX}, {"wCGR1", 0x9 | WC_PREFIX},
+ {"wCGR2", 0xa | WC_PREFIX}, {"wCGR3", 0xb | WC_PREFIX},
+ {NULL, 0}
+};
+
/* Co-processor Numbers. */
static const struct reg_entry cp_table[] =
{
{mav_mvdx_table, 15, NULL, N_("Maverick MVFX register expected")},
{mav_mvax_table, 3, NULL, N_("Maverick MVAX register expected")},
{mav_dspsc_table, 0, NULL, N_("Maverick DSPSC register expected")},
+ {iwmmxt_table, 23, NULL, N_("Intel Wireless MMX technology register expected")},
};
/* Enumeration matching entries in table above. */
REG_TYPE_MVDX = 9,
REG_TYPE_MVAX = 10,
REG_TYPE_DSPSC = 11,
+ REG_TYPE_IWMMXT = 12,
- REG_TYPE_MAX = 12
+ REG_TYPE_MAX = 13
};
/* Functions called by parser. */
static bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void));
#endif
+static int wreg_required_here PARAMS ((char **, int, enum wreg_type));
+static void do_iwmmxt_byte_addr PARAMS ((char *));
+static void do_iwmmxt_tandc PARAMS ((char *));
+static void do_iwmmxt_tbcst PARAMS ((char *));
+static void do_iwmmxt_textrc PARAMS ((char *));
+static void do_iwmmxt_textrm PARAMS ((char *));
+static void do_iwmmxt_tinsr PARAMS ((char *));
+static void do_iwmmxt_tmcr PARAMS ((char *));
+static void do_iwmmxt_tmcrr PARAMS ((char *));
+static void do_iwmmxt_tmia PARAMS ((char *));
+static void do_iwmmxt_tmovmsk PARAMS ((char *));
+static void do_iwmmxt_tmrc PARAMS ((char *));
+static void do_iwmmxt_tmrrc PARAMS ((char *));
+static void do_iwmmxt_torc PARAMS ((char *));
+static void do_iwmmxt_waligni PARAMS ((char *));
+static void do_iwmmxt_wmov PARAMS ((char *));
+static void do_iwmmxt_word_addr PARAMS ((char *));
+static void do_iwmmxt_wrwr PARAMS ((char *));
+static void do_iwmmxt_wrwrwcg PARAMS ((char *));
+static void do_iwmmxt_wrwrwr PARAMS ((char *));
+static void do_iwmmxt_wshufh PARAMS ((char *));
+static void do_iwmmxt_wzero PARAMS ((char *));
+static int cp_byte_address_offset PARAMS ((char **));
+static int cp_byte_address_required_here PARAMS ((char **));
+
/* ARM instructions take 4bytes in the object file, Thumb instructions
take 2: */
#define INSN_SIZE 4
{"mar", 0xec400000, 3, ARM_CEXT_XSCALE, do_xsc_mar},
{"mra", 0xec500000, 3, ARM_CEXT_XSCALE, do_xsc_mra},
+ /* Intel Wireless MMX technology instructions. */
+ {"tandcb", 0xee130130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
+ {"tandch", 0xee530130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
+ {"tandcw", 0xee930130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
+ {"tbcstb", 0xee400010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
+ {"tbcsth", 0xee400050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
+ {"tbcstw", 0xee400090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
+ {"textrcb", 0xee130170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
+ {"textrch", 0xee530170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
+ {"textrcw", 0xee930170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
+ {"textrmub", 0xee100070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
+ {"textrmuh", 0xee500070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
+ {"textrmuw", 0xee900070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
+ {"textrmsb", 0xee100078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
+ {"textrmsh", 0xee500078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
+ {"textrmsw", 0xee900078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
+ {"tinsrb", 0xee600010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
+ {"tinsrh", 0xee600050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
+ {"tinsrw", 0xee600090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
+ {"tmcr", 0xee000110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmcr},
+ {"tmcrr", 0xec400000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmcrr},
+ {"tmia", 0xee200010, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
+ {"tmiaph", 0xee280010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
+ {"tmiabb", 0xee2c0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
+ {"tmiabt", 0xee2d0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
+ {"tmiatb", 0xee2e0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
+ {"tmiatt", 0xee2f0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
+ {"tmovmskb", 0xee100030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
+ {"tmovmskh", 0xee500030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
+ {"tmovmskw", 0xee900030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
+ {"tmrc", 0xee100110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmrc},
+ {"tmrrc", 0xec500000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmrrc},
+ {"torcb", 0xee130150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
+ {"torch", 0xee530150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
+ {"torcw", 0xee930150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
+ {"waccb", 0xee0001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"wacch", 0xee4001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"waccw", 0xee8001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"waddbss", 0xee300180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"waddb", 0xee000180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"waddbus", 0xee100180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"waddhss", 0xee700180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"waddh", 0xee400180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"waddhus", 0xee500180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"waddwss", 0xeeb00180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"waddw", 0xee800180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"waddwus", 0xee900180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"waligni", 0xee000020, 7, ARM_CEXT_IWMMXT, do_iwmmxt_waligni},
+ {"walignr0", 0xee800020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"walignr1", 0xee900020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"walignr2", 0xeea00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"walignr3", 0xeeb00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wand", 0xee200000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wandn", 0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wavg2b", 0xee800000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wavg2br", 0xee900000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wavg2h", 0xeec00000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wavg2hr", 0xeed00000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wcmpeqb", 0xee000060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wcmpeqh", 0xee400060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wcmpeqw", 0xee800060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wcmpgtub", 0xee100060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wcmpgtuh", 0xee500060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wcmpgtuw", 0xee900060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wcmpgtsb", 0xee300060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wcmpgtsh", 0xee700060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wcmpgtsw", 0xeeb00060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wldrb", 0xec100000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
+ {"wldrh", 0xec100100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
+ {"wldrw", 0xec100200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
+ {"wldrd", 0xec100300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
+ {"wmacs", 0xee600100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmacsz", 0xee700100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmacu", 0xee400100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmacuz", 0xee500100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmadds", 0xeea00100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmaddu", 0xee800100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmaxsb", 0xee200160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmaxsh", 0xee600160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmaxsw", 0xeea00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmaxub", 0xee000160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmaxuh", 0xee400160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmaxuw", 0xee800160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wminsb", 0xee300160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wminsh", 0xee700160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wminsw", 0xeeb00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wminub", 0xee100160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wminuh", 0xee500160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wminuw", 0xee900160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmov", 0xee000000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wmov},
+ {"wmulsm", 0xee300100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmulsl", 0xee200100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmulum", 0xee100100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wmulul", 0xee000100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wor", 0xee000000, 3, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wpackhss", 0xee700080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wpackhus", 0xee500080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wpackwss", 0xeeb00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wpackwus", 0xee900080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wpackdss", 0xeef00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wpackdus", 0xeed00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wrorh", 0xee700040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wrorhg", 0xee700148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
+ {"wrorw", 0xeeb00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wrorwg", 0xeeb00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
+ {"wrord", 0xeef00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wrordg", 0xeef00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
+ {"wsadb", 0xee000120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsadbz", 0xee100120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsadh", 0xee400120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsadhz", 0xee500120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wshufh", 0xee0001e0, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wshufh},
+ {"wsllh", 0xee500040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsllhg", 0xee500148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
+ {"wsllw", 0xee900040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsllwg", 0xee900148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
+ {"wslld", 0xeed00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wslldg", 0xeed00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
+ {"wsrah", 0xee400040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsrahg", 0xee400148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
+ {"wsraw", 0xee800040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsrawg", 0xee800148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
+ {"wsrad", 0xeec00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsradg", 0xeec00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
+ {"wsrlh", 0xee600040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsrlhg", 0xee600148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
+ {"wsrlw", 0xeea00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsrlwg", 0xeea00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
+ {"wsrld", 0xeee00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsrldg", 0xeee00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
+ {"wstrb", 0xec000000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
+ {"wstrh", 0xec000100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
+ {"wstrw", 0xec000200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
+ {"wstrd", 0xec000300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
+ {"wsubbss", 0xee3001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsubb", 0xee0001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsubbus", 0xee1001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsubhss", 0xee7001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsubh", 0xee4001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsubhus", 0xee5001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsubwss", 0xeeb001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsubw", 0xee8001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wsubwus", 0xee9001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wunpckehub", 0xee0000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"wunpckehuh", 0xee4000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"wunpckehuw", 0xee8000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"wunpckehsb", 0xee2000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"wunpckehsh", 0xee6000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"wunpckehsw", 0xeea000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"wunpckihb", 0xee1000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wunpckihh", 0xee5000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wunpckihw", 0xee9000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wunpckelub", 0xee0000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"wunpckeluh", 0xee4000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"wunpckeluw", 0xee8000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"wunpckelsb", 0xee2000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"wunpckelsh", 0xee6000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"wunpckelsw", 0xeea000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
+ {"wunpckilb", 0xee1000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wunpckilh", 0xee5000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wunpckilw", 0xee9000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wxor", 0xee100000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
+ {"wzero", 0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wzero},
+
/* Cirrus Maverick instructions. */
{"cfldrs", 0xec100400, 6, ARM_CEXT_MAVERICK, do_mav_ldst_1},
{"cfldrd", 0xec500400, 6, ARM_CEXT_MAVERICK, do_mav_ldst_2},
#ifdef OBJ_ELF
{ "word", s_arm_elf_cons, 4 },
{ "long", s_arm_elf_cons, 4 },
- { "file", (void (*) PARAMS ((int))) dwarf2_directive_file, 0 },
- { "loc", dwarf2_directive_loc, 0 },
#else
{ "word", cons, 4},
#endif
static int arm_parse_cpu PARAMS ((char *));
static int arm_parse_arch PARAMS ((char *));
static int arm_parse_fpu PARAMS ((char *));
+#if defined OBJ_COFF || defined OBJ_ELF
+static void arm_add_note PARAMS ((const char *, const char *, unsigned int));
+#endif
/* Stuff needed to resolve the label ambiguity
As:
*/
symbolS * last_label_seen;
-static int label_is_thumb_function_name = false;
+static int label_is_thumb_function_name = FALSE;
/* Literal Pool stuff. */
symbolS * symbol;
segT section;
subsegT sub_section;
- struct literal_pool * next;
+ struct literal_pool * next;
} literal_pool;
/* Pointer to a linked list of literal pools. */
static int
add_to_lit_pool ()
{
- literal_pool * pool;
+ literal_pool * pool;
unsigned int entry;
pool = find_or_make_literal_pool ();
/* The following label is the name/address of the start of a Thumb function.
We need to know this for the interworking support. */
- label_is_thumb_function_name = true;
+ label_is_thumb_function_name = TRUE;
demand_empty_rest_of_line ();
}
return FAIL;
}
+/* A Intel Wireless MMX technology register
+ must be given at this point.
+ Shift is the place to put it in inst.instruction.
+ Restores input start point on err.
+ Returns the reg#, or FAIL. */
+
+static int
+wreg_required_here (str, shift, reg_type)
+ char ** str;
+ int shift;
+ enum wreg_type reg_type;
+{
+ static char buff [128];
+ int reg;
+ char * start = *str;
+
+ if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_IWMMXT].htab)) != FAIL)
+ {
+ if (wr_register (reg)
+ && (reg_type == IWMMXT_REG_WR || reg_type == IWMMXT_REG_WR_OR_WC))
+ {
+ if (shift >= 0)
+ inst.instruction |= (reg ^ WR_PREFIX) << shift;
+ return reg;
+ }
+ else if (wc_register (reg)
+ && (reg_type == IWMMXT_REG_WC || reg_type == IWMMXT_REG_WR_OR_WC))
+ {
+ if (shift >= 0)
+ inst.instruction |= (reg ^ WC_PREFIX) << shift;
+ return reg;
+ }
+ else if ((wcg_register (reg) && reg_type == IWMMXT_REG_WCG))
+ {
+ if (shift >= 0)
+ inst.instruction |= ((reg ^ WC_PREFIX) - 8) << shift;
+ return reg;
+ }
+ }
+
+ /* Restore the start point, we may have got a reg of the wrong class. */
+ *str = start;
+
+ /* In the few cases where we might be able to accept
+ something else this error can be overridden. */
+ sprintf (buff, _("Intel Wireless MMX technology register expected, not '%.100s'"), start);
+ inst.error = buff;
+
+ return FAIL;
+}
+
static const struct asm_psr *
arm_psr_parse (ccp)
register char ** ccp;
{
p++;
- if (wb_ok && skip_past_comma (& p) == SUCCESS)
+ skip_whitespace (p);
+
+ if (*p == '\0')
{
- /* [Rn], #expr */
- write_back = WRITE_BACK;
+ /* As an extension to the official ARM syntax we allow:
+
+ [Rn]
+
+ as a short hand for:
+
+ [Rn,#0] */
+ inst.instruction |= PRE_INDEX | INDEX_UP;
+ *str = p;
+ return SUCCESS;
+ }
+
+ if (skip_past_comma (& p) == FAIL)
+ {
+ inst.error = _("comma expected after closing square bracket");
+ return FAIL;
+ }
- if (reg == REG_PC)
+ skip_whitespace (p);
+
+ if (*p == '#')
+ {
+ if (wb_ok)
{
- inst.error = _("pc may not be used in post-increment");
- return FAIL;
+ /* [Rn], #expr */
+ write_back = WRITE_BACK;
+
+ if (reg == REG_PC)
+ {
+ inst.error = _("pc may not be used in post-increment");
+ return FAIL;
+ }
+
+ if (cp_address_offset (& p) == FAIL)
+ return FAIL;
}
+ else
+ pre_inc = PRE_INDEX | INDEX_UP;
+ }
+ else if (*p == '{')
+ {
+ int option;
+
+ /* [Rn], {<expr>} */
+ p++;
+
+ skip_whitespace (p);
- if (cp_address_offset (& p) == FAIL)
+ if (my_get_expression (& inst.reloc.exp, & p))
return FAIL;
+
+ if (inst.reloc.exp.X_op == O_constant)
+ {
+ option = inst.reloc.exp.X_add_number;
+
+ if (option > 255 || option < 0)
+ {
+ inst.error = _("'option' field too large");
+ return FAIL;
+ }
+
+ skip_whitespace (p);
+
+ if (*p != '}')
+ {
+ inst.error = _("'}' expected at end of 'option' field");
+ return FAIL;
+ }
+ else
+ {
+ p++;
+ inst.instruction |= option;
+ inst.instruction |= INDEX_UP;
+ }
+ }
+ else
+ {
+ inst.error = _("non-constant expressions for 'option' field not supported");
+ return FAIL;
+ }
}
else
- pre_inc = PRE_INDEX | INDEX_UP;
+ {
+ inst.error = _("# or { expected after comma");
+ return FAIL;
+ }
}
else
{
return SUCCESS;
}
+static int
+cp_byte_address_offset (str)
+ char ** str;
+{
+ int offset;
+
+ skip_whitespace (* str);
+
+ if (! is_immediate_prefix (**str))
+ {
+ inst.error = _("immediate expression expected");
+ return FAIL;
+ }
+
+ (*str)++;
+
+ if (my_get_expression (& inst.reloc.exp, str))
+ return FAIL;
+
+ if (inst.reloc.exp.X_op == O_constant)
+ {
+ offset = inst.reloc.exp.X_add_number;
+
+ if (offset > 255 || offset < -255)
+ {
+ inst.error = _("offset too large");
+ return FAIL;
+ }
+
+ if (offset >= 0)
+ inst.instruction |= INDEX_UP;
+ else
+ offset = -offset;
+
+ inst.instruction |= offset;
+ }
+ else
+ inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
+
+ return SUCCESS;
+}
+
+static int
+cp_byte_address_required_here (str)
+ char ** str;
+{
+ char * p = * str;
+ int pre_inc = 0;
+ int write_back = 0;
+
+ if (*p == '[')
+ {
+ int reg;
+
+ p++;
+ skip_whitespace (p);
+
+ if ((reg = reg_required_here (& p, 16)) == FAIL)
+ return FAIL;
+
+ skip_whitespace (p);
+
+ if (*p == ']')
+ {
+ p++;
+
+ if (skip_past_comma (& p) == SUCCESS)
+ {
+ /* [Rn], #expr */
+ write_back = WRITE_BACK;
+
+ if (reg == REG_PC)
+ {
+ inst.error = _("pc may not be used in post-increment");
+ return FAIL;
+ }
+
+ if (cp_byte_address_offset (& p) == FAIL)
+ return FAIL;
+ }
+ else
+ pre_inc = PRE_INDEX | INDEX_UP;
+ }
+ else
+ {
+ /* '['Rn, #expr']'[!] */
+
+ if (skip_past_comma (& p) == FAIL)
+ {
+ inst.error = _("pre-indexed expression expected");
+ return FAIL;
+ }
+
+ pre_inc = PRE_INDEX;
+
+ if (cp_byte_address_offset (& p) == FAIL)
+ return FAIL;
+
+ skip_whitespace (p);
+
+ if (*p++ != ']')
+ {
+ inst.error = _("missing ]");
+ return FAIL;
+ }
+
+ skip_whitespace (p);
+
+ if (*p == '!')
+ {
+ if (reg == REG_PC)
+ {
+ inst.error = _("pc may not be used with write-back");
+ return FAIL;
+ }
+
+ p++;
+ write_back = WRITE_BACK;
+ }
+ }
+ }
+ else
+ {
+ if (my_get_expression (&inst.reloc.exp, &p))
+ return FAIL;
+
+ inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
+ inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */
+ inst.reloc.pc_rel = 1;
+ inst.instruction |= (REG_PC << 16);
+ pre_inc = PRE_INDEX;
+ }
+
+ inst.instruction |= write_back | pre_inc;
+ *str = p;
+ return SUCCESS;
+}
+
static void
do_empty (str)
char * str;
end_of_line (str);
}
+static unsigned long check_iwmmxt_insn PARAMS ((char *, enum iwmmxt_insn_type, int));
+
+/* Parse INSN_TYPE insn STR having a possible IMMEDIATE_SIZE immediate. */
+
+static unsigned long
+check_iwmmxt_insn (str, insn_type, immediate_size)
+ char * str;
+ enum iwmmxt_insn_type insn_type;
+ int immediate_size;
+{
+ int reg = 0;
+ const char * inst_error;
+ expressionS expr;
+ unsigned long number;
+
+ inst_error = inst.error;
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ skip_whitespace (str);
+
+ switch (insn_type)
+ {
+ case check_rd:
+ if ((reg = reg_required_here (&str, 12)) == FAIL)
+ return FAIL;
+ break;
+
+ case check_wr:
+ if ((wreg_required_here (&str, 0, IWMMXT_REG_WR)) == FAIL)
+ return FAIL;
+ break;
+
+ case check_wrwr:
+ if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
+ return FAIL;
+ break;
+
+ case check_wrwrwr:
+ if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
+ return FAIL;
+ break;
+
+ case check_wrwrwcg:
+ if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || wreg_required_here (&str, 0, IWMMXT_REG_WCG) == FAIL))
+ return FAIL;
+ break;
+
+ case check_tbcst:
+ if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 12) == FAIL))
+ return FAIL;
+ break;
+
+ case check_tmovmsk:
+ if ((reg_required_here (&str, 12) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
+ return FAIL;
+ break;
+
+ case check_tmia:
+ if ((wreg_required_here (&str, 5, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 0) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 12) == FAIL))
+ return FAIL;
+ break;
+
+ case check_tmcrr:
+ if ((wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 12) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 16) == FAIL))
+ return FAIL;
+ break;
+
+ case check_tmrrc:
+ if ((reg_required_here (&str, 12) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 16) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
+ return FAIL;
+ break;
+
+ case check_tmcr:
+ if ((wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 12) == FAIL))
+ return FAIL;
+ break;
+
+ case check_tmrc:
+ if ((reg_required_here (&str, 12) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL))
+ return FAIL;
+ break;
+
+ case check_tinsr:
+ if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 12) == FAIL
+ || skip_past_comma (&str) == FAIL))
+ return FAIL;
+ break;
+
+ case check_textrc:
+ if ((reg_required_here (&str, 12) == FAIL
+ || skip_past_comma (&str) == FAIL))
+ return FAIL;
+ break;
+
+ case check_waligni:
+ if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL))
+ return FAIL;
+ break;
+
+ case check_textrm:
+ if ((reg_required_here (&str, 12) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL))
+ return FAIL;
+ break;
+
+ case check_wshufh:
+ if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
+ || skip_past_comma (&str) == FAIL))
+ return FAIL;
+ break;
+ }
+
+ if (immediate_size == 0)
+ {
+ end_of_line (str);
+ inst.error = inst_error;
+ return reg;
+ }
+ else
+ {
+ 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 FAIL;
+ }
+
+ number = expr.X_add_number;
+
+ if (number != (number & immediate_size))
+ {
+ inst.error = _("immediate value out of range");
+ return FAIL;
+ }
+ end_of_line (str);
+ inst.error = inst_error;
+ return number;
+ }
+}
+
+static void
+do_iwmmxt_byte_addr (str)
+ char * str;
+{
+ int op = (inst.instruction & 0x300) >> 8;
+ int reg;
+
+ inst.instruction &= ~0x300;
+ inst.instruction |= (op & 1) << 22 | (op & 2) << 7;
+
+ skip_whitespace (str);
+
+ if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
+ || skip_past_comma (& str) == FAIL
+ || cp_byte_address_required_here (&str) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ }
+ else
+ end_of_line (str);
+
+ if (wc_register (reg))
+ {
+ inst.instruction |= 0xf0000100;
+ inst.instruction &= ~0x00400000;
+ }
+}
+
+static void
+do_iwmmxt_tandc (str)
+ char * str;
+{
+ int reg;
+
+ reg = check_iwmmxt_insn (str, check_rd, 0);
+
+ if (reg != REG_PC && !inst.error)
+ inst.error = _("only r15 allowed here");
+ return;
+}
+
+static void
+do_iwmmxt_tbcst (str)
+ char * str;
+{
+ check_iwmmxt_insn (str, check_tbcst, 0);
+
+ return;
+}
+
+static void
+do_iwmmxt_textrc (str)
+ char * str;
+{
+ unsigned long number;
+
+ if ((number = check_iwmmxt_insn (str, check_textrc, 7)) == (unsigned long) FAIL)
+ return;
+
+ inst.instruction |= number & 0x7;
+ return;
+}
+
+static void
+do_iwmmxt_textrm (str)
+ char * str;
+{
+ unsigned long number;
+
+ if ((number = check_iwmmxt_insn (str, check_textrm, 7)) == (unsigned long) FAIL)
+ return;
+
+ inst.instruction |= number & 0x7;
+}
+
+static void
+do_iwmmxt_tinsr (str)
+ char * str;
+{
+ unsigned long number;
+
+ if ((number = check_iwmmxt_insn (str, check_tinsr, 7)) == (unsigned long) FAIL)
+ return;
+
+ inst.instruction |= number & 0x7;
+ return;
+}
+
+static void
+do_iwmmxt_tmcr (str)
+ char * str;
+{
+ check_iwmmxt_insn (str, check_tmcr, 0);
+
+ return;
+}
+
+static void
+do_iwmmxt_tmcrr (str)
+ char * str;
+{
+ check_iwmmxt_insn (str, check_tmcrr, 0);
+
+ return;
+}
+
+static void
+do_iwmmxt_tmia (str)
+ char * str;
+{
+ check_iwmmxt_insn (str, check_tmia, 0);
+
+ return;
+}
+
+static void
+do_iwmmxt_tmovmsk (str)
+ char * str;
+{
+ check_iwmmxt_insn (str, check_tmovmsk, 0);
+
+ return;
+}
+
+static void
+do_iwmmxt_tmrc (str)
+ char * str;
+{
+ check_iwmmxt_insn (str, check_tmrc, 0);
+
+ return;
+}
+
+static void
+do_iwmmxt_tmrrc (str)
+ char * str;
+{
+ check_iwmmxt_insn (str, check_tmrrc, 0);
+
+ return;
+}
+
+static void
+do_iwmmxt_torc (str)
+ char * str;
+{
+ check_iwmmxt_insn (str, check_rd, 0);
+ return;
+}
+
+static void
+do_iwmmxt_waligni (str)
+ char * str;
+{
+ unsigned long number;
+
+ if ((number = check_iwmmxt_insn (str, check_waligni, 7)) == (unsigned long) FAIL)
+ return;
+
+ inst.instruction |= ((number & 0x7) << 20);
+ return;
+}
+
+static void
+do_iwmmxt_wmov (str)
+ char * str;
+{
+ if (check_iwmmxt_insn (str, check_wrwr, 0) == (unsigned long) FAIL)
+ return;
+
+ inst.instruction |= ((inst.instruction >> 16) & 0xf);
+ return;
+}
+
+static void
+do_iwmmxt_word_addr (str)
+ char * str;
+{
+ int op = (inst.instruction & 0x300) >> 8;
+ int reg;
+
+ inst.instruction &= ~0x300;
+ inst.instruction |= (op & 1) << 22 | (op & 2) << 7;
+
+ skip_whitespace (str);
+
+ if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
+ || skip_past_comma (& str) == FAIL
+ || cp_address_required_here (& str, CP_WB_OK) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = BAD_ARGS;
+ }
+ else
+ end_of_line (str);
+
+ if (wc_register (reg))
+ {
+ inst.instruction |= 0xf0000100;
+ inst.instruction &= ~0x00400000;
+ }
+}
+
+static void
+do_iwmmxt_wrwr (str)
+ char * str;
+{
+ check_iwmmxt_insn (str, check_wrwr, 0);
+
+ return;
+}
+
+static void
+do_iwmmxt_wrwrwcg (str)
+ char * str;
+{
+ check_iwmmxt_insn (str, check_wrwrwcg, 0);
+
+ return;
+}
+
+static void
+do_iwmmxt_wrwrwr (str)
+ char * str;
+{
+ check_iwmmxt_insn (str, check_wrwrwr, 0);
+
+ return;
+}
+
+static void
+do_iwmmxt_wshufh (str)
+ char * str;
+{
+ unsigned long number;
+
+ if ((number = check_iwmmxt_insn (str, check_wshufh, 0xff)) == (unsigned long) FAIL)
+ return;
+
+ inst.instruction |= ((number & 0xf0) << 16) | (number & 0xf);
+ return;
+}
+
+static void
+do_iwmmxt_wzero (str)
+ char * str;
+{
+ if (check_iwmmxt_insn (str, check_wr, 0) == (unsigned long) FAIL)
+ return;
+
+ inst.instruction |= ((inst.instruction & 0xf) << 12) | ((inst.instruction & 0xf) << 16);
+ return;
+}
+
/* Xscale multiply-accumulate (argument parse)
MIAcc acc0,Rm,Rs
MIAPHcc acc0,Rm,Rs
return -1;
}
-/* Return true if anything in the expression is a bignum. */
+/* Return TRUE if anything in the expression is a bignum. */
static int
walk_no_bignums (sp)
as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
}
}
-
+
inst.instruction |= range;
end_of_line (str);
return;
}
}
+#if defined OBJ_ELF || defined OBJ_COFF
+
+#ifdef OBJ_ELF
+#define arm_Note Elf_External_Note
+#else
+typedef struct
+{
+ unsigned char namesz[4]; /* Size of entry's owner string. */
+ unsigned char descsz[4]; /* Size of the note descriptor. */
+ unsigned char type[4]; /* Interpretation of the descriptor. */
+ char name[1]; /* Start of the name+desc data. */
+} arm_Note;
+#endif
+
+/* The description is kept to a fix sized in order to make updating
+ it and merging it easier. */
+#define ARM_NOTE_DESCRIPTION_LENGTH 8
+
+static void
+arm_add_note (name, description, type)
+ const char * name;
+ const char * description;
+ unsigned int type;
+{
+ arm_Note note ATTRIBUTE_UNUSED;
+ char * p;
+ unsigned int name_len;
+
+ name_len = (strlen (name) + 1 + 3) & ~3;
+
+ p = frag_more (sizeof (note.namesz));
+ md_number_to_chars (p, (valueT) name_len, sizeof (note.namesz));
+
+ p = frag_more (sizeof (note.descsz));
+ md_number_to_chars (p, (valueT) ARM_NOTE_DESCRIPTION_LENGTH, sizeof (note.descsz));
+
+ p = frag_more (sizeof (note.type));
+ md_number_to_chars (p, (valueT) type, sizeof (note.type));
+
+ p = frag_more (name_len);
+ strcpy (p, name);
+
+ p = frag_more (ARM_NOTE_DESCRIPTION_LENGTH);
+ strncpy (p, description, ARM_NOTE_DESCRIPTION_LENGTH);
+ frag_align (2, 0, 0);
+}
+#endif
+
void
md_begin ()
{
}
else if (mfpu_opt == -1)
{
+#if !(defined (TE_LINUX) || defined (TE_NetBSD))
+ /* Some environments specify a default FPU. If they don't, infer it
+ from the processor. */
if (mcpu_fpu_opt != -1)
mfpu_opt = mcpu_fpu_opt;
else
mfpu_opt = march_fpu_opt;
+#else
+ mfpu_opt = FPU_DEFAULT;
+#endif
}
if (mfpu_opt == -1)
/* Using VFP conventions (even if soft-float). */
if (cpu_variant & FPU_VFP_EXT_NONE) flags |= F_VFP_FLOAT;
+#if defined OBJ_ELF
+ if (cpu_variant & ARM_CEXT_MAVERICK)
+ {
+ flags ^= F_SOFT_FLOAT;
+ flags |= EF_ARM_MAVERICK_FLOAT;
+ }
+#endif
bfd_set_private_flags (stdoutput, flags);
break;
default:
- mach = bfd_mach_arm_4;
+ mach = bfd_mach_arm_unknown;
break;
}
/* Catch special cases. */
- if (cpu_variant & ARM_CEXT_XSCALE)
+ if (cpu_variant & ARM_CEXT_IWMMXT)
+ mach = bfd_mach_arm_iWMMXt;
+ else if (cpu_variant & ARM_CEXT_XSCALE)
mach = bfd_mach_arm_XScale;
+ else if (cpu_variant & ARM_CEXT_MAVERICK)
+ mach = bfd_mach_arm_ep9312;
else if (cpu_variant & ARM_EXT_V5E)
mach = bfd_mach_arm_5TE;
else if (cpu_variant & ARM_EXT_V5)
else if (cpu_variant & ARM_EXT_V3M)
mach = bfd_mach_arm_3M;
+#if 0 /* Suppressed - for now. */
+#if defined (OBJ_ELF) || defined (OBJ_COFF)
+
+ /* Create a .note section to fully identify this arm binary. */
+
+#define NOTE_ARCH_STRING "arch: "
+
+#if defined OBJ_COFF && ! defined NT_VERSION
+#define NT_VERSION 1
+#define NT_ARCH 2
+#endif
+
+ {
+ segT current_seg = now_seg;
+ subsegT current_subseg = now_subseg;
+ asection * arm_arch;
+ const char * arch_string;
+
+ arm_arch = bfd_make_section_old_way (stdoutput, ARM_NOTE_SECTION);
+
+#ifdef OBJ_COFF
+ bfd_set_section_flags (stdoutput, arm_arch,
+ SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_LINK_ONCE \
+ | SEC_HAS_CONTENTS);
+#endif
+ arm_arch->output_section = arm_arch;
+ subseg_set (arm_arch, 0);
+
+ switch (mach)
+ {
+ default:
+ case bfd_mach_arm_unknown: arch_string = "unknown"; break;
+ case bfd_mach_arm_2: arch_string = "armv2"; break;
+ case bfd_mach_arm_2a: arch_string = "armv2a"; break;
+ case bfd_mach_arm_3: arch_string = "armv3"; break;
+ case bfd_mach_arm_3M: arch_string = "armv3M"; break;
+ case bfd_mach_arm_4: arch_string = "armv4"; break;
+ case bfd_mach_arm_4T: arch_string = "armv4t"; break;
+ case bfd_mach_arm_5: arch_string = "armv5"; break;
+ case bfd_mach_arm_5T: arch_string = "armv5t"; break;
+ case bfd_mach_arm_5TE: arch_string = "armv5te"; break;
+ case bfd_mach_arm_XScale: arch_string = "XScale"; break;
+ case bfd_mach_arm_ep9312: arch_string = "ep9312"; break;
+ case bfd_mach_arm_iWMMXt: arch_string = "iWMMXt"; break;
+ }
+
+ arm_add_note (NOTE_ARCH_STRING, arch_string, NT_ARCH);
+
+ subseg_set (current_seg, current_subseg);
+ }
+#endif
+#endif /* Suppressed code. */
+
bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
}
md_number_to_chars (buf, newval, INSN_SIZE);
break;
+ case BFD_RELOC_ARM_CP_OFF_IMM_S2:
+ sign = value >= 0;
+ if (value < -255 || value > 255)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Illegal value for co-processor offset"));
+ if (value < 0)
+ value = -value;
+ newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
+ newval |= value | (sign ? INDEX_UP : 0);
+ md_number_to_chars (buf, newval , INSN_SIZE);
+ break;
+
case BFD_RELOC_ARM_THUMB_OFFSET:
newval = md_chars_to_number (buf, THUMB_SIZE);
/* Exactly what ranges, and where the offset is inserted depends
/* If this is called then the a literal has
been referenced across a section boundary. */
as_bad_where (fixp->fx_file, fixp->fx_line,
- _("literal referenced across section boundary"));
+ _("literal referenced across section boundary"));
return NULL;
#ifdef OBJ_ELF
{"mstrongarm1110", NULL, &legacy_cpu, ARM_ARCH_V4,
N_("use -mcpu=strongarm1110")},
{"mxscale", NULL, &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
+ {"miwmmxt", NULL, &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
{"mall", NULL, &legacy_cpu, ARM_ANY, N_("use -mcpu=all")},
/* Architecture variants -- don't add any more to this list either. */
{"arm1020e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
/* ??? XSCALE is really an architecture. */
{"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
+ /* ??? iwmmxt is not a processor. */
+ {"iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP_V2},
{"i80200", ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
/* Maverick */
{"ep9312", ARM_ARCH_V4T | ARM_CEXT_MAVERICK, FPU_NONE},
{"armv5texp", ARM_ARCH_V5TExP, FPU_ARCH_VFP},
{"armv5tej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP},
{"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP},
+ {"iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP},
{NULL, 0, 0}
};
{
{"maverick", ARM_CEXT_MAVERICK},
{"xscale", ARM_CEXT_XSCALE},
+ {"iwmmxt", ARM_CEXT_IWMMXT},
{NULL, 0}
};
THUMB_SET_FUNC (sym, 1);
- label_is_thumb_function_name = false;
+ label_is_thumb_function_name = FALSE;
}
}
return name;
}
+#if defined OBJ_COFF || defined OBJ_ELF
void
arm_validate_fix (fixP)
fixS * fixP;
fixP->fx_addsy = find_real_start (fixP->fx_addsy);
}
}
+#endif
+
+int
+arm_force_relocation (fixp)
+ struct fix * fixp;
+{
+#if defined (OBJ_COFF) && defined (TE_PE)
+ if (fixp->fx_r_type == BFD_RELOC_RVA)
+ return 1;
+#endif
+#ifdef OBJ_ELF
+ if (fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
+ || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
+ || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
+ || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
+ return 1;
+#endif
+
+ /* Resolve these relocations even if the symbol is extern or weak. */
+ if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
+ || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
+ || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
+ return 0;
+
+ return generic_force_reloc (fixp);
+}
#ifdef OBJ_COFF
/* This is a little hack to help the gas/arm/adrl.s test. It prevents
be resolved before the binbary is emitted, so it is safe to say that
it is adjustable. */
-boolean
+bfd_boolean
arm_fix_adjustable (fixP)
fixS * fixP;
{
return 0;
}
#endif
+
#ifdef OBJ_ELF
/* Relocations against Thumb function names must be left unadjusted,
so that the linker can use this information to correctly set the
addresses also ought to have their bottom bit set (assuming that
they reside in Thumb code), but at the moment they will not. */
-boolean
+bfd_boolean
arm_fix_adjustable (fixP)
fixS * fixP;
{
elf_frob_symbol (symp, puntp);
}
-int
-arm_force_relocation (fixp)
- struct fix * fixp;
-{
- if ( fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
- || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
- || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
- || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
- || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
- || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
- return 1;
-
- return S_FORCE_RELOC (fixp->fx_addsy);
-}
-
static bfd_reloc_code_real_type
arm_parse_reloc ()
{