aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Gretton-Dann <matthew.gretton-dann@arm.com>2012-08-24 08:09:01 +0000
committerMatthew Gretton-Dann <matthew.gretton-dann@arm.com>2012-08-24 08:09:01 +0000
commit6b9a8b67903ff139b6945f6afbd35a30f9d5315d (patch)
tree074dab1573786116989f6f1506ee9f464cdd4c2f
parent73924fbcf8af2b8059f9a8df5a2ae43e888e1bb7 (diff)
downloadgdb-6b9a8b67903ff139b6945f6afbd35a30f9d5315d.zip
gdb-6b9a8b67903ff139b6945f6afbd35a30f9d5315d.tar.gz
gdb-6b9a8b67903ff139b6945f6afbd35a30f9d5315d.tar.bz2
* gas/config/tc-arm.c (CVT_FLAVOUR_VAR): New define.
(CVT_VAR): New helper define. (neon_cvt_flavour): New enumeration, function renamed... (get_neon_cvt_flavour): ...to this. (do_vfp_nsyn_cvt): Update to use new neon_cvt_flavour. (do_vfp_nsyn_cvtz): Likewise. (do_neon_cvt_1): Likewise.
-rw-r--r--gas/ChangeLog10
-rw-r--r--gas/config/tc-arm.c163
2 files changed, 85 insertions, 88 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 249205f..8083dce 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,13 @@
+2012-08-24 Matthew Gretton-Dann <matthew.gretton-dann@arm>
+
+ * config/tc-arm.c (CVT_FLAVOUR_VAR): New define.
+ (CVT_VAR): New helper define.
+ (neon_cvt_flavour): New enumeration, function renamed...
+ (get_neon_cvt_flavour): ...to this.
+ (do_vfp_nsyn_cvt): Update to use new neon_cvt_flavour.
+ (do_vfp_nsyn_cvtz): Likewise.
+ (do_neon_cvt_1): Likewise.
+
2012-08-24 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
* config/tc-arm.c (NEON_ENC_TAB): Add vmaxnm, vminnm entries.
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 4c46abc..7dc938b 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -14510,16 +14510,55 @@ do_neon_shll (void)
/* Check the various types for the VCVT instruction, and return which version
the current instruction is. */
-static int
-neon_cvt_flavour (enum neon_shape rs)
+#define CVT_FLAVOUR_VAR \
+ CVT_VAR (s32_f32, N_S32, N_F32, whole_reg, "ftosls", "ftosis", "ftosizs") \
+ CVT_VAR (u32_f32, N_U32, N_F32, whole_reg, "ftouls", "ftouis", "ftouizs") \
+ CVT_VAR (f32_s32, N_F32, N_S32, whole_reg, "fsltos", "fsitos", NULL) \
+ CVT_VAR (f32_u32, N_F32, N_U32, whole_reg, "fultos", "fuitos", NULL) \
+ /* Half-precision conversions. */ \
+ CVT_VAR (f32_f16, N_F32, N_F16, whole_reg, NULL, NULL, NULL) \
+ CVT_VAR (f16_f32, N_F16, N_F32, whole_reg, NULL, NULL, NULL) \
+ /* VFP instructions. */ \
+ CVT_VAR (f32_f64, N_F32, N_F64, N_VFP, NULL, "fcvtsd", NULL) \
+ CVT_VAR (f64_f32, N_F64, N_F32, N_VFP, NULL, "fcvtds", NULL) \
+ CVT_VAR (s32_f64, N_S32, N_F64 | key, N_VFP, "ftosld", "ftosid", "ftosizd") \
+ CVT_VAR (u32_f64, N_U32, N_F64 | key, N_VFP, "ftould", "ftouid", "ftouizd") \
+ CVT_VAR (f64_s32, N_F64 | key, N_S32, N_VFP, "fsltod", "fsitod", NULL) \
+ CVT_VAR (f64_u32, N_F64 | key, N_U32, N_VFP, "fultod", "fuitod", NULL) \
+ /* VFP instructions with bitshift. */ \
+ CVT_VAR (f32_s16, N_F32 | key, N_S16, N_VFP, "fshtos", NULL, NULL) \
+ CVT_VAR (f32_u16, N_F32 | key, N_U16, N_VFP, "fuhtos", NULL, NULL) \
+ CVT_VAR (f64_s16, N_F64 | key, N_S16, N_VFP, "fshtod", NULL, NULL) \
+ CVT_VAR (f64_u16, N_F64 | key, N_U16, N_VFP, "fuhtod", NULL, NULL) \
+ CVT_VAR (s16_f32, N_S16, N_F32 | key, N_VFP, "ftoshs", NULL, NULL) \
+ CVT_VAR (u16_f32, N_U16, N_F32 | key, N_VFP, "ftouhs", NULL, NULL) \
+ CVT_VAR (s16_f64, N_S16, N_F64 | key, N_VFP, "ftoshd", NULL, NULL) \
+ CVT_VAR (u16_f64, N_U16, N_F64 | key, N_VFP, "ftouhd", NULL, NULL)
+
+#define CVT_VAR(C, X, Y, R, BSN, CN, ZN) \
+ neon_cvt_flavour_##C,
+
+/* The different types of conversions we can do. */
+enum neon_cvt_flavour
+{
+ CVT_FLAVOUR_VAR
+ neon_cvt_flavour_invalid,
+ neon_cvt_flavour_first_fp = neon_cvt_flavour_f32_f64
+};
+
+#undef CVT_VAR
+
+static enum neon_cvt_flavour
+get_neon_cvt_flavour (enum neon_shape rs)
{
-#define CVT_VAR(C,X,Y) \
- et = neon_check_type (2, rs, whole_reg | (X), whole_reg | (Y)); \
- if (et.type != NT_invtype) \
- { \
- inst.error = NULL; \
- return (C); \
+#define CVT_VAR(C,X,Y,R,BSN,CN,ZN) \
+ et = neon_check_type (2, rs, (R) | (X), (R) | (Y)); \
+ if (et.type != NT_invtype) \
+ { \
+ inst.error = NULL; \
+ return (neon_cvt_flavour_##C); \
}
+
struct neon_type_el et;
unsigned whole_reg = (rs == NS_FFI || rs == NS_FD || rs == NS_DF
|| rs == NS_FF) ? N_VFP : 0;
@@ -14529,41 +14568,16 @@ neon_cvt_flavour (enum neon_shape rs)
here by making the size equal to the key (wider, in this case) operand. */
unsigned key = (rs == NS_QQI || rs == NS_DDI || rs == NS_FFI) ? N_KEY : 0;
- CVT_VAR (0, N_S32, N_F32);
- CVT_VAR (1, N_U32, N_F32);
- CVT_VAR (2, N_F32, N_S32);
- CVT_VAR (3, N_F32, N_U32);
- /* Half-precision conversions. */
- CVT_VAR (4, N_F32, N_F16);
- CVT_VAR (5, N_F16, N_F32);
-
- whole_reg = N_VFP;
-
- /* VFP instructions. */
- CVT_VAR (6, N_F32, N_F64);
- CVT_VAR (7, N_F64, N_F32);
- CVT_VAR (8, N_S32, N_F64 | key);
- CVT_VAR (9, N_U32, N_F64 | key);
- CVT_VAR (10, N_F64 | key, N_S32);
- CVT_VAR (11, N_F64 | key, N_U32);
- /* VFP instructions with bitshift. */
- CVT_VAR (12, N_F32 | key, N_S16);
- CVT_VAR (13, N_F32 | key, N_U16);
- CVT_VAR (14, N_F64 | key, N_S16);
- CVT_VAR (15, N_F64 | key, N_U16);
- CVT_VAR (16, N_S16, N_F32 | key);
- CVT_VAR (17, N_U16, N_F32 | key);
- CVT_VAR (18, N_S16, N_F64 | key);
- CVT_VAR (19, N_U16, N_F64 | key);
+ CVT_FLAVOUR_VAR;
- return -1;
+ return neon_cvt_flavour_invalid;
#undef CVT_VAR
}
/* Neon-syntax VFP conversions. */
static void
-do_vfp_nsyn_cvt (enum neon_shape rs, int flavour)
+do_vfp_nsyn_cvt (enum neon_shape rs, enum neon_cvt_flavour flavour)
{
const char *opname = 0;
@@ -14572,29 +14586,13 @@ do_vfp_nsyn_cvt (enum neon_shape rs, int flavour)
/* Conversions with immediate bitshift. */
const char *enc[] =
{
- "ftosls",
- "ftouls",
- "fsltos",
- "fultos",
- NULL,
- NULL,
- NULL,
- NULL,
- "ftosld",
- "ftould",
- "fsltod",
- "fultod",
- "fshtos",
- "fuhtos",
- "fshtod",
- "fuhtod",
- "ftoshs",
- "ftouhs",
- "ftoshd",
- "ftouhd"
+#define CVT_VAR(C,A,B,R,BSN,CN,ZN) BSN,
+ CVT_FLAVOUR_VAR
+ NULL
+#undef CVT_VAR
};
- if (flavour >= 0 && flavour < (int) ARRAY_SIZE (enc))
+ if (flavour < (int) ARRAY_SIZE (enc))
{
opname = enc[flavour];
constraint (inst.operands[0].reg != inst.operands[1].reg,
@@ -14608,21 +14606,13 @@ do_vfp_nsyn_cvt (enum neon_shape rs, int flavour)
/* Conversions without bitshift. */
const char *enc[] =
{
- "ftosis",
- "ftouis",
- "fsitos",
- "fuitos",
- "NULL",
- "NULL",
- "fcvtsd",
- "fcvtds",
- "ftosid",
- "ftouid",
- "fsitod",
- "fuitod"
+#define CVT_VAR(C,A,B,R,BSN,CN,ZN) CN,
+ CVT_FLAVOUR_VAR
+ NULL
+#undef CVT_VAR
};
- if (flavour >= 0 && flavour < (int) ARRAY_SIZE (enc))
+ if (flavour < (int) ARRAY_SIZE (enc))
opname = enc[flavour];
}
@@ -14634,22 +14624,16 @@ static void
do_vfp_nsyn_cvtz (void)
{
enum neon_shape rs = neon_select_shape (NS_FF, NS_FD, NS_NULL);
- int flavour = neon_cvt_flavour (rs);
+ enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
const char *enc[] =
{
- "ftosizs",
- "ftouizs",
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- "ftosizd",
- "ftouizd"
+#define CVT_VAR(C,A,B,R,BSN,CN,ZN) ZN,
+ CVT_FLAVOUR_VAR
+ NULL
+#undef CVT_VAR
};
- if (flavour >= 0 && flavour < (int) ARRAY_SIZE (enc) && enc[flavour])
+ if (flavour < (int) ARRAY_SIZE (enc) && enc[flavour])
do_vfp_nsyn_opcode (enc[flavour]);
}
@@ -14658,12 +14642,15 @@ do_neon_cvt_1 (bfd_boolean round_to_zero ATTRIBUTE_UNUSED)
{
enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_FFI, NS_DD, NS_QQ,
NS_FD, NS_DF, NS_FF, NS_QD, NS_DQ, NS_NULL);
- int flavour = neon_cvt_flavour (rs);
+ enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
/* PR11109: Handle round-to-zero for VCVT conversions. */
if (round_to_zero
&& ARM_CPU_HAS_FEATURE (cpu_variant, fpu_arch_vfp_v2)
- && (flavour == 0 || flavour == 1 || flavour == 8 || flavour == 9)
+ && (flavour == neon_cvt_flavour_s32_f32
+ || flavour == neon_cvt_flavour_u32_f32
+ || flavour == neon_cvt_flavour_s32_f64
+ || flavour == neon_cvt_flavour_u32_f64)
&& (rs == NS_FD || rs == NS_FF))
{
do_vfp_nsyn_cvtz ();
@@ -14671,7 +14658,7 @@ do_neon_cvt_1 (bfd_boolean round_to_zero ATTRIBUTE_UNUSED)
}
/* VFP rather than Neon conversions. */
- if (flavour >= 6)
+ if (flavour >= neon_cvt_flavour_first_fp)
{
do_vfp_nsyn_cvt (rs, flavour);
return;
@@ -14694,7 +14681,7 @@ do_neon_cvt_1 (bfd_boolean round_to_zero ATTRIBUTE_UNUSED)
goto int_encode;
immbits = 32 - inst.operands[2].imm;
NEON_ENCODE (IMMED, inst);
- if (flavour != -1)
+ if (flavour != neon_cvt_flavour_invalid)
inst.instruction |= enctab[flavour];
inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
inst.instruction |= HI1 (inst.operands[0].reg) << 22;
@@ -14719,8 +14706,8 @@ do_neon_cvt_1 (bfd_boolean round_to_zero ATTRIBUTE_UNUSED)
if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
return;
- if (flavour != -1)
- inst.instruction |= enctab[flavour];
+ if (flavour != neon_cvt_flavour_invalid)
+ inst.instruction |= enctab[flavour];
inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
inst.instruction |= HI1 (inst.operands[0].reg) << 22;