Skip to content

Commit

Permalink
Add ARM-specific Bfloat format support to middle-end
Browse files Browse the repository at this point in the history
2019-12-11  Stam Markianos-Wright  <[email protected]>

	* real.c (struct arm_bfloat_half_format,
	encode_arm_bfloat_half, decode_arm_bfloat_half): New.
	* real.h (arm_bfloat_half_format): New.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@279216 138bc75d-0d04-0410-961f-82ee72b054a4
  • Loading branch information
ktkachov committed Dec 11, 2019
1 parent 60961fc commit ecca7d0
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 0 deletions.
6 changes: 6 additions & 0 deletions gcc/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
2019-12-11 Stam Markianos-Wright <[email protected]>

* real.c (struct arm_bfloat_half_format,
encode_arm_bfloat_half, decode_arm_bfloat_half): New.
* real.h (arm_bfloat_half_format): New.

2019-12-11 Hongtao Liu <[email protected]>

PR target/92865
Expand Down
137 changes: 137 additions & 0 deletions gcc/real.c
Original file line number Diff line number Diff line change
Expand Up @@ -4799,6 +4799,116 @@ decode_ieee_half (const struct real_format *fmt, REAL_VALUE_TYPE *r,
}
}

/* Encode arm_bfloat types. */
static void
encode_arm_bfloat_half (const struct real_format *fmt, long *buf,
const REAL_VALUE_TYPE *r)
{
unsigned long image, sig, exp;
unsigned long sign = r->sign;
bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0;

image = sign << 15;
sig = (r->sig[SIGSZ-1] >> (HOST_BITS_PER_LONG - 8)) & 0x7f;

switch (r->cl)
{
case rvc_zero:
break;

case rvc_inf:
if (fmt->has_inf)
image |= 255 << 7;
else
image |= 0x7fff;
break;

case rvc_nan:
if (fmt->has_nans)
{
if (r->canonical)
sig = (fmt->canonical_nan_lsbs_set ? (1 << 6) - 1 : 0);
if (r->signalling == fmt->qnan_msb_set)
sig &= ~(1 << 6);
else
sig |= 1 << 6;
if (sig == 0)
sig = 1 << 5;

image |= 255 << 7;
image |= sig;
}
else
image |= 0x7fff;
break;

case rvc_normal:
if (denormal)
exp = 0;
else
exp = REAL_EXP (r) + 127 - 1;
image |= exp << 7;
image |= sig;
break;

default:
gcc_unreachable ();
}

buf[0] = image;
}

/* Decode arm_bfloat types. */
static void
decode_arm_bfloat_half (const struct real_format *fmt, REAL_VALUE_TYPE *r,
const long *buf)
{
unsigned long image = buf[0] & 0xffff;
bool sign = (image >> 15) & 1;
int exp = (image >> 7) & 0xff;

memset (r, 0, sizeof (*r));
image <<= HOST_BITS_PER_LONG - 8;
image &= ~SIG_MSB;

if (exp == 0)
{
if (image && fmt->has_denorm)
{
r->cl = rvc_normal;
r->sign = sign;
SET_REAL_EXP (r, -126);
r->sig[SIGSZ-1] = image << 1;
normalize (r);
}
else if (fmt->has_signed_zero)
r->sign = sign;
}
else if (exp == 255 && (fmt->has_nans || fmt->has_inf))
{
if (image)
{
r->cl = rvc_nan;
r->sign = sign;
r->signalling = (((image >> (HOST_BITS_PER_LONG - 2)) & 1)
^ fmt->qnan_msb_set);
r->sig[SIGSZ-1] = image;
}
else
{
r->cl = rvc_inf;
r->sign = sign;
}
}
else
{
r->cl = rvc_normal;
r->sign = sign;
SET_REAL_EXP (r, exp - 127 + 1);
r->sig[SIGSZ-1] = image | SIG_MSB;
}
}

/* Half-precision format, as specified in IEEE 754R. */
const struct real_format ieee_half_format =
{
Expand Down Expand Up @@ -4848,6 +4958,33 @@ const struct real_format arm_half_format =
false,
"arm_half"
};

/* ARM Bfloat half-precision format. This format resembles a truncated
(16-bit) version of the 32-bit IEEE 754 single-precision floating-point
format. */
const struct real_format arm_bfloat_half_format =
{
encode_arm_bfloat_half,
decode_arm_bfloat_half,
2,
8,
8,
-125,
128,
15,
15,
0,
false,
true,
true,
true,
true,
true,
true,
false,
"arm_bfloat_half"
};


/* A synthetic "format" for internal arithmetic. It's the size of the
internal significand minus the two bits needed for proper rounding.
Expand Down
1 change: 1 addition & 0 deletions gcc/real.h
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ extern const struct real_format decimal_double_format;
extern const struct real_format decimal_quad_format;
extern const struct real_format ieee_half_format;
extern const struct real_format arm_half_format;
extern const struct real_format arm_bfloat_half_format;


/* ====================================================================== */
Expand Down

0 comments on commit ecca7d0

Please sign in to comment.