diff options
| author | gingerBill <bill@gingerbill.org> | 2018-12-02 15:53:52 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2018-12-02 15:53:52 +0000 |
| commit | 00161023cda147daa5638539df5d46fb18aebfa6 (patch) | |
| tree | b2b811d47b9306e273382f4840c6c3ae9e6099ca /src/types.cpp | |
| parent | 784c48c9e36c11595b23fb0df002c063dd42a2bf (diff) | |
Endian specific integers: e.g. i32 i32le i32be
Diffstat (limited to 'src/types.cpp')
| -rw-r--r-- | src/types.cpp | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src/types.cpp b/src/types.cpp index 6024ecfd1..635cfc207 100644 --- a/src/types.cpp +++ b/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) { |