Commit 3a9a24b6 authored by Christian Würdig's avatar Christian Würdig
Browse files

changed codegen interface

removed some cg attributes
fixed nodes attribute order to avoid padding
parent a1d83c4e
......@@ -22,6 +22,7 @@
#include "list.h"
#include "ident.h"
#include "be.h"
#include "belistsched.h"
#include "beabi_t.h"
......@@ -415,7 +416,7 @@ struct _arch_code_generator_if_t {
* @param env The architecture environment.
* @return A newly created code generator.
*/
void *(*init)(FILE *file, ir_graph *irg, const arch_env_t *env);
void *(*init)(FILE *file, const be_irg_t *birg);
/**
* Called, when the graph is being normalized.
......
......@@ -290,7 +290,7 @@ static void be_main_loop(FILE *file_handle)
cg_if = isa->impl->get_code_generator_if(isa);
/* get a code generator for this graph. */
birg.cg = cg_if->init(file_handle, birg.irg, env.arch_env);
birg.cg = cg_if->init(file_handle, &birg);
/* create the code generator and generate code. */
prepare_graph(&birg);
......
......@@ -21,6 +21,7 @@
#include "irgwalk.h"
#include "type.h"
#include "../be_t.h"
#include "../bearch.h"
#include "../besched.h"
#include "../beutil.h"
......@@ -532,7 +533,7 @@ static void firm_codegen_done(void *self)
free(self);
}
static void *firm_cg_init(FILE *file_handle, ir_graph *irg, const arch_env_t *env);
static void *firm_cg_init(FILE *file_handle, const be_irg_t *birg);
static const arch_code_generator_if_t firm_code_gen_if = {
firm_cg_init,
......@@ -544,11 +545,11 @@ static const arch_code_generator_if_t firm_code_gen_if = {
firm_codegen_done
};
static void *firm_cg_init(FILE *file_handle, ir_graph *irg, const arch_env_t *env)
static void *firm_cg_init(FILE *file_handle, const be_irg_t *birg)
{
firm_code_gen_t *cg = xmalloc(sizeof(*cg));
cg->impl = &firm_code_gen_if;
cg->irg = irg;
cg->irg = birg->irg;
return cg;
}
......
......@@ -23,6 +23,7 @@
#include "../benode_t.h"
#include "../belower.h"
#include "../besched_t.h"
#include "../be.h"
#include "bearch_ia32_t.h"
#include "ia32_new_nodes.h" /* ia32 nodes interface */
......@@ -42,19 +43,11 @@ static set *cur_reg_set = NULL;
#define is_Start(irn) (get_irn_opcode(irn) == iro_Start)
ir_node *ia32_new_NoReg_gp(ia32_code_gen_t *cg) {
if (! cg->noreg_gp) {
cg->noreg_gp = be_new_NoReg(&ia32_gp_regs[REG_XXX], cg->irg, get_irg_start_block(cg->irg));
}
return cg->noreg_gp;
return be_abi_get_callee_save_irn(cg->birg->abi, &ia32_gp_regs[REG_XXX]);
}
ir_node *ia32_new_NoReg_fp(ia32_code_gen_t *cg) {
if (! cg->noreg_fp) {
cg->noreg_fp = be_new_NoReg(&ia32_fp_regs[REG_XXXX], cg->irg, get_irg_start_block(cg->irg));
}
return cg->noreg_fp;
return be_abi_get_callee_save_irn(cg->birg->abi, &ia32_fp_regs[REG_XXXX]);
}
/**************************************************
......@@ -74,45 +67,6 @@ static ir_node *my_skip_proj(const ir_node *n) {
return (ir_node *)n;
}
static int is_Call_Proj(const ir_node *n) {
if (is_Proj(n) &&
is_Proj(get_Proj_pred(n)) &&
get_irn_mode(get_Proj_pred(n)) == mode_T &&
is_ia32_Call(get_Proj_pred(get_Proj_pred(n))))
{
return 1;
}
return 0;
}
static int is_Start_Proj(const ir_node *n) {
if (is_Proj(n) &&
is_Proj(get_Proj_pred(n)) &&
get_irn_mode(get_Proj_pred(n)) == mode_T &&
is_Start(get_Proj_pred(get_Proj_pred(n))))
{
return 1;
}
return 0;
}
static int is_P_frame_base_Proj(const ir_node *n) {
if (is_Proj(n) &&
is_Start(get_Proj_pred(n)) &&
get_Proj_proj(n) == pn_Start_P_frame_base)
{
return 1;
}
return 0;
}
static int is_used_by_Keep(const ir_node *n) {
return be_is_Keep(get_edge_src_irn(get_irn_out_edge_first(n)));
}
/**
* Return register requirements for an ia32 node.
* If the node returns a tuple (mode_T) then the proj's
......@@ -413,8 +367,8 @@ static ir_node *ia32_lower_reload(void *self, ir_node *reload) {
*/
static void ia32_codegen(void *self) {
ia32_code_gen_t *cg = self;
ir_graph *irg = cg->irg;
FILE *out = cg->out;
ir_graph *irg = cg->irg;
FILE *out = cg->out;
if (cg->emit_decls) {
ia32_gen_decls(cg->out);
......@@ -435,7 +389,7 @@ static void ia32_codegen(void *self) {
free(self);
}
static void *ia32_cg_init(FILE *F, ir_graph *irg, const arch_env_t *arch_env);
static void *ia32_cg_init(FILE *F, const be_irg_t *birg);
static const arch_code_generator_if_t ia32_code_gen_if = {
ia32_cg_init,
......@@ -450,20 +404,19 @@ static const arch_code_generator_if_t ia32_code_gen_if = {
/**
* Initializes the code generator.
*/
static void *ia32_cg_init(FILE *F, ir_graph *irg, const arch_env_t *arch_env) {
ia32_isa_t *isa = (ia32_isa_t *)arch_env->isa;
static void *ia32_cg_init(FILE *F, const be_irg_t *birg) {
ia32_isa_t *isa = (ia32_isa_t *)birg->main_env->arch_env->isa;
ia32_code_gen_t *cg = xcalloc(1, sizeof(*cg));
cg->impl = &ia32_code_gen_if;
cg->irg = irg;
cg->irg = birg->irg;
cg->reg_set = new_set(ia32_cmp_irn_reg_assoc, 1024);
cg->mod = firm_dbg_register("firm.be.ia32.cg");
cg->out = F;
cg->arch_env = arch_env;
cg->arch_env = birg->main_env->arch_env;
cg->types = pmap_create();
cg->tv_ent = pmap_create();
cg->noreg_gp = NULL;
cg->noreg_fp = NULL;
cg->birg = birg;
isa->num_codegens++;
......
......@@ -4,6 +4,7 @@
#include "debug.h"
#include "bearch_ia32.h"
#include "ia32_nodes_attr.h"
#include "../be.h"
/* some typedefs */
......@@ -15,12 +16,9 @@ typedef struct _ia32_code_gen_t {
set *reg_set; /**< set to memorize registers for non-ia32 nodes (e.g. phi nodes) */
firm_dbg_module_t *mod; /**< debugging module */
int emit_decls; /**< flag indicating if decls were already emitted */
int has_alloca; /**< indicates whether the irg contains an alloca or not */
const ia32_register_req_t **reg_param_req; /**< hold the requirements for the reg param nodes */
pmap *types; /**< A map of modes to primitive types */
pmap *tv_ent; /**< A map of entities that store tarvals */
ir_node *noreg_gp; /**< Holds the unique per irg GP NoReg node */
ir_node *noreg_fp; /**< Holds the unique per irg FP NoReg node */
const be_irg_t *birg; /**< The be-irg (contains additional information about the irg) */
} ia32_code_gen_t;
typedef struct _ia32_isa_t {
......
......@@ -710,85 +710,8 @@ void emit_Proj(ir_node *irn, emit_env_t *env) {
********************/
void emit_ia32_Call(ir_node *irn, emit_env_t *emit_env) {
int i, n = get_irn_arity(irn);
int args_size = 0;
ir_node *sync = get_irn_n(irn, n - 1);
FILE *F = emit_env->out;
const lc_arg_env_t *env = ia32_get_arg_env();
if (get_irn_op(sync) == op_Sync) {
/* We have stack arguments */
ir_node **args = get_Sync_preds_arr(sync);
for (i = 0; i < get_Sync_n_preds(sync); i++) {
ir_node *n = get_irn_n(args[i], 1);
lc_efprintf(env, F, "\tpush %1D\t\t\t\t/* push %+F(%+F) on stack */\n", n, args[i], n);
if (mode_is_float(get_irn_mode(n))) {
args_size += 4;
}
else {
args_size += 16;
}
}
}
lc_efprintf(env, F, "\tcall %C\t\t\t/* %+F */\n", irn, irn);
if (get_irn_op(sync) == op_Sync) {
/* We had stack arguments: clear the stack */
fprintf(F, "\tadd %d, ", args_size);
if (emit_env->cg->has_alloca) {
fprintf(F, "%%ebp");
}
else {
fprintf(F, "%%esp");
}
fprintf(F, "\t\t\t\t/* clear stack after call */\n");
}
}
/**
* Emits code for Alloca (increase stack pointer, cpoy to destination)
*/
void emit_Alloca(ir_node *irn, emit_env_t *emit_env, int is_imm) {
const lc_arg_env_t *env = ia32_get_arg_env();
FILE *F = emit_env->out;
char *sp;
if (emit_env->cg->has_alloca) {
sp = "%ebp";
}
else {
sp = "%esp";
}
/* allocate the memory */
fprintf(F, "\tsub %s", sp);
if (is_imm) {
lc_efprintf(env, F, "%C", irn);
}
else {
lc_efprintf(env, F, "%1S", irn);
}
fprintf(F, "\t\t\t\t/* reserve memory on stack */\n");
/* copy the new stack pointer to destination register */
lc_efprintf(env, F, "\tmov %s, %1D\t\t\t/* copy stack pointer to destination */\n", sp, irn);
}
void emit_ia32_Alloca(ir_node *irn, emit_env_t *emit_env) {
emit_Alloca(irn, emit_env, 0);
}
void emit_ia32_Alloca_i(ir_node *irn, emit_env_t *emit_env) {
emit_Alloca(irn, emit_env, 1);
}
/***********************************************************************************
......
......@@ -55,15 +55,15 @@ typedef struct _ia32_attr_t {
ia32_am_flavour_t am_flavour; /**<< the concrete addrmode characteristics */
struct obstack *am_offs; /**<< offsets for AddrMode */
char offs_sign; /**<< the sign of the first offset */
int am_scale; /**<< addrmode scale for index register */
char offs_sign; /**<< the sign of the first offset */
char use_frame; /**<< indicates whether the operation uses the frame pointer or not */
tarval *tv; /**<< tarval for immediate operations */
char *sc; /**<< symconst name */
char *cnst; /**<< points to the string representation of the constant value (either tv or sc) */
char use_frame; /**<< indicates whether the operation uses the frame pointer or not */
ir_mode *ls_mode; /**<< the mode of the stored/loaded value */
ia32_op_flavour_t op_flav; /**<< flavour of an op (flavour_Div/Mod/DivMod/Mul/Mulh) */
......
......@@ -83,8 +83,6 @@ $arch = "ia32";
# 1 - caller save (register must be saved by the caller of a function)
# 2 - callee save (register must be saved by the called function)
# 4 - ignore (do not assign this register)
# 8 - this is the stack pointer
# 16 - this is the base pointer
# NOTE: Make sure to list the registers returning the call-result before all other
# caller save registers and in the correct order, otherwise it will break
# the magic!
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment