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