Commit b0e09fe0 authored by Matthias Braun's avatar Matthias Braun
Browse files

no environment anymore for emitters

[r15927]
parent 320434a2
......@@ -48,11 +48,12 @@
#define SNPRINTF_BUF_LEN 128
static const arch_env_t *arch_env;
/**
* Returns the register at in position pos.
*/
static const arch_register_t *get_in_reg(const arch_env_t *arch_env,
const ir_node *node, int pos)
static const arch_register_t *get_in_reg(const ir_node *node, int pos)
{
ir_node *op;
const arch_register_t *reg = NULL;
......@@ -72,8 +73,7 @@ static const arch_register_t *get_in_reg(const arch_env_t *arch_env,
/**
* Returns the register at out position pos.
*/
static const arch_register_t *get_out_reg(const arch_env_t *arch_env,
const ir_node *node, int pos)
static const arch_register_t *get_out_reg(const ir_node *node, int pos)
{
ir_node *proj;
const arch_register_t *reg = NULL;
......@@ -115,32 +115,31 @@ static const arch_register_t *get_out_reg(const arch_env_t *arch_env,
* |_| |_|
*************************************************************/
void TEMPLATE_emit_immediate(TEMPLATE_emit_env_t *env, const ir_node *node)
void TEMPLATE_emit_immediate(const ir_node *node)
{
(void) env;
(void) node;
/* TODO */
}
void TEMPLATE_emit_source_register(TEMPLATE_emit_env_t *env, const ir_node *node, int pos)
void TEMPLATE_emit_source_register(const ir_node *node, int pos)
{
const arch_register_t *reg = get_in_reg(env->arch_env, node, pos);
be_emit_string(env->emit, arch_register_get_name(reg));
const arch_register_t *reg = get_in_reg(node, pos);
be_emit_string(arch_register_get_name(reg));
}
void TEMPLATE_emit_dest_register(TEMPLATE_emit_env_t *env, const ir_node *node, int pos)
void TEMPLATE_emit_dest_register(const ir_node *node, int pos)
{
const arch_register_t *reg = get_out_reg(env->arch_env, node, pos);
be_emit_string(env->emit, arch_register_get_name(reg));
const arch_register_t *reg = get_out_reg(node, pos);
be_emit_string(arch_register_get_name(reg));
}
/**
* Returns the target label for a control flow node.
*/
static void TEMPLATE_emit_cfop_target(TEMPLATE_emit_env_t *env, const ir_node *node) {
static void TEMPLATE_emit_cfop_target(const ir_node *node) {
ir_node *block = get_irn_link(node);
be_emit_irprintf(env->emit, "BLOCK_%ld", get_irn_node_nr(block));
be_emit_irprintf("BLOCK_%ld", get_irn_node_nr(block));
}
/***********************************************************************************
......@@ -156,15 +155,15 @@ static void TEMPLATE_emit_cfop_target(TEMPLATE_emit_env_t *env, const ir_node *n
/**
* Emits code for a unconditional jump.
*/
static void emit_Jmp(TEMPLATE_emit_env_t *env, const ir_node *node) {
static void emit_Jmp(const ir_node *node) {
ir_node *block;
/* for now, the code works for scheduled and non-schedules blocks */
block = get_nodes_block(node);
be_emit_cstring(env->emit, "\tjmp ");
TEMPLATE_emit_cfop_target(env, node);
be_emit_finish_line_gas(env->emit, node);
be_emit_cstring("\tjmp ");
TEMPLATE_emit_cfop_target(node);
be_emit_finish_line_gas(node);
}
/**
......@@ -193,17 +192,17 @@ static void TEMPLATE_register_emitters(void) {
#undef EMIT
}
typedef void (*emit_func_ptr) (TEMPLATE_emit_env_t *, const ir_node *);
typedef void (*emit_func_ptr) (const ir_node *);
/**
* Emits code for a node.
*/
void TEMPLATE_emit_node(TEMPLATE_emit_env_t *env, const ir_node *node) {
void TEMPLATE_emit_node(const ir_node *node) {
ir_op *op = get_irn_op(node);
if (op->ops.generic) {
emit_func_ptr func = (emit_func_ptr) op->ops.generic;
(*func) (env, node);
(*func) (node);
} else {
ir_fprintf(stderr, "No emitter for node %+F\n", node);
}
......@@ -214,18 +213,18 @@ void TEMPLATE_emit_node(TEMPLATE_emit_env_t *env, const ir_node *node) {
* and emits code for each node.
*/
void TEMPLATE_gen_block(ir_node *block, void *data) {
TEMPLATE_emit_env_t *env = data;
ir_node *node;
(void) data;
if (! is_Block(block))
return;
be_emit_cstring(env->emit, "BLOCK_");
be_emit_irprintf(env->emit, "%ld:\n", get_irn_node_nr(block));
be_emit_write_line(env->emit);
be_emit_cstring("BLOCK_");
be_emit_irprintf("%ld:\n", get_irn_node_nr(block));
be_emit_write_line();
sched_foreach(block, node) {
TEMPLATE_emit_node(env, node);
TEMPLATE_emit_node(node);
}
}
......@@ -233,27 +232,27 @@ void TEMPLATE_gen_block(ir_node *block, void *data) {
/**
* Emits code for function start.
*/
void TEMPLATE_emit_func_prolog(TEMPLATE_emit_env_t *env, ir_graph *irg) {
void TEMPLATE_emit_func_prolog(ir_graph *irg) {
const char *irg_name = get_entity_name(get_irg_entity(irg));
/* TODO: emit function header */
be_emit_cstring(env->emit, "/* start of ");
be_emit_string(env->emit, irg_name);
be_emit_cstring(env->emit, " */\n");
be_emit_write_line(env->emit);
be_emit_cstring("/* start of ");
be_emit_string(irg_name);
be_emit_cstring(" */\n");
be_emit_write_line();
}
/**
* Emits code for function end
*/
void TEMPLATE_emit_func_epilog(TEMPLATE_emit_env_t *env, ir_graph *irg) {
void TEMPLATE_emit_func_epilog(ir_graph *irg) {
const char *irg_name = get_entity_name(get_irg_entity(irg));
/* TODO: emit function end */
be_emit_cstring(env->emit, "/* end of ");
be_emit_string(env->emit, irg_name);
be_emit_cstring(env->emit, " */\n");
be_emit_write_line(env->emit);
be_emit_cstring("/* end of ");
be_emit_string(irg_name);
be_emit_cstring(" */\n");
be_emit_write_line();
}
/**
......@@ -275,18 +274,14 @@ void TEMPLATE_gen_labels(ir_node *block, void *env) {
* Main driver
*/
void TEMPLATE_gen_routine(const TEMPLATE_code_gen_t *cg, ir_graph *irg) {
TEMPLATE_emit_env_t env;
env.isa = (TEMPLATE_isa_t *) cg->arch_env->isa;
env.emit = &env.isa->emit;
env.arch_env = cg->arch_env;
env.cg = cg;
arch_env = cg->arch_env;
/* register all emitter functions */
TEMPLATE_register_emitters();
TEMPLATE_emit_func_prolog(&env, irg);
irg_block_walk_graph(irg, TEMPLATE_gen_labels, NULL, &env);
irg_walk_blkwise_graph(irg, NULL, TEMPLATE_gen_block, &env);
TEMPLATE_emit_func_epilog(&env, irg);
TEMPLATE_emit_func_prolog(irg);
irg_block_walk_graph(irg, TEMPLATE_gen_labels, NULL, NULL);
irg_walk_blkwise_graph(irg, NULL, TEMPLATE_gen_block, NULL);
TEMPLATE_emit_func_epilog(irg);
}
......@@ -34,20 +34,14 @@
#include "bearch_TEMPLATE_t.h"
typedef struct _TEMPLATE_emit_env_t {
be_emit_env_t *emit;
const arch_env_t *arch_env;
const TEMPLATE_code_gen_t *cg;
TEMPLATE_isa_t *isa;
} TEMPLATE_emit_env_t;
void TEMPLATE_emit_source_register(TEMPLATE_emit_env_t *env, const ir_node *node, int pos);
void TEMPLATE_emit_dest_register(TEMPLATE_emit_env_t *env, const ir_node *node, int pos);
void TEMPLATE_emit_immediate(TEMPLATE_emit_env_t *env, const ir_node *node);
void TEMPLATE_emit_source_register(const ir_node *node, int pos);
void TEMPLATE_emit_dest_register(const ir_node *node, int pos);
void TEMPLATE_emit_immediate(const ir_node *node);
int get_TEMPLATE_reg_nr(ir_node *irn, int posi, int in_out);
const char *get_TEMPLATE_in_reg_name(ir_node *irn, int pos);
void TEMPLATE_gen_routine(const TEMPLATE_code_gen_t *cg, ir_graph *irg);
#endif
......@@ -136,19 +136,19 @@ $arch = "TEMPLATE";
); # %reg_classes
%emit_templates = (
S1 => "${arch}_emit_source_register(env, node, 0);",
S2 => "${arch}_emit_source_register(env, node, 1);",
S3 => "${arch}_emit_source_register(env, node, 2);",
S4 => "${arch}_emit_source_register(env, node, 3);",
S5 => "${arch}_emit_source_register(env, node, 4);",
S6 => "${arch}_emit_source_register(env, node, 5);",
D1 => "${arch}_emit_dest_register(env, node, 0);",
D2 => "${arch}_emit_dest_register(env, node, 1);",
D3 => "${arch}_emit_dest_register(env, node, 2);",
D4 => "${arch}_emit_dest_register(env, node, 3);",
D5 => "${arch}_emit_dest_register(env, node, 4);",
D6 => "${arch}_emit_dest_register(env, node, 5);",
C => "${arch}_emit_immediate(env, node);"
S1 => "${arch}_emit_source_register(node, 0);",
S2 => "${arch}_emit_source_register(node, 1);",
S3 => "${arch}_emit_source_register(node, 2);",
S4 => "${arch}_emit_source_register(node, 3);",
S5 => "${arch}_emit_source_register(node, 4);",
S6 => "${arch}_emit_source_register(node, 5);",
D1 => "${arch}_emit_dest_register(node, 0);",
D2 => "${arch}_emit_dest_register(node, 1);",
D3 => "${arch}_emit_dest_register(node, 2);",
D4 => "${arch}_emit_dest_register(node, 3);",
D5 => "${arch}_emit_dest_register(node, 4);",
D6 => "${arch}_emit_dest_register(node, 5);",
C => "${arch}_emit_immediate(node);"
);
#--------------------------------------------------#
......
......@@ -376,7 +376,6 @@ static TEMPLATE_isa_t TEMPLATE_isa_template = {
7, /* costs for a spill instruction */
5, /* costs for a reload instruction */
},
NULL_EMITTER, /* emitter environment */
};
/**
......@@ -393,7 +392,7 @@ static void *TEMPLATE_init(FILE *outfile) {
isa = xcalloc(1, sizeof(*isa));
memcpy(isa, &TEMPLATE_isa_template, sizeof(*isa));
be_emit_init_env(&isa->emit, outfile);
be_emit_init(outfile);
TEMPLATE_register_init();
TEMPLATE_create_opcodes();
......@@ -410,9 +409,9 @@ static void TEMPLATE_done(void *self) {
TEMPLATE_isa_t *isa = self;
/* emit now all global declarations */
be_gas_emit_decls(&isa->emit, isa->arch_isa.main_env, 0);
be_gas_emit_decls(isa->arch_isa.main_env, 0);
be_emit_destroy_env(&isa->emit);
be_emit_exit();
free(self);
}
......
......@@ -49,7 +49,6 @@ struct TEMPLATE_code_gen_t {
struct TEMPLATE_isa_t {
arch_isa_t arch_isa; /**< must be derived from arch_isa */
be_emit_env_t emit; /**< emit datastructure */
};
struct TEMPLATE_irn_ops_t {
......
This diff is collapsed.
......@@ -35,24 +35,15 @@
#include "bearch_arm_t.h"
/**
* The ARM emitter environment.
*/
typedef struct _arm_emit_env_t {
be_emit_env_t *emit; /**< environment for the generic GAS emitter. */
const arch_env_t *arch_env; /**< the architecture environment */
const arm_code_gen_t *cg; /**< the code generator object */
set *sym_or_tv; /**< set containing all indirect symbols/tarvals */
DEBUG_ONLY(firm_dbg_module_t *mod;)
} arm_emit_env_t;
void arm_emit_mode(arm_emit_env_t *env, const ir_node *node);
void arm_emit_source_register(arm_emit_env_t *env, const ir_node *node, int pos);
void arm_emit_dest_register(arm_emit_env_t *env, const ir_node *node, int pos);
void arm_emit_offset(arm_emit_env_t *env, const ir_node *node);
void arm_emit_immediate(arm_emit_env_t *env, const ir_node *node);
void arm_emit_shift(arm_emit_env_t *env, const ir_node *node);
void arm_emit_mode(const ir_node *node);
void arm_emit_source_register(const ir_node *node, int pos);
void arm_emit_dest_register(const ir_node *node, int pos);
void arm_emit_offset(const ir_node *node);
void arm_emit_immediate(const ir_node *node);
void arm_emit_shift(const ir_node *node);
void arm_gen_routine(const arm_code_gen_t *cg, ir_graph *irg);
void arm_init_emitter(void);
#endif
......@@ -150,18 +150,18 @@ $mode_fpa = "mode_E";
); # %reg_classes
%emit_templates = (
M => "${arch}_emit_mode(env, node);",
X => "${arch}_emit_shift(env, node);",
S0 => "${arch}_emit_source_register(env, node, 0);",
S1 => "${arch}_emit_source_register(env, node, 1);",
S2 => "${arch}_emit_source_register(env, node, 2);",
S3 => "${arch}_emit_source_register(env, node, 3);",
S4 => "${arch}_emit_source_register(env, node, 4);",
D0 => "${arch}_emit_dest_register(env, node, 0);",
D1 => "${arch}_emit_dest_register(env, node, 1);",
D2 => "${arch}_emit_dest_register(env, node, 2);",
C => "${arch}_emit_immediate(env, node);",
O => "${arch}_emit_offset(env, mode);",
M => "${arch}_emit_mode(node);",
X => "${arch}_emit_shift(node);",
S0 => "${arch}_emit_source_register(node, 0);",
S1 => "${arch}_emit_source_register(node, 1);",
S2 => "${arch}_emit_source_register(node, 2);",
S3 => "${arch}_emit_source_register(node, 3);",
S4 => "${arch}_emit_source_register(node, 4);",
D0 => "${arch}_emit_dest_register(node, 0);",
D1 => "${arch}_emit_dest_register(node, 1);",
D2 => "${arch}_emit_dest_register(node, 2);",
C => "${arch}_emit_immediate(node);",
O => "${arch}_emit_offset(mode);",
);
#--------------------------------------------------#
......
......@@ -765,7 +765,6 @@ static arm_isa_t arm_isa_template = {
0, /* use generic register names instead of SP, LR, PC */
ARM_FPU_ARCH_FPE, /* FPU architecture */
NULL, /* current code generator */
NULL_EMITTER, /* emitter environment */
};
/**
......@@ -784,7 +783,7 @@ static void *arm_init(FILE *file_handle) {
arm_register_init();
isa->cg = NULL;
be_emit_init_env(&isa->emit, file_handle);
be_emit_init(file_handle);
arm_create_opcodes();
arm_handle_intrinsics();
......@@ -807,9 +806,9 @@ static void *arm_init(FILE *file_handle) {
static void arm_done(void *self) {
arm_isa_t *isa = self;
be_gas_emit_decls(&isa->emit, isa->arch_isa.main_env, 1);
be_gas_emit_decls(isa->arch_isa.main_env, 1);
be_emit_destroy_env(&isa->emit);
be_emit_exit();
free(self);
}
......@@ -1286,6 +1285,7 @@ void be_init_arch_arm(void)
be_register_isa_if("arm", &arm_isa_if);
arm_init_transform();
arm_init_emitter();
}
BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_arm);
......@@ -157,7 +157,6 @@ struct _arm_isa_t {
int gen_reg_names; /**< use generic register names instead of SP, LR, PC */
int fpu_arch; /**< FPU architecture */
arm_code_gen_t *cg; /**< current code generator */
be_emit_env_t emit; /**< An emitter environment for the GAS emitter. */
};
......
......@@ -33,92 +33,94 @@
#include "ident.h"
#include "tv.h"
void be_emit_init_env(be_emit_env_t *env, FILE *F)
{
memset(env, 0, sizeof(env[0]));
FILE *emit_file;
struct obstack emit_obst;
int emit_linelength;
env->F = F;
obstack_init(&env->obst);
env->linelength = 0;
void be_emit_init(FILE *file)
{
emit_file = file;
emit_linelength = 0;
obstack_init(&emit_obst);
}
void be_emit_destroy_env(be_emit_env_t *env)
void be_emit_exit(void)
{
obstack_free(&env->obst, NULL);
obstack_free(&emit_obst, NULL);
}
void be_emit_ident(be_emit_env_t *env, ident *id)
void be_emit_ident(ident *id)
{
size_t len = get_id_strlen(id);
size_t len = get_id_strlen(id);
const char *str = get_id_str(id);
be_emit_string_len(env, str, len);
be_emit_string_len(str, len);
}
void be_emit_tarval(be_emit_env_t *env, tarval *tv)
void be_emit_tarval(tarval *tv)
{
char buf[64];
tarval_snprintf(buf, sizeof(buf), tv);
be_emit_string(env, buf);
be_emit_string(buf);
}
void be_emit_irvprintf(be_emit_env_t *env, const char *fmt, va_list args)
void be_emit_irvprintf(const char *fmt, va_list args)
{
char buf[256];
ir_vsnprintf(buf, sizeof(buf), fmt, args);
be_emit_string(env, buf);
be_emit_string(buf);
}
void be_emit_irprintf(be_emit_env_t *env, const char *fmt, ...)
void be_emit_irprintf(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
be_emit_irvprintf(env, fmt, ap);
be_emit_irvprintf(fmt, ap);
va_end(ap);
}
void be_emit_write_line(be_emit_env_t *env)
void be_emit_write_line(void)
{
char *finished_line = obstack_finish(&env->obst);
char *finished_line = obstack_finish(&emit_obst);
fwrite(finished_line, env->linelength, 1, env->F);
env->linelength = 0;
obstack_free(&env->obst, finished_line);
fwrite(finished_line, emit_linelength, 1, emit_file);
emit_linelength = 0;
obstack_free(&emit_obst, finished_line);
}
void be_emit_pad_comment(be_emit_env_t *env)
void be_emit_pad_comment(void)
{
while(env->linelength <= 30) {
be_emit_char(env, ' ');
while(emit_linelength <= 30) {
be_emit_char(' ');
}
be_emit_cstring(env, " ");
be_emit_cstring(" ");
}
void be_emit_finish_line_gas(be_emit_env_t *env, const ir_node *node)
void be_emit_finish_line_gas(const ir_node *node)
{
dbg_info *dbg;
dbg_info *dbg;
const char *sourcefile;
unsigned lineno;
unsigned lineno;
if(node == NULL) {
be_emit_char(env, '\n');
be_emit_write_line(env);
be_emit_char('\n');
be_emit_write_line();
return;
}
be_emit_pad_comment(env);
be_emit_cstring(env, "/* ");
be_emit_irprintf(env, "%+F ", node);
be_emit_pad_comment();
be_emit_cstring("/* ");
be_emit_irprintf("%+F ", node);
dbg = get_irn_dbg_info(node);
dbg = get_irn_dbg_info(node);
sourcefile = be_retrieve_dbg_info(dbg, &lineno);
if(sourcefile != NULL) {
be_emit_string(env, sourcefile);
be_emit_irprintf(env, ":%u", lineno);
be_emit_string(sourcefile);
be_emit_irprintf(":%u", lineno);
}
be_emit_cstring(env, " */\n");
be_emit_write_line(env);
be_emit_cstring(" */\n");
be_emit_write_line();
}
......@@ -23,6 +23,8 @@
* @author Matthias Braun
* @date 12.03.2007
* @version $Id$
*
* This is a framework for emitting data (usually the final assembly code)
*/
#ifndef FIRM_BE_BEEMITTER_H
#define FIRM_BE_BEEMITTER_H
......@@ -35,25 +37,20 @@
#include "obst.h"
#include "be.h"
/* framework for emitting data (usually the final assembly code) */
/** The emitter environment. */
typedef struct be_emit_env_t {
FILE *F; /**< The handle of the (assembler) file that is written to. */
struct obstack obst; /**< An obstack for temporary storage. */
int linelength; /**< The length of the current line. */
} be_emit_env_t;
#define NULL_EMITTER { NULL, NULL_OBST, 0 }
/* don't use the following vars directly, they're only here for the inlines */
extern FILE *emit_file;
extern struct obstack emit_obst;
extern int emit_linelength;
/**
* Emit a character to the (assembler) output.
*
* @param env the emitter environment
*/
static INLINE void be_emit_char(be_emit_env_t *env, char c) {
obstack_1grow(&env->obst, c);
env->linelength++;
static INLINE void be_emit_char(char c)
{
obstack_1grow(&emit_obst, c);
emit_linelength++;
}
/**
......@@ -63,11 +60,10 @@ static INLINE void be_emit_char(be_emit_env_t *env, char c) {
* @param str the string
* @param l the length of the given string
*/
static INLINE void be_emit_string_len(be_emit_env_t *env, const char *str,
size_t l)
static INLINE void be_emit_string_len(const char *str, size_t l)
{
obstack_grow(&env->obst, str, l);
env->linelength += l;
obstack_grow(&emit_obst, str, l);
emit_linelength += l;
}
/**
......@@ -76,10 +72,10 @@ static INLINE void be_emit_string_len(be_emit_env_t *env, const char *str,
* @param env the emitter environment
* @param str the null-terminated string
*/
static INLINE void be_emit_string(be_emit_env_t *env, const char *str)
static INLINE void be_emit_string(const char *str)
{
size_t len = strlen(str);
be_emit_string_len(env, str, len);
be_emit_string_len(str, len);
}
/**
......@@ -88,7 +84,8 @@ static INLINE void be_emit_string(be_emit_env_t *env, const char *str)
* @param env the emitter environment
* @param str the null-terminated string constant
*/