@@ -3295,20 +3295,24 @@
[(set_attr "type" "f_cvtf2i")]
)
-(define_insn "float<GPI:mode><GPF:mode>2"
- [(set (match_operand:GPF 0 "register_operand" "=w")
- (float:GPF (match_operand:GPI 1 "register_operand" "r")))]
- "TARGET_FLOAT"
- "scvtf\\t%<GPF:s>0, %<GPI:w>1"
- [(set_attr "type" "f_cvti2f")]
+(define_insn "<optab><fcvt_target><GPF:mode>2"
+ [(set (match_operand:GPF 0 "register_operand" "=w,w")
+ (FLOATUORS:GPF (match_operand:<FCVT_TARGET> 1 "register_operand" "w,r")))]
+ ""
+ "@
+ <su_optab>cvtf\t%<GPF:s>0, %<s>1
+ <su_optab>cvtf\t%<GPF:s>0, %<w1>1"
+ [(set_attr "simd" "yes,no")
+ (set_attr "fp" "no,yes")
+ (set_attr "type" "neon_int_to_fp_<Vetype>,f_cvti2f")]
)
-(define_insn "floatuns<GPI:mode><GPF:mode>2"
+(define_insn "<optab><fcvt_iesize><GPF:mode>2"
[(set (match_operand:GPF 0 "register_operand" "=w")
- (unsigned_float:GPF (match_operand:GPI 1 "register_operand" "r")))]
+ (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand" "r")))]
"TARGET_FLOAT"
- "ucvtf\\t%<GPF:s>0, %<GPI:w>1"
- [(set_attr "type" "f_cvt")]
+ "<su_optab>cvtf\t%<GPF:s>0, %<w2>1"
+ [(set_attr "type" "f_cvti2f")]
)
;; -------------------------------------------------------------------
@@ -293,6 +293,10 @@
;; 32-bit version and "%x0" in the 64-bit version.
(define_mode_attr w [(QI "w") (HI "w") (SI "w") (DI "x") (SF "s") (DF "d")])
+;; For inequal width int to float conversion
+(define_mode_attr w1 [(SF "w") (DF "x")])
+(define_mode_attr w2 [(SF "x") (DF "w")])
+
;; For constraints used in scalar immediate vector moves
(define_mode_attr hq [(HI "h") (QI "q")])
@@ -558,8 +562,12 @@
(define_mode_attr atomic_sfx
[(QI "b") (HI "h") (SI "") (DI "")])
-(define_mode_attr fcvt_target [(V2DF "v2di") (V4SF "v4si") (V2SF "v2si")])
-(define_mode_attr FCVT_TARGET [(V2DF "V2DI") (V4SF "V4SI") (V2SF "V2SI")])
+(define_mode_attr fcvt_target [(V2DF "v2di") (V4SF "v4si") (V2SF "v2si") (SF "si") (DF "di")])
+(define_mode_attr FCVT_TARGET [(V2DF "V2DI") (V4SF "V4SI") (V2SF "V2SI") (SF "SI") (DF "DI")])
+
+;; for the inequal width integer to fp conversions
+(define_mode_attr fcvt_iesize [(SF "di") (DF "si")])
+(define_mode_attr FCVT_IESIZE [(SF "DI") (DF "SI")])
(define_mode_attr VSWAP_WIDTH [(V8QI "V16QI") (V16QI "V8QI")
(V4HI "V8HI") (V8HI "V4HI")
new file mode 100644
@@ -0,0 +1,95 @@
+/* { dg-do run } */
+/* { dg-options "-save-temps -fno-inline -O1" } */
+
+#define FCVTDEF(ftype,itype) \
+void \
+cvt_##itype##_to_##ftype (itype a, ftype b)\
+{\
+ ftype c;\
+ c = (ftype) a;\
+ if ( (c - b) > 0.00001) abort();\
+}
+
+#define force_simd_for_float(v) asm volatile ("mov %s0, %1.s[0]" :"=w" (v) :"w" (v) :)
+#define force_simd_for_double(v) asm volatile ("mov %d0, %1.d[0]" :"=w" (v) :"w" (v) :)
+
+#define FCVTDEF_SISD(ftype,itype) \
+void \
+cvt_##itype##_to_##ftype##_sisd (itype a, ftype b)\
+{\
+ ftype c;\
+ force_simd_for_##ftype(a);\
+ c = (ftype) a;\
+ if ( (c - b) > 0.00001) abort();\
+}
+
+#define FCVT(ftype,itype,ival,fval) cvt_##itype##_to_##ftype (ival, fval);
+#define FCVT_SISD(ftype,itype,ival,fval) cvt_##itype##_to_##ftype##_sisd (ival, fval);
+
+typedef int int32_t;
+typedef unsigned int uint32_t;
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+
+extern void abort();
+
+FCVTDEF (float, int32_t)
+/* { dg-final { scan-assembler "scvtf\ts\[0-9\]+,\ w\[0-9\]+" } } */
+FCVTDEF (float, uint32_t)
+/* { dg-final { scan-assembler "ucvtf\ts\[0-9\]+,\ w\[0-9\]+" } } */
+FCVTDEF (double, int32_t)
+/* "scvtf\td\[0-9\]+,\ w\[0-9\]+" */
+FCVTDEF (double, uint32_t)
+/* "ucvtf\td\[0-9\]+,\ w\[0-9\]+" */
+FCVTDEF (float, int64_t)
+/* "scvtf\ts\[0-9\]+,\ x\[0-9\]+" */
+FCVTDEF (float, uint64_t)
+/* "ucvtf\ts\[0-9\]+,\ x\[0-9\]+" */
+FCVTDEF (double, int64_t)
+/* { dg-final { scan-assembler "scvtf\td\[0-9\]+,\ x\[0-9\]+" } } */
+FCVTDEF (double, uint64_t)
+/* { dg-final { scan-assembler "ucvtf\td\[0-9\]+,\ x\[0-9\]+" } } */
+FCVTDEF_SISD (float, int32_t)
+/* { dg-final { scan-assembler "scvtf\ts\[0-9\]+,\ s\[0-9\]+" } } */
+FCVTDEF_SISD (double, int64_t)
+/* { dg-final { scan-assembler "scvtf\td\[0-9\]+,\ d\[0-9\]+" } } */
+FCVTDEF_SISD (float, uint32_t)
+/* { dg-final { scan-assembler "ucvtf\ts\[0-9\]+,\ s\[0-9\]+" } } */
+FCVTDEF_SISD (double, uint64_t)
+/* { dg-final { scan-assembler "ucvtf\td\[0-9\]+,\ d\[0-9\]+" } } */
+FCVTDEF_SISD (float, int64_t)
+/* { dg-final { scan-assembler-times "scvtf\ts\[0-9\]+,\ x\[0-9\]+" 2 } } */
+FCVTDEF_SISD (float, uint64_t)
+/* { dg-final { scan-assembler-times "ucvtf\ts\[0-9\]+,\ x\[0-9\]+" 2 } } */
+FCVTDEF_SISD (double, int32_t)
+/* { dg-final { scan-assembler-times "scvtf\td\[0-9\]+,\ w\[0-9\]+" 2 } } */
+FCVTDEF_SISD (double, uint32_t)
+/* { dg-final { scan-assembler-times "ucvtf\td\[0-9\]+,\ w\[0-9\]+" 2 } } */
+
+int32_t ival = -1234;
+int64_t llival = -13031303L;
+uint32_t uival = 1234;
+uint64_t ullival = 13031303L;
+
+int main ()
+{
+ float x;
+ double y;
+
+ FCVT (float, int32_t, ival, -1234.0);
+ FCVT (float, uint32_t, uival, 1234.0);
+ FCVT (float, int64_t, llival, -13031303.0);
+ FCVT (float, uint64_t, ullival, 13031303.0);
+ FCVT (double, int32_t, ival, -1234.0);
+ FCVT (double, uint32_t, uival, 1234.0);
+ FCVT (double, int64_t, llival, -13031303.0);
+ FCVT (double, uint64_t, ullival, 13031303.0);
+ FCVT_SISD (float, int32_t, ival, -1234.0);
+ FCVT_SISD (double, int64_t, llival, -13031303.0);
+ FCVT_SISD (float, uint32_t, uival, 1234.0);
+ FCVT_SISD (double, uint64_t, ullival, 13031303.0);
+
+ return 0;
+}
+
+/* { dg-final { cleanup-saved-temps } } */