authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-04 13:45:49-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-04-04 13:45:49-04:00
logcf8728aabd4ed7190a912579fcca657ee5f037e8
treed91886de4fa57fc9e679078a409a12e4f366e639
parentd73808f3ff7d36b32d53cc38cf9a5b29b1ea57d4
parentad2ebc87f2870ae297cdc2b8fd071668a90c2d83
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #4935 from LemonBoy/stage1-eb

Big-endian fixes for stage1

1 files changed, 73 insertions(+), 38 deletions(-)

src/ir.cpp+73-38
......@@ -10993,48 +10993,77 @@ static void float_negate(ZigValue *out_val, ZigValue *op) {
1099310993}
1099410994
1099510995void float_write_ieee597(ZigValue *op, uint8_t *buf, bool is_big_endian) {
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 {
10996 if (op->type->id != ZigTypeIdFloat)
1101410997 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 }
1101511026 }
1101611027}
1101711028
1101811029void float_read_ieee597(ZigValue *val, uint8_t *buf, bool is_big_endian) {
11019 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 {
11030 if (val->type->id != ZigTypeIdFloat)
1103711031 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();
1103811067 }
1103911068}
1104011069
......@@ -28417,6 +28446,7 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
2841728446 }
2841828447 BigInt big_int;
2841928448 bigint_read_twos_complement(&big_int, buf + offset, big_int_byte_count * 8, is_big_endian, false);
28449 uint64_t bit_offset = 0;
2842028450 while (src_i < src_field_count) {
2842128451 TypeStructField *field = val->type->data.structure.fields[src_i];
2842228452 src_assert(field->gen_index != SIZE_MAX, source_node);
......@@ -28429,7 +28459,11 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
2842928459
2843028460 BigInt child_val;
2843128461 if (is_big_endian) {
28432 zig_panic("TODO buf_read_value_bytes packed struct big endian");
28462 BigInt packed_bits_size_bi;
28463 bigint_init_unsigned(&packed_bits_size_bi, big_int_byte_count * 8 - packed_bits_size - bit_offset);
28464 BigInt tmp;
28465 bigint_shr(&tmp, &big_int, &packed_bits_size_bi);
28466 bigint_truncate(&child_val, &tmp, packed_bits_size, false);
2843328467 } else {
2843428468 BigInt packed_bits_size_bi;
2843528469 bigint_init_unsigned(&packed_bits_size_bi, packed_bits_size);
......@@ -28439,11 +28473,12 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
2843928473 big_int = tmp;
2844028474 }
2844128475
28442 bigint_write_twos_complement(&child_val, child_buf, big_int_byte_count * 8, is_big_endian);
28476 bigint_write_twos_complement(&child_val, child_buf, packed_bits_size, is_big_endian);
2844328477 if ((err = buf_read_value_bytes(ira, codegen, source_node, child_buf, field_val))) {
2844428478 return err;
2844528479 }
2844628480
28481 bit_offset += packed_bits_size;
2844728482 src_i += 1;
2844828483 }
2844928484 offset += big_int_byte_count;