From 9076361d98ade23d6477176733fea4a2d8f55472 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Tue, 20 Mar 2007 10:23:45 +0000 Subject: [PATCH] make the mips backend do some half-usefull things again --- ir/be/mips/bearch_mips.c | 8 +- ir/be/mips/mips_emitter.c | 28 ++- ir/be/mips/mips_gen_decls.c | 30 --- ir/be/mips/mips_new_nodes.c | 8 +- ir/be/mips/mips_spec.pl | 351 +++++++++++++++++++----------------- ir/be/mips/mips_transform.c | 77 ++++---- 6 files changed, 255 insertions(+), 247 deletions(-) diff --git a/ir/be/mips/bearch_mips.c b/ir/be/mips/bearch_mips.c index 91ae7e55a..bdd65d375 100644 --- a/ir/be/mips/bearch_mips.c +++ b/ir/be/mips/bearch_mips.c @@ -638,7 +638,7 @@ static const arch_register_t *mips_abi_prologue(void *self, ir_node** mem, pmap initialstackframesize = 24; // - setup first part of stackframe - sp = new_rd_mips_addi(dbg, irg, block, sp, mode_Is); + sp = new_rd_mips_addiu(dbg, irg, block, sp); attr = get_mips_attr(sp); attr->tv = new_tarval_from_long(-initialstackframesize, mode_Is); mips_set_irn_reg(NULL, sp, &mips_gp_regs[REG_SP]); @@ -681,7 +681,7 @@ static const arch_register_t *mips_abi_prologue(void *self, ir_node** mem, pmap initialstackframesize = 4; // save old framepointer - sp = new_rd_mips_addi(dbg, irg, block, sp, mode_Is); + sp = new_rd_mips_addiu(dbg, irg, block, sp); attr = get_mips_attr(sp); attr->tv = new_tarval_from_long(-initialstackframesize, mode_Is); mips_set_irn_reg(NULL, sp, &mips_gp_regs[REG_SP]); @@ -697,7 +697,7 @@ static const arch_register_t *mips_abi_prologue(void *self, ir_node** mem, pmap } // setup framepointer - fp = new_rd_mips_addi(dbg, irg, block, sp, mode_Is); + fp = new_rd_mips_addiu(dbg, irg, block, sp); attr = get_mips_attr(fp); attr->tv = new_tarval_from_long(initialstackframesize, mode_Is); mips_set_irn_reg(NULL, fp, &mips_gp_regs[REG_FP]); @@ -722,7 +722,7 @@ static void mips_abi_epilogue(void *self, ir_node *block, ir_node **mem, pmap *r int fp_save_offset = env->debug ? 16 : 0; // copy fp to sp - sp = new_rd_mips_move(dbg, irg, block, fp, mode_Iu); + sp = new_rd_mips_move(dbg, irg, block, fp); mips_set_irn_reg(NULL, sp, &mips_gp_regs[REG_SP]); //arch_set_irn_register(mips_get_arg_env(), fp, &mips_gp_regs[REG_SP]); diff --git a/ir/be/mips/mips_emitter.c b/ir/be/mips/mips_emitter.c index 7bdc5317f..8abeeb7bc 100644 --- a/ir/be/mips/mips_emitter.c +++ b/ir/be/mips/mips_emitter.c @@ -1,8 +1,7 @@ /* mips emitter */ /* $Id$ */ - #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif #include @@ -17,6 +16,7 @@ #include "irargs_t.h" #include "irprog_t.h" #include "irouts.h" +#include "error.h" #include "../besched.h" #include "../benode_t.h" @@ -346,14 +346,22 @@ static void mips_emit_IncSP(const ir_node *node, mips_emit_env_t *env) return; } - fprintf(F, "\taddi $sp, $sp, %d\n", -offset); + if(offset > 0xffff || offset < -0xffff) { + panic("stackframe > 2^16 bytes not supported yet\n"); + } + + if(offset > 0) { + fprintf(F, "\tsubu $sp, $sp, %d\n", offset); + } else { + fprintf(F, "\taddu $sp, $sp, %d\n", -offset); + } } static void mips_emit_Copy(const ir_node *node, mips_emit_env_t *env) { FILE *F = env->out; - lc_efprintf(mips_get_arg_env(), F, "\tor %1D, $zero, %1S\t\t\t# copy\n", node, node); + lc_efprintf(mips_get_arg_env(), F, "\tmove %1D, %1S\t\t\t# copy\n", node, node); } static void mips_emit_Return(const ir_node* node, mips_emit_env_t *env) @@ -696,8 +704,14 @@ void mips_emit_start(FILE *F, ir_graph *irg) irg_walk_graph(irg, NULL, dump_jump_tables, F); fprintf(F, "\n\n"); - fprintf(F, "# Function Start of %s\n", irg_name); + fprintf(F, "\t.balign\t4\n"); + fprintf(F, "\t.global\t%s\n", irg_name); + fprintf(F, "\t.set\tnomips16\n"); + fprintf(F, "\t.ent\t%s\n", irg_name); fprintf(F, "%s:\n", irg_name); + fprintf(F, "\t.frame\t$fp, 24, $ra\n"); + fprintf(F, "\t.mask\t0xc0000000, -4\n"); + fprintf(F, "\t.fmask\t0x00000000, 0\n"); } /** @@ -706,9 +720,7 @@ void mips_emit_start(FILE *F, ir_graph *irg) void mips_emit_end(FILE *F, ir_graph *irg) { const char *irg_name = get_entity_name(get_irg_entity(irg)); - - fprintf(F, "# End of function %s we should never get here...\n", irg_name); - fprintf(F, "\tjal exit\n"); + fprintf(F, "\t.end\t%s\n", irg_name); } /** diff --git a/ir/be/mips/mips_gen_decls.c b/ir/be/mips/mips_gen_decls.c index a07714520..671c935af 100644 --- a/ir/be/mips/mips_gen_decls.c +++ b/ir/be/mips/mips_gen_decls.c @@ -519,32 +519,6 @@ void mips_dump_globals(struct obstack *rdata_obstack, struct obstack *data_obsta dump_global(rdata_obstack, data_obstack, comm_obstack, get_class_member(gt, i)); } - -static void mips_emit_stdlib_call(FILE *F, const char* name, int num) { - fprintf(F, "%s:\n", name); - fprintf(F, "\tori $v0, $zero, %d\n", num); - fprintf(F, "\tsyscall\n"); - fprintf(F, "\tj $ra\n"); - fprintf(F, "\n"); -} - -/** - * Emits a default library for spim... Hack for now... - */ -static void mips_emit_standard_lib(FILE* F) { - static int output = 0; - if(output) - return; - output = 1; - - mips_emit_stdlib_call(F, "print_int", 1); - mips_emit_stdlib_call(F, "print_string", 4); - mips_emit_stdlib_call(F, "read_int", 5); - mips_emit_stdlib_call(F, "read_string", 8); - mips_emit_stdlib_call(F, "sbrk", 9); - mips_emit_stdlib_call(F, "exit", 10); -} - /************************************************************************/ void mips_gen_decls(FILE *out) { @@ -582,8 +556,4 @@ void mips_gen_decls(FILE *out) { obstack_free(&rodata, NULL); obstack_free(&data, NULL); obstack_free(&comm, NULL); - - fprintf(out, "\t.text\n"); - - mips_emit_standard_lib(out); } diff --git a/ir/be/mips/mips_new_nodes.c b/ir/be/mips/mips_new_nodes.c index c7b299e7a..df70986fd 100644 --- a/ir/be/mips/mips_new_nodes.c +++ b/ir/be/mips/mips_new_nodes.c @@ -412,7 +412,7 @@ ir_node *mips_transform_##srcnode(ir_node* node) \ mips_attr_t *attr, *op_attr = get_mips_attr(op2); \ long val = get_tarval_long(op_attr->tv); \ result = new_rd_mips_##inode(get_irn_dbg_info(node), get_irn_irg(node), get_nodes_block(node), \ - op1, get_irn_mode(node)); \ + op1); \ attr = get_mips_attr(result); \ attr->tv = new_tarval_from_long(val, get_mode_sign(get_irn_mode(node)) ? mode_Hs : mode_Hu); \ return result; \ @@ -422,7 +422,7 @@ ir_node *mips_transform_##srcnode(ir_node* node) \ mips_attr_t *attr, *op_attr = get_mips_attr(op1); \ long val = get_tarval_long(op_attr->tv); \ result = new_rd_mips_##inode(get_irn_dbg_info(node), get_irn_irg(node), get_nodes_block(node), \ - op2, get_irn_mode(node)); \ + op2); \ attr = get_mips_attr(result); \ attr->tv = new_tarval_from_long(val, get_mode_sign(get_irn_mode(node)) ? mode_Hs : mode_Hu); \ return result; \ @@ -431,7 +431,7 @@ ir_node *mips_transform_##srcnode(ir_node* node) \ return node; \ } -MIPS_MAKE_IFOLDING_TRANSFORM(add, addi, 1) +MIPS_MAKE_IFOLDING_TRANSFORM(addu, addiu, 1) MIPS_MAKE_IFOLDING_TRANSFORM(and, andi, 1) MIPS_MAKE_IFOLDING_TRANSFORM(or, ori, 1) MIPS_MAKE_IFOLDING_TRANSFORM(sra, srai, 0) @@ -441,7 +441,7 @@ MIPS_MAKE_IFOLDING_TRANSFORM(sr, sri, 0) MIPS_MAKE_IFOLDING_TRANSFORM(slt, slti, 0) void mips_init_opcode_transforms(void) { - op_mips_add->ops.transform_node = mips_transform_add; + op_mips_addu->ops.transform_node = mips_transform_addu; op_mips_and->ops.transform_node = mips_transform_and; op_mips_or->ops.transform_node = mips_transform_or; op_mips_sra->ops.transform_node = mips_transform_sra; diff --git a/ir/be/mips/mips_spec.pl b/ir/be/mips/mips_spec.pl index 9a926b1f9..16258eac5 100644 --- a/ir/be/mips/mips_spec.pl +++ b/ir/be/mips/mips_spec.pl @@ -94,43 +94,37 @@ $comment_string_end = ""; "gp" => [ { name => "zero", type => 4+2 }, # always zero { name => "at", type => 4 }, # reserved for assembler - { name => "v0", type => 1 }, # first return value - { name => "v1", type => 1 }, # second return value - { name => "a0", type => 1 }, # first argument - { name => "a1", type => 1 }, # second argument - { name => "a2", type => 1 }, # third argument - { name => "a3", type => 1 }, # fourth argument - { name => "t0", type => 1 }, - { name => "t1", type => 1 }, - { name => "t2", type => 1 }, - { name => "t3", type => 1 }, - { name => "t4", type => 1 }, - { name => "t5", type => 1 }, - { name => "t6", type => 1 }, - { name => "t7", type => 1 }, - { name => "s0", type => 2 }, - { name => "s1", type => 2 }, - { name => "s2", type => 2 }, - { name => "s3", type => 2 }, - { name => "s4", type => 2 }, - { name => "s5", type => 2 }, - { name => "s6", type => 2 }, - { name => "s7", type => 2 }, - { name => "t8", type => 1 }, - { name => "t9", type => 1 }, - { name => "k0", type => 4 }, # reserved for OS - { name => "k1", type => 4 }, # reserved for OS + { name => "v0", realname => "2", type => 1 }, # first return value + { name => "v1", realname => "3", type => 1 }, # second return value + { name => "a0", realname => "4", type => 1 }, # first argument + { name => "a1", realname => "5", type => 1 }, # second argument + { name => "a2", realname => "6", type => 1 }, # third argument + { name => "a3", realname => "7", type => 1 }, # fourth argument + { name => "t0", realname => "8", type => 1 }, + { name => "t1", realname => "9", type => 1 }, + { name => "t2", realname => "10", type => 1 }, + { name => "t3", realname => "11", type => 1 }, + { name => "t4", realname => "12", type => 1 }, + { name => "t5", realname => "13", type => 1 }, + { name => "t6", realname => "14", type => 1 }, + { name => "t7", realname => "15", type => 1 }, + { name => "s0", realname => "16", type => 2 }, + { name => "s1", realname => "17", type => 2 }, + { name => "s2", realname => "18", type => 2 }, + { name => "s3", realname => "19", type => 2 }, + { name => "s4", realname => "20", type => 2 }, + { name => "s5", realname => "21", type => 2 }, + { name => "s6", realname => "22", type => 2 }, + { name => "s7", realname => "23", type => 2 }, + { name => "t8", realname => "24", type => 1 }, + { name => "t9", realname => "25", type => 1 }, + { name => "kt0", type => 4 }, # reserved for OS + { name => "kt1", type => 4 }, # reserved for OS { name => "gp", type => 4 }, # general purpose - { name => "sp", type => 4+2 }, # stack pointer - { name => "fp", type => 4+2 }, # frame pointer - { name => "ra", type => 2+1 }, # return address. This is also caller - # save, because the jla instruction that - # is used for calls modifies the ra - # register. It is callee save too, - # because at the last command of a - # function (the ja $ra) it needs to have - # it's old value. - { mode => "mode_P" } + { name => "sp", type => 4 }, # stack pointer + { name => "fp", type => 4 }, # frame pointer + { name => "ra", type => 2+1 }, # return address + { mode => "mode_Iu" } ], ); # %reg_classes @@ -160,166 +154,183 @@ $comment_string_end = ""; # commutative operations -add => { - op_flags => "C", - reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, - emit => '. addu %D1, %S1, %S2' +addu => { + op_flags => "C", + reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, + emit => '. addu %D1, %S1, %S2', + mode => "mode_Iu", }, -addi => { - reg_req => { in => [ "gp" ], out => [ "gp" ] }, - emit => '. addiu %D1, %S1, %C', - cmp_attr => 'return attr_a->tv != attr_b->tv;', +addiu => { + reg_req => { in => [ "gp" ], out => [ "gp" ] }, + emit => '. addiu %D1, %S1, %C', + cmp_attr => 'return attr_a->tv != attr_b->tv;', + mode => "mode_Iu", }, and => { - op_flags => "C", - reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, - emit => '. and %D1, %S1, %S2', + op_flags => "C", + reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, + emit => '. and %D1, %S1, %S2', + mode => "mode_Iu", }, andi => { - reg_req => { in => [ "gp" ], out => [ "gp" ] }, - emit => '. andi %D1, %S1, %C', - cmp_attr => 'return attr_a->tv != attr_b->tv;', + reg_req => { in => [ "gp" ], out => [ "gp" ] }, + emit => '. andi %D1, %S1, %C', + cmp_attr => 'return attr_a->tv != attr_b->tv;', + mode => "mode_Iu", }, div => { - reg_req => { in => [ "gp", "gp" ], out => [ "none", "none", "none", "none" ] }, - emit => ' - mips_attr_t *attr = get_mips_attr(n); - if (attr->modes.original_mode->sign) { -2. div %S1, %S2 - } else { -2. divu %S1, %S2 - } -', + reg_req => { in => [ "gp", "gp" ], out => [ "none" ] }, + emit => '. div %S1, %S2', + mode => "mode_M", +}, + +divu => { + reg_req => { in => [ "gp", "gp" ], out => [ "none" ] }, + emit => '. divu %S1, %S2', + mode => "mode_M", }, mult => { - op_flags => "C", - reg_req => { in => [ "gp", "gp" ], out => [ "none" ] }, - emit => ' - if (mode_is_signed(get_irn_mode(n))) { -2. mult %S1, %S2 - } - else { -2. multu %S1, %S2 - } -', + op_flags => "C", + reg_req => { in => [ "gp", "gp" ], out => [ "none" ] }, + emit => '. mult %S1, %S2', + mode => "mode_M" +}, + +multu => { + op_flags => "C", + reg_req => { in => [ "gp", "gp" ], out => [ "none" ] }, + emit => '. multu %S1, %S2', + mode => "mode_M", }, nor => { - op_flags => "C", - reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, - emit => '. nor %D1, %S1, %S2' + op_flags => "C", + reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, + emit => '. nor %D1, %S1, %S2', + mode => "mode_Iu" }, not => { - reg_req => { in => [ "gp" ], out => [ "gp" ] }, - emit => '. nor %D1, %S1, $zero' + reg_req => { in => [ "gp" ], out => [ "gp" ] }, + emit => '. nor %D1, %S1, $zero', + mode => "mode_Iu" }, or => { - op_flags => "C", - reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, - emit => '. or %D1, %S1, %S2' + op_flags => "C", + reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, + emit => '. or %D1, %S1, %S2', + mode => "mode_Iu" }, ori => { - reg_req => { in => [ "gp" ], out => [ "gp" ] }, - emit => '. ori %D1, %S1, %C', - cmp_attr => 'return attr_a->tv != attr_b->tv;', + reg_req => { in => [ "gp" ], out => [ "gp" ] }, + emit => '. ori %D1, %S1, %C', + cmp_attr => 'return attr_a->tv != attr_b->tv;', + mode => "mode_Iu" }, sl => { - reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, - emit => ' + reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, + emit => ' if (mode_is_signed(get_irn_mode(n))) { 2. sal %D1, %S1, %S2 - } - else { + } else { 2. sll %D1, %S1, %S2 } ', + mode => "mode_Iu", }, sli => { - reg_req => { in => [ "gp" ], out => [ "gp" ] }, - emit => ' + reg_req => { in => [ "gp" ], out => [ "gp" ] }, + emit => ' if (mode_is_signed(get_irn_mode(n))) { 2. sal %D1, %S1, %C - } - else { + } else { 2. sll %D1, %S1, %C } ', + mode => "mode_Iu", }, sra => { - reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, - emit => '. sra %D1, %S1, %S2', + reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, + emit => '. sra %D1, %S1, %S2', + mode => "mode_Iu" }, srai => { - reg_req => { in => [ "gp" ], out => [ "gp" ] }, - emit => '. sra %D1, %S1, %C', - cmp_attr => 'return attr_a->tv != attr_b->tv;', + reg_req => { in => [ "gp" ], out => [ "gp" ] }, + emit => '. sra %D1, %S1, %C', + cmp_attr => 'return attr_a->tv != attr_b->tv;', + mode => "mode_Iu", }, sr => { - reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, - emit => ' + reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, + emit => ' if (mode_is_signed(get_irn_mode(n))) { 2. sra %D1, %S1, %S2 - } - else { + } else { 2. srl %D1, %S1, %S2 } ', + mode => "mode_Iu", }, sri => { - reg_req => { in => [ "gp" ], out => [ "gp" ] }, - emit => ' + reg_req => { in => [ "gp" ], out => [ "gp" ] }, + emit => ' if (mode_is_signed(get_irn_mode(n))) { 2. sra %D1, %S1, %C - } - else { + } else { 2. srl %D1, %S1, %C } ', + mode => "mode_Iu" }, srlv => { - reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, - emit => '. srlv %D1, %S1, %S2', + reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, + emit => '. srlv %D1, %S1, %S2', + mode => "mode_Iu" }, sllv => { - reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, - emit => '. sllv %D1, %S1, %S2', + reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, + emit => '. sllv %D1, %S1, %S2', + mode => "mode_Iu" }, sub => { - reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, - emit => '. subu %D1, %S1, %S2', + reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, + emit => '. subu %D1, %S1, %S2', + mode => "mode_Iu" }, subuzero => { - reg_req => { in => [ "gp" ], out => [ "gp" ] }, - emit => '. subu %D1, $zero, %S1', + reg_req => { in => [ "gp" ], out => [ "gp" ] }, + emit => '. subu %D1, $zero, %S1', + mode => "mode_Iu", }, xor => { - reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, - emit => '. xor %D1, %S1, %S2' + reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, + emit => '. xor %D1, %S1, %S2', + mode => "mode_Iu", }, xori => { - reg_req => { in => [ "gp" ], out => [ "gp" ] }, - emit => '. xori %D1, %S1, %C', - cmp_attr => 'return attr_a->tv != attr_b->tv;', + reg_req => { in => [ "gp" ], out => [ "gp" ] }, + emit => '. xori %D1, %S1, %C', + cmp_attr => 'return attr_a->tv != attr_b->tv;', + mode => "mode_Iu", }, # ____ _ _ @@ -331,40 +342,46 @@ xori => { # load upper imediate lui => { - op_flags => "c", - reg_req => { out => [ "gp" ] }, - emit => '. lui %D1, %C', - cmp_attr => 'return attr_a->tv != attr_b->tv;', + op_flags => "c", + reg_req => { out => [ "gp" ] }, + emit => '. lui %D1, %C', + cmp_attr => 'return attr_a->tv != attr_b->tv;', + mode => "mode_Iu", }, # load lower immediate lli => { - op_flags => "c", - reg_req => { in => [ "gp" ], out => [ "gp" ] }, - emit => '. ori %D1, %S1, %C', - cmp_attr => 'return attr_a->tv != attr_b->tv;', + op_flags => "c", + reg_req => { in => [ "gp" ], out => [ "gp" ] }, + emit => '. ori %D1, %S1, %C', + cmp_attr => 'return attr_a->tv != attr_b->tv;', + mode => "mode_Iu", }, la => { - op_flags => "c", - reg_req => { out => [ "gp" ] }, - emit => '. la %D1, %C', - cmp_attr => 'return attr_a->symconst_id != attr_b->symconst_id;', + op_flags => "c", + reg_req => { out => [ "gp" ] }, + emit => '. la %D1, %C', + cmp_attr => 'return attr_a->symconst_id != attr_b->symconst_id;', + mode => "mode_Iu", }, mflo => { - reg_req => { in => [ "none" ], out => [ "gp" ] }, - emit => '. mflo %D1' + reg_req => { in => [ "none" ], out => [ "gp" ] }, + emit => '. mflo %D1', + mode => "mode_Iu" }, mfhi => { - reg_req => { in => [ "none" ], out => [ "gp" ] }, - emit => '. mfhi %D1' + reg_req => { in => [ "none" ], out => [ "gp" ] }, + emit => '. mfhi %D1', + mode => "mode_Iu" }, zero => { - reg_req => { out => [ "zero" ] }, - emit => '', + reg_req => { out => [ "zero" ] }, + emit => '', + mode => "mode_Iu" }, # @@ -386,6 +403,7 @@ slt => { 2. sltu %D1, %S1, %S2 } ', + mode => "mode_Iu", }, slti => { @@ -398,7 +416,8 @@ slti => { 2. sltiu %D1, %S1, %C } ', - cmp_attr => 'return attr_a->tv != attr_b->tv;', + cmp_attr => 'return attr_a->tv != attr_b->tv;', + mode => "mode_Iu", }, beq => { @@ -464,10 +483,10 @@ j => { }, b => { - op_flags => "X", - # -> X - reg_req => { in => [ ], out => [ "none" ] }, - emit => ' + op_flags => "X", + # -> X + reg_req => { in => [ ], out => [ "none" ] }, + emit => ' ir_node *jumpblock = get_irn_link(n); assert(jumpblock != NULL); @@ -478,17 +497,17 @@ b => { }, fallthrough => { - op_flags => "X", - # -> X - reg_req => { in => [ ], out => [ "none" ] }, - emit => '. # fallthrough' + op_flags => "X", + # -> X + reg_req => { in => [ ], out => [ "none" ] }, + emit => '. # fallthrough' }, SwitchJump => { - op_flags => "X", - # -> X,X,... - reg_req => { in => [ "gp" ], out => [ "none" ] }, - emit => '. j %S1' + op_flags => "X", + # -> X,X,... + reg_req => { in => [ "gp" ], out => [ "none" ] }, + emit => '. j %S1' }, # _ _ @@ -499,8 +518,8 @@ SwitchJump => { # load_r => { - reg_req => { in => [ "none", "gp" ], out => [ "none", "none", "gp" ] }, - emit => ' + reg_req => { in => [ "none", "gp" ], out => [ "none", "none", "gp" ] }, + emit => ' mips_attr_t* attr = get_mips_attr(n); ir_mode *mode; @@ -510,16 +529,14 @@ load_r => { case 8: if (mode_is_signed(mode)) { 3. lb %D3, %C(%S2) - } - else { + } else { 3. lbu %D3, %C(%S2) } break; case 16: if (mode_is_signed(mode)) { 3. lh %D3, %C(%S2) - } - else { + } else { 3. lhu %D3, %C(%S2) } break; @@ -531,7 +548,7 @@ load_r => { break; } ', - cmp_attr => 'return attr_a->tv != attr_b->tv || attr_a->stack_entity != attr_b->stack_entity;', + cmp_attr => 'return attr_a->tv != attr_b->tv || attr_a->stack_entity != attr_b->stack_entity;', }, @@ -543,8 +560,8 @@ load_r => { # store_r => { - reg_req => { in => [ "none", "gp", "gp" ], out => [ "none", "none" ] }, - emit => ' + reg_req => { in => [ "none", "gp", "gp" ], out => [ "none", "none" ] }, + emit => ' mips_attr_t* attr = get_mips_attr(n); ir_mode* mode; @@ -567,12 +584,12 @@ store_r => { break; } ', - cmp_attr => 'return attr_a->tv != attr_b->tv;', + cmp_attr => 'return attr_a->tv != attr_b->tv;', }, store_i => { - reg_req => { in => [ "none", "none", "gp" ], out => [ "none", "none" ] }, - emit => ' + reg_req => { in => [ "none", "none", "gp" ], out => [ "none", "none" ] }, + emit => ' mips_attr_t* attr = get_mips_attr(n); ir_mode *mode; @@ -593,14 +610,13 @@ store_i => { break; } ', - cmp_attr => ' - return attr_a->stack_entity != attr_b->stack_entity; -', + cmp_attr => 'return attr_a->stack_entity != attr_b->stack_entity;', }, move => { - reg_req => { in => [ "gp" ], out => [ "gp" ] }, - emit => '. or %D1, $zero, %S1' + reg_req => { in => [ "gp" ], out => [ "gp" ] }, + emit => '. move %D1, %S1', + mode => "mode_Iu" }, # @@ -608,8 +624,9 @@ move => { # reinterpret_conv => { - reg_req => { in => [ "gp" ], out => [ "in_r1" ] }, - emit => '. # reinterpret %S1 -> %D1', + reg_req => { in => [ "gp" ], out => [ "in_r1" ] }, + emit => '. # reinterpret %S1 -> %D1', + mode => "mode_Iu" }, # @@ -617,9 +634,9 @@ reinterpret_conv => { # nop => { - op_flags => "K", - reg_req => { in => [], out => [ "none" ] }, - emit => '. nop # nop', + op_flags => "K", + reg_req => { in => [], out => [ "none" ] }, + emit => '. nop', }, ); # end of %nodes diff --git a/ir/be/mips/mips_transform.c b/ir/be/mips/mips_transform.c index 97f43ed81..4732b1ec5 100644 --- a/ir/be/mips/mips_transform.c +++ b/ir/be/mips/mips_transform.c @@ -50,10 +50,10 @@ /*assert(get_irn_mode(op1) == get_irn_mode(op2));*/ \ /*assert(get_irn_mode(op1) == env->mode);*/ \ assert(get_mode_size_bits(env->mode) == 32); \ - return new_rd_mips_##mips_nodetype(env->dbg, env->irg, env->block, op1, op2, env->mode);\ + return new_rd_mips_##mips_nodetype(env->dbg, env->irg, env->block, op1, op2); \ } -MIPS_GENBINFUNC(add) +MIPS_GENBINFUNC(addu) MIPS_GENBINFUNC(sub) MIPS_GENBINFUNC(and) MIPS_GENBINFUNC(or) @@ -67,7 +67,7 @@ MIPS_GENBINFUNC(sra) ASSERT_NO_FLOAT(env->mode); \ assert(get_irn_mode(op) == env->mode); \ assert(get_mode_size_bits(env->mode) == 32); \ - return new_rd_mips_##mips_nodetype(env->dbg, env->irg, env->block, op, env->mode); \ + return new_rd_mips_##mips_nodetype(env->dbg, env->irg, env->block, op); \ } MIPS_GENUNFUNC(not) @@ -102,21 +102,21 @@ static ir_node* gen_node_for_Const(mips_transform_env_t *env, dbg_info *dbg, ir_ upper = (val >> 16) & 0xffff; if(upper == 0) { ir_node *zero = gen_zero_node(env, dbg, irg, block); - ir_node *lli = new_rd_mips_lli(dbg, irg, block, zero, mode); + ir_node *lli = new_rd_mips_lli(dbg, irg, block, zero); attr = get_mips_attr(lli); attr->tv = new_tarval_from_long(val, mode); return lli; } - lui = new_rd_mips_lui(dbg, irg, block, mode); + lui = new_rd_mips_lui(dbg, irg, block); attr = get_mips_attr(lui); attr->tv = new_tarval_from_long(val, mode); if(lower == 0) return lui; - lli = new_rd_mips_lli(dbg, irg, block, lui, mode); + lli = new_rd_mips_lli(dbg, irg, block, lui); attr = get_mips_attr(lli); attr->tv = new_tarval_from_long(val, mode); @@ -146,7 +146,6 @@ static ir_node* gen_node_for_SymConst(mips_transform_env_t *env, ir_node* pred, ir_node *node = env->irn; dbg_info *dbg = get_irn_dbg_info(pred); ir_graph *irg = get_irn_irg(node); - ir_mode* mode = get_irn_mode(pred); ir_node *block; if (is_Phi(node)) { @@ -158,12 +157,12 @@ static ir_node* gen_node_for_SymConst(mips_transform_env_t *env, ir_node* pred, kind = get_SymConst_kind(pred); if(kind == symconst_addr_ent) { - result = new_rd_mips_la(dbg, irg, block, mode); + result = new_rd_mips_la(dbg, irg, block); attr = get_mips_attr(result); attr->symconst_id = get_entity_ld_ident(get_SymConst_entity(pred)); return result; } else if(kind == symconst_addr_name) { - result = new_rd_mips_la(dbg, irg, block, mode); + result = new_rd_mips_la(dbg, irg, block); attr = get_mips_attr(result); attr->symconst_id = get_SymConst_name(pred); return result; @@ -253,9 +252,9 @@ static ir_node *gen_node_for_div_Proj(mips_transform_env_t *env) { set_Proj_proj(new_proj, n); if(n == pn_DivMod_res_div) { - return new_rd_mips_mflo(env->dbg, env->irg, env->block, new_proj, env->mode); + return new_rd_mips_mflo(env->dbg, env->irg, env->block, new_proj); } else if(n == pn_DivMod_res_mod) { - return new_rd_mips_mfhi(env->dbg, env->irg, env->block, new_proj, env->mode); + return new_rd_mips_mfhi(env->dbg, env->irg, env->block, new_proj); } return proj; @@ -317,7 +316,7 @@ static ir_node *gen_node_for_Cond_Proj(mips_transform_env_t *env, ir_node* node, if(!true_false) return make_jmp_or_fallthrough(env); - cmp = new_rd_mips_slt(dbg, irg, block, op1, op2, get_irn_mode(op1)); + cmp = new_rd_mips_slt(dbg, irg, block, op1, op2); condjmp = new_rd_mips_bgtz(dbg, irg, block, cmp, mode_T); return new_rd_Proj(dbg, irg, block, condjmp, mode_X, 1); @@ -325,7 +324,7 @@ static ir_node *gen_node_for_Cond_Proj(mips_transform_env_t *env, ir_node* node, if(!true_false) return make_jmp_or_fallthrough(env); - cmp = new_rd_mips_slt(dbg, irg, block, op2, op1, get_irn_mode(op1)); + cmp = new_rd_mips_slt(dbg, irg, block, op2, op1); condjmp = new_rd_mips_blez(dbg, irg, block, cmp, mode_T); return new_rd_Proj(dbg, irg, block, condjmp, mode_X, 1); @@ -333,7 +332,7 @@ static ir_node *gen_node_for_Cond_Proj(mips_transform_env_t *env, ir_node* node, if(!true_false) return make_jmp_or_fallthrough(env); - cmp = new_rd_mips_slt(dbg, irg, block, op2, op1, get_irn_mode(op1)); + cmp = new_rd_mips_slt(dbg, irg, block, op2, op1); condjmp = new_rd_mips_bgtz(dbg, irg, block, cmp, mode_T); return new_rd_Proj(dbg, irg, block, condjmp, mode_X, 1); @@ -341,7 +340,7 @@ static ir_node *gen_node_for_Cond_Proj(mips_transform_env_t *env, ir_node* node, if(!true_false) return make_jmp_or_fallthrough(env); - cmp = new_rd_mips_slt(dbg, irg, block, op1, op2, get_irn_mode(op1)); + cmp = new_rd_mips_slt(dbg, irg, block, op1, op2); condjmp = new_rd_mips_blez(dbg, irg, block, cmp, mode_T); return new_rd_Proj(dbg, irg, block, condjmp, mode_X, 1); @@ -444,7 +443,7 @@ static ir_node *gen_node_for_Cond(mips_transform_env_t *env) if(minval != 0) { minval_const = new_rd_Const(dbg, irg, block, selector_mode, new_tarval_from_long(minval, selector_mode)); minval_const = gen_node_for_Const(env, dbg, irg, block, minval_const); - sub = new_rd_mips_sub(dbg, irg, block, selector, minval_const, selector_mode); + sub = new_rd_mips_sub(dbg, irg, block, selector, minval_const); } else { sub = selector; } @@ -457,7 +456,7 @@ static ir_node *gen_node_for_Cond(mips_transform_env_t *env) max_const = new_rd_Const(dbg, irg, block, unsigned_mode, new_tarval_from_long(maxval - minval + 1, unsigned_mode)); max_const = gen_node_for_Const(env, dbg, irg, block, max_const); - sltu = new_rd_mips_slt(dbg, irg, block, sub, max_const, unsigned_mode); + sltu = new_rd_mips_slt(dbg, irg, block, sub, max_const); zero = gen_zero_node(env, dbg, irg, block); beq = new_rd_mips_beq(dbg, irg, block, sltu, zero, mode_T); @@ -468,10 +467,10 @@ static ir_node *gen_node_for_Cond(mips_transform_env_t *env) two_const = new_rd_Const(dbg, irg, block, unsigned_mode, new_tarval_from_long(2, unsigned_mode)); two_const = gen_node_for_Const(env, dbg, irg, block, two_const); - sl = new_rd_mips_sl(dbg, irg, block, sub, two_const, unsigned_mode); + sl = new_rd_mips_sl(dbg, irg, block, sub, two_const); - la = new_rd_mips_la(dbg, irg, block, mode_Iu); - add = new_rd_mips_add(dbg, irg, block, sl, la, mode_Iu); + la = new_rd_mips_la(dbg, irg, block); + add = new_rd_mips_addu(dbg, irg, block, sl, la); load = new_rd_mips_load_r(dbg, irg, block, new_rd_NoMem(irg), add, mode_T); attr = get_mips_attr(load); attr->modes.load_store_mode = mode_Iu; @@ -541,7 +540,7 @@ static ir_node *create_conv_and(mips_transform_env_t *env, long immediate) { mips_attr_t *attr; pred = get_Conv_op(node); - result = new_rd_mips_andi(env->dbg, env->irg, env->block, pred, node->mode); + result = new_rd_mips_andi(env->dbg, env->irg, env->block, pred); attr = get_mips_attr(result); attr->tv = new_tarval_from_long(immediate, mode_Iu); @@ -564,7 +563,7 @@ static ir_node *gen_node_for_Conv(mips_transform_env_t *env) { if(srcmode->size >= destmode->size) { assert(srcmode->size > destmode->size || srcmode->sign != destmode->sign); - return new_rd_mips_reinterpret_conv(env->dbg, env->irg, env->block, pred, node->mode); + return new_rd_mips_reinterpret_conv(env->dbg, env->irg, env->block, pred); } if(srcmode->sign) { if(srcmode->size == 8) { @@ -590,8 +589,13 @@ static ir_node *gen_node_mips_div(mips_transform_env_t *env, ir_node* op1, ir_no ir_node *node = env->irn; ir_node *div; const ir_edge_t *edge; + ir_mode *mode = get_irn_mode(node); - div = new_rd_mips_div(env->dbg, env->irg, env->block, op1, op2, mode_T); + if(mode_is_signed(mode)) { + div = new_rd_mips_div(env->dbg, env->irg, env->block, op1, op2); + } else { + div = new_rd_mips_divu(env->dbg, env->irg, env->block, op1, op2); + } // Adjust div projs foreach_out_edge(node, edge) { @@ -640,6 +644,7 @@ static ir_node *gen_node_for_Mul(mips_transform_env_t *env) { ir_node *mul; ir_node *mflo; ir_node *op1, *op2; + ir_mode *mode = get_irn_mode(node); op1 = get_Mul_left(node); op2 = get_Mul_right(node); @@ -648,8 +653,12 @@ static ir_node *gen_node_for_Mul(mips_transform_env_t *env) { assert(get_mode_size_bits(get_irn_mode(op1)) == get_mode_size_bits(env->mode)); assert(get_mode_size_bits(get_irn_mode(op2)) == get_mode_size_bits(env->mode)); - mul = new_rd_mips_mult(env->dbg, env->irg, env->block, get_Mul_left(node), get_Mul_right(node), env->mode); - mflo = new_rd_mips_mflo(env->dbg, env->irg, env->block, mul, env->mode); + if(mode_is_signed(mode)) { + mul = new_rd_mips_mult(env->dbg, env->irg, env->block, get_Mul_left(node), get_Mul_right(node)); + } else { + mul = new_rd_mips_multu(env->dbg, env->irg, env->block, get_Mul_left(node), get_Mul_right(node)); + } + mflo = new_rd_mips_mflo(env->dbg, env->irg, env->block, mul); return mflo; } @@ -671,11 +680,11 @@ static ir_node *gen_node_for_Abs(mips_transform_env_t *env) { // TODO for other bit sizes... assert(get_mode_size_bits(env->mode) == 32); - sra = new_rd_mips_srai(env->dbg, env->irg, env->block, get_Abs_op(node), node->mode); + sra = new_rd_mips_srai(env->dbg, env->irg, env->block, get_Abs_op(node)); attr = get_mips_attr(sra); attr->tv = new_tarval_from_long(31, mode_Iu); - add = new_rd_mips_add(env->dbg, env->irg, env->block, get_Abs_op(node), sra, node->mode); - xor = new_rd_mips_xor(env->dbg, env->irg, env->block, sra, add, node->mode); + add = new_rd_mips_addu(env->dbg, env->irg, env->block, get_Abs_op(node), sra); + xor = new_rd_mips_xor(env->dbg, env->irg, env->block, sra, add); return xor; } @@ -684,10 +693,10 @@ static ir_node *gen_node_for_Rot(mips_transform_env_t *env) { ir_node *node = env->irn; ir_node *subu, *srlv, *sllv, *or; - subu = new_rd_mips_subuzero(env->dbg, env->irg, env->block, get_Rot_right(node), env->mode); - srlv = new_rd_mips_srlv(env->dbg, env->irg, env->block, get_Rot_left(node), subu, env->mode); - sllv = new_rd_mips_sllv(env->dbg, env->irg, env->block, get_Rot_left(node), get_Rot_right(node), env->mode); - or = new_rd_mips_or(env->dbg, env->irg, env->block, sllv, srlv, env->mode); + subu = new_rd_mips_subuzero(env->dbg, env->irg, env->block, get_Rot_right(node)); + srlv = new_rd_mips_srlv(env->dbg, env->irg, env->block, get_Rot_left(node), subu); + sllv = new_rd_mips_sllv(env->dbg, env->irg, env->block, get_Rot_left(node), get_Rot_right(node)); + or = new_rd_mips_or(env->dbg, env->irg, env->block, sllv, srlv); return or; } @@ -946,7 +955,7 @@ static ir_node *gen_node_for_AddSP(mips_transform_env_t *env) op1 = get_irn_n(node, 0); op2 = get_irn_n(node, 1); - add = new_rd_mips_add(env->dbg, env->irg, env->block, op1, op2, mode_Iu); + add = new_rd_mips_addu(env->dbg, env->irg, env->block, op1, op2); /* copy the register requirements from the old node to the new node */ reg = arch_get_irn_register(env->cg->arch_env, node); @@ -998,7 +1007,7 @@ void mips_transform_node(ir_node *node, void *env) { DBG((tenv.mod, LEVEL_1, "check %+F ... ", node)); switch (code) { - BINOP(Add, add); + BINOP(Add, addu); BINOP(Sub, sub); BINOP(And, and); BINOP(Or, or); -- 2.20.1