Files
c3c/src/compiler/tilde_internal.h
2023-01-19 00:08:31 +01:00

187 lines
6.7 KiB
C

#pragma once
#include "codegen_internal.h"
// Copyright (c) 2022 Christoffer Lerno. All rights reserved.
// Use of this source code is governed by a LGPLv3.0
// a copy of which can be found in the LICENSE file.
#undef TB_Reg
#include <tb.h>
typedef enum
{
TBE_VALUE,
TBE_ADDRESS,
TBE_ADDRESS_OPTIONAL,
} TBBackendValueKind;
typedef struct
{
TBBackendValueKind kind: 5;
AlignSize alignment;
Type *type; // Should never be a distinct or canonical type.
TB_Reg reg;
TB_Reg failable;
} TBEValue;
typedef struct
{
Module *code_module;
const char *object_filename;
const char *ir_filename;
const char *asm_filename;
TB_Function **functions;
TB_Module *module;
TB_FeatureSet features;
struct
{
const char *name;
FunctionPrototype *prototype;
Type *rtype;
} cur_func;
Decl *curr_func;
TB_Function *f;
TB_Reg opt_var;
TB_Label catch_block;
TBEValue retval;
TB_Reg return_out;
TB_Reg optional_out;
struct
{
TB_Reg last_ptr;
TB_Reg stack_slot;
} debug;
} TildeContext;
TB_DataType tildetype(Type *type);
#define PUSH_OPT() TB_Label _old_catch = c->catch_block; TB_Reg _old_opt_var = c->opt_var
#define POP_OPT() c->catch_block = _old_catch; c->opt_var = _old_opt_var
// -- store ---
static inline void tilde_store_internal(TildeContext *c, TB_DataType type, TB_Reg addr, TB_Reg value, AlignSize alignment);
void tilde_store_to_ptr_raw_aligned(TildeContext *c, Type *type, TB_Reg addr, TB_Reg value, AlignSize alignment);
void tilde_store_to_ptr_raw(TildeContext *c, TB_Reg addr, TB_Reg value, Type *type);
void tilde_store_value_raw(TildeContext *c, TBEValue *destination, TB_Reg value);
void tilde_store_to_ptr_aligned(TildeContext *c, TB_Reg destination, TBEValue *value, AlignSize alignment);
void tilde_store_value_aligned(TildeContext *c, TB_Reg destination, TBEValue *value, AlignSize alignment);
void tilde_store(TildeContext *c, TBEValue *dst, TBEValue *value);
void tilde_store_decl_raw(TildeContext *c, Decl *decl, TB_Reg value);
TB_Reg tilde_load_natural_alignment(TildeContext *c, Type *type, TB_Reg pointer);
TB_Reg tilde_load_value_store(TildeContext *c, TBEValue *value);
void tilde_store_zero(TildeContext *c, Type *type, TB_Reg addr, AlignSize alignment);
void tilde_store_value_zero(TildeContext *c, TBEValue *to);
INLINE void tilde_store_to_ptr(TildeContext *c, TB_Reg destination, TBEValue *value);
// -- load ---
static inline TB_Reg tilde_load(TildeContext *c, TB_DataType type, TB_Reg addr, AlignSize alignment);
TB_Reg tilde_load_abi_alignment(TildeContext *c, Type *type, TB_Reg pointer);
TB_Reg tilde_load_value(TildeContext *c, TBEValue *value);
// -- value --
void value_set(TBEValue *value, TB_Reg val, Type *type);
void value_set_address(TBEValue *value, TB_Reg addr, Type *type, AlignSize alignment);
void value_set_address_abi_aligned(TBEValue *value, TB_Reg val, Type *type);
void value_set_decl_address(TildeContext *c, TBEValue *value, Decl *decl);
void value_set_decl(TildeContext *c, TBEValue *value, Decl *decl);
void value_addr(TildeContext *c, TBEValue *value);
static inline bool value_is_addr(TBEValue *value) { return value->kind == TBE_ADDRESS || value->kind == TBE_ADDRESS_OPTIONAL; }
void value_fold_optional(TildeContext *c, TBEValue *value);
void value_rvalue(TildeContext *c, TBEValue *value);
TB_Reg tilde_get_ref(TildeContext *c, Decl *decl);
TB_Reg tilde_get_opt_ref(TildeContext *c, Decl *decl);
TB_Reg tilde_get_const_int(TildeContext *c, Type *type, uint64_t i);
TB_Reg tilde_get_const_float(TildeContext *c, Type *type, double d);
TB_Register tilde_get_zero(TildeContext *c, Type *type);
// -- type ---
// -- instructions --
void tilde_emit_cond_br(TildeContext *c, TBEValue *value, TB_Label then_block, TB_Label else_block);
TB_Reg tilde_emit_lshr_fixed(TildeContext *c, Type *type, TB_Reg reg, int shift);
// -- stmt ---
void tilde_emit_stmt(TildeContext *c, Ast *ast);
// -- general ---
TB_Register tilde_emit_is_no_error(TildeContext *c, TB_Reg reg);
void tilde_emit_global_initializer(TildeContext *c, Decl *decl);
TB_Reg tilde_emit_alloca(TildeContext *c, Type *type, AlignSize alignment);
void tilde_emit_local_var_alloca(TildeContext *c, Decl *decl);
void tilde_emit_and_set_decl_alloca(TildeContext *c, Decl *decl);
INLINE TB_Linkage tilde_linkage_for_decl(Decl *decl);
void tilde_emit_parameter(TildeContext *c, TB_Reg *args, unsigned *arg_count_ref, ABIArgInfo *info, TBEValue *be_value, Type *type);
// -- expr --
void tilde_emit_expr(TildeContext *c, TBEValue *result, Expr *expr);
TBEValue tilde_emit_assign_expr(TildeContext *c, TBEValue *ref, Expr *expr, TB_Reg optional);
void tilde_emit_cast(TildeContext *c, CastKind cast_kind, Expr *expr, TBEValue *value, Type *to_type, Type *from_type);
// -- comparisons --
void tilde_emit_comp(TildeContext *c, TBEValue *result, TBEValue *lhs, TBEValue *rhs, BinaryOp binary_op);
void tilde_emit_int_comp(TildeContext *c, TBEValue *result, TBEValue *lhs, TBEValue *rhs, BinaryOp binary_op);
void tilde_emit_int_comp_zero(TildeContext *c, TBEValue *result, TBEValue *lhs, BinaryOp binary_op);
void tilde_emit_int_comp_raw(TildeContext *c, TBEValue *result, Type *lhs_type, Type *rhs_type, TB_Reg lhs_value, TB_Reg rhs_value, BinaryOp binary_op);
// -- optional --
void tilde_emit_jump_to_optional_exit(TildeContext *c, TB_Reg opt_value);
TB_Reg tilde_emit_is_no_opt(TildeContext *c, TB_Reg error_value);
// -- jumps ---
bool tilde_emit_goto_if_needed(TildeContext *c, TB_Label jump);
INLINE void tilde_emit_block(TildeContext *c, TB_Label block);
void tilde_emit_memclear_size_align(TildeContext *c, TB_Register ref, uint64_t size, AlignSize align);
#define EMIT_LOC(x, y) do { } while(0)
static inline void tilde_store_internal(TildeContext *c, TB_DataType type, TB_Reg addr, TB_Reg value, AlignSize alignment)
{
assert(alignment > 0);
tb_inst_store(c->f, type, addr, value, alignment);
}
static inline TB_Reg tilde_load(TildeContext *c, TB_DataType type, TB_Reg addr, AlignSize alignment)
{
assert(alignment > 0);
return tb_inst_load(c->f, type, addr, alignment);
}
static inline TB_Reg decl_reg(Decl *decl)
{
if (decl->decl_kind == DECL_VAR && decl->var.kind == VARDECL_UNWRAPPED) return decl_reg(decl->var.alias);
assert(!decl->is_value);
return decl->tb_register;
}
TB_DataType tilde_get_int_type_of_bytesize(int byte_size);
TB_FunctionPrototype *tilde_get_func_prototype(TildeContext *c, FunctionPrototype *prototype);
INLINE TB_Linkage tilde_linkage_for_decl(Decl *decl)
{
if (!decl->is_external_visible && decl->visibility == VISIBLE_LOCAL) return TB_LINKAGE_PRIVATE;
return TB_LINKAGE_PUBLIC;
}
INLINE void tilde_store_to_ptr(TildeContext *c, TB_Reg destination, TBEValue *value)
{
return tilde_store_to_ptr_aligned(c, destination, value, type_alloca_alignment(value->type));
}
INLINE void tilde_emit_block(TildeContext *c, TB_Label block)
{
tb_inst_set_label(c->f, block);
}