mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-25 15:05:00 -07:00
f16/f128,u|i128, basic vector support.
This commit is contained in:
+28
-13
@@ -96,14 +96,18 @@ void ssa_print_type(gbFile *f, BaseTypeSizes s, Type *t) {
|
||||
case Basic_i16: ssa_fprintf(f, "i16"); break;
|
||||
case Basic_i32: ssa_fprintf(f, "i32"); break;
|
||||
case Basic_i64: ssa_fprintf(f, "i64"); break;
|
||||
case Basic_i128: ssa_fprintf(f, "i128"); break;
|
||||
case Basic_u8: ssa_fprintf(f, "i8"); break;
|
||||
case Basic_u16: ssa_fprintf(f, "i16"); break;
|
||||
case Basic_u32: ssa_fprintf(f, "i32"); break;
|
||||
case Basic_u64: ssa_fprintf(f, "i64"); break;
|
||||
case Basic_u128: ssa_fprintf(f, "u128"); break;
|
||||
case Basic_f16: ssa_fprintf(f, "half"); break;
|
||||
case Basic_f32: ssa_fprintf(f, "float"); break;
|
||||
case Basic_f64: ssa_fprintf(f, "double"); break;
|
||||
case Basic_rawptr: ssa_fprintf(f, "%%-rawptr"); break;
|
||||
case Basic_string: ssa_fprintf(f, "%%-string"); break;
|
||||
case Basic_f128: ssa_fprintf(f, "fp128"); break;
|
||||
case Basic_rawptr: ssa_fprintf(f, "%%.rawptr"); break;
|
||||
case Basic_string: ssa_fprintf(f, "%%.string"); break;
|
||||
case Basic_uint: ssa_fprintf(f, "i%lld", word_bits); break;
|
||||
case Basic_int: ssa_fprintf(f, "i%lld", word_bits); break;
|
||||
}
|
||||
@@ -113,6 +117,12 @@ void ssa_print_type(gbFile *f, BaseTypeSizes s, Type *t) {
|
||||
ssa_print_type(f, s, t->array.elem);
|
||||
ssa_fprintf(f, "]");
|
||||
break;
|
||||
case Type_Vector: {
|
||||
// TODO(bill): actually do correctly
|
||||
ssa_fprintf(f, "<%lld x ", t->vector.count);
|
||||
ssa_print_type(f, s, t->vector.elem);
|
||||
ssa_fprintf(f, ">");
|
||||
} break;
|
||||
case Type_Slice:
|
||||
ssa_fprintf(f, "{");
|
||||
ssa_print_type(f, s, t->slice.elem);
|
||||
@@ -366,11 +376,15 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) {
|
||||
case ssaInstr_BinaryOp: {
|
||||
auto *bo = &value->instr.binary_op;
|
||||
Type *type = ssa_value_type(bo->left);
|
||||
Type *elem_type = type;
|
||||
while (elem_type->kind == Type_Vector) {
|
||||
elem_type = elem_type->vector.elem;
|
||||
}
|
||||
|
||||
ssa_fprintf(f, "%%%d = ", value->id);
|
||||
|
||||
if (gb_is_between(bo->op.kind, Token__ComparisonBegin+1, Token__ComparisonEnd-1)) {
|
||||
if (is_type_float(type)) {
|
||||
if (is_type_float(elem_type)) {
|
||||
ssa_fprintf(f, "fcmp ");
|
||||
switch (bo->op.kind) {
|
||||
case Token_CmpEq: ssa_fprintf(f, "oeq"); break;
|
||||
@@ -384,7 +398,7 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) {
|
||||
ssa_fprintf(f, "icmp ");
|
||||
if (bo->op.kind != Token_CmpEq &&
|
||||
bo->op.kind != Token_NotEq) {
|
||||
if (is_type_unsigned(type)) {
|
||||
if (is_type_unsigned(elem_type)) {
|
||||
ssa_fprintf(f, "u");
|
||||
} else {
|
||||
ssa_fprintf(f, "s");
|
||||
@@ -400,24 +414,25 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (is_type_float(type))
|
||||
if (is_type_float(elem_type))
|
||||
ssa_fprintf(f, "f");
|
||||
|
||||
switch (bo->op.kind) {
|
||||
case Token_Add: ssa_fprintf(f, "add"); break;
|
||||
case Token_Sub: ssa_fprintf(f, "sub"); break;
|
||||
case Token_And: ssa_fprintf(f, "and"); break;
|
||||
case Token_Or: ssa_fprintf(f, "or"); break;
|
||||
case Token_Or: ssa_fprintf(f, "or"); break;
|
||||
case Token_Xor: ssa_fprintf(f, "xor"); break;
|
||||
case Token_Shl: ssa_fprintf(f, "shl"); break;
|
||||
case Token_Shr: ssa_fprintf(f, "lshr"); break;
|
||||
case Token_Mul: ssa_fprintf(f, "mul"); break;
|
||||
|
||||
case Token_AndNot: GB_PANIC("Token_AndNot Should never be called");
|
||||
|
||||
case Token_Mul: ssa_fprintf(f, "mul"); break;
|
||||
|
||||
default: {
|
||||
if (!is_type_float(type)) {
|
||||
if (is_type_unsigned(type)) ssa_fprintf(f, "u");
|
||||
else ssa_fprintf(f, "s");
|
||||
if (!is_type_float(elem_type)) {
|
||||
if (is_type_unsigned(elem_type)) ssa_fprintf(f, "u");
|
||||
else ssa_fprintf(f, "s");
|
||||
}
|
||||
|
||||
switch (bo->op.kind) {
|
||||
@@ -483,12 +498,12 @@ void ssa_print_llvm_ir(gbFile *f, ssaModule *m) {
|
||||
ssa_fprintf(f, "target datalayout = %.*s\n", LIT(m->layout));
|
||||
}
|
||||
|
||||
ssa_print_encoded_local(f, make_string("-string"));
|
||||
ssa_print_encoded_local(f, make_string(".string"));
|
||||
ssa_fprintf(f, " = type {i8*, ");
|
||||
ssa_print_type(f, m->sizes, t_int);
|
||||
ssa_fprintf(f, "} ; Basic_string\n\n");
|
||||
|
||||
ssa_print_encoded_local(f, make_string("-rawptr"));
|
||||
ssa_print_encoded_local(f, make_string(".rawptr"));
|
||||
ssa_fprintf(f, " = type i8*");
|
||||
ssa_fprintf(f, " ; Basic_rawptr\n\n");
|
||||
|
||||
|
||||
+44
-9
@@ -284,8 +284,15 @@ Type *ssa_instr_type(ssaInstr *instr) {
|
||||
return instr->binary_op.type;
|
||||
case ssaInstr_Conv:
|
||||
return instr->conv.to;
|
||||
case ssaInstr_Call:
|
||||
return instr->call.type;
|
||||
case ssaInstr_Call: {
|
||||
Type *pt = instr->call.type;
|
||||
GB_ASSERT(pt->kind == Type_Proc);
|
||||
auto *tuple = &pt->proc.results->tuple;
|
||||
if (tuple->variable_count != 1)
|
||||
return pt->proc.results;
|
||||
else
|
||||
return tuple->variables[0]->type;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -560,12 +567,28 @@ b32 ssa_is_blank_ident(AstNode *node) {
|
||||
}
|
||||
|
||||
|
||||
ssaInstr *ssa_get_last_instr(ssaBlock *block) {
|
||||
isize len = gb_array_count(block->instrs);
|
||||
if (len > 0) {
|
||||
ssaValue *v = block->instrs[len-1];
|
||||
GB_ASSERT(v->kind == ssaValue_Instr);
|
||||
return &v->instr;
|
||||
}
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
ssaValue *ssa_emit(ssaProcedure *proc, ssaValue *instr) {
|
||||
ssaBlock *b = proc->curr_block;
|
||||
instr->instr.parent = b;
|
||||
if (b) {
|
||||
gb_array_append(b->instrs, instr);
|
||||
ssaInstr *i = ssa_get_last_instr(b);
|
||||
if (i && (i->kind == ssaInstr_Ret || i->kind == ssaInstr_Unreachable)) {
|
||||
// NOTE(bill): any instruction in the current block after a `ret`
|
||||
// or an `unreachable`, is never executed
|
||||
} else {
|
||||
gb_array_append(b->instrs, instr);
|
||||
}
|
||||
}
|
||||
return instr;
|
||||
}
|
||||
@@ -688,11 +711,13 @@ void ssa_emit_if(ssaProcedure *proc, ssaValue *cond, ssaBlock *true_block, ssaBl
|
||||
|
||||
ssaBlock *ssa__make_block(ssaProcedure *proc, AstNode *node, String label) {
|
||||
Scope *scope = NULL;
|
||||
Scope **found = map_get(&proc->module->info->scopes, hash_pointer(node));
|
||||
if (found) {
|
||||
scope = *found;
|
||||
} else {
|
||||
GB_PANIC("Block scope not found");
|
||||
if (node != NULL) {
|
||||
Scope **found = map_get(&proc->module->info->scopes, hash_pointer(node));
|
||||
if (found) {
|
||||
scope = *found;
|
||||
} else {
|
||||
GB_PANIC("Block scope not found for %.*s", LIT(ast_node_strings[node->kind]));
|
||||
}
|
||||
}
|
||||
|
||||
ssaValue *block = ssa_make_value_block(proc, node, scope, label);
|
||||
@@ -1021,6 +1046,8 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t) {
|
||||
|
||||
Type *src = get_base_type(src_type);
|
||||
Type *dst = get_base_type(t);
|
||||
if (are_types_identical(t, src_type))
|
||||
return value;
|
||||
|
||||
if (value->kind == ssaValue_Constant) {
|
||||
if (dst->kind == Type_Basic)
|
||||
@@ -1035,6 +1062,12 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t) {
|
||||
if (dz >= sz) {
|
||||
kind = ssaConv_zext;
|
||||
}
|
||||
|
||||
if (sz == dz) {
|
||||
// NOTE(bill): In LLVM, all integers are signed and rely upon 2's compliment
|
||||
return value;
|
||||
}
|
||||
|
||||
return ssa_emit(proc, ssa_make_instr_conv(proc, kind, value, src, dst));
|
||||
}
|
||||
|
||||
@@ -1117,7 +1150,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
|
||||
case_ast_node(i, Ident, expr);
|
||||
Entity *e = *map_get(&proc->module->info->uses, hash_pointer(expr));
|
||||
if (e->kind == Entity_Builtin) {
|
||||
GB_PANIC("TODO(bill): Entity_Builtin");
|
||||
GB_PANIC("TODO(bill): ssa_build_single_expr Entity_Builtin");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1181,6 +1214,8 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
|
||||
case Token_Or:
|
||||
case Token_Xor:
|
||||
case Token_AndNot:
|
||||
case Token_Shl:
|
||||
case Token_Shr:
|
||||
return ssa_emit_arith(proc, be->op,
|
||||
ssa_build_expr(proc, be->left),
|
||||
ssa_build_expr(proc, be->right),
|
||||
|
||||
Reference in New Issue
Block a user