@@ -1238,11 +1238,13 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, TypeTableEntry
1238
1238
return nullptr ;
1239
1239
}
1240
1240
1241
+ bool big_endian = g->is_big_endian ;
1242
+
1241
1243
LLVMValueRef containing_int = gen_load (g, ptr, ptr_type, " " );
1242
1244
1243
1245
uint32_t bit_offset = ptr_type->data .pointer .bit_offset ;
1244
1246
uint32_t host_bit_count = LLVMGetIntTypeWidth (LLVMTypeOf (containing_int));
1245
- uint32_t shift_amt = host_bit_count - bit_offset - unaligned_bit_count;
1247
+ uint32_t shift_amt = big_endian ? host_bit_count - bit_offset - unaligned_bit_count : bit_offset ;
1246
1248
LLVMValueRef shift_amt_val = LLVMConstInt (LLVMTypeOf (containing_int), shift_amt, false );
1247
1249
1248
1250
LLVMValueRef mask_val = LLVMConstAllOnes (child_type->type_ref );
@@ -2198,12 +2200,14 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, IrI
2198
2200
if (unaligned_bit_count == 0 )
2199
2201
return get_handle_value (g, ptr, child_type, ptr_type);
2200
2202
2203
+ bool big_endian = g->is_big_endian ;
2204
+
2201
2205
assert (!handle_is_ptr (child_type));
2202
2206
LLVMValueRef containing_int = gen_load (g, ptr, ptr_type, " " );
2203
2207
2204
2208
uint32_t bit_offset = ptr_type->data .pointer .bit_offset ;
2205
2209
uint32_t host_bit_count = LLVMGetIntTypeWidth (LLVMTypeOf (containing_int));
2206
- uint32_t shift_amt = host_bit_count - bit_offset - unaligned_bit_count;
2210
+ uint32_t shift_amt = big_endian ? host_bit_count - bit_offset - unaligned_bit_count : bit_offset ;
2207
2211
2208
2212
LLVMValueRef shift_amt_val = LLVMConstInt (LLVMTypeOf (containing_int), shift_amt, false );
2209
2213
LLVMValueRef shifted_value = LLVMBuildLShr (g->builder , containing_int, shift_amt_val, " " );
@@ -3796,17 +3800,26 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
3796
3800
case TypeTableEntryIdStruct:
3797
3801
{
3798
3802
assert (type_entry->data .structure .layout == ContainerLayoutPacked);
3803
+ bool is_big_endian = g->is_big_endian ; // TODO get endianness from struct type
3799
3804
3800
3805
LLVMValueRef val = LLVMConstInt (big_int_type_ref, 0 , false );
3806
+ size_t used_bits = 0 ;
3801
3807
for (size_t i = 0 ; i < type_entry->data .structure .src_field_count ; i += 1 ) {
3802
3808
TypeStructField *field = &type_entry->data .structure .fields [i];
3803
3809
if (field->gen_index == SIZE_MAX) {
3804
3810
continue ;
3805
3811
}
3806
3812
LLVMValueRef child_val = pack_const_int (g, big_int_type_ref, &const_val->data .x_struct .fields [i]);
3807
- LLVMValueRef shift_amt = LLVMConstInt (big_int_type_ref, field->packed_bits_size , false );
3808
- val = LLVMConstShl (val, shift_amt);
3809
- val = LLVMConstOr (val, child_val);
3813
+ if (is_big_endian) {
3814
+ LLVMValueRef shift_amt = LLVMConstInt (big_int_type_ref, field->packed_bits_size , false );
3815
+ val = LLVMConstShl (val, shift_amt);
3816
+ val = LLVMConstOr (val, child_val);
3817
+ } else {
3818
+ LLVMValueRef shift_amt = LLVMConstInt (big_int_type_ref, used_bits, false );
3819
+ LLVMValueRef child_val_shifted = LLVMConstShl (child_val, shift_amt);
3820
+ val = LLVMConstOr (val, child_val_shifted);
3821
+ used_bits += field->packed_bits_size ;
3822
+ }
3810
3823
}
3811
3824
return val;
3812
3825
}
@@ -3931,20 +3944,29 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
3931
3944
fields[type_struct_field->gen_index ] = val;
3932
3945
make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type (field_val->type , val);
3933
3946
} else {
3947
+ bool is_big_endian = g->is_big_endian ; // TODO get endianness from struct type
3934
3948
LLVMTypeRef big_int_type_ref = LLVMStructGetTypeAtIndex (type_entry->type_ref ,
3935
3949
(unsigned )type_struct_field->gen_index );
3936
3950
LLVMValueRef val = LLVMConstInt (big_int_type_ref, 0 , false );
3951
+ size_t used_bits = 0 ;
3937
3952
for (size_t i = src_field_index; i < src_field_index_end; i += 1 ) {
3938
3953
TypeStructField *it_field = &type_entry->data .structure .fields [i];
3939
3954
if (it_field->gen_index == SIZE_MAX) {
3940
3955
continue ;
3941
3956
}
3942
3957
LLVMValueRef child_val = pack_const_int (g, big_int_type_ref,
3943
3958
&const_val->data .x_struct .fields [i]);
3944
- LLVMValueRef shift_amt = LLVMConstInt (big_int_type_ref,
3945
- it_field->packed_bits_size , false );
3946
- val = LLVMConstShl (val, shift_amt);
3947
- val = LLVMConstOr (val, child_val);
3959
+ if (is_big_endian) {
3960
+ LLVMValueRef shift_amt = LLVMConstInt (big_int_type_ref,
3961
+ it_field->packed_bits_size , false );
3962
+ val = LLVMConstShl (val, shift_amt);
3963
+ val = LLVMConstOr (val, child_val);
3964
+ } else {
3965
+ LLVMValueRef shift_amt = LLVMConstInt (big_int_type_ref, used_bits, false );
3966
+ LLVMValueRef child_val_shifted = LLVMConstShl (child_val, shift_amt);
3967
+ val = LLVMConstOr (val, child_val_shifted);
3968
+ used_bits += it_field->packed_bits_size ;
3969
+ }
3948
3970
}
3949
3971
fields[type_struct_field->gen_index ] = val;
3950
3972
}
0 commit comments