|
From: <sv...@va...> - 2005-12-02 15:55:34
|
Author: cerion
Date: 2005-12-02 15:55:27 +0000 (Fri, 02 Dec 2005)
New Revision: 5267
Log:
Added tests for ppc32 floating point load/stores
- not yet set to run in automated test.
Modified:
trunk/none/tests/ppc32/jm-insns.c
Modified: trunk/none/tests/ppc32/jm-insns.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/none/tests/ppc32/jm-insns.c 2005-12-02 14:28:28 UTC (rev 5266)
+++ trunk/none/tests/ppc32/jm-insns.c 2005-12-02 15:55:27 UTC (rev 5267)
@@ -221,7 +221,29 @@
#define FDPRINTF(fmt, args...) do { } while (0)
#endif
=20
+/* Produce the 64-bit pattern corresponding to the supplied double. */
+static uint64_t double_to_bits ( double d )
+{
+ union { uint64_t i; double d; } u;
+ assert(8 =3D=3D sizeof(uint64_t));
+ assert(8 =3D=3D sizeof(double));
+ assert(8 =3D=3D sizeof(u));
+ u.d =3D d;
+ return u.i;
+}
=20
+#if 0
+static float bits_to_float ( uint32_t i )
+{
+ union { uint32_t i; float f; } u;
+ assert(4 =3D=3D sizeof(uint32_t));
+ assert(4 =3D=3D sizeof(float));
+ assert(4 =3D=3D sizeof(u));
+ u.i =3D i;
+ return u.f;
+}
+#endif
+
#define unused __attribute__ (( unused ))
=20
/* -------------- BEGIN #include "ops-ppc.c" -------------- */
@@ -1745,6 +1767,154 @@
};
#endif /* !defined (NO_FLOAT) */
=20
+
+#if !defined (NO_FLOAT)
+extern void test_lfs (void);
+asm(".text\n"
+ "test_lfs:\n"
+ "\tlfs 17,0(14)\n"
+ "\tblr\n"
+ ".previous\n"
+);
+
+extern void test_lfsu (void);
+asm(".text\n"
+ "test_lfsu:\n"
+ "\tlfsu 17,0(14)\n"
+ "\tblr\n"
+ ".previous\n"
+);
+
+extern void test_lfd (void);
+asm(".text\n"
+ "test_lfd:\n"
+ "\tlfd 17,0(14)\n"
+ "\tblr\n"
+ ".previous\n"
+);
+
+extern void test_lfdu (void);
+asm(".text\n"
+ "test_lfdu:\n"
+ "\tlfdu 17,0(14)\n"
+ "\tblr\n"
+ ".previous\n"
+);
+
+static test_t tests_fld_ops_two_i16[] =3D {
+ { &test_lfs , " lfs", },
+ { &test_lfsu , " lfsu", },
+ { &test_lfd , " lfd", },
+ { &test_lfdu , " lfdu", },
+ { NULL, NULL, },
+};
+#endif /* !defined (NO_FLOAT) */
+
+#if !defined (NO_FLOAT)
+static void test_lfsx (void)
+{
+ __asm__ __volatile__ ("lfsx 17,14,15");
+}
+
+static void test_lfsux (void)
+{
+ __asm__ __volatile__ ("lfsux 17,14,15");
+}
+
+static void test_lfdx (void)
+{
+ __asm__ __volatile__ ("lfdx 17,14,15");
+}
+
+static void test_lfdux (void)
+{
+ __asm__ __volatile__ ("lfdux 17,14,15");
+}
+
+static test_t tests_fld_ops_two[] =3D {
+ { &test_lfsx , " lfsx", },
+ { &test_lfsux , " lfsux", },
+ { &test_lfdx , " lfdx", },
+ { &test_lfdux , " lfdux", },
+ { NULL, NULL, },
+};
+#endif /* !defined (NO_FLOAT) */
+
+#if !defined (NO_FLOAT)
+extern void test_stfs (void);
+asm(".text\n"
+ "test_stfs:\n"
+ "\tstfs 14,0(15)\n"
+ "\tblr\n"
+ ".previous\n"
+);
+
+extern void test_stfsu (void);
+asm(".text\n"
+ "test_stfsu:\n"
+ "\tstfsu 14,0(15)\n"
+ "\tblr\n"
+ ".previous\n"
+);
+
+extern void test_stfd (void);
+asm(".text\n"
+ "test_stfd:\n"
+ "\tstfd 14,0(15)\n"
+ "\tblr\n"
+ ".previous\n"
+);
+
+extern void test_stfdu (void);
+asm(".text\n"
+ "test_stfdu:\n"
+ "\tstfdu 14,0(15)\n"
+ "\tblr\n"
+ ".previous\n"
+);
+
+static test_t tests_fst_ops_three_i16[] =3D {
+// TODO: Fix VEX to stop rounding these twice...
+// { &test_stfs , " stfs", },
+// { &test_stfsu , " stfsu", },
+ { &test_stfd , " stfd", },
+ { &test_stfdu , " stfdu", },
+ { NULL, NULL, },
+};
+#endif /* !defined (NO_FLOAT) */
+
+#if !defined (NO_FLOAT)
+static void test_stfsx (void)
+{
+ __asm__ __volatile__ ("stfsx 14,15,16");
+}
+
+static void test_stfsux (void)
+{
+ __asm__ __volatile__ ("stfsux 14,15,16");
+}
+
+static void test_stfdx (void)
+{
+ __asm__ __volatile__ ("stfdx 14,15,16");
+}
+
+static void test_stfdux (void)
+{
+ __asm__ __volatile__ ("stfdux 14,15,16");
+}
+
+static test_t tests_fst_ops_three[] =3D {
+// TODO: Fix VEX to stop rounding these twice...
+// { &test_stfsx , " stfsx", },
+// { &test_stfsux , " stfsux", },
+ { &test_stfdx , " stfdx", },
+ { &test_stfdux , " stfdux", },
+ { NULL, NULL, },
+};
+#endif /* !defined (NO_FLOAT) */
+
+
#if defined (HAS_ALTIVEC)
static void test_vmhaddshs (void)
{
@@ -3509,7 +3679,7 @@
#endif /* !defined (NO_FLOAT) */
#if !defined (NO_FLOAT)
{
- tests_far_ops_three ,
+ tests_far_ops_three ,
"PPC floating point arith insns\n with three args with flags =
update",
0x01020103,
},
@@ -3563,6 +3733,34 @@
0x01020207,
},
#endif /* !defined (NO_FLOAT) */
+#if !defined (NO_FLOAT)
+ {
+ tests_fld_ops_two_i16 ,
+ "PPC float load insns\n with one register + one 16 bits immed=
iate args with flags update",
+ 0x00020508,
+ },
+#endif /* !defined (NO_FLOAT) */
+#if !defined (NO_FLOAT)
+ {
+ tests_fld_ops_two ,
+ "PPC float load insns with two register args",
+ 0x00020509,
+ },
+#endif /* !defined (NO_FLOAT) */
+#if !defined (NO_FLOAT)
+ {
+ tests_fst_ops_three_i16,
+ "PPC float store insns\n with one register + one 16 bits imme=
diate args with flags update",
+ 0x0002050a,
+ },
+#endif /* !defined (NO_FLOAT) */
+#if !defined (NO_FLOAT)
+ {
+ tests_fst_ops_three ,
+ "PPC float store insns with three register args",
+ 0x0002050b,
+ },
+#endif /* !defined (NO_FLOAT) */
#if defined (HAS_ALTIVEC)
{
tests_aa_ops_three ,
@@ -3725,19 +3923,34 @@
=20
static void build_fargs_table (void)
{
- /* Sign goes from zero to one
- * Exponent goes from 0 to ((1 << 12) - 1)
- * Mantissa goes from 1 to ((1 << 52) - 1)
+ /* Double precision:
+ * Sign goes from zero to one (1 bit)
+ * Exponent goes from 0 to ((1 << 12) - 1) (11 bits)
+ * Mantissa goes from 1 to ((1 << 52) - 1) (52 bits)
* + special values:
- * +0.0 : 0 0x000 0x0000000000000
- * -0.0 : 1 0x000 0x0000000000000
- * +infinity : 0 0x7FF 0x0000000000000
- * -infinity : 1 0x7FF 0x0000000000000
- * +SNaN : 0 0x7FF 0x7FFFFFFFFFFFF
- * -SNaN : 1 0x7FF 0x7FFFFFFFFFFFF
- * +QNaN : 0 0x7FF 0x8000000000000
- * -QNaN : 1 0x7FF 0x8000000000000
+ * +0.0 : 0 0x000 0x0000000000000 =3D> 0x0000000000000000
+ * -0.0 : 1 0x000 0x0000000000000 =3D> 0x8000000000000000
+ * +infinity : 0 0x7FF 0x0000000000000 =3D> 0x7FF0000000000000
+ * -infinity : 1 0x7FF 0x0000000000000 =3D> 0xFFF0000000000000
+ * +QNaN : 0 0x7FF 0x7FFFFFFFFFFFF =3D> 0x7FF7FFFFFFFFFFFF
+ * -QNaN : 1 0x7FF 0x7FFFFFFFFFFFF =3D> 0xFFF7FFFFFFFFFFFF
+ * +SNaN : 0 0x7FF 0x8000000000000 =3D> 0x7FF8000000000000
+ * -SNaN : 1 0x7FF 0x8000000000000 =3D> 0xFFF8000000000000
* (8 values)
+
+ * Ref only:
+ * Single precision
+ * Sign: 1 bit
+ * Exponent: 8 bits
+ * Mantissa: 23 bits
+ * +0.0 : 0 0x00 0x000000 =3D> 0x00000000
+ * -0.0 : 1 0x00 0x000000 =3D> 0x80000000
+ * +infinity : 0 0xFF 0x000000 =3D> 0x7F800000
+ * -infinity : 1 0xFF 0x000000 =3D> 0xFF800000
+ * +QNaN : 0 0xFF 0x3FFFFF =3D> 0x7FBFFFFF
+ * -QNaN : 1 0xFF 0x3FFFFF =3D> 0xFFBFFFFF
+ * +SNaN : 0 0xFF 0x400000 =3D> 0x7FC00000
+ * -SNaN : 1 0xFF 0x400000 =3D> 0xFFC00000
*/
uint64_t mant;
uint16_t exp, e0, e1;
@@ -3805,27 +4018,28 @@
exp =3D 0x7FF;
mant =3D 0x0000000000000ULL;
register_farg(&fargs[i++], s, exp, mant);
- /* +SNaN : 0 0x7FF 0x7FFFFFFFFFFFF */
+ /* +QNaN : 0 0x7FF 0x7FFFFFFFFFFFF */
s =3D 0;
exp =3D 0x7FF;
mant =3D 0x7FFFFFFFFFFFFULL;
register_farg(&fargs[i++], s, exp, mant);
- /* -SNaN : 1 0x7FF 0x7FFFFFFFFFFFF */
+ /* -QNaN : 1 0x7FF 0x7FFFFFFFFFFFF */
s =3D 1;
exp =3D 0x7FF;
mant =3D 0x7FFFFFFFFFFFFULL;
register_farg(&fargs[i++], s, exp, mant);
- /* +QNaN : 0 0x7FF 0x8000000000000 */
+ /* +SNaN : 0 0x7FF 0x8000000000000 */
s =3D 0;
exp =3D 0x7FF;
mant =3D 0x8000000000000ULL;
register_farg(&fargs[i++], s, exp, mant);
- /* -QNaN : 1 0x7FF 0x8000000000000 */
+ /* -SNaN : 1 0x7FF 0x8000000000000 */
s =3D 1;
exp =3D 0x7FF;
mant =3D 0x8000000000000ULL;
register_farg(&fargs[i++], s, exp, mant);
AB_DPRINTF("Registered %d fargs values\n", i);
+
nb_fargs =3D i;
}
=20
@@ -3920,11 +4134,9 @@
vector uint32_t* vfargI =3D (vector uint32_t*)vfarg;
=20
tmp =3D ((uint64_t)s << 31) | ((uint64_t)exp << 23) | mant;
- //float f =3D *(float*)&tmp;
- //*vfarg =3D (vector float){ f,f,f,f };
*vfargI =3D (vector uint32_t){ tmp,tmp,tmp,tmp };
AB_DPRINTF("%d %02x %06x =3D> %08x %0e\n",
- s, exp, mant, *((uint32_t*)&tmp), f);
+ s, exp, mant, *((uint32_t*)&tmp), *(float*)&tmp);
}
=20
static void build_vfargs_table (void)
@@ -5128,12 +5340,12 @@
=20
// +ve d
for (i=3D0; i<nb_iargs; i++) {
- j =3D i * 4; // sizeof(uint32_t)
+ j =3D i * 4; // offset =3D i * sizeof(uint32_=
t)
p =3D (void *)func;
func_buf[1] =3D p[1];
patch_op_imm16(func_buf, p, j);
func =3D (void *)func_buf;
- r14 =3D (uint32_t)&iargs[0];
+ r14 =3D (uint32_t)&iargs[0]; // base reg =3D start of array
=20
/* Save flags */
__asm__ __volatile__ ("mfcr 18");
@@ -5411,7 +5623,7 @@
uint64_t u0, u1, u2, ur;
volatile uint32_t flags, tmpcr, tmpxer;
int i, j, k;
- =20
+
for (i=3D0; i<nb_fargs; i+=3D3) {
for (j=3D0; j<nb_fargs; j+=3D5) {
for (k=3D0; k<nb_fargs; k+=3D7) {
@@ -5421,6 +5633,7 @@
f14 =3D fargs[i];
f15 =3D fargs[j];
f16 =3D fargs[k];
+
/* Save flags */
__asm__ __volatile__ ("mfcr 18");
tmpcr =3D r18;
@@ -5588,6 +5801,251 @@
test_special(special_float_ops, name, func, test_flags);
}
=20
+
+static void test_float_ld_one_reg_imm16 (const char* name,
+ test_func_t func,
+ unused uint32_t test_flags)
+{
+ uint32_t base, func_buf[2], *p;
+ volatile uint32_t flags, xer, tmpcr, tmpxer;
+ volatile double src, res;
+ int i, offs;
+
+ /* offset within [1-nb_fargs:nb_fargs] */
+ for (i=3D1-nb_fargs; i<nb_fargs; i++) {
+ offs =3D i * 8; // offset =3D i * sizeof(double)
+ if (i < 0) {
+ src =3D fargs[nb_fargs-1 + i];
+ base =3D (uint32_t)&fargs[nb_fargs-1];
+ } else {
+ src =3D fargs[i];
+ base =3D (uint32_t)&fargs[0];
+ }
+
+ p =3D (void *)func;
+ func_buf[1] =3D p[1];
+ patch_op_imm16(func_buf, p, offs);
+ func =3D (void *)func_buf;
+
+ // load from fargs[idx] =3D> r14 + offs
+ r14 =3D base;
+
+ /* Save flags */
+ __asm__ __volatile__ ("mfcr 18");
+ tmpcr =3D r18;
+ __asm__ __volatile__ ("mfxer 18");
+ tmpxer =3D r18;
+ =20
+ /* Set up flags for test */
+ r18 =3D 0;
+ __asm__ __volatile__ ("mtcr 18");
+ __asm__ __volatile__ ("mtxer 18");
+ (*func)();
+ __asm__ __volatile__ ("mfcr 18");
+ flags =3D r18;
+ __asm__ __volatile__ ("mfxer 18");
+ xer =3D r18;
+ res =3D f17;
+
+ /* Restore flags */
+ r18 =3D tmpcr;
+ __asm__ __volatile__ ("mtcr 18");
+ r18 =3D tmpxer;
+ __asm__ __volatile__ ("mtxer 18");
+
+ printf("%s %016llx, %4d =3D> %016llx, %08x (%08x %08x)\n",
+ name, double_to_bits(src), offs,
+ double_to_bits(res), r14, flags, xer);
+ }
+ if (verbose) printf("\n");
+}
+
+static void test_float_ld_two_regs (const char* name,
+ test_func_t func,
+ unused uint32_t test_flags)
+{
+ volatile uint32_t base, flags, xer, tmpcr, tmpxer;
+ volatile double src, res;
+ int i;
+ =20
+ /* offset within [1-nb_fargs:nb_fargs] */
+ for (i=3D1-nb_fargs; i<nb_fargs; i++) {
+ r15 =3D i * 8; // offset =3D i * sizeof(double)
+ if (i < 0) { // base reg =3D start of array
+ src =3D fargs[nb_fargs-1 + i];
+ base =3D (uint32_t)&fargs[nb_fargs-1];
+ } else {
+ src =3D fargs[i];
+ base =3D (uint32_t)&fargs[0];
+ }
+
+ r14 =3D base;
+
+ /* Save flags */
+ __asm__ __volatile__ ("mfcr 18");
+ tmpcr =3D r18;
+ __asm__ __volatile__ ("mfxer 18");
+ tmpxer =3D r18;
+ =20
+ /* Set up flags for test */
+ r18 =3D 0;
+ __asm__ __volatile__ ("mtcr 18");
+ __asm__ __volatile__ ("mtxer 18");
+ (*func)();
+ __asm__ __volatile__ ("mfcr 18");
+ flags =3D r18;
+ __asm__ __volatile__ ("mfxer 18");
+ xer =3D r18;
+ res =3D f17;
+
+ /* Restore flags */
+ r18 =3D tmpcr;
+ __asm__ __volatile__ ("mtcr 18");
+ r18 =3D tmpxer;
+ __asm__ __volatile__ ("mtxer 18");
+
+ printf("%s %016llx, %4d =3D> %016llx, %08x (%08x %08x)\n",
+ name, double_to_bits(src), r15,
+ double_to_bits(res), r14, flags, xer);
+ }
+}
+
+static void test_float_st_two_regs_imm16 (const char* name,
+ test_func_t func,
+ unused uint32_t test_flags)
+{
+ uint32_t base, func_buf[2], *p;
+ volatile uint32_t flags, xer, tmpcr, tmpxer;
+ double src, *p_dst;
+ int i, offs;
+ double *fargs_priv;
+ =20
+ // private fargs table to store to
+ fargs_priv =3D malloc(nb_fargs * sizeof(double));
+ =20
+ /* offset within [1-nb_fargs:nb_fargs] */
+ for (i=3D1-nb_fargs; i<nb_fargs; i++) {
+ offs =3D i * 8; // offset =3D i * sizeof(double)
+ if (i < 0) {
+ src =3D fargs [nb_fargs-1 + i];
+ p_dst =3D &fargs_priv[nb_fargs-1 + i];
+ base =3D (uint32_t)&fargs_priv[nb_fargs-1];
+ } else {
+ src =3D fargs [i];
+ p_dst =3D &fargs_priv[i];
+ base =3D (uint32_t)&fargs_priv[0];
+ }
+ *p_dst =3D 0; // clear dst
+
+ p =3D (void *)func;
+ func_buf[1] =3D p[1];
+ patch_op_imm16(func_buf, p, offs);
+ func =3D (void *)func_buf;
+
+ // read from fargs[idx] =3D> f14
+ // store to fargs_priv[idx] =3D> r15 + offs
+ f14 =3D src;
+ r15 =3D base;
+
+ /* Save flags */
+ __asm__ __volatile__ ("mfcr 18");
+ tmpcr =3D r18;
+ __asm__ __volatile__ ("mfxer 18");
+ tmpxer =3D r18;
+ =20
+ /* Set up flags for test */
+ r18 =3D 0;
+ __asm__ __volatile__ ("mtcr 18");
+ __asm__ __volatile__ ("mtxer 18");
+ (*func)();
+ __asm__ __volatile__ ("mfcr 18");
+ flags =3D r18;
+ __asm__ __volatile__ ("mfxer 18");
+ xer =3D r18;
+
+ /* Restore flags */
+ r18 =3D tmpcr;
+ __asm__ __volatile__ ("mtcr 18");
+ r18 =3D tmpxer;
+ __asm__ __volatile__ ("mtxer 18");
+
+ printf("%s %016llx, %4d =3D> %016llx, %08x (%08x %08x)\n",
+ name, double_to_bits(src), offs,
+ double_to_bits(*p_dst), r15, flags, xer);
+ }
+ free(fargs_priv);
+}
+
+static void test_float_st_three_regs (const char* name,
+ test_func_t func,
+ unused uint32_t test_flags)
+{
+ volatile uint32_t base, flags, xer, tmpcr, tmpxer;
+ double src, *p_dst;
+ int i, offs;
+ double *fargs_priv;
+
+ // private fargs table to store to
+ fargs_priv =3D malloc(nb_fargs * sizeof(double));
+ =20
+ // /* offset within [1-nb_fargs:nb_fargs] */
+ // for (i=3D1-nb_fargs; i<nb_fargs; i++) {
+ for (i=3D0; i<nb_fargs; i++) {
+ offs =3D i * 8; // offset =3D i * sizeof(double)
+ if (i < 0) {
+ src =3D fargs [nb_fargs-1 + i];
+ p_dst =3D &fargs_priv[nb_fargs-1 + i];
+ base =3D (uint32_t)&fargs_priv[nb_fargs-1];
+ } else {
+ src =3D fargs [i];
+ p_dst =3D &fargs_priv[i];
+ base =3D (uint32_t)&fargs_priv[0];
+ }
+ *p_dst =3D 0; // clear dst
+
+ f14 =3D src; // read from fargs
+ r15 =3D base; // store to r15 + offs
+ r16 =3D offs;
+
+ /* Save flags */
+ __asm__ __volatile__ ("mfcr 18");
+ tmpcr =3D r18;
+ __asm__ __volatile__ ("mfxer 18");
+ tmpxer =3D r18;
+ =20
+ /* Set up flags for test */
+ r18 =3D 0;
+ __asm__ __volatile__ ("mtcr 18");
+ __asm__ __volatile__ ("mtxer 18");
+ (*func)();
+ __asm__ __volatile__ ("mfcr 18");
+ flags =3D r18;
+ __asm__ __volatile__ ("mfxer 18");
+ xer =3D r18;
+
+ /* Restore flags */
+ r18 =3D tmpcr;
+ __asm__ __volatile__ ("mtcr 18");
+ r18 =3D tmpxer;
+ __asm__ __volatile__ ("mtxer 18");
+
+#if 1
+ printf("%s %016llx (%014e), %4d =3D> %016llx (%014e), %08x (%08x %=
08x)\n",
+ name, double_to_bits(src), src, offs,
+ double_to_bits(*p_dst), *p_dst, r15, flags, xer);
+#else
+ // print single precision result
+ printf("%s %016llx (%014e), %4d =3D> %08x (%f), %08x (%08x %08x)\n=
",
+ name, double_to_bits(src), src, offs,
+ (uint32_t)(double_to_bits(*p_dst) >> 32),
+ bits_to_float( (uint32_t)(double_to_bits(*p_dst) >> 32) ),
+ r15, flags, xer);
+#endif
+ }
+ free(fargs_priv);
+}
+
+
/* Used in do_tests, indexed by flags->nb_args
Elements correspond to enum test_flags::num args
*/
@@ -5599,10 +6057,10 @@
NULL,
NULL,
&test_float_special,
- NULL,
- NULL,
- NULL,
- NULL,
+ &test_float_ld_one_reg_imm16,
+ &test_float_ld_two_regs,
+ &test_float_st_two_regs_imm16,
+ &test_float_st_three_regs,
};
#endif /* !defined (NO_FLOAT) */
=20
|
|
From: Yao Qi <qiy...@cn...> - 2005-12-03 11:43:43
|
On Fri, Dec 02, 2005 at 03:55:28PM +0000, sv...@va... wrote: > Author: cerion > Date: 2005-12-02 15:55:27 +0000 (Fri, 02 Dec 2005) > New Revision: 5267 > > Log: > Added tests for ppc32 floating point load/stores > - not yet set to run in automated test. I enabled ppc32 floating point load/stores in automated test and compiled jm-insns.c by GCC 3.4.4 and GCC 4.1.0 respectively, it works well! :-) > > > -- Regards, Yao ------------ Yao Qi |