X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fmips%2Fmips_emitter.c;h=a04d4d5feca65c2b2d1308b766125e9d05e9d8fd;hb=b599aa34a918a033aa4e50e63b4c445b07d2e0ec;hp=dd0e56ac5cacd51aed6a0f983688ba4f62d7c35d;hpb=86fe675b2126c88d1417ff62ac31dbb08a709b0e;p=libfirm diff --git a/ir/be/mips/mips_emitter.c b/ir/be/mips/mips_emitter.c index dd0e56ac5..a04d4d5fe 100644 --- a/ir/be/mips/mips_emitter.c +++ b/ir/be/mips/mips_emitter.c @@ -54,6 +54,8 @@ DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;) +#define BLOCK_PREFIX ".L" + #define SNPRINTF_BUF_LEN 128 /** @@ -229,27 +231,78 @@ static const char *node_const_to_str(ir_node *n) } #endif +void mips_emit_load_store_address(mips_emit_env_t *env, const ir_node *node, + int pos) +{ + const mips_load_store_attr_t *attr = get_mips_load_store_attr_const(node); + + be_emit_irprintf(env->emit, "%d(", attr->offset); + mips_emit_source_register(env, node, pos); + be_emit_char(env->emit, ')'); +} + +void mips_emit_immediate_suffix(mips_emit_env_t *env, const ir_node *node, + int pos) +{ + ir_node *op = get_irn_n(node, pos); + if(is_mips_Immediate(op)) + be_emit_char(env->emit, 'i'); +} + void mips_emit_immediate(mips_emit_env_t *env, const ir_node *node) { - const mips_attr_t *attr = get_mips_attr(node); + const mips_immediate_attr_t *attr = get_mips_immediate_attr_const(node); + + switch(attr->imm_type) { + case MIPS_IMM_CONST: + be_emit_irprintf(env->emit, "%d", attr->val); + break; + case MIPS_IMM_SYMCONST_LO: + be_emit_cstring(env->emit, "%lo($"); + be_emit_ident(env->emit, get_entity_ld_ident(attr->entity)); + if(attr->val != 0) { + be_emit_irprintf(env->emit, "%+d", attr->val); + } + be_emit_char(env->emit, ')'); + break; + case MIPS_IMM_SYMCONST_HI: + be_emit_cstring(env->emit, "%hi($"); + be_emit_ident(env->emit, get_entity_ld_ident(attr->entity)); + if(attr->val != 0) { + be_emit_irprintf(env->emit, "%+d", attr->val); + } + be_emit_char(env->emit, ')'); + break; + default: + panic("invalid immediate type found"); + } +} - if(attr->tv != NULL) { - be_emit_tarval(env->emit, attr->tv); +/** + * Emit the name of the destination register at given output position. + */ +void mips_emit_source_register_or_immediate(mips_emit_env_t *env, + const ir_node *node, int pos) +{ + const ir_node *op = get_irn_n(node, pos); + if(is_mips_Immediate(op)) { + mips_emit_immediate(env, op); } else { - be_emit_cstring(env->emit, "/* TODO */ 0"); + mips_emit_source_register(env, node, pos); } } +#if 0 /* * Add a number to a prefix. This number will not be used a second time. */ -static -char *get_unique_label(char *buf, size_t buflen, const char *prefix) +static char *get_unique_label(char *buf, size_t buflen, const char *prefix) { static unsigned long id = 0; snprintf(buf, buflen, "%s%lu", prefix, ++id); return buf; } +#endif /************************************************************************/ /* ABI Handling */ @@ -382,7 +435,14 @@ const char* mips_get_block_label(const ir_node* block) static void mips_emit_block_label(mips_emit_env_t *env, const ir_node *block) { - be_emit_irprintf(env->emit, "BLOCK_%d", get_irn_node_nr(block)); + if (has_Block_label(block)) { + be_emit_string(env, be_gas_label_prefix()); + be_emit_irprintf(env->emit, "%lu", get_Block_label(block)); + } else { + be_emit_cstring(env, BLOCK_PREFIX); + be_emit_irprintf(env->emit, "%d", get_irn_node_nr(block)); + + } } static void mips_emit_Jump(mips_emit_env_t *env, const ir_node *node) @@ -450,6 +510,7 @@ void mips_emit_jump_or_fallthrough(mips_emit_env_t *env, const ir_node *node, * * ************************************************************************/ +#if 0 /* jump table entry (target and corresponding number) */ typedef struct _branch_t { ir_node *target; @@ -469,7 +530,8 @@ typedef struct _jmp_tbl_t { /** * Compare two variables of type branch_t. Used to sort all switch cases */ -static int mips_cmp_branch_t(const void *a, const void *b) { +static int mips_cmp_branch_t(const void *a, const void *b) +{ branch_t *b1 = (branch_t *)a; branch_t *b2 = (branch_t *)b; @@ -492,11 +554,11 @@ const char* mips_get_jumptbl_label(const ir_node* switchjmp) * possible otherwise a cmp-jmp cascade). Stolen from ia32 */ void emit_mips_jump_table(mips_emit_env_t *env, const ir_node *irn) { - int lastval, i, i2, pn; - jmp_tbl_t tbl; - ir_node *proj; - const ir_edge_t *edge; - mips_attr_t *attr = get_mips_attr(irn); + int lastval, i, i2, pn; + jmp_tbl_t tbl; + ir_node *proj; + const ir_edge_t *edge; + const mips_attr_t *attr = get_mips_attr_const(irn); /* fill the table structure */ tbl.label = xmalloc(SNPRINTF_BUF_LEN); @@ -573,6 +635,7 @@ void dump_jump_tables(ir_node* node, void *data) be_emit_write_line(env->emit); } } +#endif /*********************************************************************************** * _ __ _ @@ -689,7 +752,7 @@ void mips_emit_func_prolog(mips_emit_env_t *env, ir_graph *irg) be_emit_env_t *eenv = env->emit; // dump jump tables - irg_walk_graph(irg, NULL, dump_jump_tables, env); + //irg_walk_graph(irg, NULL, dump_jump_tables, env); be_emit_write_line(eenv); be_gas_emit_switch_section(eenv, GAS_SECTION_TEXT); @@ -736,6 +799,7 @@ void mips_gen_labels(ir_node *block, void *env) { ir_node *pred; int n = get_Block_n_cfgpreds(block); + (void) env; for (n--; n >= 0; n--) { pred = get_Block_cfgpred(block, n);