-/**
- * 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;
- DEBUG_ONLY(tenv.mod = cgenv->mod;)
- 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
-
- DBG((tenv.mod, LEVEL_1, "check %+F ... ", node));
-
- 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;
-
- /* 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(Phi);
- 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);
- DB((tenv.mod, LEVEL_1, "created node %+F[%p]\n", asm_node, asm_node));
- } else {
- DB((tenv.mod, LEVEL_1, "ignored\n"));
- }