/*
- * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved.
+ * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
*
* This file is part of libFirm.
*
* @author Matthias Braun, Mehdi
* @version $Id$
*/
-#ifdef HAVE_CONFIG_H
#include "config.h"
-#endif
#include <limits.h>
#include "gen_mips_regalloc_if.h"
-/** hold the current code generator during transformation */
-static mips_code_gen_t *env_cg = NULL;
-
/****************************************************************************************************
* _ _ __ _ _
* | | | | / _| | | (_)
tv = get_Const_tarval(node);
if(tarval_is_long(tv)) {
val = get_tarval_long(tv);
- } else if(tarval_is_null(tv)) {
- val = 0;
} else {
ir_fprintf(stderr, "Optimisation Warning: tarval %+F is not a long?\n",
node);
if(tarval_is_long(tv)) {
val = get_tarval_long(tv);
- } else if(tarval_is_null(tv)) {
- val = 0;
} else {
- panic("Can't get value of tarval %+F\n", node);
+ panic("Can't get value of tarval %+F", node);
}
val = get_tarval_long(tv);
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *block = be_transform_node(get_nodes_block(node));
ir_entity *entity;
+ const arch_register_t **slots;
ir_node *lui, *or_const, *or;
if(get_SymConst_kind(node) != symconst_addr_ent) {
MIPS_IMM_SYMCONST_LO, entity, 0);
or = new_rd_mips_or(dbgi, irg, block, lui, or_const);
+ slots = get_mips_slots(or_const);
+ slots[0] = &mips_gp_regs[REG_GP_NOREG];
+
return or;
}
break;
}
- panic("invalid proj attached to %+F\n", divmod);
+ panic("invalid proj attached to %+F", divmod);
}
static ir_node *gen_Proj_Start(ir_node *node)
copy_node_attr(node, phi);
be_duplicate_deps(node, phi);
- be_set_transformed_node(node, phi);
be_enqueue_preds(node);
return phi;
} else if(src_size == 16) {
res = new_rd_mips_seh(dbgi, irg, block, new_op);
} else {
- panic("invalid conv %+F\n", node);
+ panic("invalid conv %+F", node);
}
} else {
ir_node *and_const;
} else if(src_size == 16) {
and_const = mips_create_Immediate(0xffff);
} else {
- panic("invalid conv %+F\n", node);
+ panic("invalid conv %+F", node);
}
res = new_rd_mips_and(dbgi, irg, block, new_op, and_const);
}
long n = get_Proj_proj(node);
if(n == pn_CopyB_M_except) {
- assert(0);
+ panic("Unsupported Proj from CopyB");
} else if(n == pn_CopyB_M_regular) {
set_Proj_proj(node, pn_Store_M);
} else if(n == pn_CopyB_M_except) {
}
/* copy the register from the old node to the new Load */
- reg = arch_get_irn_register(env->cg->arch_env, node);
- arch_set_irn_register(env->cg->arch_env, proj, reg);
+ reg = arch_get_irn_register(node);
+ arch_set_irn_register(proj, reg);
exchange(node, proj);
}
-#if 0
-static ir_node *gen_node_for_StackParam(mips_transform_env_t *env)
-{
- ir_node *node = env->irn;
- ir_node *sp = get_irn_n(node, 0);
- ir_node *load;
- ir_node *nomem = new_rd_NoMem(env->irg);
- ir_node *proj;
- mips_attr_t *attr;
-
- load = new_rd_mips_load_r(env->dbg, env->irg, env->block, nomem, sp, mode_T);
- attr = get_mips_attr(load);
- attr->stack_entity = be_get_frame_entity(node);
- attr->modes.load_store_mode = env->mode;
-
- proj = new_rd_Proj(env->dbg, env->irg, env->block, load, env->mode, pn_Load_res);
-
- return proj;
-}
-#endif
-
#if 0
static ir_node *gen_AddSP(ir_node *node)
{
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);
- arch_set_irn_register(env->cg->arch_env, add, reg);
+ reg = arch_get_irn_register(node);
+ arch_set_irn_register(add, reg);
return add;
}
*
*********************************************************/
-static ir_node *gen_Bad(ir_node *node)
+typedef ir_node *(*mips_transform_func) (ir_node *node);
+
+static void register_transformer(ir_op *op, mips_transform_func func)
{
- panic("Unexpected node %+F found in mips transform phase.\n", node);
- return NULL;
+ assert(op->ops.generic == NULL);
+ op->ops.generic = (op_func) func;
}
static void register_transformers(void)
{
clear_irp_opcodes_generic_func();
- op_Add->ops.generic = (op_func) gen_Add;
- op_Sub->ops.generic = (op_func) gen_Sub;
- op_And->ops.generic = (op_func) gen_And;
- op_Or->ops.generic = (op_func) gen_Or;
- op_Eor->ops.generic = (op_func) gen_Eor;
- op_Shl->ops.generic = (op_func) gen_Shl;
- op_Shr->ops.generic = (op_func) gen_Shr;
- op_Shrs->ops.generic = (op_func) gen_Shrs;
- op_Not->ops.generic = (op_func) gen_Not;
- op_Minus->ops.generic = (op_func) gen_Minus;
- op_Div->ops.generic = (op_func) gen_Div;
- op_Mod->ops.generic = (op_func) gen_Mod;
- op_DivMod->ops.generic = (op_func) gen_DivMod;
- op_Abs->ops.generic = (op_func) gen_Abs;
- op_Load->ops.generic = (op_func) gen_Load;
- op_Store->ops.generic = (op_func) gen_Store;
- op_Cond->ops.generic = (op_func) gen_Cond;
- op_Conv->ops.generic = (op_func) gen_Conv;
- op_Const->ops.generic = (op_func) gen_Const;
- op_SymConst->ops.generic = (op_func) gen_SymConst;
- op_Unknown->ops.generic = (op_func) gen_Unknown;
- op_Proj->ops.generic = (op_func) gen_Proj;
- op_Phi->ops.generic = (op_func) gen_Phi;
-
- op_Raise->ops.generic = (op_func) gen_Bad;
- op_Sel->ops.generic = (op_func) gen_Bad;
- op_InstOf->ops.generic = (op_func) gen_Bad;
- op_Cast->ops.generic = (op_func) gen_Bad;
- op_Free->ops.generic = (op_func) gen_Bad;
- op_Tuple->ops.generic = (op_func) gen_Bad;
- op_Id->ops.generic = (op_func) gen_Bad;
- op_Confirm->ops.generic = (op_func) gen_Bad;
- op_Filter->ops.generic = (op_func) gen_Bad;
- op_CallBegin->ops.generic = (op_func) gen_Bad;
- op_EndReg->ops.generic = (op_func) gen_Bad;
- op_EndExcept->ops.generic = (op_func) gen_Bad;
+ register_transformer(op_Add, gen_Add);
+ register_transformer(op_Sub, gen_Sub);
+ register_transformer(op_And, gen_And);
+ register_transformer(op_Or, gen_Or);
+ register_transformer(op_Eor, gen_Eor);
+ register_transformer(op_Shl, gen_Shl);
+ register_transformer(op_Shr, gen_Shr);
+ register_transformer(op_Shrs, gen_Shrs);
+ register_transformer(op_Not, gen_Not);
+ register_transformer(op_Minus, gen_Minus);
+ register_transformer(op_Div, gen_Div);
+ register_transformer(op_Mod, gen_Mod);
+ register_transformer(op_DivMod, gen_DivMod);
+ register_transformer(op_Abs, gen_Abs);
+ register_transformer(op_Load, gen_Load);
+ register_transformer(op_Store, gen_Store);
+ register_transformer(op_Cond, gen_Cond);
+ register_transformer(op_Conv, gen_Conv);
+ register_transformer(op_Const, gen_Const);
+ register_transformer(op_SymConst, gen_SymConst);
+ register_transformer(op_Unknown, gen_Unknown);
+ register_transformer(op_Proj, gen_Proj);
+ register_transformer(op_Phi, gen_Phi);
}
-#if 0
-/**
- * Transforms the given firm node (and maybe some other related nodes)
- * into one or more assembler nodes.
- *
- * @param node the firm node
- * @param env the debug module
- */
-void mips_transform_node(ir_node *node, void *env) {
- mips_code_gen_t *cgenv = (mips_code_gen_t *)env;
- ir_opcode code = get_irn_opcode(node);
- ir_node *asm_node = node;
- mips_transform_env_t tenv;
-
- if (is_Block(node))
- return;
-
- tenv.block = get_nodes_block(node);
- tenv.dbg = get_irn_dbg_info(node);
- tenv.irg = current_ir_graph;
- tenv.irn = node;
- tenv.mode = get_irn_mode(node);
- tenv.cg = cgenv;
-
-#define UNOP(firm_opcode, mips_nodetype) case iro_##firm_opcode: asm_node = mips_gen_##mips_nodetype(&tenv, get_##firm_opcode##_op(node)); break
-#define BINOP(firm_opcode, mips_nodetype) case iro_##firm_opcode: asm_node = mips_gen_##mips_nodetype(&tenv, get_##firm_opcode##_left(node), get_##firm_opcode##_right(node)); break
-#define IGN(a) case iro_##a: break
-#define BAD(a) case iro_##a: goto bad
-
- switch (code) {
- BINOP(Add, addu);
- BINOP(Sub, sub);
- BINOP(And, and);
- BINOP(Or, or);
- BINOP(Eor, xor);
- UNOP(Not, not);
- BINOP(Shl, sl);
- BINOP(Shr, sr);
- BINOP(Shrs, sra);
-
- case iro_Abs:
- asm_node = gen_node_for_Abs(&tenv);
- break;
-
- case iro_Rot:
- asm_node = gen_node_for_Rot(&tenv);
- break;
-
- case iro_Div:
- asm_node = gen_node_for_Div(&tenv);
- break;
-
- case iro_Mod:
- asm_node = gen_node_for_Mod(&tenv);
- break;
-
- case iro_Load:
- asm_node = gen_node_for_Load(&tenv);
- break;
-
- case iro_Store:
- asm_node = gen_node_for_Store(&tenv);
- break;
-
- case iro_Proj:
- asm_node = gen_node_for_Proj(&tenv);
- break;
-
- case iro_Conv:
- asm_node = gen_node_for_Conv(&tenv);
- break;
-
- case iro_DivMod:
- asm_node = gen_node_for_DivMod(&tenv);
- break;
-
- case iro_Mul:
- asm_node = gen_node_for_Mul(&tenv);
- break;
-
- case iro_Jmp:
- asm_node = gen_node_for_Jmp(&tenv);
- break;
-
- case iro_IJmp:
- asm_node = gen_node_for_IJmp(&tenv);
- break;
-
- case iro_Unknown:
- asm_node = gen_node_for_Unknown(&tenv);
- break;
-
- case iro_Cond:
- asm_node = gen_node_for_Cond(&tenv);
- break;
-
- case iro_Phi:
- asm_node = gen_node_for_Phi(&tenv);
- break;
-
- /* TODO: implement these nodes */
- BAD(Mux);
-
- /* You probably don't need to handle the following nodes */
-
- // call is handled in the emit phase
- IGN(Call);
- // Cmp is handled together with Cond
- IGN(Cmp);
- IGN(Alloc);
-
- IGN(Block);
- IGN(Start);
- IGN(End);
- IGN(NoMem);
- IGN(Break);
- IGN(Sync);
-
- IGN(Const);
- IGN(SymConst);
-
- BAD(Raise);
- BAD(Sel);
- BAD(InstOf);
- BAD(Cast);
- BAD(Free);
- BAD(Tuple);
- BAD(Id);
- BAD(Bad);
- BAD(Confirm);
- BAD(Filter);
- BAD(CallBegin);
- BAD(EndReg);
- BAD(EndExcept);
-
- default:
- if(be_is_StackParam(node)) {
- //asm_node = gen_node_for_StackParam(&tenv);
- } else if(be_is_AddSP(node)) {
- asm_node = gen_node_for_AddSP(&tenv);
- }
- break;
-
-bad:
- fprintf(stderr, "Not implemented: %s\n", get_irn_opname(node));
- assert(0);
- }
-
- if (asm_node != node) {
- exchange(node, asm_node);
- }
-}
-#endif
-
void mips_transform_graph(mips_code_gen_t *cg)
{
- env_cg = cg;
register_transformers();
- be_transform_graph(cg->birg, NULL, cg);
+ be_transform_graph(cg->birg, NULL);
}
/**