aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2016-11-16 18:27:54 +0000
committerGinger Bill <bill@gingerbill.org>2016-11-16 18:27:54 +0000
commit4895031df56c8378db756db8d330f5cb07d4b14a (patch)
tree71fcbfe366e88bb5ca7785305dc9035dd71072f7
parente2d98324bae3c8e5f5e41d0fad9b67bfe2d345d1 (diff)
Actually fix alignment for vectors
Whoops :P
-rw-r--r--src/checker/types.cpp2
-rw-r--r--src/ssa.cpp42
2 files changed, 37 insertions, 7 deletions
diff --git a/src/checker/types.cpp b/src/checker/types.cpp
index 98b5f297f..92111f186 100644
--- a/src/checker/types.cpp
+++ b/src/checker/types.cpp
@@ -1059,7 +1059,7 @@ i64 type_align_of(BaseTypeSizes s, gbAllocator allocator, Type *t) {
return type_align_of(s, allocator, t->Array.elem);
case Type_Vector: {
i64 size = type_size_of(s, allocator, t->Vector.elem);
- i64 count = gb_max(prev_pow2(size), 1);
+ i64 count = gb_max(prev_pow2(t->Vector.count), 1);
i64 total = size * count;
return gb_clamp(total, 1, s.max_align);
} break;
diff --git a/src/ssa.cpp b/src/ssa.cpp
index a20756e7d..47b81a8e0 100644
--- a/src/ssa.cpp
+++ b/src/ssa.cpp
@@ -1907,8 +1907,8 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t) {
}
- Type *src = get_enum_base_type(base_type(src_type));
- Type *dst = get_enum_base_type(base_type(t));
+ Type *src = base_type(get_enum_base_type(src_type));
+ Type *dst = base_type(get_enum_base_type(t));
if (value->kind == ssaValue_Constant) {
if (is_type_any(dst)) {
@@ -3021,13 +3021,43 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
case BuiltinProc_abs: {
ssa_emit_comment(proc, make_string("abs"));
+ gbAllocator a = proc->module->allocator;
ssaValue *x = ssa_build_expr(proc, ce->args[0]);
- Type *t = ssa_type(x);
+ Type *original_type = ssa_type(x);
+ Type *t = original_type;
+ i64 sz = type_size_of(proc->module->sizes, a, t);
+ GB_ASSERT(is_type_integer(t) || is_type_float(t));
+ if (is_type_float(t)) {
+ if (sz == 4) {
+ t = t_i32;
+ } else if (sz == 8) {
+ t = t_i64;
+ } else {
+ GB_PANIC("unknown float type for `abs`");
+ }
+
+ x = ssa_emit_bitcast(proc, x, t);
+ }
- ssaValue *neg_x = ssa_emit_arith(proc, Token_Sub, v_zero, x, t);
- ssaValue *cond = ssa_emit_comp(proc, Token_Lt, x, v_zero);
- return ssa_emit_select(proc, cond, neg_x, x);
+ /*
+ NOTE(bill): See Hacker's Delight, section 2-4.
+ m := x >> (int_size-1)
+ b := x ^ m
+ return b - m
+ */
+
+ ssaValue *m = ssa_emit_arith(proc, Token_Shr,
+ x,
+ ssa_make_value_constant(a, t, make_exact_value_integer(sz-1)),
+ t);
+ ssaValue *b = ssa_emit_arith(proc, Token_Xor, x, m, t);
+ ssaValue *v = ssa_emit_arith(proc, Token_Sub, b, m, t);
+
+ if (is_type_float(t)) {
+ v = ssa_emit_bitcast(proc, v, original_type);
+ }
+ return v;
} break;
case BuiltinProc_enum_to_string: {