All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/4] Implment fpu floating point instructions
@ 2015-11-08  5:42 Chen Gang
  2015-11-08  5:43 ` [Qemu-devel] [PATCH 1/4] target-tilegx: Add fpu header file Chen Gang
                   ` (3 more replies)
  0 siblings, 4 replies; 13+ messages in thread
From: Chen Gang @ 2015-11-08  5:42 UTC (permalink / raw)
  To: rth, Peter Maydell, Chris Metcalf; +Cc: qemu-devel

>From 8fab455a5ac5508d06cc69f778e926ad098fbe5b Mon Sep 17 00:00:00 2001
From: Chen Gang <gang.chen.5i5j@gmail.com>
Date: Sun, 8 Nov 2015 09:28:16 +0800
Subject: [PATCH 0/4] Implment fpu floating point instructions

It passes gcc testsuite: get the same result like the original floating
point implementation has done (original implementation is temporary).

Chen Gang (4):
  target-tilegx: Add fpu header file
  target-tilegx: Implement fpu single floating point instructions
  target-tilegx: Implement fpu fdouble floating point instructions
  target-tilegx: Let fpu implementation code can be built and used

 target-tilegx/Makefile.objs    |   3 +-
 target-tilegx/cpu.h            |   2 +
 target-tilegx/fdouble_helper.c | 290 +++++++++++++++++++++++++++++++++++++++++
 target-tilegx/fpu.h            | 228 ++++++++++++++++++++++++++++++++
 target-tilegx/fsingle_helper.c | 168 ++++++++++++++++++++++++
 target-tilegx/helper.h         |  12 ++
 target-tilegx/translate.c      |  68 ++++++++--
 7 files changed, 761 insertions(+), 10 deletions(-)
 create mode 100644 target-tilegx/fdouble_helper.c
 create mode 100644 target-tilegx/fpu.h
 create mode 100644 target-tilegx/fsingle_helper.c

-- 
1.9.3

 		 	   		  

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH 1/4] target-tilegx: Add fpu header file
  2015-11-08  5:42 [Qemu-devel] [PATCH 0/4] Implment fpu floating point instructions Chen Gang
@ 2015-11-08  5:43 ` Chen Gang
  2015-11-12 14:34   ` Richard Henderson
  2015-11-08  5:44 ` [Qemu-devel] [PATCH 2/4] target-tilegx: Implement fpu single floating point Chen Gang
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 13+ messages in thread
From: Chen Gang @ 2015-11-08  5:43 UTC (permalink / raw)
  To: rth, Peter Maydell, Chris Metcalf; +Cc: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 10641 bytes --]

>From 91a3d7d591cac6c4a39d4dbc5c3ffe8c17b10b6a Mon Sep 17 00:00:00 2001
From: Chen Gang <gang.chen.5i5j@gmail.com>
Date: Sun, 8 Nov 2015 09:05:29 +0800
Subject: [PATCH 1/4] target-tilegx: Add fpu header file

It defines the main data structures for tilegx fpu. Also it provides the
summary description for each floating point instructions impmementation.

Signed-off-by: Chen Gang <gang.chen.5i5j@gmail.com>
---
 target-tilegx/fpu.h | 228 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 228 insertions(+)
 create mode 100644 target-tilegx/fpu.h

diff --git a/target-tilegx/fpu.h b/target-tilegx/fpu.h
new file mode 100644
index 0000000..adfa1f5
--- /dev/null
+++ b/target-tilegx/fpu.h
@@ -0,0 +1,228 @@
+/*
+ *  TILE-Gx virtual FPU header
+ *
+ *  Copyright (c) 2015 Chen Gang
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef FPU_TILEGX_H
+#define FPU_TILEGX_H
+
+/*
+ * From IEEE standard, exp of float is 8-bits, exp of double is 11-bits.
+ */
+#define TILEGX_F_EXP_FZERO  0x7f  /* Zero exp for single 8-bits */
+#define TILEGX_F_EXP_FMAX   0xfe  /* max exp for single 8-bits */
+#define TILEGX_F_EXP_DZERO  0x3ff /* Zero exp for double 11-bits */
+#define TILEGX_F_EXP_DMAX   0x7fe /* max exp for double 11-bits */
+#define TILEGX_F_EXP_DUF    0x1000/* underflow exp bit for double */
+
+/*
+ * For fdouble absolute cacluation flag
+ */
+#define TILEGX_F_CALC_CVT   0     /* Perform int to fsingle/fdouble */
+#define TILEGX_F_CALC_ADD   1     /* Perform absolute add operation */
+#define TILEGX_F_CALC_SUB   2     /* Perform absolute sub operation */
+#define TILEGX_F_CALC_MUL   3     /* Perform absolute mul operation */
+
+#pragma pack(push, 1)
+
+/*
+ * Single format, it is 64-bit.
+ *
+ * Single exp analyzing: 0x9e - 0x1e(30) = 0x80
+ *
+ *   7   6   5   4   3   2   1   0
+ *
+ *   1   0   0   1   1   1   1   0
+ *
+ *   0   0   0   1   1   1   1   1    => 0x1f(31)
+ *
+ *   0   1   1   1   1   1   1   1    => 0x7f
+ */
+typedef struct TileGXFPSFmt {
+
+#if !defined(HOST_WORDS_BIGENDIAN)
+    /* According to float(uns)sisf2 and float(uns)sidf2 in gcc tilegx.md */
+    uint64_t exp : 8;             /* exp, 0x9e: 31 + TILEGX_F_EXP_FZERO */
+    uint64_t uiknown0 : 2;        /* unknown */
+    uint64_t sign : 1;            /* Sign bit for the total value */
+    uint64_t calc: 2;             /* calculation flag */
+    uint64_t unknown1 : 12;       /* unknown */
+
+    /* Come from TILE-Gx ISA document, Table 7-2 for floating point */
+    uint64_t unordered : 1;       /* The two are unordered */
+    uint64_t lt : 1;              /* 1st is less than 2nd */
+    uint64_t le : 1;              /* 1st is less than or equal to 2nd */
+    uint64_t gt : 1;              /* 1st is greater than 2nd */
+    uint64_t ge : 1;              /* 1st is greater than or equal to 2nd */
+    uint64_t eq : 1;              /* The two operands are equal */
+    uint64_t neq : 1;             /* The two operands are not equal */
+
+    /* According to float(uns)sisf2 and float(uns)sidf2 in gcc tilegx.md */
+    uint64_t mantissa : 32;       /* mantissa */
+#else
+    uint64_t mantissa : 32;       /* mantissa */
+    uint64_t neq : 1;             /* The two operands are not equal */
+    uint64_t eq : 1;              /* The two operands are equal */
+    uint64_t ge : 1;              /* 1st is greater than or equal to 2nd */
+    uint64_t gt : 1;              /* 1st is greater than 2nd */
+    uint64_t le : 1;              /* 1st is less than or equal to 2nd */
+    uint64_t lt : 1;              /* 1st is less than 2nd */
+    uint64_t unordered : 1;       /* The two are unordered */
+    uint64_t unknown1 : 12;       /* unknown */
+    uint64_t calc: 2;             /* calculation flag */
+    uint64_t sign : 1;            /* Sign bit for the total value */
+    uint64_t unknown0 : 2;        /* unknown */
+    uint64_t exp : 8;             /* exp, 0x9e: 31 + TILEGX_F_EXP_FZERO */
+#endif
+} TileGXFPSFmt;
+/*
+ * FSingle instructions implemenation:
+ *
+ * fsingle_add1         ; calc srca and srcb,
+ *                      ; convert float_32 to TileGXFPSFmt result.
+ *                      ; move TileGXFPSFmt result to dest.
+ *
+ * fsingle_sub1         ; calc srca and srcb.
+ *                      ; convert float_32 to TileGXFPSFmt result.
+ *                      ; move TileGXFPSFmt result to dest.
+ *
+ * fsingle_addsub2      ; nop.
+ *
+ * fsingle_mul1         ; calc srca and srcb.
+ *                      ; convert float_32 value to TileGXFPSFmt result.
+ *                      ; move TileGXFPSFmt result to dest.
+ *
+ * fsingle_mul2         ; move srca to dest.
+ *
+ * fsingle_pack1        ; nop
+ *
+ * fsingle_pack2        ; treate srca as TileGXFPSFmt result.
+ *                      ; convert TileGXFPSFmt result to float_32 value.
+ *                      ; move float_32 value to dest.
+ */
+
+/*
+ * Dobule format. flag: 64 bits, value: 64 bits.
+ *
+ * Double exp analyzing: (0x21b00 << 1) - 0x36(54) = 0x400
+ *
+ *   17  16  15  14  13  12  11  10   9   8   7    6   5   4   3   2   1   0
+ *
+ *    1   0   0   0   0   1   1   0   1   1   0    0   0   0   0   0   0   0
+ *
+ *    0   0   0   0   0   1   1   0   1   1   1    => 0x37(55)
+ *
+ *    0   1   1   1   1   1   1   1   1   1   1    => 0x3ff
+ *
+ */
+typedef union TileGXFPDFmtF {
+
+    struct {
+#if !defined(HOST_WORDS_BIGENDIAN)
+        uint64_t unknown0 : 7;    /* unknown */
+        uint64_t vexp : 13;      /* vexp = exp | ov | uv */
+#if 0
+        uint64_t exp : 11;        /* exp, 0x21b << 1: 55 + TILEGX_F_EXP_DZERO */
+        uint64_t ov : 1;          /* overflow for mul, low priority */
+        uint64_t uv : 1;          /* underflow for mul, high priority */
+#endif
+        uint64_t sign : 1;        /* Sign bit for the total value */
+
+        uint64_t calc: 2;         /* absolute add, sub, or mul */
+        uint64_t inf: 1;          /* infinit */
+        uint64_t nan: 1;          /* nan */
+
+        /* Come from TILE-Gx ISA document, Table 7-2 for floating point */
+        uint64_t unordered : 1;   /* The two are unordered */
+        uint64_t lt : 1;          /* 1st is less than 2nd */
+        uint64_t le : 1;          /* 1st is less than or equal to 2nd */
+        uint64_t gt : 1;          /* 1st is greater than 2nd */
+        uint64_t ge : 1;          /* 1st is greater than or equal to 2nd */
+        uint64_t eq : 1;          /* The two operands are equal */
+        uint64_t neq : 1;         /* The two operands are not equal */
+
+        uint64_t unknown1 : 32;   /* unknown */
+#else
+        uint64_t unknown1 : 32;   /* unknown */
+        uint64_t neq : 1;         /* The two operands are not equal */
+        uint64_t eq : 1;          /* The two operands are equal */
+        uint64_t ge : 1;          /* 1st is greater than or equal to 2nd */
+        uint64_t gt : 1;          /* 1st is greater than 2nd */
+        uint64_t le : 1;          /* 1st is less than or equal to 2nd */
+        uint64_t lt : 1;          /* 1st is less than 2nd */
+        uint64_t unordered : 1;   /* The two are unordered */
+        uint64_t nan: 1;          /* nan */
+        uint64_t inf: 1;          /* infinit */
+        uint64_t calc: 2;         /* absolute add, sub, or mul */
+        uint64_t sign : 1;        /* Sign bit for the total value */
+        uint64_t vexp : 13;      /* vexp = exp | ov | uv */
+        uint64_t unknown0 : 7;    /* unknown */
+#endif
+    } fmt;
+    uint64_t ll;                  /* only for easy using */
+} TileGXFPDFmtF;
+
+typedef union TileGXFPDFmtV {
+    struct {
+#if !defined(HOST_WORDS_BIGENDIAN)
+        uint64_t mantissa : 60;   /* mantissa */
+        uint64_t overflow : 1;    /* carry/overflow bit for absolute add/mul */
+        uint64_t unknown1 : 3;    /* unknown */
+#else
+        uint64_t unknown1 : 3;    /* unknown */
+        uint64_t overflow : 1;    /* carry/overflow bit for absolute add/mul */
+        uint64_t mantissa : 60;   /* mantissa */
+#endif
+    } fmt;
+    uint64_t ll;                  /* only for easy using */
+} TileGXFPDFmtV;
+/*
+ * FDouble instructions implemenation:
+ *
+ * fdouble_unpack_min   ; srca and srcb are float_64 value.
+ *                      ; get the min absolute value's mantissa.
+ *                      ; move "mantissa>> (exp_max - exp_min)" to dest.
+ *
+ * fdouble_unpack_max   ; srca and srcb are float_64 value.
+ *                      ; get the max absolute value's mantissa.
+ *                      ; move mantissa to dest.
+ *
+ * fdouble_add_flags    ; srca and srcb are float_64 value.
+ *                      ; calc exp (exp_max), sign, and comp bits for flags.
+ *                      ; set addsub bit to flags and move flags to dest.
+ *
+ * fdouble_sub_flags    ; srca and srcb are float_64 value.
+ *                      ; calc exp (exp_max), sign, and comp bits for flags.
+ *                      ; set addsub bit to flags and move flags to dest.
+ *
+ * fdouble_addsub:      ; dest, srca (max, min mantissa), and srcb (flags).
+ *                      ; "dest +/- srca" depend on the add/sub bit of flags.
+ *                      ; move result mantissa to dest.
+ *
+ * fdouble_mul_flags:   ; srca and srcb are float_64 value.
+ *                      ; calc sign (xor), exp (exp_min + exp_max), and comp bits.
+ *                      ; mix sign, exp, and comp bits as flags to dest.
+ *
+ * fdouble_pack1        ; move srcb (flags) to dest.
+ *
+ * fdouble_pack2        ; srca, srcb (high, low mantissa), and dest (flags)
+ *                      ; normalize and pack result from srca, srcb, and dest.
+ *                      ; move result to dest.
+ */
+
+#pragma pack(pop)
+
+#endif /* FPU_TILEGX_H */
-- 
1.9.3

 		 	   		  

[-- Attachment #2: 0001-target-tilegx-Add-fpu-header-file.patch --]
[-- Type: application/octet-stream, Size: 10378 bytes --]

From 91a3d7d591cac6c4a39d4dbc5c3ffe8c17b10b6a Mon Sep 17 00:00:00 2001
From: Chen Gang <gang.chen.5i5j@gmail.com>
Date: Sun, 8 Nov 2015 09:05:29 +0800
Subject: [PATCH 1/4] target-tilegx: Add fpu header file

It defines the main data structures for tilegx fpu. Also it provides the
summary description for each floating point instructions impmementation.

Signed-off-by: Chen Gang <gang.chen.5i5j@gmail.com>
---
 target-tilegx/fpu.h | 228 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 228 insertions(+)
 create mode 100644 target-tilegx/fpu.h

diff --git a/target-tilegx/fpu.h b/target-tilegx/fpu.h
new file mode 100644
index 0000000..adfa1f5
--- /dev/null
+++ b/target-tilegx/fpu.h
@@ -0,0 +1,228 @@
+/*
+ *  TILE-Gx virtual FPU header
+ *
+ *  Copyright (c) 2015 Chen Gang
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef FPU_TILEGX_H
+#define FPU_TILEGX_H
+
+/*
+ * From IEEE standard, exp of float is 8-bits, exp of double is 11-bits.
+ */
+#define TILEGX_F_EXP_FZERO  0x7f  /* Zero exp for single 8-bits */
+#define TILEGX_F_EXP_FMAX   0xfe  /* max exp for single 8-bits */
+#define TILEGX_F_EXP_DZERO  0x3ff /* Zero exp for double 11-bits */
+#define TILEGX_F_EXP_DMAX   0x7fe /* max exp for double 11-bits */
+#define TILEGX_F_EXP_DUF    0x1000/* underflow exp bit for double */
+
+/*
+ * For fdouble absolute cacluation flag
+ */
+#define TILEGX_F_CALC_CVT   0     /* Perform int to fsingle/fdouble */
+#define TILEGX_F_CALC_ADD   1     /* Perform absolute add operation */
+#define TILEGX_F_CALC_SUB   2     /* Perform absolute sub operation */
+#define TILEGX_F_CALC_MUL   3     /* Perform absolute mul operation */
+
+#pragma pack(push, 1)
+
+/*
+ * Single format, it is 64-bit.
+ *
+ * Single exp analyzing: 0x9e - 0x1e(30) = 0x80
+ *
+ *   7   6   5   4   3   2   1   0
+ *
+ *   1   0   0   1   1   1   1   0
+ *
+ *   0   0   0   1   1   1   1   1    => 0x1f(31)
+ *
+ *   0   1   1   1   1   1   1   1    => 0x7f
+ */
+typedef struct TileGXFPSFmt {
+
+#if !defined(HOST_WORDS_BIGENDIAN)
+    /* According to float(uns)sisf2 and float(uns)sidf2 in gcc tilegx.md */
+    uint64_t exp : 8;             /* exp, 0x9e: 31 + TILEGX_F_EXP_FZERO */
+    uint64_t uiknown0 : 2;        /* unknown */
+    uint64_t sign : 1;            /* Sign bit for the total value */
+    uint64_t calc: 2;             /* calculation flag */
+    uint64_t unknown1 : 12;       /* unknown */
+
+    /* Come from TILE-Gx ISA document, Table 7-2 for floating point */
+    uint64_t unordered : 1;       /* The two are unordered */
+    uint64_t lt : 1;              /* 1st is less than 2nd */
+    uint64_t le : 1;              /* 1st is less than or equal to 2nd */
+    uint64_t gt : 1;              /* 1st is greater than 2nd */
+    uint64_t ge : 1;              /* 1st is greater than or equal to 2nd */
+    uint64_t eq : 1;              /* The two operands are equal */
+    uint64_t neq : 1;             /* The two operands are not equal */
+
+    /* According to float(uns)sisf2 and float(uns)sidf2 in gcc tilegx.md */
+    uint64_t mantissa : 32;       /* mantissa */
+#else
+    uint64_t mantissa : 32;       /* mantissa */
+    uint64_t neq : 1;             /* The two operands are not equal */
+    uint64_t eq : 1;              /* The two operands are equal */
+    uint64_t ge : 1;              /* 1st is greater than or equal to 2nd */
+    uint64_t gt : 1;              /* 1st is greater than 2nd */
+    uint64_t le : 1;              /* 1st is less than or equal to 2nd */
+    uint64_t lt : 1;              /* 1st is less than 2nd */
+    uint64_t unordered : 1;       /* The two are unordered */
+    uint64_t unknown1 : 12;       /* unknown */
+    uint64_t calc: 2;             /* calculation flag */
+    uint64_t sign : 1;            /* Sign bit for the total value */
+    uint64_t unknown0 : 2;        /* unknown */
+    uint64_t exp : 8;             /* exp, 0x9e: 31 + TILEGX_F_EXP_FZERO */
+#endif
+} TileGXFPSFmt;
+/*
+ * FSingle instructions implemenation:
+ *
+ * fsingle_add1         ; calc srca and srcb,
+ *                      ; convert float_32 to TileGXFPSFmt result.
+ *                      ; move TileGXFPSFmt result to dest.
+ *
+ * fsingle_sub1         ; calc srca and srcb.
+ *                      ; convert float_32 to TileGXFPSFmt result.
+ *                      ; move TileGXFPSFmt result to dest.
+ *
+ * fsingle_addsub2      ; nop.
+ *
+ * fsingle_mul1         ; calc srca and srcb.
+ *                      ; convert float_32 value to TileGXFPSFmt result.
+ *                      ; move TileGXFPSFmt result to dest.
+ *
+ * fsingle_mul2         ; move srca to dest.
+ *
+ * fsingle_pack1        ; nop
+ *
+ * fsingle_pack2        ; treate srca as TileGXFPSFmt result.
+ *                      ; convert TileGXFPSFmt result to float_32 value.
+ *                      ; move float_32 value to dest.
+ */
+
+/*
+ * Dobule format. flag: 64 bits, value: 64 bits.
+ *
+ * Double exp analyzing: (0x21b00 << 1) - 0x36(54) = 0x400
+ *
+ *   17  16  15  14  13  12  11  10   9   8   7    6   5   4   3   2   1   0
+ *
+ *    1   0   0   0   0   1   1   0   1   1   0    0   0   0   0   0   0   0
+ *
+ *    0   0   0   0   0   1   1   0   1   1   1    => 0x37(55)
+ *
+ *    0   1   1   1   1   1   1   1   1   1   1    => 0x3ff
+ *
+ */
+typedef union TileGXFPDFmtF {
+
+    struct {
+#if !defined(HOST_WORDS_BIGENDIAN)
+        uint64_t unknown0 : 7;    /* unknown */
+        uint64_t vexp : 13;      /* vexp = exp | ov | uv */
+#if 0
+        uint64_t exp : 11;        /* exp, 0x21b << 1: 55 + TILEGX_F_EXP_DZERO */
+        uint64_t ov : 1;          /* overflow for mul, low priority */
+        uint64_t uv : 1;          /* underflow for mul, high priority */
+#endif
+        uint64_t sign : 1;        /* Sign bit for the total value */
+
+        uint64_t calc: 2;         /* absolute add, sub, or mul */
+        uint64_t inf: 1;          /* infinit */
+        uint64_t nan: 1;          /* nan */
+
+        /* Come from TILE-Gx ISA document, Table 7-2 for floating point */
+        uint64_t unordered : 1;   /* The two are unordered */
+        uint64_t lt : 1;          /* 1st is less than 2nd */
+        uint64_t le : 1;          /* 1st is less than or equal to 2nd */
+        uint64_t gt : 1;          /* 1st is greater than 2nd */
+        uint64_t ge : 1;          /* 1st is greater than or equal to 2nd */
+        uint64_t eq : 1;          /* The two operands are equal */
+        uint64_t neq : 1;         /* The two operands are not equal */
+
+        uint64_t unknown1 : 32;   /* unknown */
+#else
+        uint64_t unknown1 : 32;   /* unknown */
+        uint64_t neq : 1;         /* The two operands are not equal */
+        uint64_t eq : 1;          /* The two operands are equal */
+        uint64_t ge : 1;          /* 1st is greater than or equal to 2nd */
+        uint64_t gt : 1;          /* 1st is greater than 2nd */
+        uint64_t le : 1;          /* 1st is less than or equal to 2nd */
+        uint64_t lt : 1;          /* 1st is less than 2nd */
+        uint64_t unordered : 1;   /* The two are unordered */
+        uint64_t nan: 1;          /* nan */
+        uint64_t inf: 1;          /* infinit */
+        uint64_t calc: 2;         /* absolute add, sub, or mul */
+        uint64_t sign : 1;        /* Sign bit for the total value */
+        uint64_t vexp : 13;      /* vexp = exp | ov | uv */
+        uint64_t unknown0 : 7;    /* unknown */
+#endif
+    } fmt;
+    uint64_t ll;                  /* only for easy using */
+} TileGXFPDFmtF;
+
+typedef union TileGXFPDFmtV {
+    struct {
+#if !defined(HOST_WORDS_BIGENDIAN)
+        uint64_t mantissa : 60;   /* mantissa */
+        uint64_t overflow : 1;    /* carry/overflow bit for absolute add/mul */
+        uint64_t unknown1 : 3;    /* unknown */
+#else
+        uint64_t unknown1 : 3;    /* unknown */
+        uint64_t overflow : 1;    /* carry/overflow bit for absolute add/mul */
+        uint64_t mantissa : 60;   /* mantissa */
+#endif
+    } fmt;
+    uint64_t ll;                  /* only for easy using */
+} TileGXFPDFmtV;
+/*
+ * FDouble instructions implemenation:
+ *
+ * fdouble_unpack_min   ; srca and srcb are float_64 value.
+ *                      ; get the min absolute value's mantissa.
+ *                      ; move "mantissa >> (exp_max - exp_min)" to dest.
+ *
+ * fdouble_unpack_max   ; srca and srcb are float_64 value.
+ *                      ; get the max absolute value's mantissa.
+ *                      ; move mantissa to dest.
+ *
+ * fdouble_add_flags    ; srca and srcb are float_64 value.
+ *                      ; calc exp (exp_max), sign, and comp bits for flags.
+ *                      ; set addsub bit to flags and move flags to dest.
+ *
+ * fdouble_sub_flags    ; srca and srcb are float_64 value.
+ *                      ; calc exp (exp_max), sign, and comp bits for flags.
+ *                      ; set addsub bit to flags and move flags to dest.
+ *
+ * fdouble_addsub:      ; dest, srca (max, min mantissa), and srcb (flags).
+ *                      ; "dest +/- srca" depend on the add/sub bit of flags.
+ *                      ; move result mantissa to dest.
+ *
+ * fdouble_mul_flags:   ; srca and srcb are float_64 value.
+ *                      ; calc sign (xor), exp (exp_min + exp_max), and comp bits.
+ *                      ; mix sign, exp, and comp bits as flags to dest.
+ *
+ * fdouble_pack1        ; move srcb (flags) to dest.
+ *
+ * fdouble_pack2        ; srca, srcb (high, low mantissa), and dest (flags)
+ *                      ; normalize and pack result from srca, srcb, and dest.
+ *                      ; move result to dest.
+ */
+
+#pragma pack(pop)
+
+#endif /* FPU_TILEGX_H */
-- 
1.9.3


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH 2/4] target-tilegx: Implement fpu single floating point
  2015-11-08  5:42 [Qemu-devel] [PATCH 0/4] Implment fpu floating point instructions Chen Gang
  2015-11-08  5:43 ` [Qemu-devel] [PATCH 1/4] target-tilegx: Add fpu header file Chen Gang
@ 2015-11-08  5:44 ` Chen Gang
  2015-11-12 14:36   ` Richard Henderson
  2015-11-08  5:46 ` [Qemu-devel] [PATCH 3/4] target-tilegx: Implement fpu fdouble " Chen Gang
  2015-11-08  5:47 ` [Qemu-devel] [PATCH 4/4] target-tilegx: Let fpu implementation code can be built and used Chen Gang
  3 siblings, 1 reply; 13+ messages in thread
From: Chen Gang @ 2015-11-08  5:44 UTC (permalink / raw)
  To: rth, Peter Maydell, Chris Metcalf; +Cc: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 5201 bytes --]

>From 3270485ebd56429f6f62f0a4f967009d8a1b14d6 Mon Sep 17 00:00:00 2001
From: Chen Gang <gang.chen.5i5j@gmail.com>
Date: Sun, 8 Nov 2015 09:08:40 +0800
Subject: [PATCH 2/4] target-tilegx: Implement fpu single floating point
 instructions

Signed-off-by: Chen Gang <gang.chen.5i5j@gmail.com>
---
 target-tilegx/fsingle_helper.c | 168 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 168 insertions(+)
 create mode 100644 target-tilegx/fsingle_helper.c

diff --git a/target-tilegx/fsingle_helper.c b/target-tilegx/fsingle_helper.c
new file mode 100644
index 0000000..f8f6b69
--- /dev/null
+++ b/target-tilegx/fsingle_helper.c
@@ -0,0 +1,168 @@
+/*
+ * QEMU TILE-Gx helpers
+ *
+ *  Copyright (c) 2015 Chen Gang
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+
+#include "cpu.h"
+#include "qemu-common.h"
+#include "exec/helper-proto.h"
+#include "fpu/softfloat.h"
+
+#include "fpu.h"
+
+#pragma pack(push, 1)
+typedef union F32Fmt {
+    uint32_t f;
+    struct {
+#if defined(HOST_WORDS_BIGENDIAN)
+        uint32_t sign : 1;
+        uint32_t exp  : 8;
+        uint32_t frac : 23;
+#else
+        uint32_t frac : 23;
+        uint32_t exp  : 8;
+        uint32_t sign : 1;
+#endif
+    } bits;
+} F32Fmt;
+#pragma pack(pop)
+
+static uint64_t sfmt_to_uint64(TileGXFPSFmt a)
+{
+    union {
+        TileGXFPSFmt a;
+        uint64_t v;
+    } t;
+    t.a = a;
+    return t.v;
+}
+
+static TileGXFPSFmt uint64_to_sfmt(uint64 v)
+{
+    union {
+        TileGXFPSFmt a;
+        uint64_t v;
+    } t;
+    t.v = v;
+    return t.a;
+}
+
+static TileGXFPSFmt float32_to_sfmt(float32 f)
+{
+    F32Fmt tmp = {f};
+    union {
+        TileGXFPSFmt fmt;
+        uint64_t v;
+    } sfmt;
+
+    sfmt.v = 0;
+    sfmt.fmt.sign = tmp.bits.sign;
+    sfmt.fmt.exp = tmp.bits.exp;
+    sfmt.fmt.mantissa = (tmp.bits.frac << 8) | (1 << 31);
+
+    return sfmt.fmt;
+}
+
+static float32 sfmt_to_float32(TileGXFPSFmt sfmt, float_status *fp_status)
+{
+    F32Fmt f;
+
+    if (sfmt.calc == TILEGX_F_CALC_CVT) {
+        if (sfmt.sign)
+            f.f = int32_to_float32(0 - sfmt.mantissa, fp_status);
+        else
+            f.f = uint32_to_float32(sfmt.mantissa, fp_status);
+    } else {
+        f.bits.sign = sfmt.sign;
+        f.bits.exp = sfmt.exp;
+        f.bits.frac = sfmt.mantissa>> 8;
+    }
+
+    return f.f;
+}
+
+uint64_t helper_fsingle_pack2(CPUTLGState *env, uint64_t srca)
+{
+    return float32_val(sfmt_to_float32(uint64_to_sfmt(srca), &env->fp_status));
+}
+
+static void ana_bits(float_status *fp_status,
+                     float32 fsrca, float32 fsrcb, TileGXFPSFmt *sfmt)
+{
+    if (float32_eq(fsrca, fsrcb, fp_status)) {
+        sfmt->eq = 1;
+    } else {
+        sfmt->neq = 1;
+    }
+
+    if (float32_lt(fsrca, fsrcb, fp_status)) {
+        sfmt->lt = 1;
+    }
+    if (float32_le(fsrca, fsrcb, fp_status)) {
+        sfmt->le = 1;
+    }
+
+    if (float32_lt(fsrcb, fsrca, fp_status)) {
+        sfmt->gt = 1;
+    }
+    if (float32_le(fsrcb, fsrca, fp_status)) {
+        sfmt->ge = 1;
+    }
+
+    if (float32_unordered(fsrca, fsrcb, fp_status)) {
+        sfmt->unordered = 1;
+    }
+}
+
+static uint64_t main_calc(float_status *fp_status,
+                          float32 fsrca, float32 fsrcb,
+                          float32 (*calc)(float32, float32, float_status *))
+{
+    TileGXFPSFmt sfmt = float32_to_sfmt(calc(fsrca, fsrcb, fp_status));
+
+    ana_bits(fp_status, fsrca, fsrcb, &sfmt);
+
+    if (calc == float32_add)
+        sfmt.calc = TILEGX_F_CALC_ADD;
+    else if (calc == float32_sub)
+        sfmt.calc = TILEGX_F_CALC_SUB;
+    else
+        sfmt.calc = TILEGX_F_CALC_MUL;
+
+    sfmt_to_float32(sfmt, fp_status);
+
+    return sfmt_to_uint64(sfmt);
+}
+
+uint64_t helper_fsingle_add1(CPUTLGState *env, uint64_t srca, uint64_t srcb)
+{
+    return main_calc(&env->fp_status,
+                     make_float32(srca), make_float32(srcb), float32_add);
+}
+
+uint64_t helper_fsingle_sub1(CPUTLGState *env, uint64_t srca, uint64_t srcb)
+{
+    return main_calc(&env->fp_status,
+                     make_float32(srca), make_float32(srcb), float32_sub);
+}
+
+uint64_t helper_fsingle_mul1(CPUTLGState *env, uint64_t srca, uint64_t srcb)
+{
+    return main_calc(&env->fp_status,
+                     make_float32(srca), make_float32(srcb), float32_mul);
+}
-- 
1.9.3

 		 	   		  

[-- Attachment #2: 0002-target-tilegx-Implement-fpu-single-floating-point-in.patch --]
[-- Type: application/octet-stream, Size: 5000 bytes --]

From 3270485ebd56429f6f62f0a4f967009d8a1b14d6 Mon Sep 17 00:00:00 2001
From: Chen Gang <gang.chen.5i5j@gmail.com>
Date: Sun, 8 Nov 2015 09:08:40 +0800
Subject: [PATCH 2/4] target-tilegx: Implement fpu single floating point
 instructions

Signed-off-by: Chen Gang <gang.chen.5i5j@gmail.com>
---
 target-tilegx/fsingle_helper.c | 168 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 168 insertions(+)
 create mode 100644 target-tilegx/fsingle_helper.c

diff --git a/target-tilegx/fsingle_helper.c b/target-tilegx/fsingle_helper.c
new file mode 100644
index 0000000..f8f6b69
--- /dev/null
+++ b/target-tilegx/fsingle_helper.c
@@ -0,0 +1,168 @@
+/*
+ * QEMU TILE-Gx helpers
+ *
+ *  Copyright (c) 2015 Chen Gang
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+
+#include "cpu.h"
+#include "qemu-common.h"
+#include "exec/helper-proto.h"
+#include "fpu/softfloat.h"
+
+#include "fpu.h"
+
+#pragma pack(push, 1)
+typedef union F32Fmt {
+    uint32_t f;
+    struct {
+#if defined(HOST_WORDS_BIGENDIAN)
+        uint32_t sign : 1;
+        uint32_t exp  : 8;
+        uint32_t frac : 23;
+#else
+        uint32_t frac : 23;
+        uint32_t exp  : 8;
+        uint32_t sign : 1;
+#endif
+    } bits;
+} F32Fmt;
+#pragma pack(pop)
+
+static uint64_t sfmt_to_uint64(TileGXFPSFmt a)
+{
+    union {
+        TileGXFPSFmt a;
+        uint64_t v;
+    } t;
+    t.a = a;
+    return t.v;
+}
+
+static TileGXFPSFmt uint64_to_sfmt(uint64 v)
+{
+    union {
+        TileGXFPSFmt a;
+        uint64_t v;
+    } t;
+    t.v = v;
+    return t.a;
+}
+
+static TileGXFPSFmt float32_to_sfmt(float32 f)
+{
+    F32Fmt tmp = {f};
+    union {
+        TileGXFPSFmt fmt;
+        uint64_t v;
+    } sfmt;
+
+    sfmt.v = 0;
+    sfmt.fmt.sign = tmp.bits.sign;
+    sfmt.fmt.exp = tmp.bits.exp;
+    sfmt.fmt.mantissa = (tmp.bits.frac << 8) | (1 << 31);
+
+    return sfmt.fmt;
+}
+
+static float32 sfmt_to_float32(TileGXFPSFmt sfmt, float_status *fp_status)
+{
+    F32Fmt f;
+
+    if (sfmt.calc == TILEGX_F_CALC_CVT) {
+        if (sfmt.sign)
+            f.f = int32_to_float32(0 - sfmt.mantissa, fp_status);
+        else
+            f.f = uint32_to_float32(sfmt.mantissa, fp_status);
+    } else {
+        f.bits.sign = sfmt.sign;
+        f.bits.exp = sfmt.exp;
+        f.bits.frac = sfmt.mantissa >> 8;
+    }
+
+    return f.f;
+}
+
+uint64_t helper_fsingle_pack2(CPUTLGState *env, uint64_t srca)
+{
+    return float32_val(sfmt_to_float32(uint64_to_sfmt(srca), &env->fp_status));
+}
+
+static void ana_bits(float_status *fp_status,
+                     float32 fsrca, float32 fsrcb, TileGXFPSFmt *sfmt)
+{
+    if (float32_eq(fsrca, fsrcb, fp_status)) {
+        sfmt->eq = 1;
+    } else {
+        sfmt->neq = 1;
+    }
+
+    if (float32_lt(fsrca, fsrcb, fp_status)) {
+        sfmt->lt = 1;
+    }
+    if (float32_le(fsrca, fsrcb, fp_status)) {
+        sfmt->le = 1;
+    }
+
+    if (float32_lt(fsrcb, fsrca, fp_status)) {
+        sfmt->gt = 1;
+    }
+    if (float32_le(fsrcb, fsrca, fp_status)) {
+        sfmt->ge = 1;
+    }
+
+    if (float32_unordered(fsrca, fsrcb, fp_status)) {
+        sfmt->unordered = 1;
+    }
+}
+
+static uint64_t main_calc(float_status *fp_status,
+                          float32 fsrca, float32 fsrcb,
+                          float32 (*calc)(float32, float32, float_status *))
+{
+    TileGXFPSFmt sfmt = float32_to_sfmt(calc(fsrca, fsrcb, fp_status));
+
+    ana_bits(fp_status, fsrca, fsrcb, &sfmt);
+
+    if (calc == float32_add)
+        sfmt.calc = TILEGX_F_CALC_ADD;
+    else if (calc == float32_sub)
+        sfmt.calc = TILEGX_F_CALC_SUB;
+    else
+        sfmt.calc = TILEGX_F_CALC_MUL;
+
+    sfmt_to_float32(sfmt, fp_status);
+
+    return sfmt_to_uint64(sfmt);
+}
+
+uint64_t helper_fsingle_add1(CPUTLGState *env, uint64_t srca, uint64_t srcb)
+{
+    return main_calc(&env->fp_status,
+                     make_float32(srca), make_float32(srcb), float32_add);
+}
+
+uint64_t helper_fsingle_sub1(CPUTLGState *env, uint64_t srca, uint64_t srcb)
+{
+    return main_calc(&env->fp_status,
+                     make_float32(srca), make_float32(srcb), float32_sub);
+}
+
+uint64_t helper_fsingle_mul1(CPUTLGState *env, uint64_t srca, uint64_t srcb)
+{
+    return main_calc(&env->fp_status,
+                     make_float32(srca), make_float32(srcb), float32_mul);
+}
-- 
1.9.3


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH 3/4] target-tilegx: Implement fpu fdouble floating point
  2015-11-08  5:42 [Qemu-devel] [PATCH 0/4] Implment fpu floating point instructions Chen Gang
  2015-11-08  5:43 ` [Qemu-devel] [PATCH 1/4] target-tilegx: Add fpu header file Chen Gang
  2015-11-08  5:44 ` [Qemu-devel] [PATCH 2/4] target-tilegx: Implement fpu single floating point Chen Gang
@ 2015-11-08  5:46 ` Chen Gang
  2015-11-08  5:47 ` [Qemu-devel] [PATCH 4/4] target-tilegx: Let fpu implementation code can be built and used Chen Gang
  3 siblings, 0 replies; 13+ messages in thread
From: Chen Gang @ 2015-11-08  5:46 UTC (permalink / raw)
  To: rth, Peter Maydell, Chris Metcalf; +Cc: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 9658 bytes --]

>From c467db1c0a5f4c6560b8bdddd2115732aa718c4b Mon Sep 17 00:00:00 2001
From: Chen Gang <gang.chen.5i5j@gmail.com>
Date: Sun, 8 Nov 2015 09:10:17 +0800
Subject: [PATCH 3/4] target-tilegx: Implement fpu fdouble floating point
 instructions

Signed-off-by: Chen Gang <gang.chen.5i5j@gmail.com>
---
 target-tilegx/fdouble_helper.c | 290 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 290 insertions(+)
 create mode 100644 target-tilegx/fdouble_helper.c

diff --git a/target-tilegx/fdouble_helper.c b/target-tilegx/fdouble_helper.c
new file mode 100644
index 0000000..7ba0583
--- /dev/null
+++ b/target-tilegx/fdouble_helper.c
@@ -0,0 +1,290 @@
+/*
+ * QEMU TILE-Gx helpers
+ *
+ *  Copyright (c) 2015 Chen Gang
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+
+#include "cpu.h"
+#include "qemu-common.h"
+#include "exec/helper-proto.h"
+#include "fpu/softfloat.h"
+
+#include "fpu.h"
+
+#define TILEGX_F_MAN_HBIT        (1ULL << 59)
+
+#pragma pack(push, 1)
+typedef union F64Fmt {
+    float64 d;
+    struct {
+#if defined(HOST_WORDS_BIGENDIAN)
+        uint64_t sign : 1;
+        uint64_t exp  : 11;
+        uint64_t frac : 52;
+#else
+        uint64_t frac : 52;
+        uint64_t exp  : 11;
+        uint64_t sign : 1;
+#endif
+    } bits;
+} F64Fmt;
+#pragma pack(pop)
+
+static uint64_t fr_to_man(F64Fmt v)
+{
+    uint64_t val = (uint64_t)v.bits.frac << 7;
+
+    if (v.bits.exp)
+        val |= TILEGX_F_MAN_HBIT;
+
+    return val;
+}
+
+uint64_t helper_fdouble_unpack_min(CPUTLGState *env,
+                                   uint64_t srca, uint64_t srcb)
+{
+    F64Fmt va, vb;
+    TileGXFPDFmtV v;
+
+    va.d = make_float64(srca);
+    vb.d = make_float64(srcb);
+    v.ll = 0; /* also cause v.fmt.overflow = 0 */
+
+    if (float64_is_any_nan(srca) || float64_is_any_nan(srcb)
+        || float64_is_infinity(srca) || float64_is_infinity(srcb))
+        ;
+    else if (va.bits.exp> vb.bits.exp) {
+        if (va.bits.exp - vb.bits.exp < 64)
+            v.fmt.mantissa = fr_to_man(vb)>> (va.bits.exp - vb.bits.exp);
+    } else if (va.bits.exp < vb.bits.exp) {
+        if (vb.bits.exp - va.bits.exp < 64)
+            v.fmt.mantissa = fr_to_man(va)>> (vb.bits.exp - va.bits.exp);
+    } else if (va.bits.frac> vb.bits.frac)
+        v.fmt.mantissa = fr_to_man(vb);
+    else
+        v.fmt.mantissa = fr_to_man(va);
+
+    return v.ll;
+}
+
+uint64_t helper_fdouble_unpack_max(CPUTLGState *env,
+                                   uint64_t srca, uint64_t srcb)
+{
+    F64Fmt va, vb;
+    TileGXFPDFmtV v;
+
+    va.d = make_float64(srca);
+    vb.d = make_float64(srcb);
+    v.ll = 0; /* also cause v.fmt.overflow = 0 */
+
+    if (float64_is_any_nan(srca) || float64_is_any_nan(srcb)
+        || float64_is_infinity(srca) || float64_is_infinity(srcb))
+        ;
+    else if (va.bits.exp> vb.bits.exp)
+        v.fmt.mantissa = fr_to_man(va);
+    else if (va.bits.exp < vb.bits.exp)
+        v.fmt.mantissa = fr_to_man(vb);
+    else if (va.bits.frac> vb.bits.frac)
+        v.fmt.mantissa = fr_to_man(va);
+    else
+        v.fmt.mantissa = fr_to_man(vb);
+
+    return v.ll;
+}
+
+uint64_t helper_fdouble_addsub(CPUTLGState *env,
+                               uint64_t dest, uint64_t srca, uint64_t srcb)
+{
+    TileGXFPDFmtF flags;
+    TileGXFPDFmtV v;
+
+    flags.ll = srcb;
+    if (flags.fmt.calc == TILEGX_F_CALC_ADD) {
+        v.ll = dest + srca; /* maybe set addsub overflow bit */
+    } else
+        v.ll = dest - srca;
+
+    return v.ll;
+}
+
+/* absolute-add/mul may cause add/mul carry or overflow */
+static bool proc_oflow(TileGXFPDFmtF *flags, TileGXFPDFmtV *v, uint64_t *srcb)
+{
+    if (v->fmt.overflow) {
+        flags->fmt.vexp++;
+        *srcb>>= 1;
+        *srcb |= (uint64_t)v->ll << 63;
+        v->ll>>= 1;
+        v->fmt.overflow = 0;
+    }
+    return flags->fmt.vexp> TILEGX_F_EXP_DMAX;
+}
+
+uint64_t helper_fdouble_pack2(CPUTLGState *env,
+                              uint64_t dest, uint64_t srca, uint64_t srcb)
+{
+    TileGXFPDFmtF flags;
+    TileGXFPDFmtV v;
+    F64Fmt d;
+
+    flags.ll = dest;
+    v.ll = srca;
+
+    d.d = 0;
+    d.bits.sign = flags.fmt.sign;
+
+    /*
+     * fdouble_add_flags, fdouble_sub_flags, or fdouble_mul_flags have
+     * processed exceptions. So need not process fp_status, again.
+     */
+
+    if (flags.fmt.nan)
+        return float64_val(float64_default_nan);
+    else if (flags.fmt.inf)
+        return float64_val(d.d |= float64_infinity);
+
+    /* absolute-mul needs left shift 4 + 1 bytes to match the real mantissa */
+    if (flags.fmt.calc == TILEGX_F_CALC_MUL) {
+        v.ll <<= 5;
+        v.ll |= srcb>> 59;
+        srcb <<= 5;
+    }
+
+    if (flags.fmt.vexp & TILEGX_F_EXP_DUF) /* must check underflow, firstly */
+        return float64_val(d.d);
+
+    if (proc_oflow(&flags, &v, &srcb))
+        return float64_val(d.d |= float64_infinity);
+
+    while (!(v.fmt.mantissa & TILEGX_F_MAN_HBIT) && (v.fmt.mantissa | srcb)) {
+        flags.fmt.vexp--;
+        v.fmt.mantissa <<= 1;
+        v.fmt.mantissa |= srcb>> 63;
+        srcb <<= 1;
+    }
+
+    /* check underflow, again, after format */
+    if ((flags.fmt.vexp & TILEGX_F_EXP_DUF) || !v.fmt.mantissa)
+        return float64_val(d.d);
+
+    if (flags.fmt.sign)
+        d.d = int64_to_float64(0 - (int64_t)v.fmt.mantissa, &env->fp_status);
+    else
+        d.d = uint64_to_float64((uint64_t)v.fmt.mantissa, &env->fp_status);
+
+    if (d.bits.exp == 59 + TILEGX_F_EXP_DZERO)
+        d.bits.exp = flags.fmt.vexp;
+    else {                            /* for carry and overflow again */
+        d.bits.exp = flags.fmt.vexp + 1;
+        if (d.bits.exp == TILEGX_F_EXP_DMAX)
+            d.d = float64_infinity;
+    }
+
+    d.bits.sign = flags.fmt.sign;
+
+    return float64_val(d.d);
+}
+
+static void ana_bits(float_status *fp_status,
+                     float64 fsrca, float64 fsrcb, TileGXFPDFmtF *dfmt)
+{
+    if (float64_eq(fsrca, fsrcb, fp_status)) {
+        dfmt->fmt.eq = 1;
+    } else {
+        dfmt->fmt.neq = 1;
+    }
+
+    if (float64_lt(fsrca, fsrcb, fp_status)) {
+        dfmt->fmt.lt = 1;
+    }
+    if (float64_le(fsrca, fsrcb, fp_status)) {
+        dfmt->fmt.le = 1;
+    }
+
+    if (float64_lt(fsrcb, fsrca, fp_status)) {
+        dfmt->fmt.gt = 1;
+    }
+    if (float64_le(fsrcb, fsrca, fp_status)) {
+        dfmt->fmt.ge = 1;
+    }
+
+    if (float64_unordered(fsrca, fsrcb, fp_status)) {
+        dfmt->fmt.unordered = 1;
+    }
+}
+
+static uint64_t main_calc(float_status *fp_status,
+                          float64 fsrca, float64 fsrcb,
+                          float64 (*calc)(float64, float64, float_status *))
+{
+    F64Fmt va, vb, vf;
+    TileGXFPDFmtF flags;
+
+    flags.ll = 0;
+    ana_bits(fp_status, fsrca, fsrcb, &flags);
+
+    vf.d = calc(fsrca, fsrcb, fp_status); /* also check exceptions */
+    flags.fmt.sign = vf.bits.sign;
+
+    va.d = fsrca;
+    vb.d = fsrcb;
+    if (float64_is_any_nan(vf.d))
+        flags.fmt.nan = 1;
+    else if (float64_is_infinity(vf.d))
+        flags.fmt.inf = 1;
+    else if (calc == float64_add) {
+        flags.fmt.vexp = (va.bits.exp> vb.bits.exp)
+                             ? va.bits.exp : vb.bits.exp;
+        flags.fmt.calc = (va.bits.sign == vb.bits.sign)
+                             ? TILEGX_F_CALC_ADD : TILEGX_F_CALC_SUB;
+
+    } else if (calc == float64_sub) {
+        flags.fmt.vexp = (va.bits.exp> vb.bits.exp)
+                             ? va.bits.exp : vb.bits.exp;
+        flags.fmt.calc = (va.bits.sign != vb.bits.sign)
+                             ? TILEGX_F_CALC_ADD : TILEGX_F_CALC_SUB;
+
+    } else {
+        flags.fmt.vexp = (int64_t)(va.bits.exp - TILEGX_F_EXP_DZERO)
+                                   + (int64_t)(vb.bits.exp - TILEGX_F_EXP_DZERO)
+                                   + TILEGX_F_EXP_DZERO;
+        flags.fmt.calc = TILEGX_F_CALC_MUL;
+    }
+
+    return flags.ll;
+}
+
+uint64_t helper_fdouble_add_flags(CPUTLGState *env,
+                                  uint64_t srca, uint64_t srcb)
+{
+    return main_calc(&env->fp_status,
+                     make_float64(srca), make_float64(srcb), float64_add);
+}
+
+uint64_t helper_fdouble_sub_flags(CPUTLGState *env,
+                                  uint64_t srca, uint64_t srcb)
+{
+    return main_calc(&env->fp_status,
+                     make_float64(srca), make_float64(srcb), float64_sub);
+}
+
+uint64_t helper_fdouble_mul_flags(CPUTLGState *env,
+                                  uint64_t srca, uint64_t srcb)
+{
+    return main_calc(&env->fp_status,
+                     make_float64(srca), make_float64(srcb), float64_mul);
+}
-- 
1.9.3

 		 	   		  

[-- Attachment #2: 0003-target-tilegx-Implement-fpu-fdouble-floating-point-i.patch --]
[-- Type: application/octet-stream, Size: 9347 bytes --]

From c467db1c0a5f4c6560b8bdddd2115732aa718c4b Mon Sep 17 00:00:00 2001
From: Chen Gang <gang.chen.5i5j@gmail.com>
Date: Sun, 8 Nov 2015 09:10:17 +0800
Subject: [PATCH 3/4] target-tilegx: Implement fpu fdouble floating point
 instructions

Signed-off-by: Chen Gang <gang.chen.5i5j@gmail.com>
---
 target-tilegx/fdouble_helper.c | 290 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 290 insertions(+)
 create mode 100644 target-tilegx/fdouble_helper.c

diff --git a/target-tilegx/fdouble_helper.c b/target-tilegx/fdouble_helper.c
new file mode 100644
index 0000000..7ba0583
--- /dev/null
+++ b/target-tilegx/fdouble_helper.c
@@ -0,0 +1,290 @@
+/*
+ * QEMU TILE-Gx helpers
+ *
+ *  Copyright (c) 2015 Chen Gang
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+
+#include "cpu.h"
+#include "qemu-common.h"
+#include "exec/helper-proto.h"
+#include "fpu/softfloat.h"
+
+#include "fpu.h"
+
+#define TILEGX_F_MAN_HBIT        (1ULL << 59)
+
+#pragma pack(push, 1)
+typedef union F64Fmt {
+    float64 d;
+    struct {
+#if defined(HOST_WORDS_BIGENDIAN)
+        uint64_t sign : 1;
+        uint64_t exp  : 11;
+        uint64_t frac : 52;
+#else
+        uint64_t frac : 52;
+        uint64_t exp  : 11;
+        uint64_t sign : 1;
+#endif
+    } bits;
+} F64Fmt;
+#pragma pack(pop)
+
+static uint64_t fr_to_man(F64Fmt v)
+{
+    uint64_t val = (uint64_t)v.bits.frac << 7;
+
+    if (v.bits.exp)
+        val |= TILEGX_F_MAN_HBIT;
+
+    return val;
+}
+
+uint64_t helper_fdouble_unpack_min(CPUTLGState *env,
+                                   uint64_t srca, uint64_t srcb)
+{
+    F64Fmt va, vb;
+    TileGXFPDFmtV v;
+
+    va.d = make_float64(srca);
+    vb.d = make_float64(srcb);
+    v.ll = 0; /* also cause v.fmt.overflow = 0 */
+
+    if (float64_is_any_nan(srca) || float64_is_any_nan(srcb)
+        || float64_is_infinity(srca) || float64_is_infinity(srcb))
+        ;
+    else if (va.bits.exp > vb.bits.exp) {
+        if (va.bits.exp - vb.bits.exp < 64)
+            v.fmt.mantissa = fr_to_man(vb) >> (va.bits.exp - vb.bits.exp);
+    } else if (va.bits.exp < vb.bits.exp) {
+        if (vb.bits.exp - va.bits.exp < 64)
+            v.fmt.mantissa = fr_to_man(va) >> (vb.bits.exp - va.bits.exp);
+    } else if (va.bits.frac > vb.bits.frac)
+        v.fmt.mantissa = fr_to_man(vb);
+    else
+        v.fmt.mantissa = fr_to_man(va);
+
+    return v.ll;
+}
+
+uint64_t helper_fdouble_unpack_max(CPUTLGState *env,
+                                   uint64_t srca, uint64_t srcb)
+{
+    F64Fmt va, vb;
+    TileGXFPDFmtV v;
+
+    va.d = make_float64(srca);
+    vb.d = make_float64(srcb);
+    v.ll = 0; /* also cause v.fmt.overflow = 0 */
+
+    if (float64_is_any_nan(srca) || float64_is_any_nan(srcb)
+        || float64_is_infinity(srca) || float64_is_infinity(srcb))
+        ;
+    else if (va.bits.exp > vb.bits.exp)
+        v.fmt.mantissa = fr_to_man(va);
+    else if (va.bits.exp < vb.bits.exp)
+        v.fmt.mantissa = fr_to_man(vb);
+    else if (va.bits.frac > vb.bits.frac)
+        v.fmt.mantissa = fr_to_man(va);
+    else
+        v.fmt.mantissa = fr_to_man(vb);
+
+    return v.ll;
+}
+
+uint64_t helper_fdouble_addsub(CPUTLGState *env,
+                               uint64_t dest, uint64_t srca, uint64_t srcb)
+{
+    TileGXFPDFmtF flags;
+    TileGXFPDFmtV v;
+
+    flags.ll = srcb;
+    if (flags.fmt.calc == TILEGX_F_CALC_ADD) {
+        v.ll = dest + srca; /* maybe set addsub overflow bit */
+    } else
+        v.ll = dest - srca;
+
+    return v.ll;
+}
+
+/* absolute-add/mul may cause add/mul carry or overflow */
+static bool proc_oflow(TileGXFPDFmtF *flags, TileGXFPDFmtV *v, uint64_t *srcb)
+{
+    if (v->fmt.overflow) {
+        flags->fmt.vexp++;
+        *srcb >>= 1;
+        *srcb |= (uint64_t)v->ll << 63;
+        v->ll >>= 1;
+        v->fmt.overflow = 0;
+    }
+    return flags->fmt.vexp > TILEGX_F_EXP_DMAX;
+}
+
+uint64_t helper_fdouble_pack2(CPUTLGState *env,
+                              uint64_t dest, uint64_t srca, uint64_t srcb)
+{
+    TileGXFPDFmtF flags;
+    TileGXFPDFmtV v;
+    F64Fmt d;
+
+    flags.ll = dest;
+    v.ll = srca;
+
+    d.d = 0;
+    d.bits.sign = flags.fmt.sign;
+
+    /*
+     * fdouble_add_flags, fdouble_sub_flags, or fdouble_mul_flags have
+     * processed exceptions. So need not process fp_status, again.
+     */
+
+    if (flags.fmt.nan)
+        return float64_val(float64_default_nan);
+    else if (flags.fmt.inf)
+        return float64_val(d.d |= float64_infinity);
+
+    /* absolute-mul needs left shift 4 + 1 bytes to match the real mantissa */
+    if (flags.fmt.calc == TILEGX_F_CALC_MUL) {
+        v.ll <<= 5;
+        v.ll |= srcb >> 59;
+        srcb <<= 5;
+    }
+
+    if (flags.fmt.vexp & TILEGX_F_EXP_DUF) /* must check underflow, firstly */
+        return float64_val(d.d);
+
+    if (proc_oflow(&flags, &v, &srcb))
+        return float64_val(d.d |= float64_infinity);
+
+    while (!(v.fmt.mantissa & TILEGX_F_MAN_HBIT) && (v.fmt.mantissa | srcb)) {
+        flags.fmt.vexp--;
+        v.fmt.mantissa <<= 1;
+        v.fmt.mantissa |= srcb >> 63;
+        srcb <<= 1;
+    }
+
+    /* check underflow, again, after format */
+    if ((flags.fmt.vexp & TILEGX_F_EXP_DUF) || !v.fmt.mantissa)
+        return float64_val(d.d);
+
+    if (flags.fmt.sign)
+        d.d = int64_to_float64(0 - (int64_t)v.fmt.mantissa, &env->fp_status);
+    else
+        d.d = uint64_to_float64((uint64_t)v.fmt.mantissa, &env->fp_status);
+
+    if (d.bits.exp == 59 + TILEGX_F_EXP_DZERO)
+        d.bits.exp = flags.fmt.vexp;
+    else {                            /* for carry and overflow again */
+        d.bits.exp = flags.fmt.vexp + 1;
+        if (d.bits.exp == TILEGX_F_EXP_DMAX)
+            d.d = float64_infinity;
+    }
+
+    d.bits.sign = flags.fmt.sign;
+
+    return float64_val(d.d);
+}
+
+static void ana_bits(float_status *fp_status,
+                     float64 fsrca, float64 fsrcb, TileGXFPDFmtF *dfmt)
+{
+    if (float64_eq(fsrca, fsrcb, fp_status)) {
+        dfmt->fmt.eq = 1;
+    } else {
+        dfmt->fmt.neq = 1;
+    }
+
+    if (float64_lt(fsrca, fsrcb, fp_status)) {
+        dfmt->fmt.lt = 1;
+    }
+    if (float64_le(fsrca, fsrcb, fp_status)) {
+        dfmt->fmt.le = 1;
+    }
+
+    if (float64_lt(fsrcb, fsrca, fp_status)) {
+        dfmt->fmt.gt = 1;
+    }
+    if (float64_le(fsrcb, fsrca, fp_status)) {
+        dfmt->fmt.ge = 1;
+    }
+
+    if (float64_unordered(fsrca, fsrcb, fp_status)) {
+        dfmt->fmt.unordered = 1;
+    }
+}
+
+static uint64_t main_calc(float_status *fp_status,
+                          float64 fsrca, float64 fsrcb,
+                          float64 (*calc)(float64, float64, float_status *))
+{
+    F64Fmt va, vb, vf;
+    TileGXFPDFmtF flags;
+
+    flags.ll = 0;
+    ana_bits(fp_status, fsrca, fsrcb, &flags);
+
+    vf.d = calc(fsrca, fsrcb, fp_status); /* also check exceptions */
+    flags.fmt.sign = vf.bits.sign;
+
+    va.d = fsrca;
+    vb.d = fsrcb;
+    if (float64_is_any_nan(vf.d))
+        flags.fmt.nan = 1;
+    else if (float64_is_infinity(vf.d))
+        flags.fmt.inf = 1;
+    else if (calc == float64_add) {
+        flags.fmt.vexp = (va.bits.exp > vb.bits.exp)
+                             ? va.bits.exp : vb.bits.exp;
+        flags.fmt.calc = (va.bits.sign == vb.bits.sign)
+                             ? TILEGX_F_CALC_ADD : TILEGX_F_CALC_SUB;
+
+    } else if (calc == float64_sub) {
+        flags.fmt.vexp = (va.bits.exp > vb.bits.exp)
+                             ? va.bits.exp : vb.bits.exp;
+        flags.fmt.calc = (va.bits.sign != vb.bits.sign)
+                             ? TILEGX_F_CALC_ADD : TILEGX_F_CALC_SUB;
+
+    } else {
+        flags.fmt.vexp = (int64_t)(va.bits.exp - TILEGX_F_EXP_DZERO)
+                                   + (int64_t)(vb.bits.exp - TILEGX_F_EXP_DZERO)
+                                   + TILEGX_F_EXP_DZERO;
+        flags.fmt.calc = TILEGX_F_CALC_MUL;
+    }
+
+    return flags.ll;
+}
+
+uint64_t helper_fdouble_add_flags(CPUTLGState *env,
+                                  uint64_t srca, uint64_t srcb)
+{
+    return main_calc(&env->fp_status,
+                     make_float64(srca), make_float64(srcb), float64_add);
+}
+
+uint64_t helper_fdouble_sub_flags(CPUTLGState *env,
+                                  uint64_t srca, uint64_t srcb)
+{
+    return main_calc(&env->fp_status,
+                     make_float64(srca), make_float64(srcb), float64_sub);
+}
+
+uint64_t helper_fdouble_mul_flags(CPUTLGState *env,
+                                  uint64_t srca, uint64_t srcb)
+{
+    return main_calc(&env->fp_status,
+                     make_float64(srca), make_float64(srcb), float64_mul);
+}
-- 
1.9.3


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH 4/4] target-tilegx: Let fpu implementation code can be built and used
  2015-11-08  5:42 [Qemu-devel] [PATCH 0/4] Implment fpu floating point instructions Chen Gang
                   ` (2 preceding siblings ...)
  2015-11-08  5:46 ` [Qemu-devel] [PATCH 3/4] target-tilegx: Implement fpu fdouble " Chen Gang
@ 2015-11-08  5:47 ` Chen Gang
  3 siblings, 0 replies; 13+ messages in thread
From: Chen Gang @ 2015-11-08  5:47 UTC (permalink / raw)
  To: rth, Peter Maydell, Chris Metcalf; +Cc: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 7856 bytes --]

>From 8fab455a5ac5508d06cc69f778e926ad098fbe5b Mon Sep 17 00:00:00 2001
From: Chen Gang <gang.chen.5i5j@gmail.com>
Date: Sun, 8 Nov 2015 09:11:36 +0800
Subject: [PATCH 4/4] target-tilegx: Let fpu implementation code can be built
 and used

It passes gcc testsuite: it can get the same result as the original fpu
implementation have done.

Signed-off-by: Chen Gang <gang.chen.5i5j@gmail.com>
---
 target-tilegx/Makefile.objs |  3 +-
 target-tilegx/cpu.h         |  2 ++
 target-tilegx/helper.h      | 12 ++++++++
 target-tilegx/translate.c   | 68 +++++++++++++++++++++++++++++++++++++++------
 4 files changed, 75 insertions(+), 10 deletions(-)

diff --git a/target-tilegx/Makefile.objs b/target-tilegx/Makefile.objs
index 0db778f..c2cf2f1 100644
--- a/target-tilegx/Makefile.objs
+++ b/target-tilegx/Makefile.objs
@@ -1 +1,2 @@
-obj-y += cpu.o translate.o helper.o simd_helper.o
+obj-y += cpu.o translate.o helper.o simd_helper.o \
+		fsingle_helper.o fdouble_helper.o
diff --git a/target-tilegx/cpu.h b/target-tilegx/cpu.h
index 03df107..445a606 100644
--- a/target-tilegx/cpu.h
+++ b/target-tilegx/cpu.h
@@ -88,6 +88,8 @@ typedef struct CPUTLGState {
     uint64_t spregs[TILEGX_SPR_COUNT]; /* Special used registers by outside */
     uint64_t pc;                       /* Current pc */
 
+    float_status fp_status;            /* floating point status */
+
 #if defined(CONFIG_USER_ONLY)
     uint64_t excaddr;                  /* exception address */
     uint64_t atomic_srca;              /* Arguments to atomic "exceptions" */
diff --git a/target-tilegx/helper.h b/target-tilegx/helper.h
index 9281d0f..b785bf2 100644
--- a/target-tilegx/helper.h
+++ b/target-tilegx/helper.h
@@ -24,3 +24,15 @@ DEF_HELPER_FLAGS_2(v1shrs, TCG_CALL_NO_RWG_SE, i64, i64, i64)
 DEF_HELPER_FLAGS_2(v2shl, TCG_CALL_NO_RWG_SE, i64, i64, i64)
 DEF_HELPER_FLAGS_2(v2shru, TCG_CALL_NO_RWG_SE, i64, i64, i64)
 DEF_HELPER_FLAGS_2(v2shrs, TCG_CALL_NO_RWG_SE, i64, i64, i64)
+
+DEF_HELPER_3(fsingle_add1, i64, env, i64, i64)
+DEF_HELPER_3(fsingle_sub1, i64, env, i64, i64)
+DEF_HELPER_3(fsingle_mul1, i64, env, i64, i64)
+DEF_HELPER_2(fsingle_pack2, i64, env, i64)
+DEF_HELPER_3(fdouble_unpack_min, i64, env, i64, i64)
+DEF_HELPER_3(fdouble_unpack_max, i64, env, i64, i64)
+DEF_HELPER_3(fdouble_add_flags, i64, env, i64, i64)
+DEF_HELPER_3(fdouble_sub_flags, i64, env, i64, i64)
+DEF_HELPER_4(fdouble_addsub, i64, env, i64, i64, i64)
+DEF_HELPER_3(fdouble_mul_flags, i64, env, i64, i64)
+DEF_HELPER_4(fdouble_pack2, i64, env, i64, i64, i64)
diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
index b8ca401..4d74b1d 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -597,6 +597,11 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned opext,
         }
         qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s %s", mnemonic, reg_names[srca]);
         return ret;
+
+    case OE_RR_X0(FSINGLE_PACK1):
+    case OE_RR_Y0(FSINGLE_PACK1):
+        mnemonic = "fsingle_pack1";
+        goto done2;
     }
 
     tdest = dest_gr(dc, dest);
@@ -613,9 +618,6 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned opext,
         gen_helper_cnttz(tdest, tsrca);
         mnemonic = "cnttz";
         break;
-    case OE_RR_X0(FSINGLE_PACK1):
-    case OE_RR_Y0(FSINGLE_PACK1):
-        return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
     case OE_RR_X1(LD1S):
         memop = MO_SB;
         mnemonic = "ld1s"; /* prefetch_l1_fault */
@@ -734,6 +736,7 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned opext,
         return TILEGX_EXCP_OPCODE_UNKNOWN;
     }
 
+done2:
     qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s %s, %s", mnemonic,
                   reg_names[dest], reg_names[srca]);
     return ret;
@@ -742,13 +745,21 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned opext,
 static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned opext,
                                unsigned dest, unsigned srca, unsigned srcb)
 {
-    TCGv tdest = dest_gr(dc, dest);
-    TCGv tsrca = load_gr(dc, srca);
-    TCGv tsrcb = load_gr(dc, srcb);
+    TCGv tdest, tsrca, tsrcb;
     TCGv t0;
     const char *mnemonic;
 
     switch (opext) {
+    case OE_RRR(FSINGLE_ADDSUB2, 0, X0):
+        mnemonic = "fsingle_addsub2";
+        goto done2;
+    }
+
+    tdest = dest_gr(dc, dest);
+    tsrca = load_gr(dc, srca);
+    tsrcb = load_gr(dc, srcb);
+
+    switch (opext) {
     case OE_RRR(ADDXSC, 0, X0):
     case OE_RRR(ADDXSC, 0, X1):
         gen_saturate_op(tdest, tsrca, tsrcb, tcg_gen_add_tl);
@@ -906,14 +917,39 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned opext,
         mnemonic = "exch";
         break;
     case OE_RRR(FDOUBLE_ADDSUB, 0, X0):
+        gen_helper_fdouble_addsub(tdest, cpu_env,
+                                  load_gr(dc, dest),tsrca, tsrcb);
+        mnemonic = "fdouble_addsub";
+        break;
     case OE_RRR(FDOUBLE_ADD_FLAGS, 0, X0):
+        gen_helper_fdouble_add_flags(tdest, cpu_env, tsrca, tsrcb);
+        mnemonic = "fdouble_add_flags";
+        break;
     case OE_RRR(FDOUBLE_MUL_FLAGS, 0, X0):
+        gen_helper_fdouble_mul_flags(tdest, cpu_env, tsrca, tsrcb);
+        mnemonic = "fdouble_mul_flags";
+        break;
     case OE_RRR(FDOUBLE_PACK1, 0, X0):
+        tcg_gen_mov_i64(tdest, tsrcb);
+        mnemonic = "fdouble_pack1";
+        break;
     case OE_RRR(FDOUBLE_PACK2, 0, X0):
+        gen_helper_fdouble_pack2(tdest, cpu_env,
+                                 load_gr(dc, dest), tsrca, tsrcb);
+        mnemonic = "fdouble_pack2";
+        break;
     case OE_RRR(FDOUBLE_SUB_FLAGS, 0, X0):
+        gen_helper_fdouble_sub_flags(tdest, cpu_env, tsrca, tsrcb);
+        mnemonic = "fdouble_sub_flags";
+        break;
     case OE_RRR(FDOUBLE_UNPACK_MAX, 0, X0):
+        gen_helper_fdouble_unpack_max(tdest, cpu_env, tsrca, tsrcb);
+        mnemonic = "fdouble_unpack_max";
+        break;
     case OE_RRR(FDOUBLE_UNPACK_MIN, 0, X0):
-        return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
+        gen_helper_fdouble_unpack_min(tdest, cpu_env, tsrca, tsrcb);
+        mnemonic = "fdouble_unpack_min";
+        break;
     case OE_RRR(FETCHADD4, 0, X1):
         gen_atomic_excp(dc, dest, tdest, tsrca, tsrcb,
                         TILEGX_EXCP_OPCODE_FETCHADD4);
@@ -955,12 +991,25 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned opext,
         mnemonic = "fetchor";
         break;
     case OE_RRR(FSINGLE_ADD1, 0, X0):
-    case OE_RRR(FSINGLE_ADDSUB2, 0, X0):
+        gen_helper_fsingle_add1(tdest, cpu_env, tsrca, tsrcb);
+        mnemonic = "fsingle_add1";
+        break;
     case OE_RRR(FSINGLE_MUL1, 0, X0):
+        gen_helper_fsingle_mul1(tdest, cpu_env, tsrca, tsrcb);
+        mnemonic = "fsingle_mul1";
+        break;
     case OE_RRR(FSINGLE_MUL2, 0, X0):
+        tcg_gen_mov_i64(tdest, tsrca);
+        mnemonic = "fsingle_mul2";
+        break;
     case OE_RRR(FSINGLE_PACK2, 0, X0):
+        gen_helper_fsingle_pack2(tdest, cpu_env, tsrca);
+        mnemonic = "fsingle_pack2";
+        break;
     case OE_RRR(FSINGLE_SUB1, 0, X0):
-        return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
+        gen_helper_fsingle_sub1(tdest, cpu_env, tsrca, tsrcb);
+        mnemonic = "fsingle_sub1";
+        break;
     case OE_RRR(MNZ, 0, X0):
     case OE_RRR(MNZ, 0, X1):
     case OE_RRR(MNZ, 4, Y0):
@@ -1464,6 +1513,7 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned opext,
         return TILEGX_EXCP_OPCODE_UNKNOWN;
     }
 
+done2:
     qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s %s, %s, %s", mnemonic,
                   reg_names[dest], reg_names[srca], reg_names[srcb]);
     return TILEGX_EXCP_NONE;
-- 
1.9.3

 		 	   		  

[-- Attachment #2: 0004-target-tilegx-Let-fpu-implementation-code-can-be-bui.patch --]
[-- Type: application/octet-stream, Size: 7646 bytes --]

From 8fab455a5ac5508d06cc69f778e926ad098fbe5b Mon Sep 17 00:00:00 2001
From: Chen Gang <gang.chen.5i5j@gmail.com>
Date: Sun, 8 Nov 2015 09:11:36 +0800
Subject: [PATCH 4/4] target-tilegx: Let fpu implementation code can be built
 and used

It passes gcc testsuite: it can get the same result as the original fpu
implementation have done.

Signed-off-by: Chen Gang <gang.chen.5i5j@gmail.com>
---
 target-tilegx/Makefile.objs |  3 +-
 target-tilegx/cpu.h         |  2 ++
 target-tilegx/helper.h      | 12 ++++++++
 target-tilegx/translate.c   | 68 +++++++++++++++++++++++++++++++++++++++------
 4 files changed, 75 insertions(+), 10 deletions(-)

diff --git a/target-tilegx/Makefile.objs b/target-tilegx/Makefile.objs
index 0db778f..c2cf2f1 100644
--- a/target-tilegx/Makefile.objs
+++ b/target-tilegx/Makefile.objs
@@ -1 +1,2 @@
-obj-y += cpu.o translate.o helper.o simd_helper.o
+obj-y += cpu.o translate.o helper.o simd_helper.o \
+		fsingle_helper.o fdouble_helper.o
diff --git a/target-tilegx/cpu.h b/target-tilegx/cpu.h
index 03df107..445a606 100644
--- a/target-tilegx/cpu.h
+++ b/target-tilegx/cpu.h
@@ -88,6 +88,8 @@ typedef struct CPUTLGState {
     uint64_t spregs[TILEGX_SPR_COUNT]; /* Special used registers by outside */
     uint64_t pc;                       /* Current pc */
 
+    float_status fp_status;            /* floating point status */
+
 #if defined(CONFIG_USER_ONLY)
     uint64_t excaddr;                  /* exception address */
     uint64_t atomic_srca;              /* Arguments to atomic "exceptions" */
diff --git a/target-tilegx/helper.h b/target-tilegx/helper.h
index 9281d0f..b785bf2 100644
--- a/target-tilegx/helper.h
+++ b/target-tilegx/helper.h
@@ -24,3 +24,15 @@ DEF_HELPER_FLAGS_2(v1shrs, TCG_CALL_NO_RWG_SE, i64, i64, i64)
 DEF_HELPER_FLAGS_2(v2shl, TCG_CALL_NO_RWG_SE, i64, i64, i64)
 DEF_HELPER_FLAGS_2(v2shru, TCG_CALL_NO_RWG_SE, i64, i64, i64)
 DEF_HELPER_FLAGS_2(v2shrs, TCG_CALL_NO_RWG_SE, i64, i64, i64)
+
+DEF_HELPER_3(fsingle_add1, i64, env, i64, i64)
+DEF_HELPER_3(fsingle_sub1, i64, env, i64, i64)
+DEF_HELPER_3(fsingle_mul1, i64, env, i64, i64)
+DEF_HELPER_2(fsingle_pack2, i64, env, i64)
+DEF_HELPER_3(fdouble_unpack_min, i64, env, i64, i64)
+DEF_HELPER_3(fdouble_unpack_max, i64, env, i64, i64)
+DEF_HELPER_3(fdouble_add_flags, i64, env, i64, i64)
+DEF_HELPER_3(fdouble_sub_flags, i64, env, i64, i64)
+DEF_HELPER_4(fdouble_addsub, i64, env, i64, i64, i64)
+DEF_HELPER_3(fdouble_mul_flags, i64, env, i64, i64)
+DEF_HELPER_4(fdouble_pack2, i64, env, i64, i64, i64)
diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
index b8ca401..4d74b1d 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -597,6 +597,11 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned opext,
         }
         qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s %s", mnemonic, reg_names[srca]);
         return ret;
+
+    case OE_RR_X0(FSINGLE_PACK1):
+    case OE_RR_Y0(FSINGLE_PACK1):
+        mnemonic = "fsingle_pack1";
+        goto done2;
     }
 
     tdest = dest_gr(dc, dest);
@@ -613,9 +618,6 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned opext,
         gen_helper_cnttz(tdest, tsrca);
         mnemonic = "cnttz";
         break;
-    case OE_RR_X0(FSINGLE_PACK1):
-    case OE_RR_Y0(FSINGLE_PACK1):
-        return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
     case OE_RR_X1(LD1S):
         memop = MO_SB;
         mnemonic = "ld1s"; /* prefetch_l1_fault */
@@ -734,6 +736,7 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned opext,
         return TILEGX_EXCP_OPCODE_UNKNOWN;
     }
 
+done2:
     qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s %s, %s", mnemonic,
                   reg_names[dest], reg_names[srca]);
     return ret;
@@ -742,13 +745,21 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned opext,
 static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned opext,
                                unsigned dest, unsigned srca, unsigned srcb)
 {
-    TCGv tdest = dest_gr(dc, dest);
-    TCGv tsrca = load_gr(dc, srca);
-    TCGv tsrcb = load_gr(dc, srcb);
+    TCGv tdest, tsrca, tsrcb;
     TCGv t0;
     const char *mnemonic;
 
     switch (opext) {
+    case OE_RRR(FSINGLE_ADDSUB2, 0, X0):
+        mnemonic = "fsingle_addsub2";
+        goto done2;
+    }
+
+    tdest = dest_gr(dc, dest);
+    tsrca = load_gr(dc, srca);
+    tsrcb = load_gr(dc, srcb);
+
+    switch (opext) {
     case OE_RRR(ADDXSC, 0, X0):
     case OE_RRR(ADDXSC, 0, X1):
         gen_saturate_op(tdest, tsrca, tsrcb, tcg_gen_add_tl);
@@ -906,14 +917,39 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned opext,
         mnemonic = "exch";
         break;
     case OE_RRR(FDOUBLE_ADDSUB, 0, X0):
+        gen_helper_fdouble_addsub(tdest, cpu_env,
+                                  load_gr(dc, dest),tsrca, tsrcb);
+        mnemonic = "fdouble_addsub";
+        break;
     case OE_RRR(FDOUBLE_ADD_FLAGS, 0, X0):
+        gen_helper_fdouble_add_flags(tdest, cpu_env, tsrca, tsrcb);
+        mnemonic = "fdouble_add_flags";
+        break;
     case OE_RRR(FDOUBLE_MUL_FLAGS, 0, X0):
+        gen_helper_fdouble_mul_flags(tdest, cpu_env, tsrca, tsrcb);
+        mnemonic = "fdouble_mul_flags";
+        break;
     case OE_RRR(FDOUBLE_PACK1, 0, X0):
+        tcg_gen_mov_i64(tdest, tsrcb);
+        mnemonic = "fdouble_pack1";
+        break;
     case OE_RRR(FDOUBLE_PACK2, 0, X0):
+        gen_helper_fdouble_pack2(tdest, cpu_env,
+                                 load_gr(dc, dest), tsrca, tsrcb);
+        mnemonic = "fdouble_pack2";
+        break;
     case OE_RRR(FDOUBLE_SUB_FLAGS, 0, X0):
+        gen_helper_fdouble_sub_flags(tdest, cpu_env, tsrca, tsrcb);
+        mnemonic = "fdouble_sub_flags";
+        break;
     case OE_RRR(FDOUBLE_UNPACK_MAX, 0, X0):
+        gen_helper_fdouble_unpack_max(tdest, cpu_env, tsrca, tsrcb);
+        mnemonic = "fdouble_unpack_max";
+        break;
     case OE_RRR(FDOUBLE_UNPACK_MIN, 0, X0):
-        return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
+        gen_helper_fdouble_unpack_min(tdest, cpu_env, tsrca, tsrcb);
+        mnemonic = "fdouble_unpack_min";
+        break;
     case OE_RRR(FETCHADD4, 0, X1):
         gen_atomic_excp(dc, dest, tdest, tsrca, tsrcb,
                         TILEGX_EXCP_OPCODE_FETCHADD4);
@@ -955,12 +991,25 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned opext,
         mnemonic = "fetchor";
         break;
     case OE_RRR(FSINGLE_ADD1, 0, X0):
-    case OE_RRR(FSINGLE_ADDSUB2, 0, X0):
+        gen_helper_fsingle_add1(tdest, cpu_env, tsrca, tsrcb);
+        mnemonic = "fsingle_add1";
+        break;
     case OE_RRR(FSINGLE_MUL1, 0, X0):
+        gen_helper_fsingle_mul1(tdest, cpu_env, tsrca, tsrcb);
+        mnemonic = "fsingle_mul1";
+        break;
     case OE_RRR(FSINGLE_MUL2, 0, X0):
+        tcg_gen_mov_i64(tdest, tsrca);
+        mnemonic = "fsingle_mul2";
+        break;
     case OE_RRR(FSINGLE_PACK2, 0, X0):
+        gen_helper_fsingle_pack2(tdest, cpu_env, tsrca);
+        mnemonic = "fsingle_pack2";
+        break;
     case OE_RRR(FSINGLE_SUB1, 0, X0):
-        return TILEGX_EXCP_OPCODE_UNIMPLEMENTED;
+        gen_helper_fsingle_sub1(tdest, cpu_env, tsrca, tsrcb);
+        mnemonic = "fsingle_sub1";
+        break;
     case OE_RRR(MNZ, 0, X0):
     case OE_RRR(MNZ, 0, X1):
     case OE_RRR(MNZ, 4, Y0):
@@ -1464,6 +1513,7 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned opext,
         return TILEGX_EXCP_OPCODE_UNKNOWN;
     }
 
+done2:
     qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s %s, %s, %s", mnemonic,
                   reg_names[dest], reg_names[srca], reg_names[srcb]);
     return TILEGX_EXCP_NONE;
-- 
1.9.3


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH 1/4] target-tilegx: Add fpu header file
  2015-11-08  5:43 ` [Qemu-devel] [PATCH 1/4] target-tilegx: Add fpu header file Chen Gang
@ 2015-11-12 14:34   ` Richard Henderson
  2015-11-12 16:04     ` Chen Gang
  0 siblings, 1 reply; 13+ messages in thread
From: Richard Henderson @ 2015-11-12 14:34 UTC (permalink / raw)
  To: Chen Gang, Peter Maydell, Chris Metcalf; +Cc: qemu-devel

On 11/08/2015 06:43 AM, Chen Gang wrote:

> +#if !defined(HOST_WORDS_BIGENDIAN)
> +    /* According to float(uns)sisf2 and float(uns)sidf2 in gcc tilegx.md */
> +    uint64_t exp : 8;             /* exp, 0x9e: 31 + TILEGX_F_EXP_FZERO */
> +    uint64_t uiknown0 : 2;        /* unknown */

I would really rather you didn't use bitfields, because of exactly this sort of 
endianness problem.  Because, really, you can't trust this layout.  But I won't 
press this point, because it is complicated enough already.

> +#endif
> +} TileGXFPSFmt;
> +/*

Watch your spacing.

> + * Double exp analyzing: (0x21b00 << 1) - 0x36(54) = 0x400
> + *
> + *   17  16  15  14  13  12  11  10   9   8   7    6   5   4   3   2   1   0
> + *
> + *    1   0   0   0   0   1   1   0   1   1   0    0   0   0   0   0   0   0
> + *
> + *    0   0   0   0   0   1   1   0   1   1   1    => 0x37(55)
> + *
> + *    0   1   1   1   1   1   1   1   1   1   1    => 0x3ff

What is this table supposed to mean?

> +#if 0
> +        uint64_t exp : 11;        /* exp, 0x21b << 1: 55 + TILEGX_F_EXP_DZERO */
> +        uint64_t ov : 1;          /* overflow for mul, low priority */
> +        uint64_t uv : 1;          /* underflow for mul, high priority */
> +#endif


No if 0.

> +#pragma pack(pop)

Huh?  What are you attempting to do here?


r~

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH 2/4] target-tilegx: Implement fpu single floating point
  2015-11-08  5:44 ` [Qemu-devel] [PATCH 2/4] target-tilegx: Implement fpu single floating point Chen Gang
@ 2015-11-12 14:36   ` Richard Henderson
  2015-11-12 16:12     ` Chen Gang
  0 siblings, 1 reply; 13+ messages in thread
From: Richard Henderson @ 2015-11-12 14:36 UTC (permalink / raw)
  To: Chen Gang, Peter Maydell, Chris Metcalf; +Cc: qemu-devel

> +    if (sfmt.calc == TILEGX_F_CALC_CVT) {
> +        if (sfmt.sign)
> +            f.f = int32_to_float32(0 - sfmt.mantissa, fp_status);
> +        else
> +            f.f = uint32_to_float32(sfmt.mantissa, fp_status);
> +    } else {

Formatting.

You really should know better by now.
I'm not even going to look at the rest.


r~

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH 1/4] target-tilegx: Add fpu header file
  2015-11-12 14:34   ` Richard Henderson
@ 2015-11-12 16:04     ` Chen Gang
  2015-11-12 16:10       ` Peter Maydell
  0 siblings, 1 reply; 13+ messages in thread
From: Chen Gang @ 2015-11-12 16:04 UTC (permalink / raw)
  To: Richard Henderson, Peter Maydell, Chris Metcalf; +Cc: qemu-devel

On 11/12/15 22:34, Richard Henderson wrote:
> On 11/08/2015 06:43 AM, Chen Gang wrote:
> 
>> +#if !defined(HOST_WORDS_BIGENDIAN)
>> +    /* According to float(uns)sisf2 and float(uns)sidf2 in gcc tilegx.md */
>> +    uint64_t exp : 8;             /* exp, 0x9e: 31 + TILEGX_F_EXP_FZERO */
>> +    uint64_t uiknown0 : 2;        /* unknown */
> 
> I would really rather you didn't use bitfields, because of exactly this sort of endianness problem.  Because, really, you can't trust this layout.  But I won't press this point, because it is complicated enough already.
> 

Because of endianess issues, for me, I don't like bit fields either. But
I can not find any other simpler ways than current.

>> +#endif
>> +} TileGXFPSFmt;
>> +/*
> 
> Watch your spacing.
> 

OK, thanks. And I also shall let the related comments above the structure.


>> + * Double exp analyzing: (0x21b00 << 1) - 0x36(54) = 0x400

Oh, it should be (0x21b00 << 1) - 0x37(55) = 0x3ff

>> + *
>> + *   17  16  15  14  13  12  11  10   9   8   7    6   5   4   3   2   1   0
>> + *
>> + *    1   0   0   0   0   1   1   0   1   1   0    0   0   0   0   0   0   0
>> + *
>> + *    0   0   0   0   0   1   1   0   1   1   1    => 0x37(55)
>> + *
>> + *    0   1   1   1   1   1   1   1   1   1   1    => 0x3ff
> 
> What is this table supposed to mean?
> 

I want to use this table to explain my guess: at first, we don't know
the internal exp position, neither know the internal mantasa bits. We
have to guess both of them:

 - the real exp should not be less than 11 bits (IEEE double exp is 11
   bits).

 - Since IEEE double exp 0 is 0x3ff, probobly, for tilegx internally,
   0x3ff shoul be '0', too (don't move mantissa).

 - After analyzing the data from floatunssidf2 in gcc tilegx.md (the
   table above is part for it), I found that "(0x21b00 << 1) - 0x37 =
   0x3ff" is the best to match "all things".

So, I guess: the double exp is from bit 7 to bit 17, then the mantissa
is 60 bits (55 + 1 + 4), it from bit 0 to bit 59.

We can use 7 - 19 bits for normal exp calculation, then can get the real
exp (7 - 17 bits) with the overflow and underflow (so, I guess 18 bit is
for overflow, and 19 bit is for underflow).

>> +#if 0
>> +        uint64_t exp : 11;        /* exp, 0x21b << 1: 55 + TILEGX_F_EXP_DZERO */
>> +        uint64_t ov : 1;          /* overflow for mul, low priority */
>> +        uint64_t uv : 1;          /* underflow for mul, high priority */
>> +#endif
> 
> 
> No if 0.
> 

OK, I shall remove them.

>> +#pragma pack(pop)
> 
> Huh?  What are you attempting to do here?
> 

It is for matching "#pragma pack(push, 1)" which is above all related
struct/unions in this header file.

For the bit fields, we use uint64_t, but gcc still treate it as two
uint32_t, so for safety reason, I use pragma pack for our structures.

Thanks.
-- 
Chen Gang (陈刚)

Open, share, and attitude like air, water, and life which God blessed

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH 1/4] target-tilegx: Add fpu header file
  2015-11-12 16:04     ` Chen Gang
@ 2015-11-12 16:10       ` Peter Maydell
  2015-11-12 16:28         ` Chen Gang
  0 siblings, 1 reply; 13+ messages in thread
From: Peter Maydell @ 2015-11-12 16:10 UTC (permalink / raw)
  To: Chen Gang; +Cc: Chris Metcalf, qemu-devel, Richard Henderson

On 12 November 2015 at 16:04, Chen Gang <xili_gchen_5257@hotmail.com> wrote:
> On 11/12/15 22:34, Richard Henderson wrote:
>> On 11/08/2015 06:43 AM, Chen Gang wrote:
>>
>>> +#if !defined(HOST_WORDS_BIGENDIAN)
>>> +    /* According to float(uns)sisf2 and float(uns)sidf2 in gcc tilegx.md */
>>> +    uint64_t exp : 8;             /* exp, 0x9e: 31 + TILEGX_F_EXP_FZERO */
>>> +    uint64_t uiknown0 : 2;        /* unknown */
>>
>> I would really rather you didn't use bitfields, because of exactly this sort of endianness problem.  Because, really, you can't trust this layout.  But I won't press this point, because it is complicated enough already.
>>
>
> Because of endianess issues, for me, I don't like bit fields either. But
> I can not find any other simpler ways than current.

> OK, I shall remove them.
>
>>> +#pragma pack(pop)
>>
>> Huh?  What are you attempting to do here?
>>
>
> It is for matching "#pragma pack(push, 1)" which is above all related
> struct/unions in this header file.

Please don't use 'pragma pack' or bitfields. If you need to pack
and unpack things from a target-CPU defined field use bit operations
and/or extract32/deposit32/extract64/deposit64.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH 2/4] target-tilegx: Implement fpu single floating point
  2015-11-12 14:36   ` Richard Henderson
@ 2015-11-12 16:12     ` Chen Gang
  2015-11-12 16:18       ` Richard Henderson
  0 siblings, 1 reply; 13+ messages in thread
From: Chen Gang @ 2015-11-12 16:12 UTC (permalink / raw)
  To: Richard Henderson, Peter Maydell, Chris Metcalf; +Cc: qemu-devel

On 11/12/15 22:36, Richard Henderson wrote:
>> +    if (sfmt.calc == TILEGX_F_CALC_CVT) {
>> +        if (sfmt.sign)
>> +            f.f = int32_to_float32(0 - sfmt.mantissa, fp_status);
>> +        else
>> +            f.f = uint32_to_float32(sfmt.mantissa, fp_status);
>> +    } else {
> 
> Formatting.
> 
> You really should know better by now.
> I'm not even going to look at the rest.
> 

Excuse me, my English is not quite well, I am not quite understand your
meaning.

Does the code above have issues?

Thanks.
-- 
Chen Gang (陈刚)

Open, share, and attitude like air, water, and life which God blessed

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH 2/4] target-tilegx: Implement fpu single floating point
  2015-11-12 16:12     ` Chen Gang
@ 2015-11-12 16:18       ` Richard Henderson
  2015-11-12 16:29         ` Chen Gang
  0 siblings, 1 reply; 13+ messages in thread
From: Richard Henderson @ 2015-11-12 16:18 UTC (permalink / raw)
  To: Chen Gang, Peter Maydell, Chris Metcalf; +Cc: qemu-devel

On 11/12/2015 05:12 PM, Chen Gang wrote:
> On 11/12/15 22:36, Richard Henderson wrote:
>>> +    if (sfmt.calc == TILEGX_F_CALC_CVT) {
>>> +        if (sfmt.sign)
>>> +            f.f = int32_to_float32(0 - sfmt.mantissa, fp_status);
>>> +        else
>>> +            f.f = uint32_to_float32(sfmt.mantissa, fp_status);
>>> +    } else {
>>
>> Formatting.
>>
>> You really should know better by now.
>> I'm not even going to look at the rest.
>>
>
> Excuse me, my English is not quite well, I am not quite understand your
> meaning.
>
> Does the code above have issues?
>

Please read ./CODING_STYLE, and use ./scripts/checkpatch.pl.


r~

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH 1/4] target-tilegx: Add fpu header file
  2015-11-12 16:10       ` Peter Maydell
@ 2015-11-12 16:28         ` Chen Gang
  0 siblings, 0 replies; 13+ messages in thread
From: Chen Gang @ 2015-11-12 16:28 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Chris Metcalf, qemu-devel, Richard Henderson

On 11/13/15 00:10, Peter Maydell wrote:
> On 12 November 2015 at 16:04, Chen Gang <xili_gchen_5257@hotmail.com> wrote:
>> On 11/12/15 22:34, Richard Henderson wrote:
>>> On 11/08/2015 06:43 AM, Chen Gang wrote:
>>>
>>>> +#if !defined(HOST_WORDS_BIGENDIAN)
>>>> +    /* According to float(uns)sisf2 and float(uns)sidf2 in gcc tilegx.md */
>>>> +    uint64_t exp : 8;             /* exp, 0x9e: 31 + TILEGX_F_EXP_FZERO */
>>>> +    uint64_t uiknown0 : 2;        /* unknown */
>>>
>>> I would really rather you didn't use bitfields, because of exactly this sort of endianness problem.  Because, really, you can't trust this layout.  But I won't press this point, because it is complicated enough already.
>>>
>>
>> Because of endianess issues, for me, I don't like bit fields either. But
>> I can not find any other simpler ways than current.
> 
>> OK, I shall remove them.
>>
>>>> +#pragma pack(pop)
>>>
>>> Huh?  What are you attempting to do here?
>>>
>>
>> It is for matching "#pragma pack(push, 1)" which is above all related
>> struct/unions in this header file.
> 
> Please don't use 'pragma pack' or bitfields. If you need to pack
> and unpack things from a target-CPU defined field use bit operations
> and/or extract32/deposit32/extract64/deposit64.
> 

OK, thanks, although it means I have to rewrite most of code, and test
them again. I shall try to send patch v2 within the next week.

Thanks.
-- 
Chen Gang (陈刚)

Open, share, and attitude like air, water, and life which God blessed

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH 2/4] target-tilegx: Implement fpu single floating point
  2015-11-12 16:18       ` Richard Henderson
@ 2015-11-12 16:29         ` Chen Gang
  0 siblings, 0 replies; 13+ messages in thread
From: Chen Gang @ 2015-11-12 16:29 UTC (permalink / raw)
  To: Richard Henderson, Peter Maydell, Chris Metcalf; +Cc: qemu-devel

On 11/13/15 00:18, Richard Henderson wrote:
> On 11/12/2015 05:12 PM, Chen Gang wrote:
>> On 11/12/15 22:36, Richard Henderson wrote:
>>>> +    if (sfmt.calc == TILEGX_F_CALC_CVT) {
>>>> +        if (sfmt.sign)
>>>> +            f.f = int32_to_float32(0 - sfmt.mantissa, fp_status);
>>>> +        else
>>>> +            f.f = uint32_to_float32(sfmt.mantissa, fp_status);
>>>> +    } else {
>>>
>>> Formatting.
>>>
>>> You really should know better by now.
>>> I'm not even going to look at the rest.
>>>
>>
>> Excuse me, my English is not quite well, I am not quite understand your
>> meaning.
>>
>> Does the code above have issues?
>>
> 
> Please read ./CODING_STYLE, and use ./scripts/checkpatch.pl.
> 

Oh, sorry.



Thanks.
-- 
Chen Gang (陈刚)

Open, share, and attitude like air, water, and life which God blessed

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2015-11-12 16:26 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-08  5:42 [Qemu-devel] [PATCH 0/4] Implment fpu floating point instructions Chen Gang
2015-11-08  5:43 ` [Qemu-devel] [PATCH 1/4] target-tilegx: Add fpu header file Chen Gang
2015-11-12 14:34   ` Richard Henderson
2015-11-12 16:04     ` Chen Gang
2015-11-12 16:10       ` Peter Maydell
2015-11-12 16:28         ` Chen Gang
2015-11-08  5:44 ` [Qemu-devel] [PATCH 2/4] target-tilegx: Implement fpu single floating point Chen Gang
2015-11-12 14:36   ` Richard Henderson
2015-11-12 16:12     ` Chen Gang
2015-11-12 16:18       ` Richard Henderson
2015-11-12 16:29         ` Chen Gang
2015-11-08  5:46 ` [Qemu-devel] [PATCH 3/4] target-tilegx: Implement fpu fdouble " Chen Gang
2015-11-08  5:47 ` [Qemu-devel] [PATCH 4/4] target-tilegx: Let fpu implementation code can be built and used Chen Gang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.