<html>
<head>
<style>
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
FONT-SIZE: 10pt;
FONT-FAMILY:Tahoma
}
</style>
</head>
<body class='hmmessage'>
Tony, the way floats/doubles are read/used by parse.c is definitely wrong.<BR>
Gcc wants an array of longs.<BR>
At the very least, the current code hits alignment faults on OpenBSD/sparc64.<BR>
  32 bit architectures would be ok, as would AMD64.<BR>
 <BR>
As well, gcc wants 32 bits per long -- even if the longs are larger than that.<BR>
So even on AMD64 it is probably reading garbage.<BR>
 <BR>
So how about something like this:<BR>
 <BR>
static tree<BR>scan_float (unsigned *fkind)<BR>{<BR>  unsigned long i = get_int ();<BR>  long n_bytes;<BR>  long longs[(sizeof(long double) + sizeof(long) - 1) / sizeof(long)] = { 0 };<BR>
  tree tipe;<BR>  REAL_VALUE_TYPE val;<BR>
 <BR>
  *fkind = i;<BR>  switch (i) {<BR>  case 0:  tipe = t_reel;  n_bytes = REEL_BYTES;  break;<BR>  case 1:  tipe = t_lreel; n_bytes = LREEL_BYTES; break;<BR>  case 2:  tipe = t_xreel; n_bytes = XREEL_BYTES; break;<BR>  default:<BR>    fatal_error(" *** invalid floating point value, precision = 0x%lx, at m3cg_lineno %d",<BR>                i, m3cg_lineno);<BR>  }<BR>
 <BR>
  /* read the value's bytes; each long holds 32 bits */<BR>  for (i = 0;  i < n_bytes;  i++)<BR>  {<BR>      longs[i / 4] |= ((0xFF & get_int ()) << ((i % 4) * 8));<BR>  }<BR>
 <BR>
  /* finally, assemble a floating point value */<BR>  if (tipe == t_reel) {<BR>    real_from_target_fmt (&val, longs, &ieee_single_format);<BR>  } else {<BR>    real_from_target_fmt (&val, longs, &ieee_double_format);<BR>  }<BR>  return build_real (tipe, val);<BR>}<BR><BR>I'd also feel better if get_int returned an unsigned type but don't have enough evidence there yet to change it.<BR>
 <BR>
And this looks suspicous:<BR>
 <BR>
#define INTEGER(x) long x = get_int()<BR>#define UNUSED_INTEGER(x) int x ATTRIBUTE_UNUSED = get_int()<BR>static long<BR>get_int (void)<BR>{<BR>  long i, n_bytes, sign, val, shift;<BR>
  i = (long) get_byte ();<BR>  switch (i) {<BR>  case M3CG_Int1:   return (long) get_byte ();<BR>  case M3CG_NInt1:  return - (long) get_byte ();<BR>  case M3CG_Int2:   n_bytes = 2;  sign =  1;  break;<BR>  case M3CG_NInt2:  n_bytes = 2;  sign = -1;  break;<BR>  case M3CG_Int4:   n_bytes = 4;  sign =  1;  break;<BR>  case M3CG_NInt4:  n_bytes = 4;  sign = -1;  break;<BR>  case M3CG_Int8:   n_bytes = 8;  sign =  1;  break;<BR>  case M3CG_NInt8:  n_bytes = 8;  sign = -1;  break;<BR>  default:          return i;<BR>  }<BR>
  for (val = 0, shift = 0; n_bytes > 0;  n_bytes--, shift += 8) {<BR>    val = val | (((long) get_byte ()) << shift);<BR>  }<BR>  return sign * val;<BR>}<BR><BR>
 <BR>
8 bytes in a long?<BR>
I think it needs to be a high and low host wide int, or at least a host wide int and assume that is 64 bits.<BR>
But I haven't debugged this either, just went groveling for "long".<BR>
Oh, scan_target_int looks better.<BR>
Probably get_int is guaranteeably only up to 32 bits and the "8" cases should fail an assertion?<BR>or get_int is guaranteed to fit in a host long, so should only assert on the 8 cases if a long is smaller than 8 bytes?<BR>
 <BR>
It appears that cm3 and cm3cg must be on the same host, that the IL format is not "portable".<BR>
Because of the endianness of the float/double constants.<BR>
But I'm not 100% sure.<BR>
 <BR>
If you don't have time to look at, fix, test this, I will.<BR>
Just that, you know, I can be both lazy and respectful at the same time. :)<BR>
 <BR>
Thank,<BR> - Jay<BR></body>
</html>