qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [Consult] tilegx: About floating point instructions


From: Chen Gang
Subject: Re: [Qemu-devel] [Consult] tilegx: About floating point instructions
Date: Sun, 25 Oct 2015 23:38:41 +0800
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:31.0) Gecko/20100101 Thunderbird/31.7.0

On 8/18/15 01:31, Richard Henderson wrote:
> 
> For single-precision it appears that the format is
> 
>   63                                      31          24   10  9     0
>   [ mantissa with implicit and guard bits | cmp flags | ?? | s | exp ]
> 
> We are able to deduce the bias for the exponent based on the input gcc gives 
> us
> for floatunssisf: 0x9e == 2**31 when the mantissa is normalized.
>

For me, 0x9e == 2**30:

 - For int32_t: 31-bits for values, highest bit for sign. Mantissa can
   'move' 30 bits to express 31-bits values, and 31st bit will never
   'move'.

 - 0x9e - 0x1e(30) = 0x80, which is the smallest 8-bits number, in our
   case, 0x80 means: "do not 'move' mantissa bits".

 - According to IEEE standard, the exp of float type is 8-bits, so 0x80
   is really the smallest value of exp.

/*
 * 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   0    => 0x1e(30)
 *
 *   1   0   0   0   0   0   0   0    => 0x80
 */

[...]
 
> 
> For double-precision things are more complicated.  Precisely because there is
> no dedicated fdouble_mul[1-4] instructions, but instead gcc is to use a normal
> 128-bit integer multiplication on the mantissa.
> 
> For double-precision it appears that the format is
> 
>          63               57                           4            0
>   unpack [ overflow bits? | mantissa with implicit bit | guard bits ]
> 
>          63   31          24   20  19    8    0
>   flags  [ ?? | cmp flags | ?? | s | exp | ?? ]
> 
> Similarly we can compute the bias for exp as 0x21b == 2**53.
> Or is it 20 bits of exponent and 0x21b00 == 2**53?
> 

For me, exp is (0x21b << 1):

 - According to IEEE standard for double, it's exp is 11 bits, the
   smallest exp is 0x400.

 - So for 0x21b00, we can only consider about bits between 0 and 17 (the
   highest bit must be 1).

 - And it is 11 bits, so the real value of 0x21b00 is (0x21b << 1). Then
   we know it 'move' 0x36(54) bits to get integer, then we know fdouble
   mantissa have 55-bits internally.

/*
 * Double exp analyzing: (0x21b << 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   0    => 0x36(54)
 *
 *    1   0   0   0   0   0   0   0   0   0   0    => 0x400
 *
 */

So for me, the format in C header file is:

#pragma pack(push, 1)

/*
 * Single format, it is 64-bit.
 */
typedef struct TileGXFPSFmt {

    /* According to float(uns)sisf2 and float(uns)sidf2 in gcc tilegx.md */
    uint64_t exp : 8;             /* exp, 0x9e: 30 + TILEGX_F_EXP_FZERO */
    uint64_t unknown0 : 1;        /* unknown */
    uint64_t sign : 1;            /* Sign bit for the total value */
    uint64_t unknown1 : 15;       /* 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 : 31;       /* mantissa */
    uint64_t unknown2 : 1;        /* unknown */
} TileGXFPSFmt;

/*
 * Dobule format, flag, 64-bit.
 */
typedef struct TileGXFPDFmtF {

    uint64_t unknown0 : 7;        /* unknown */
    uint64_t exp : 11;            /* exp, 0x21b << 1: 54 + TILEGX_F_EXP_DZERO */
    uint64_t unknown1 : 2;        /* unknown */
    uint64_t sign : 1;            /* Sign bit for the total value */
    uint64_t unknown2: 4;         /* 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 */

    uint64_t unknown3 : 32;       /* unknown */
} TileGXFPDFmtF;

/*
 * Dobule format, value, 64-bit.
 */
typedef struct TileGXFPDFmtV {
    uint64_t unknown0 : 4;        /* unknown */
    uint64_t mantissa : 55;       /* mantissa */
    uint64_t unknown1 : 5;        /* unknown */
} TileGXFPDFmtV;

#pragma pack(pop)


Welcome any ideas, suggestions, and completions from any members.

Thanks.
-- 
Chen Gang (陈刚)

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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]