aboutsummaryrefslogtreecommitdiff
path: root/src/types.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2018-12-02 15:53:52 +0000
committergingerBill <bill@gingerbill.org>2018-12-02 15:53:52 +0000
commit00161023cda147daa5638539df5d46fb18aebfa6 (patch)
treeb2b811d47b9306e273382f4840c6c3ae9e6099ca /src/types.cpp
parent784c48c9e36c11595b23fb0df002c063dd42a2bf (diff)
Endian specific integers: e.g. i32 i32le i32be
Diffstat (limited to 'src/types.cpp')
-rw-r--r--src/types.cpp104
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) {