new file mode 100644
@@ -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 */