[ARM] vfp: fix fuitod/fsitod instructions

These two instructions exceptionally take a single precision register
as their operand.  This means we can't use vfp_get_dm() to read the
register number - we need to use vfp_get_sm() instead.  Add a flag to
indicate this exception to the general rule.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
diff --git a/arch/arm/vfp/vfp.h b/arch/arm/vfp/vfp.h
index 54a2ad6..791d023 100644
--- a/arch/arm/vfp/vfp.h
+++ b/arch/arm/vfp/vfp.h
@@ -361,10 +361,12 @@
  *  OP_SCALAR - this operation always operates in scalar mode
  *  OP_SD - the instruction exceptionally writes to a single precision result.
  *  OP_DD - the instruction exceptionally writes to a double precision result.
+ *  OP_SM - the instruction exceptionally reads from a single precision operand.
  */
 #define OP_SCALAR	(1 << 0)
 #define OP_SD		(1 << 1)
 #define OP_DD		(1 << 1)
+#define OP_SM		(1 << 2)
 
 struct op {
 	u32 (* const fn)(int dd, int dn, int dm, u32 fpscr);
diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c
index 190a09a..6cac43b 100644
--- a/arch/arm/vfp/vfpdouble.c
+++ b/arch/arm/vfp/vfpdouble.c
@@ -668,8 +668,8 @@
 	[FEXT_TO_IDX(FEXT_FCMPZ)]	= { vfp_double_fcmpz,  OP_SCALAR },
 	[FEXT_TO_IDX(FEXT_FCMPEZ)]	= { vfp_double_fcmpez, OP_SCALAR },
 	[FEXT_TO_IDX(FEXT_FCVT)]	= { vfp_double_fcvts,  OP_SCALAR|OP_SD },
-	[FEXT_TO_IDX(FEXT_FUITO)]	= { vfp_double_fuito,  OP_SCALAR },
-	[FEXT_TO_IDX(FEXT_FSITO)]	= { vfp_double_fsito,  OP_SCALAR },
+	[FEXT_TO_IDX(FEXT_FUITO)]	= { vfp_double_fuito,  OP_SCALAR|OP_SM },
+	[FEXT_TO_IDX(FEXT_FSITO)]	= { vfp_double_fsito,  OP_SCALAR|OP_SM },
 	[FEXT_TO_IDX(FEXT_FTOUI)]	= { vfp_double_ftoui,  OP_SCALAR|OP_SD },
 	[FEXT_TO_IDX(FEXT_FTOUIZ)]	= { vfp_double_ftouiz, OP_SCALAR|OP_SD },
 	[FEXT_TO_IDX(FEXT_FTOSI)]	= { vfp_double_ftosi,  OP_SCALAR|OP_SD },
@@ -1128,7 +1128,7 @@
 	u32 exceptions = 0;
 	unsigned int dest;
 	unsigned int dn = vfp_get_dn(inst);
-	unsigned int dm = vfp_get_dm(inst);
+	unsigned int dm;
 	unsigned int vecitr, veclen, vecstride;
 	struct op *fop;
 
@@ -1146,6 +1146,14 @@
 		dest = vfp_get_dd(inst);
 
 	/*
+	 * f[us]ito takes a sN operand, not a dN operand.
+	 */
+	if (fop->flags & OP_SM)
+		dm = vfp_get_sm(inst);
+	else
+		dm = vfp_get_dm(inst);
+
+	/*
 	 * If destination bank is zero, vector length is always '1'.
 	 * ARM DDI0100F C5.1.3, C5.3.2.
 	 */