aboutsummaryrefslogtreecommitdiffstats
path: root/pack.c
diff options
context:
space:
mode:
authornaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-07-05 02:08:55 +0000
committernaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-07-05 02:08:55 +0000
commit5a8765bb810efccaf42501b7004b9300450a4e83 (patch)
tree209f966d6aa25d58fc3a3f790b383f3df4c97661 /pack.c
parent73236254494259b467303e61ea29902634d38081 (diff)
downloadruby-5a8765bb810efccaf42501b7004b9300450a4e83.tar.gz
* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55573 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'pack.c')
-rw-r--r--pack.c203
1 files changed, 54 insertions, 149 deletions
diff --git a/pack.c b/pack.c
index ea7bd16fe8..3fff3e65df 100644
--- a/pack.c
+++ b/pack.c
@@ -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))
@@ -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
@@ -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;
@@ -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;
@@ -1578,13 +1491,11 @@ 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;
@@ -1592,13 +1503,11 @@ pack_unpack(VALUE str, VALUE fmt)
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;
@@ -1618,13 +1527,11 @@ 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;
@@ -1632,13 +1539,11 @@ pack_unpack(VALUE str, VALUE fmt)
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;