+unsigned get_atomic_type_size(atomic_type_kind_t kind)
+{
+ switch(kind) {
+ case ATOMIC_TYPE_CHAR:
+ case ATOMIC_TYPE_SCHAR:
+ case ATOMIC_TYPE_UCHAR:
+ return 1;
+
+ case ATOMIC_TYPE_SHORT:
+ case ATOMIC_TYPE_USHORT:
+ return 2;
+
+ case ATOMIC_TYPE_BOOL:
+ case ATOMIC_TYPE_INT:
+ case ATOMIC_TYPE_UINT:
+ return machine_size >> 3;
+
+ case ATOMIC_TYPE_LONG:
+ case ATOMIC_TYPE_ULONG:
+ return machine_size > 16 ? machine_size >> 3 : 4;
+
+ case ATOMIC_TYPE_LONGLONG:
+ case ATOMIC_TYPE_ULONGLONG:
+ return machine_size > 16 ? 8 : 4;
+
+ case ATOMIC_TYPE_FLOAT_IMAGINARY:
+ case ATOMIC_TYPE_FLOAT:
+ return 4;
+
+ case ATOMIC_TYPE_DOUBLE_IMAGINARY:
+ case ATOMIC_TYPE_DOUBLE:
+ return 8;
+
+ case ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY:
+ case ATOMIC_TYPE_LONG_DOUBLE:
+ return 12;
+
+ case ATOMIC_TYPE_VOID:
+ return 1;
+
+ case ATOMIC_TYPE_FLOAT_COMPLEX:
+ return 2 * get_atomic_type_size(ATOMIC_TYPE_FLOAT);
+
+ case ATOMIC_TYPE_DOUBLE_COMPLEX:
+ return 2 * get_atomic_type_size(ATOMIC_TYPE_DOUBLE);
+
+ case ATOMIC_TYPE_LONG_DOUBLE_COMPLEX:
+ return 2 * get_atomic_type_size(ATOMIC_TYPE_LONG_DOUBLE);
+
+ case ATOMIC_TYPE_INVALID:
+ break;
+ }
+ panic("Trying to determine size of invalid atomic type");
+}
+
+/**
+ * Find the atomic type kind representing a given size (signed).
+ */
+atomic_type_kind_t find_signed_int_atomic_type_kind_for_size(unsigned size) {
+ static atomic_type_kind_t kinds[32];
+
+ assert(size < 32);
+ atomic_type_kind_t kind = kinds[size];
+ if(kind == ATOMIC_TYPE_INVALID) {
+ static const atomic_type_kind_t possible_kinds[] = {
+ ATOMIC_TYPE_SCHAR,
+ ATOMIC_TYPE_SHORT,
+ ATOMIC_TYPE_INT,
+ ATOMIC_TYPE_LONG,
+ ATOMIC_TYPE_LONGLONG
+ };
+ for(unsigned i = 0; i < sizeof(possible_kinds)/sizeof(possible_kinds[0]); ++i) {
+ if(get_atomic_type_size(possible_kinds[i]) == size) {
+ kind = possible_kinds[i];
+ break;
+ }
+ }
+ kinds[size] = kind;
+ }
+ return kind;
+}