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 */
