aboutsummaryrefslogtreecommitdiff
path: root/src/ir.c
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-06-01 14:23:46 +0100
committerGinger Bill <bill@gingerbill.org>2017-06-01 14:23:46 +0100
commit0d4945dc8788e8aa134fbdbd0941d9a6db0b67bc (patch)
tree5344e3270f99746fdcee6237ebe768c1babfb822 /src/ir.c
parentfec6df65b3306005077ee6124458eaaf3ea7ce2c (diff)
Implement u128/i128 features; Add bits.odin
Diffstat (limited to 'src/ir.c')
-rw-r--r--src/ir.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/src/ir.c b/src/ir.c
index 6702096c4..e505865cd 100644
--- a/src/ir.c
+++ b/src/ir.c
@@ -2117,9 +2117,26 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *
if (op == Token_ModMod) {
irValue *n = left;
irValue *m = right;
- irValue *a = ir_emit(proc, ir_instr_binary_op(proc, Token_Mod, n, m, type));
- irValue *b = ir_emit(proc, ir_instr_binary_op(proc, Token_Add, a, m, type));
- return ir_emit(proc, ir_instr_binary_op(proc, Token_Mod, b, m, type));
+ irValue *a = ir_emit_arith(proc, Token_Mod, n, m, type);
+ irValue *b = ir_emit_arith(proc, Token_Add, a, m, type);
+ return ir_emit_arith(proc, Token_Mod, b, m, type);
+ }
+
+ if (is_type_i128_or_u128(type)) {
+ // IMPORTANT NOTE(bill): LLVM is goddamn buggy!
+ bool is_unsigned = is_type_unsigned(type);
+ char *name = NULL;
+ if (op == Token_Quo) {
+ name = is_unsigned ? "__udivti3" : "__divti3";
+ } else if (op == Token_Mod) {
+ name = is_unsigned ? "__umodti3" : "__modti3";
+ }
+ if (name != NULL) {
+ irValue **args = gb_alloc_array(proc->module->allocator, irValue *, 2);
+ args[0] = left;
+ args[1] = right;
+ return ir_emit_global_call(proc, name, args, 2);
+ }
}
return ir_emit(proc, ir_instr_binary_op(proc, op, left, right, type));
@@ -7529,6 +7546,8 @@ void ir_gen_tree(irGen *s) {
case Basic_u32:
case Basic_i64:
case Basic_u64:
+ case Basic_i128:
+ case Basic_u128:
case Basic_int:
case Basic_uint: {
tag = ir_emit_conv(proc, ti_ptr, t_type_info_integer_ptr);