authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-04-04 16:46:39+02:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-04-04 16:55:24+02:00
logad2ebc87f2870ae297cdc2b8fd071668a90c2d83
tree31b47cf32d3ae535754975b643b0d8d3b5f8bb38
parent084c62f5d1fd6bf5e8df84e0cc87408ae38ca48f

stage1: Byteswap floats when serializing them


1 files changed, 65 insertions(+), 36 deletions(-)

src/ir.cpp+65-36
...@@ -10993,48 +10993,77 @@ static void float_negate(ZigValue *out_val, ZigValue *op) {...@@ -10993,48 +10993,77 @@ static void float_negate(ZigValue *out_val, ZigValue *op) {
10993}10993}
1099410994
10995void float_write_ieee597(ZigValue *op, uint8_t *buf, bool is_big_endian) {10995void float_write_ieee597(ZigValue *op, uint8_t *buf, bool is_big_endian) {
10996 if (op->type->id == ZigTypeIdFloat) {10996 if (op->type->id != ZigTypeIdFloat)
10997 switch (op->type->data.floating.bit_count) {
10998 case 16:
10999 memcpy(buf, &op->data.x_f16, 2); // TODO wrong when compiler is big endian
11000 return;
11001 case 32:
11002 memcpy(buf, &op->data.x_f32, 4); // TODO wrong when compiler is big endian
11003 return;
11004 case 64:
11005 memcpy(buf, &op->data.x_f64, 8); // TODO wrong when compiler is big endian
11006 return;
11007 case 128:
11008 memcpy(buf, &op->data.x_f128, 16); // TODO wrong when compiler is big endian
11009 return;
11010 default:
11011 zig_unreachable();
11012 }
11013 } else {
11014 zig_unreachable();10997 zig_unreachable();
10998
10999 const unsigned n = op->type->data.floating.bit_count / 8;
11000 assert(n <= 16);
11001
11002 switch (op->type->data.floating.bit_count) {
11003 case 16:
11004 memcpy(buf, &op->data.x_f16, 2);
11005 break;
11006 case 32:
11007 memcpy(buf, &op->data.x_f32, 4);
11008 break;
11009 case 64:
11010 memcpy(buf, &op->data.x_f64, 8);
11011 break;
11012 case 128:
11013 memcpy(buf, &op->data.x_f128, 16);
11014 break;
11015 default:
11016 zig_unreachable();
11017 }
11018
11019 if (is_big_endian) {
11020 // Byteswap in place if needed
11021 for (size_t i = 0; i < n / 2; i++) {
11022 uint8_t u = buf[i];
11023 buf[i] = buf[n - 1 - i];
11024 buf[n - 1 - i] = u;
11025 }
11015 }11026 }
11016}11027}
1101711028
11018void float_read_ieee597(ZigValue *val, uint8_t *buf, bool is_big_endian) {11029void float_read_ieee597(ZigValue *val, uint8_t *buf, bool is_big_endian) {
11019 if (val->type->id == ZigTypeIdFloat) {11030 if (val->type->id != ZigTypeIdFloat)
11020 switch (val->type->data.floating.bit_count) {
11021 case 16:
11022 memcpy(&val->data.x_f16, buf, 2); // TODO wrong when compiler is big endian
11023 return;
11024 case 32:
11025 memcpy(&val->data.x_f32, buf, 4); // TODO wrong when compiler is big endian
11026 return;
11027 case 64:
11028 memcpy(&val->data.x_f64, buf, 8); // TODO wrong when compiler is big endian
11029 return;
11030 case 128:
11031 memcpy(&val->data.x_f128, buf, 16); // TODO wrong when compiler is big endian
11032 return;
11033 default:
11034 zig_unreachable();
11035 }
11036 } else {
11037 zig_unreachable();11031 zig_unreachable();
11032
11033 const unsigned n = val->type->data.floating.bit_count / 8;
11034 assert(n <= 16);
11035
11036 uint8_t tmp[16];
11037 uint8_t *ptr = buf;
11038
11039 if (is_big_endian) {
11040 memcpy(tmp, buf, n);
11041
11042 // Byteswap if needed
11043 for (size_t i = 0; i < n / 2; i++) {
11044 uint8_t u = tmp[i];
11045 tmp[i] = tmp[n - 1 - i];
11046 tmp[n - 1 - i] = u;
11047 }
11048
11049 ptr = tmp;
11050 }
11051
11052 switch (val->type->data.floating.bit_count) {
11053 case 16:
11054 memcpy(&val->data.x_f16, ptr, 2);
11055 return;
11056 case 32:
11057 memcpy(&val->data.x_f32, ptr, 4);
11058 return;
11059 case 64:
11060 memcpy(&val->data.x_f64, ptr, 8);
11061 return;
11062 case 128:
11063 memcpy(&val->data.x_f128, ptr, 16);
11064 return;
11065 default:
11066 zig_unreachable();
11038 }11067 }
11039}11068}
1104011069