qemu-devel.nongnu.org archive mirror
 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@twiddle.net, 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@twiddle.net, 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 related	[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@twiddle.net, 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 related	[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@twiddle.net, 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 related	[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@twiddle.net, 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 related	[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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).