| ... | @@ -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 | } |
| 10994 | | 10994 | |
| 10995 | void float_write_ieee597(ZigValue *op, uint8_t *buf, bool is_big_endian) { | 10995 | void 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 | } |
| 11017 | | 11028 | |
| 11018 | void float_read_ieee597(ZigValue *val, uint8_t *buf, bool is_big_endian) { | 11029 | void 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 | } |
| 11040 | | 11069 | |
| ... | @@ -28417,6 +28446,7 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou | ... | @@ -28417,6 +28446,7 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou |
| 28417 | } | 28446 | } |
| 28418 | BigInt big_int; | 28447 | BigInt big_int; |
| 28419 | bigint_read_twos_complement(&big_int, buf + offset, big_int_byte_count * 8, is_big_endian, false); | 28448 | bigint_read_twos_complement(&big_int, buf + offset, big_int_byte_count * 8, is_big_endian, false); |
| | 28449 | uint64_t bit_offset = 0; |
| 28420 | while (src_i < src_field_count) { | 28450 | while (src_i < src_field_count) { |
| 28421 | TypeStructField *field = val->type->data.structure.fields[src_i]; | 28451 | TypeStructField *field = val->type->data.structure.fields[src_i]; |
| 28422 | src_assert(field->gen_index != SIZE_MAX, source_node); | 28452 | 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 | ... | @@ -28429,7 +28459,11 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou |
| 28429 | | 28459 | |
| 28430 | BigInt child_val; | 28460 | BigInt child_val; |
| 28431 | if (is_big_endian) { | 28461 | 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); |
| 28433 | } else { | 28467 | } else { |
| 28434 | BigInt packed_bits_size_bi; | 28468 | BigInt packed_bits_size_bi; |
| 28435 | bigint_init_unsigned(&packed_bits_size_bi, packed_bits_size); | 28469 | 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 | ... | @@ -28439,11 +28473,12 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou |
| 28439 | big_int = tmp; | 28473 | big_int = tmp; |
| 28440 | } | 28474 | } |
| 28441 | | 28475 | |
| 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); |
| 28443 | if ((err = buf_read_value_bytes(ira, codegen, source_node, child_buf, field_val))) { | 28477 | if ((err = buf_read_value_bytes(ira, codegen, source_node, child_buf, field_val))) { |
| 28444 | return err; | 28478 | return err; |
| 28445 | } | 28479 | } |
| 28446 | | 28480 | |
| | 28481 | bit_offset += packed_bits_size; |
| 28447 | src_i += 1; | 28482 | src_i += 1; |
| 28448 | } | 28483 | } |
| 28449 | offset += big_int_byte_count; | 28484 | offset += big_int_byte_count; |