mirror of
https://github.com/odin-lang/Odin.git
synced 2026-01-04 12:07:45 +00:00
Endian specific integers: e.g. i32 i32le i32be
This commit is contained in:
@@ -3,6 +3,7 @@ package fmt
|
||||
import "core:runtime"
|
||||
import "core:os"
|
||||
import "core:mem"
|
||||
import "core:bits"
|
||||
import "core:unicode/utf8"
|
||||
import "core:types"
|
||||
import "core:strconv"
|
||||
@@ -1279,6 +1280,20 @@ fmt_arg :: proc(fi: ^Fmt_Info, arg: any, verb: rune) {
|
||||
|
||||
case typeid: write_typeid(fi.buf, a);
|
||||
|
||||
case i16le: fmt_int(fi, u64(a), true, 16, verb);
|
||||
case u16le: fmt_int(fi, u64(a), false, 16, verb);
|
||||
case i32le: fmt_int(fi, u64(a), true, 32, verb);
|
||||
case u32le: fmt_int(fi, u64(a), false, 32, verb);
|
||||
case i64le: fmt_int(fi, u64(a), true, 64, verb);
|
||||
case u64le: fmt_int(fi, u64(a), false, 64, verb);
|
||||
|
||||
case i16be: fmt_int(fi, u64(a), true, 16, verb);
|
||||
case u16be: fmt_int(fi, u64(a), false, 16, verb);
|
||||
case i32be: fmt_int(fi, u64(a), true, 32, verb);
|
||||
case u32be: fmt_int(fi, u64(a), false, 32, verb);
|
||||
case i64be: fmt_int(fi, u64(a), true, 64, verb);
|
||||
case u64be: fmt_int(fi, u64(a), false, 64, verb);
|
||||
|
||||
case: fmt_value(fi, arg, verb);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,9 +40,15 @@ Type_Info_Enum_Value :: union {
|
||||
u8, u16, u32, u64, uint, uintptr,
|
||||
};
|
||||
|
||||
Type_Info_Endianness :: enum u8 {
|
||||
Platform = 0,
|
||||
Little = 1,
|
||||
Big = 2,
|
||||
}
|
||||
|
||||
// Variant Types
|
||||
Type_Info_Named :: struct {name: string, base: ^Type_Info};
|
||||
Type_Info_Integer :: struct {signed: bool};
|
||||
Type_Info_Integer :: struct {signed: bool, endianness: Type_Info_Endianness};
|
||||
Type_Info_Rune :: struct {};
|
||||
Type_Info_Float :: struct {};
|
||||
Type_Info_Complex :: struct {};
|
||||
|
||||
@@ -80,6 +80,8 @@ struct BuildContext {
|
||||
String ODIN_ROOT; // Odin ROOT
|
||||
bool ODIN_DEBUG; // Odin in debug mode
|
||||
|
||||
TargetEndianKind endian_kind;
|
||||
|
||||
// In bytes
|
||||
i64 word_size; // Size of a pointer, must be >= 4
|
||||
i64 max_align; // max alignment, must be >= 1 (and typically >= word_size)
|
||||
@@ -539,6 +541,7 @@ void init_build_context(void) {
|
||||
bc->ODIN_OS = target_os_names[metrics.os];
|
||||
bc->ODIN_ARCH = target_arch_names[metrics.arch];
|
||||
bc->ODIN_ENDIAN = target_endian_names[target_endians[metrics.arch]];
|
||||
bc->endian_kind = target_endians[metrics.arch];
|
||||
bc->word_size = metrics.word_size;
|
||||
bc->max_align = metrics.max_align;
|
||||
bc->link_flags = str_lit(" ");
|
||||
|
||||
@@ -1304,6 +1304,13 @@ bool check_representable_as_constant(CheckerContext *c, ExactValue in_value, Typ
|
||||
case Basic_i32:
|
||||
case Basic_i64:
|
||||
case Basic_int:
|
||||
|
||||
case Basic_i16le:
|
||||
case Basic_i32le:
|
||||
case Basic_i64le:
|
||||
case Basic_i16be:
|
||||
case Basic_i32be:
|
||||
case Basic_i64be:
|
||||
{
|
||||
// return imin <= i && i <= imax;
|
||||
int a = big_int_cmp(&imin, &i);
|
||||
@@ -1318,6 +1325,12 @@ bool check_representable_as_constant(CheckerContext *c, ExactValue in_value, Typ
|
||||
case Basic_uint:
|
||||
case Basic_uintptr:
|
||||
|
||||
case Basic_u16le:
|
||||
case Basic_u32le:
|
||||
case Basic_u64le:
|
||||
case Basic_u16be:
|
||||
case Basic_u32be:
|
||||
case Basic_u64be:
|
||||
{
|
||||
// return 0ull <= i && i <= umax;
|
||||
int b = big_int_cmp(&i, &umax);
|
||||
|
||||
125
src/ir.cpp
125
src/ir.cpp
@@ -299,7 +299,13 @@ gbAllocator ir_allocator(void) {
|
||||
IR_CONV_KIND(sitofp) \
|
||||
IR_CONV_KIND(ptrtoint) \
|
||||
IR_CONV_KIND(inttoptr) \
|
||||
IR_CONV_KIND(bitcast)
|
||||
IR_CONV_KIND(bitcast) \
|
||||
IR_CONV_KIND(byteswap)
|
||||
/*
|
||||
Odin specifc conversion
|
||||
byteswap - swap bytes for endian change
|
||||
*/
|
||||
|
||||
|
||||
enum irInstrKind {
|
||||
irInstr_Invalid,
|
||||
@@ -852,6 +858,7 @@ irDebugInfo *ir_add_debug_info_local(irProcedure *proc, Entity *e, i32 arg_id);
|
||||
irDebugInfo *ir_add_debug_info_file(irModule *module, AstFile *file);
|
||||
irDebugInfo *ir_add_debug_info_proc(irProcedure *proc);
|
||||
|
||||
irValue *ir_emit_byte_swap(irProcedure *proc, irValue *value, Type *t);
|
||||
|
||||
irValue *ir_alloc_value(irValueKind kind) {
|
||||
irValue *v = gb_alloc_item(ir_allocator(), irValue);
|
||||
@@ -1273,6 +1280,9 @@ irValue *ir_const_int(i64 i) {
|
||||
irValue *ir_const_uintptr(u64 i) {
|
||||
return ir_value_constant(t_uintptr, exact_value_i64(i));
|
||||
}
|
||||
irValue *ir_const_u8(u32 i) {
|
||||
return ir_value_constant(t_u8, exact_value_i64(i));
|
||||
}
|
||||
irValue *ir_const_i32(i32 i) {
|
||||
return ir_value_constant(t_i32, exact_value_i64(i));
|
||||
}
|
||||
@@ -3476,6 +3486,13 @@ irValue *ir_emit_unary_arith(irProcedure *proc, TokenKind op, irValue *x, Type *
|
||||
return ir_emit_conv(proc, cmp, type);
|
||||
}
|
||||
|
||||
if (op == Token_Sub && is_type_integer(type) && is_type_different_to_arch_endianness(type)) {
|
||||
Type *platform_type = integer_endian_type_to_platform_type(type);
|
||||
irValue *v = ir_emit_byte_swap(proc, x, platform_type);
|
||||
irValue *res = ir_emit(proc, ir_instr_unary_op(proc, op, v, platform_type));
|
||||
return ir_emit_byte_swap(proc, res, type);
|
||||
}
|
||||
|
||||
return ir_emit(proc, ir_instr_unary_op(proc, op, x, type));
|
||||
}
|
||||
|
||||
@@ -3607,6 +3624,24 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *
|
||||
}
|
||||
#endif
|
||||
|
||||
if (is_type_integer(type) && is_type_different_to_arch_endianness(type)) {
|
||||
switch (op) {
|
||||
case Token_AndNot:
|
||||
case Token_And:
|
||||
case Token_Or:
|
||||
case Token_Xor:
|
||||
goto handle_op;
|
||||
}
|
||||
Type *platform_type = integer_endian_type_to_platform_type(type);
|
||||
irValue *x = ir_emit_byte_swap(proc, left, integer_endian_type_to_platform_type(t_left));
|
||||
irValue *y = ir_emit_byte_swap(proc, right, integer_endian_type_to_platform_type(t_right));
|
||||
|
||||
irValue *res = ir_emit_arith(proc, op, x, y, platform_type);
|
||||
|
||||
return ir_emit_byte_swap(proc, res, type);
|
||||
}
|
||||
|
||||
handle_op:
|
||||
switch (op) {
|
||||
case Token_Shl:
|
||||
case Token_Shr:
|
||||
@@ -3878,6 +3913,16 @@ irValue *ir_emit_comp(irProcedure *proc, TokenKind op_kind, irValue *left, irVal
|
||||
}
|
||||
}
|
||||
|
||||
if (op_kind != Token_CmpEq && op_kind != Token_NotEq) {
|
||||
Type *t = ir_type(left);
|
||||
if (is_type_integer(t) && is_type_different_to_arch_endianness(t)) {
|
||||
Type *platform_type = integer_endian_type_to_platform_type(t);
|
||||
irValue *x = ir_emit_byte_swap(proc, left, platform_type);
|
||||
irValue *y = ir_emit_byte_swap(proc, right, platform_type);
|
||||
return ir_emit(proc, ir_instr_binary_op(proc, op_kind, x, y, t_llvm_bool));
|
||||
}
|
||||
}
|
||||
|
||||
return ir_emit(proc, ir_instr_binary_op(proc, op_kind, left, right, t_llvm_bool));
|
||||
}
|
||||
|
||||
@@ -4325,6 +4370,12 @@ irValue *ir_emit_uintptr_to_ptr(irProcedure *proc, irValue *value, Type *t) {
|
||||
return ir_emit(proc, ir_instr_conv(proc, irConv_inttoptr, value, vt, t));
|
||||
}
|
||||
|
||||
irValue *ir_emit_byte_swap(irProcedure *proc, irValue *value, Type *t) {
|
||||
Type *vt = core_type(ir_type(value));
|
||||
GB_ASSERT(type_size_of(vt) == type_size_of(t));
|
||||
return ir_emit(proc, ir_instr_conv(proc, irConv_byteswap, value, vt, t));
|
||||
}
|
||||
|
||||
|
||||
void ir_emit_store_union_variant(irProcedure *proc, irValue *parent, irValue *variant, Type *variant_type) {
|
||||
gbAllocator a = ir_allocator();
|
||||
@@ -4397,12 +4448,18 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) {
|
||||
return ir_emit(proc, ir_instr_conv(proc, irConv_zext, value, src_type, t));
|
||||
}
|
||||
|
||||
|
||||
// integer -> integer
|
||||
if (is_type_integer(src) && is_type_integer(dst)) {
|
||||
GB_ASSERT(src->kind == Type_Basic &&
|
||||
dst->kind == Type_Basic);
|
||||
i64 sz = type_size_of(default_type(src));
|
||||
i64 dz = type_size_of(default_type(dst));
|
||||
|
||||
if (sz > 1 && is_type_different_to_arch_endianness(src)) {
|
||||
Type *platform_src_type = integer_endian_type_to_platform_type(src);
|
||||
value = ir_emit_byte_swap(proc, value, platform_src_type);
|
||||
}
|
||||
irConvKind kind = irConv_trunc;
|
||||
|
||||
if (dz < sz) {
|
||||
@@ -4419,7 +4476,13 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) {
|
||||
}
|
||||
}
|
||||
|
||||
return ir_emit(proc, ir_instr_conv(proc, kind, value, src_type, t));
|
||||
if (dz > 1 && is_type_different_to_arch_endianness(dst)) {
|
||||
Type *platform_dst_type = integer_endian_type_to_platform_type(dst);
|
||||
irValue *res = ir_emit(proc, ir_instr_conv(proc, kind, value, src_type, platform_dst_type));
|
||||
return ir_emit_byte_swap(proc, res, t);
|
||||
} else {
|
||||
return ir_emit(proc, ir_instr_conv(proc, kind, value, src_type, t));
|
||||
}
|
||||
}
|
||||
|
||||
// boolean -> boolean/integer
|
||||
@@ -4454,40 +4517,6 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) {
|
||||
gbAllocator a = ir_allocator();
|
||||
i64 sz = type_size_of(src);
|
||||
i64 dz = type_size_of(dst);
|
||||
// if (sz == 2) {
|
||||
// switch (dz) {
|
||||
// case 2: return value;
|
||||
// case 4: {
|
||||
// auto args = array_make<irValue *>(ir_allocator(), 1);
|
||||
// args[0] = value;
|
||||
// return ir_emit_runtime_call(proc, "gnu_h2f_ieee", args);
|
||||
// break;
|
||||
// }
|
||||
// case 8: {
|
||||
// auto args = array_make<irValue *>(ir_allocator(), 1);
|
||||
// args[0] = value;
|
||||
// return ir_emit_runtime_call(proc, "f16_to_f64", args);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// } else if (dz == 2) {
|
||||
// switch (sz) {
|
||||
// case 2: return value;
|
||||
// case 4: {
|
||||
// auto args = array_make<irValue *>(ir_allocator(), 1);
|
||||
// args[0] = value;
|
||||
// return ir_emit_runtime_call(proc, "gnu_f2h_ieee", args);
|
||||
// break;
|
||||
// }
|
||||
// case 8: {
|
||||
// auto args = array_make<irValue *>(ir_allocator(), 1);
|
||||
// args[0] = value;
|
||||
// return ir_emit_runtime_call(proc, "truncdfhf2", args);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
irConvKind kind = irConv_fptrunc;
|
||||
if (dz >= sz) {
|
||||
kind = irConv_fpext;
|
||||
@@ -9128,12 +9157,36 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
|
||||
case Basic_u32:
|
||||
case Basic_i64:
|
||||
case Basic_u64:
|
||||
|
||||
case Basic_i16le:
|
||||
case Basic_u16le:
|
||||
case Basic_i32le:
|
||||
case Basic_u32le:
|
||||
case Basic_i64le:
|
||||
case Basic_u64le:
|
||||
case Basic_i16be:
|
||||
case Basic_u16be:
|
||||
case Basic_i32be:
|
||||
case Basic_u32be:
|
||||
case Basic_i64be:
|
||||
case Basic_u64be:
|
||||
|
||||
|
||||
case Basic_int:
|
||||
case Basic_uint:
|
||||
case Basic_uintptr: {
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_integer_ptr);
|
||||
irValue *is_signed = ir_const_bool((t->Basic.flags & BasicFlag_Unsigned) == 0);
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), is_signed);
|
||||
// NOTE(bill): This is matches the runtime layout
|
||||
u8 endianness_value = 0;
|
||||
if (t->Basic.flags & BasicFlag_EndianLittle) {
|
||||
endianness_value = 1;
|
||||
} else if (t->Basic.flags & BasicFlag_EndianBig) {
|
||||
endianness_value = 2;
|
||||
}
|
||||
irValue *endianness = ir_const_u8(endianness_value);
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 1), endianness);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -69,13 +69,21 @@ void ir_write_u64(irFileBuffer *f, u64 i) {
|
||||
String str = u64_to_string(i, f->buf, IR_FILE_BUFFER_BUF_LEN-1);
|
||||
ir_write_string(f, str);
|
||||
}
|
||||
void ir_write_big_int(irFileBuffer *f, BigInt const &x) {
|
||||
void ir_write_big_int(irFileBuffer *f, BigInt const &x, Type *type, bool swap_endian) {
|
||||
i64 i = 0;
|
||||
if (x.neg) {
|
||||
i = big_int_to_i64(&x);
|
||||
} else {
|
||||
i = cast(i64)big_int_to_u64(&x);
|
||||
}
|
||||
if (swap_endian) {
|
||||
i64 size = type_size_of(type);
|
||||
switch (size) {
|
||||
case 2: i = cast(i64)cast(i16)gb_endian_swap16(cast(u16)cast(i16)i); break;
|
||||
case 4: i = cast(i64)cast(i32)gb_endian_swap32(cast(u32)cast(i32)i); break;
|
||||
case 8: i = cast(i64)gb_endian_swap64(cast(u64)i); break;
|
||||
}
|
||||
}
|
||||
ir_write_i64(f, i);
|
||||
}
|
||||
|
||||
@@ -352,6 +360,20 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t, bool in_struct) {
|
||||
case Basic_i64: ir_write_str_lit(f, "i64"); return;
|
||||
case Basic_u64: ir_write_str_lit(f, "i64"); return;
|
||||
|
||||
case Basic_i16le: ir_write_str_lit(f, "i16"); return;
|
||||
case Basic_u16le: ir_write_str_lit(f, "i16"); return;
|
||||
case Basic_i32le: ir_write_str_lit(f, "i32"); return;
|
||||
case Basic_u32le: ir_write_str_lit(f, "i32"); return;
|
||||
case Basic_i64le: ir_write_str_lit(f, "i64"); return;
|
||||
case Basic_u64le: ir_write_str_lit(f, "i64"); return;
|
||||
|
||||
case Basic_i16be: ir_write_str_lit(f, "i16"); return;
|
||||
case Basic_u16be: ir_write_str_lit(f, "i16"); return;
|
||||
case Basic_i32be: ir_write_str_lit(f, "i32"); return;
|
||||
case Basic_u32be: ir_write_str_lit(f, "i32"); return;
|
||||
case Basic_i64be: ir_write_str_lit(f, "i64"); return;
|
||||
case Basic_u64be: ir_write_str_lit(f, "i64"); return;
|
||||
|
||||
case Basic_rune: ir_write_str_lit(f, "i32"); return;
|
||||
|
||||
case Basic_int:
|
||||
@@ -677,13 +699,13 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
|
||||
ir_write_str_lit(f, "inttoptr (");
|
||||
ir_print_type(f, m, t_int);
|
||||
ir_write_byte(f, ' ');
|
||||
ir_write_big_int(f, value.value_integer);
|
||||
ir_write_big_int(f, value.value_integer, type, is_type_different_to_arch_endianness(type));
|
||||
ir_write_str_lit(f, " to ");
|
||||
ir_print_type(f, m, t_rawptr);
|
||||
ir_write_str_lit(f, ")");
|
||||
}
|
||||
} else {
|
||||
ir_write_big_int(f, value.value_integer);
|
||||
ir_write_big_int(f, value.value_integer, type, is_type_different_to_arch_endianness(type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1550,15 +1572,25 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
||||
|
||||
case irInstr_Conv: {
|
||||
irInstrConv *c = &instr->Conv;
|
||||
ir_fprintf(f, "%%%d = ", value->index);
|
||||
ir_write_string(f, ir_conv_strings[c->kind]);
|
||||
ir_write_byte(f, ' ');
|
||||
ir_print_type(f, m, c->from);
|
||||
ir_write_byte(f, ' ');
|
||||
ir_print_value(f, m, c->value, c->from);
|
||||
ir_write_str_lit(f, " to ");
|
||||
ir_print_type(f, m, c->to);
|
||||
ir_print_debug_location(f, m, value);
|
||||
if (c->kind == irConv_byteswap) {
|
||||
int sz = cast(int)(8*type_size_of(c->from));
|
||||
ir_fprintf(f, "%%%d = call i%d @llvm.bswap.i%d(", value->index, sz, sz);
|
||||
ir_print_type(f, m, c->from);
|
||||
ir_write_byte(f, ' ');
|
||||
ir_print_value(f, m, c->value, c->from);
|
||||
ir_write_byte(f, ')');
|
||||
ir_print_debug_location(f, m, value);
|
||||
} else {
|
||||
ir_fprintf(f, "%%%d = ", value->index);
|
||||
ir_write_string(f, ir_conv_strings[c->kind]);
|
||||
ir_write_byte(f, ' ');
|
||||
ir_print_type(f, m, c->from);
|
||||
ir_write_byte(f, ' ');
|
||||
ir_print_value(f, m, c->value, c->from);
|
||||
ir_write_str_lit(f, " to ");
|
||||
ir_print_type(f, m, c->to);
|
||||
ir_print_debug_location(f, m, value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2096,6 +2128,9 @@ void print_llvm_ir(irGen *ir) {
|
||||
ir_write_str_lit(f, "} ; Basic_any\n");
|
||||
|
||||
ir_write_str_lit(f, "declare void @llvm.dbg.declare(metadata, metadata, metadata) #3 \n");
|
||||
ir_write_str_lit(f, "declare i16 @llvm.bswap.i16(i16) #3 \n");
|
||||
ir_write_str_lit(f, "declare i32 @llvm.bswap.i32(i32) #3 \n");
|
||||
ir_write_str_lit(f, "declare i64 @llvm.bswap.i64(i64) #3 \n");
|
||||
ir_write_byte(f, '\n');
|
||||
|
||||
|
||||
|
||||
104
src/types.cpp
104
src/types.cpp
@@ -40,6 +40,22 @@ enum BasicKind {
|
||||
|
||||
Basic_typeid,
|
||||
|
||||
// Endian Specific Types
|
||||
Basic_i16le,
|
||||
Basic_u16le,
|
||||
Basic_i32le,
|
||||
Basic_u32le,
|
||||
Basic_i64le,
|
||||
Basic_u64le,
|
||||
|
||||
Basic_i16be,
|
||||
Basic_u16be,
|
||||
Basic_i32be,
|
||||
Basic_u32be,
|
||||
Basic_i64be,
|
||||
Basic_u64be,
|
||||
|
||||
// Untyped types
|
||||
Basic_UntypedBool,
|
||||
Basic_UntypedInteger,
|
||||
Basic_UntypedFloat,
|
||||
@@ -67,6 +83,9 @@ enum BasicFlag {
|
||||
|
||||
BasicFlag_LLVM = GB_BIT(10),
|
||||
|
||||
BasicFlag_EndianLittle = GB_BIT(13),
|
||||
BasicFlag_EndianBig = GB_BIT(14),
|
||||
|
||||
BasicFlag_Numeric = BasicFlag_Integer | BasicFlag_Float | BasicFlag_Complex,
|
||||
BasicFlag_Ordered = BasicFlag_Integer | BasicFlag_Float | BasicFlag_String | BasicFlag_Pointer | BasicFlag_Rune,
|
||||
BasicFlag_OrderedNumeric = BasicFlag_Integer | BasicFlag_Float | BasicFlag_Rune,
|
||||
@@ -313,6 +332,22 @@ gb_global Type basic_types[] = {
|
||||
|
||||
{Type_Basic, {Basic_typeid, 0, -1, STR_LIT("typeid")}},
|
||||
|
||||
// Endian
|
||||
{Type_Basic, {Basic_i16le, BasicFlag_Integer | BasicFlag_EndianBig, 2, STR_LIT("i16le")}},
|
||||
{Type_Basic, {Basic_u16le, BasicFlag_Integer | BasicFlag_Unsigned | BasicFlag_EndianBig, 2, STR_LIT("u16le")}},
|
||||
{Type_Basic, {Basic_i32le, BasicFlag_Integer | BasicFlag_EndianBig, 4, STR_LIT("i32le")}},
|
||||
{Type_Basic, {Basic_u32le, BasicFlag_Integer | BasicFlag_Unsigned | BasicFlag_EndianBig, 4, STR_LIT("u32le")}},
|
||||
{Type_Basic, {Basic_i64le, BasicFlag_Integer | BasicFlag_EndianBig, 8, STR_LIT("i64le")}},
|
||||
{Type_Basic, {Basic_u64le, BasicFlag_Integer | BasicFlag_Unsigned | BasicFlag_EndianBig, 8, STR_LIT("u64le")}},
|
||||
|
||||
{Type_Basic, {Basic_i16be, BasicFlag_Integer | BasicFlag_EndianBig, 2, STR_LIT("i16be")}},
|
||||
{Type_Basic, {Basic_u16be, BasicFlag_Integer | BasicFlag_Unsigned | BasicFlag_EndianBig, 2, STR_LIT("u16be")}},
|
||||
{Type_Basic, {Basic_i32be, BasicFlag_Integer | BasicFlag_EndianBig, 4, STR_LIT("i32be")}},
|
||||
{Type_Basic, {Basic_u32be, BasicFlag_Integer | BasicFlag_Unsigned | BasicFlag_EndianBig, 4, STR_LIT("u32be")}},
|
||||
{Type_Basic, {Basic_i64be, BasicFlag_Integer | BasicFlag_EndianBig, 8, STR_LIT("i64be")}},
|
||||
{Type_Basic, {Basic_u64be, BasicFlag_Integer | BasicFlag_Unsigned | BasicFlag_EndianBig, 8, STR_LIT("u64be")}},
|
||||
|
||||
// Untyped types
|
||||
{Type_Basic, {Basic_UntypedBool, BasicFlag_Boolean | BasicFlag_Untyped, 0, STR_LIT("untyped bool")}},
|
||||
{Type_Basic, {Basic_UntypedInteger, BasicFlag_Integer | BasicFlag_Untyped, 0, STR_LIT("untyped integer")}},
|
||||
{Type_Basic, {Basic_UntypedFloat, BasicFlag_Float | BasicFlag_Untyped, 0, STR_LIT("untyped float")}},
|
||||
@@ -978,6 +1013,75 @@ bool is_type_map(Type *t) {
|
||||
}
|
||||
|
||||
|
||||
bool is_type_integer_endian_big(Type *t) {
|
||||
t = core_type(t);
|
||||
if (t->kind == Type_Basic) {
|
||||
if (t->Basic.flags & BasicFlag_EndianBig) {
|
||||
return true;
|
||||
} else if (t->Basic.flags & BasicFlag_EndianLittle) {
|
||||
return false;
|
||||
}
|
||||
} else if (t->kind == Type_BitSet) {
|
||||
return is_type_integer_endian_big(t->BitSet.elem);
|
||||
} else {
|
||||
GB_PANIC("Unsupported type: %s", type_to_string);
|
||||
}
|
||||
return build_context.endian_kind == TargetEndian_Big;
|
||||
}
|
||||
|
||||
bool is_type_integer_endian_little(Type *t) {
|
||||
t = core_type(t);
|
||||
if (t->kind == Type_Basic) {
|
||||
if (t->Basic.flags & BasicFlag_EndianLittle) {
|
||||
return true;
|
||||
} else if (t->Basic.flags & BasicFlag_EndianBig) {
|
||||
return false;
|
||||
}
|
||||
} else if (t->kind == Type_BitSet) {
|
||||
return is_type_integer_endian_little(t->BitSet.elem);
|
||||
} else {
|
||||
GB_PANIC("Unsupported type: %s", type_to_string);
|
||||
}
|
||||
return build_context.endian_kind == TargetEndian_Little;
|
||||
}
|
||||
|
||||
bool is_type_different_to_arch_endianness(Type *t) {
|
||||
switch (build_context.endian_kind) {
|
||||
case TargetEndian_Little:
|
||||
return !is_type_integer_endian_little(t);
|
||||
case TargetEndian_Big:
|
||||
return !is_type_integer_endian_big(t);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Type *integer_endian_type_to_platform_type(Type *t) {
|
||||
t = core_type(t);
|
||||
if (t->kind == Type_BitSet) {
|
||||
t = core_type(t->BitSet.elem);
|
||||
}
|
||||
GB_ASSERT(t->kind == Type_Basic);
|
||||
|
||||
switch (t->Basic.kind) {
|
||||
// Endian Specific Types
|
||||
case Basic_i16le: return t_i16;
|
||||
case Basic_u16le: return t_u16;
|
||||
case Basic_i32le: return t_i32;
|
||||
case Basic_u32le: return t_u32;
|
||||
case Basic_i64le: return t_i64;
|
||||
case Basic_u64le: return t_u64;
|
||||
|
||||
case Basic_i16be: return t_i16;
|
||||
case Basic_u16be: return t_u16;
|
||||
case Basic_i32be: return t_i32;
|
||||
case Basic_u32be: return t_u32;
|
||||
case Basic_i64be: return t_i64;
|
||||
case Basic_u64be: return t_u64;
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool is_type_any(Type *t) {
|
||||
|
||||
Reference in New Issue
Block a user