Skip to content

Commit

Permalink
* pack.c (pack_pack): use union instead of bare variable to ease
Browse files Browse the repository at this point in the history
  optimizations and avoid assigning x87 floating point number.
  [ruby-core:74496] [Bug #12209]

* pack.c (pack_unpack): ditto.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55573 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information
nurse committed Jul 5, 2016
1 parent c73eb62 commit e90e916
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 149 deletions.
8 changes: 8 additions & 0 deletions ChangeLog
@@ -1,3 +1,11 @@
Tue Jul 5 11:07:14 2016 NARUSE, Yui <naruse@ruby-lang.org>

* pack.c (pack_pack): use union instead of bare variable to ease
optimizations and avoid assigning x87 floating point number.
[ruby-core:74496] [Bug #12209]

* pack.c (pack_unpack): ditto.

Mon Jul 4 13:56:34 2016 NARUSE, Yui <naruse@ruby-lang.org>

* process.c: define sig_t if not exist.
Expand Down
203 changes: 54 additions & 149 deletions pack.c
Expand Up @@ -68,59 +68,18 @@ static const char endstr[] = "sSiIlLqQjJ";
# define NATINT_LEN(type,len) ((int)sizeof(type))
#endif

#define define_swapx(x, xtype) \
static xtype \
TOKEN_PASTE(swap,x)(xtype z) \
{ \
xtype r; \
xtype *zp; \
unsigned char *s, *t; \
int i; \
\
zp = xmalloc(sizeof(xtype)); \
*zp = z; \
s = (unsigned char*)zp; \
t = xmalloc(sizeof(xtype)); \
for (i=0; i<sizeof(xtype); i++) { \
t[sizeof(xtype)-i-1] = s[i]; \
} \
r = *(xtype *)t; \
xfree(t); \
xfree(zp); \
return r; \
}

#if SIZEOF_FLOAT == 4 && defined(HAVE_INT32_T)
# define swapf(x) swap32(x)
# define FLOAT_SWAPPER uint32_t
#else
define_swapx(f,float)
#endif

#if SIZEOF_DOUBLE == 8 && defined(HAVE_INT64_T)
# define swapd(x) swap64(x)
# define DOUBLE_SWAPPER uint64_t
#elif SIZEOF_DOUBLE == 8 && defined(HAVE_INT32_T)
static double
swapd(const double d)
{
double dtmp = d;
uint32_t utmp[2];
uint32_t utmp0;

utmp[0] = 0; utmp[1] = 0;
memcpy(utmp,&dtmp,sizeof(double));
utmp0 = utmp[0];
utmp[0] = swap32(utmp[1]);
utmp[1] = swap32(utmp0);
memcpy(&dtmp,utmp,sizeof(double));
return dtmp;
}
#else
define_swapx(d, double)
#endif

#undef define_swapx
typedef union {
float f;
uint32_t u;
char buf[4];
} FLOAT_SWAPPER;
typedef union {
double d;
uint64_t u;
char buf[8];
} DOUBLE_SWAPPER;
#define swapf(x) swap32(x)
#define swapd(x) swap64(x)

#define rb_ntohf(x) (BIGENDIAN_P()?(x):swapf(x))
#define rb_ntohd(x) (BIGENDIAN_P()?(x):swapd(x))
Expand All @@ -131,57 +90,17 @@ TOKEN_PASTE(swap,x)(xtype z) \
#define rb_vtohf(x) (BIGENDIAN_P()?swapf(x):(x))
#define rb_vtohd(x) (BIGENDIAN_P()?swapd(x):(x))

#ifdef FLOAT_SWAPPER
# define FLOAT_CONVWITH(y) FLOAT_SWAPPER y;
# define HTONF(x,y) (memcpy(&(y),&(x),sizeof(float)), \
(y) = rb_htonf((FLOAT_SWAPPER)(y)), \
memcpy(&(x),&(y),sizeof(float)), \
(x))
# define HTOVF(x,y) (memcpy(&(y),&(x),sizeof(float)), \
(y) = rb_htovf((FLOAT_SWAPPER)(y)), \
memcpy(&(x),&(y),sizeof(float)), \
(x))
# define NTOHF(x,y) (memcpy(&(y),&(x),sizeof(float)), \
(y) = rb_ntohf((FLOAT_SWAPPER)(y)), \
memcpy(&(x),&(y),sizeof(float)), \
(x))
# define VTOHF(x,y) (memcpy(&(y),&(x),sizeof(float)), \
(y) = rb_vtohf((FLOAT_SWAPPER)(y)), \
memcpy(&(x),&(y),sizeof(float)), \
(x))
#else
# define FLOAT_CONVWITH(y)
# define HTONF(x,y) rb_htonf(x)
# define HTOVF(x,y) rb_htovf(x)
# define NTOHF(x,y) rb_ntohf(x)
# define VTOHF(x,y) rb_vtohf(x)
#endif
#define FLOAT_CONVWITH(x) FLOAT_SWAPPER x;
#define HTONF(x) ((x).u = rb_htonf((x).u))
#define HTOVF(x) ((x).u = rb_htovf((x).u))
#define NTOHF(x) ((x).u = rb_ntohf((x).u))
#define VTOHF(x) ((x).u = rb_vtohf((x).u))

#ifdef DOUBLE_SWAPPER
# define DOUBLE_CONVWITH(y) DOUBLE_SWAPPER y;
# define HTOND(x,y) (memcpy(&(y),&(x),sizeof(double)), \
(y) = rb_htond((DOUBLE_SWAPPER)(y)), \
memcpy(&(x),&(y),sizeof(double)), \
(x))
# define HTOVD(x,y) (memcpy(&(y),&(x),sizeof(double)), \
(y) = rb_htovd((DOUBLE_SWAPPER)(y)), \
memcpy(&(x),&(y),sizeof(double)), \
(x))
# define NTOHD(x,y) (memcpy(&(y),&(x),sizeof(double)), \
(y) = rb_ntohd((DOUBLE_SWAPPER)(y)), \
memcpy(&(x),&(y),sizeof(double)), \
(x))
# define VTOHD(x,y) (memcpy(&(y),&(x),sizeof(double)), \
(y) = rb_vtohd((DOUBLE_SWAPPER)(y)), \
memcpy(&(x),&(y),sizeof(double)), \
(x))
#else
# define DOUBLE_CONVWITH(y)
# define HTOND(x,y) rb_htond(x)
# define HTOVD(x,y) rb_htovd(x)
# define NTOHD(x,y) rb_ntohd(x)
# define VTOHD(x,y) rb_vtohd(x)
#endif
#define DOUBLE_CONVWITH(x) DOUBLE_SWAPPER x;
#define HTOND(x) ((x).u = rb_htond((x).u))
#define HTOVD(x) ((x).u = rb_htovd((x).u))
#define NTOHD(x) ((x).u = rb_ntohd((x).u))
#define VTOHD(x) ((x).u = rb_vtohd((x).u))

#define MAX_INTEGER_PACK_SIZE 8

Expand Down Expand Up @@ -728,25 +647,22 @@ pack_pack(VALUE ary, VALUE fmt)

case 'e': /* single precision float in VAX byte-order */
while (len-- > 0) {
float f;
FLOAT_CONVWITH(ftmp);
FLOAT_CONVWITH(tmp);

from = NEXTFROM;
f = (float)RFLOAT_VALUE(rb_to_float(from));
f = HTOVF(f,ftmp);
rb_str_buf_cat(res, (char*)&f, sizeof(float));
tmp.f = (float)RFLOAT_VALUE(rb_to_float(from));
HTOVF(tmp);
rb_str_buf_cat(res, tmp.buf, sizeof(float));
}
break;

case 'E': /* double precision float in VAX byte-order */
while (len-- > 0) {
double d;
DOUBLE_CONVWITH(dtmp);

DOUBLE_CONVWITH(tmp);
from = NEXTFROM;
d = RFLOAT_VALUE(rb_to_float(from));
d = HTOVD(d,dtmp);
rb_str_buf_cat(res, (char*)&d, sizeof(double));
tmp.d = RFLOAT_VALUE(rb_to_float(from));
HTOVD(tmp);
rb_str_buf_cat(res, tmp.buf, sizeof(double));
}
break;

Expand All @@ -763,25 +679,22 @@ pack_pack(VALUE ary, VALUE fmt)

case 'g': /* single precision float in network byte-order */
while (len-- > 0) {
float f;
FLOAT_CONVWITH(ftmp);

FLOAT_CONVWITH(tmp);
from = NEXTFROM;
f = (float)RFLOAT_VALUE(rb_to_float(from));
f = HTONF(f,ftmp);
rb_str_buf_cat(res, (char*)&f, sizeof(float));
tmp.f = (float)RFLOAT_VALUE(rb_to_float(from));
HTONF(tmp);
rb_str_buf_cat(res, tmp.buf, sizeof(float));
}
break;

case 'G': /* double precision float in network byte-order */
while (len-- > 0) {
double d;
DOUBLE_CONVWITH(dtmp);
DOUBLE_CONVWITH(tmp);

from = NEXTFROM;
d = RFLOAT_VALUE(rb_to_float(from));
d = HTOND(d,dtmp);
rb_str_buf_cat(res, (char*)&d, sizeof(double));
tmp.d = RFLOAT_VALUE(rb_to_float(from));
HTOND(tmp);
rb_str_buf_cat(res, tmp.buf, sizeof(double));
}
break;

Expand Down Expand Up @@ -1578,27 +1491,23 @@ pack_unpack(VALUE str, VALUE fmt)
case 'e':
PACK_LENGTH_ADJUST_SIZE(sizeof(float));
while (len-- > 0) {
float tmp;
FLOAT_CONVWITH(ftmp);

memcpy(&tmp, s, sizeof(float));
FLOAT_CONVWITH(tmp);
memcpy(tmp.buf, s, sizeof(float));
s += sizeof(float);
tmp = VTOHF(tmp,ftmp);
UNPACK_PUSH(DBL2NUM((double)tmp));
VTOHF(tmp);
UNPACK_PUSH(DBL2NUM(tmp.f));
}
PACK_ITEM_ADJUST();
break;

case 'E':
PACK_LENGTH_ADJUST_SIZE(sizeof(double));
while (len-- > 0) {
double tmp;
DOUBLE_CONVWITH(dtmp);

memcpy(&tmp, s, sizeof(double));
DOUBLE_CONVWITH(tmp);
memcpy(tmp.buf, s, sizeof(double));
s += sizeof(double);
tmp = VTOHD(tmp,dtmp);
UNPACK_PUSH(DBL2NUM(tmp));
VTOHD(tmp);
UNPACK_PUSH(DBL2NUM(tmp.d));
}
PACK_ITEM_ADJUST();
break;
Expand All @@ -1618,27 +1527,23 @@ pack_unpack(VALUE str, VALUE fmt)
case 'g':
PACK_LENGTH_ADJUST_SIZE(sizeof(float));
while (len-- > 0) {
float tmp;
FLOAT_CONVWITH(ftmp);

memcpy(&tmp, s, sizeof(float));
FLOAT_CONVWITH(tmp);
memcpy(tmp.buf, s, sizeof(float));
s += sizeof(float);
tmp = NTOHF(tmp,ftmp);
UNPACK_PUSH(DBL2NUM((double)tmp));
NTOHF(tmp);
UNPACK_PUSH(DBL2NUM(tmp.f));
}
PACK_ITEM_ADJUST();
break;

case 'G':
PACK_LENGTH_ADJUST_SIZE(sizeof(double));
while (len-- > 0) {
double tmp;
DOUBLE_CONVWITH(dtmp);

memcpy(&tmp, s, sizeof(double));
DOUBLE_CONVWITH(tmp);
memcpy(tmp.buf, s, sizeof(double));
s += sizeof(double);
tmp = NTOHD(tmp,dtmp);
UNPACK_PUSH(DBL2NUM(tmp));
NTOHD(tmp);
UNPACK_PUSH(DBL2NUM(tmp.d));
}
PACK_ITEM_ADJUST();
break;
Expand Down

0 comments on commit e90e916

Please sign in to comment.