refactor: precompute compiler enum mappings
This commit is contained in:
+50
-34
@@ -1,6 +1,7 @@
|
||||
import "@std/mem"
|
||||
import "@std/arraylist"
|
||||
import "@std/debug"
|
||||
import "@std/enummap"
|
||||
import "@source/diagnostics"
|
||||
|
||||
FunctionId :: distinct u32
|
||||
@@ -33,44 +34,51 @@ aggregate proc(type Type) bool {
|
||||
return type == .array or type == .record
|
||||
}
|
||||
|
||||
@hide:file
|
||||
integer_widths :: $enummap.init_filled(Type, usize, usize(0), {
|
||||
i8 = 8, u8 = 8,
|
||||
i16 = 16, u16 = 16,
|
||||
i32 = 32, u32 = 32,
|
||||
int = 64, isize = 64, usize = 64, u64 = 64,
|
||||
})
|
||||
|
||||
#! integer storage widths for the supported 64-bit target; zero for noninteger types.
|
||||
integer_bits proc(type Type) usize {
|
||||
return match type {
|
||||
.i8, .u8: 8
|
||||
.i16, .u16: 16
|
||||
.i32, .u32: 32
|
||||
.int, .isize, .usize, .u64: 64
|
||||
else: 0
|
||||
}
|
||||
if (enummap.get(&integer_widths, type)) |width| return width
|
||||
return 0
|
||||
}
|
||||
|
||||
unsigned_integer proc(type Type) bool {
|
||||
return type == .u8 or type == .u16 or type == .u32 or type == .u64 or type == .usize
|
||||
}
|
||||
|
||||
@hide:file
|
||||
integer_maxima :: $enummap.init_filled(Type, u64, u64(0), {
|
||||
i8 = 127,
|
||||
i16 = 32767,
|
||||
i32 = 2147483647,
|
||||
int = u64(maxval!(i64)), isize = u64(maxval!(i64)),
|
||||
u8 = 255,
|
||||
u16 = 65535,
|
||||
u32 = 4294967295,
|
||||
u64 = maxval!(u64), usize = maxval!(u64),
|
||||
})
|
||||
|
||||
integer_max proc(type Type) u64 {
|
||||
return match type {
|
||||
.i8: 127
|
||||
.i16: 32767
|
||||
.i32: 2147483647
|
||||
.int, .isize: u64(maxval!(i64))
|
||||
.u8: 255
|
||||
.u16: 65535
|
||||
.u32: 4294967295
|
||||
.u64, .usize: maxval!(u64)
|
||||
else: unreachable
|
||||
}
|
||||
return enummap.get(&integer_maxima, type)?
|
||||
}
|
||||
|
||||
@hide:file
|
||||
integer_minima :: $enummap.init_filled(Type, i64, i64(0), {
|
||||
i8 = i64(-128),
|
||||
i16 = i64(-32768),
|
||||
i32 = i64(-2147483648),
|
||||
int = minval!(i64), isize = minval!(i64),
|
||||
u8 = 0, u16 = 0, u32 = 0, u64 = 0, usize = 0,
|
||||
})
|
||||
|
||||
integer_min proc(type Type) i64 {
|
||||
return match type {
|
||||
.i8: -128
|
||||
.i16: -32768
|
||||
.i32: -2147483648
|
||||
.int, .isize: minval!(i64)
|
||||
.u8, .u16, .u32, .u64, .usize: 0
|
||||
else: unreachable
|
||||
}
|
||||
return enummap.get(&integer_minima, type)?
|
||||
}
|
||||
|
||||
ValueData :: union {
|
||||
@@ -412,24 +420,32 @@ aligned_size proc(size, alignment usize) usize {
|
||||
return divtrunc!(size + alignment - 1, alignment) * alignment
|
||||
}
|
||||
|
||||
@hide:file
|
||||
scalar_alignments :: $enummap.init_filled(Type, usize, usize(1), {
|
||||
float = 8, string = 8, function = 8, pointer = 8,
|
||||
})
|
||||
|
||||
@hide:file
|
||||
scalar_sizes :: $enummap.init_filled(Type, usize, usize(0), {
|
||||
float = 8, function = 8, pointer = 8,
|
||||
string = 16,
|
||||
bool = 1,
|
||||
void = 0,
|
||||
})
|
||||
|
||||
storage_alignment proc(module @Module, type Type, shape ArrayId) usize {
|
||||
if (aggregate(type)) return module.arrays.items[usize(shape)].alignment
|
||||
bits :: integer_bits(type)
|
||||
if (bits != 0) return divtrunc!(bits, 8)
|
||||
return if (type == .float or type == .string or type == .function or type == .pointer) 8 else 1
|
||||
if (enummap.get(&scalar_alignments, type)) |alignment| return alignment
|
||||
return 1
|
||||
}
|
||||
|
||||
storage_size proc(module @Module, type Type, shape ArrayId) usize {
|
||||
if (aggregate(type)) return module.arrays.items[usize(shape)].byte_size
|
||||
bits :: integer_bits(type)
|
||||
if (bits != 0) return divtrunc!(bits, 8)
|
||||
return match type {
|
||||
.float, .function, .pointer: 8
|
||||
.string: 16
|
||||
.bool: 1
|
||||
.void: 0
|
||||
else: unreachable
|
||||
}
|
||||
return enummap.get(&scalar_sizes, type)?
|
||||
}
|
||||
|
||||
#! loads a scalar or borrows an aggregate from byte cells without allocating.
|
||||
|
||||
Reference in New Issue
Block a user