adapt mips backend to new transform logic, use Immediate nodes, fixes
[libfirm] / ir / be / mips / mips_transform.c
1 /*
2  * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief   The codegenrator (transform FIRM into mips FIRM
23  * @author  Matthias Braun, Mehdi
24  * @version $Id$
25  */
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include <limits.h>
31
32 #include "irnode_t.h"
33 #include "irgraph_t.h"
34 #include "irmode_t.h"
35 #include "irgmod.h"
36 #include "iredges.h"
37 #include "irvrfy.h"
38 #include "ircons.h"
39 #include "irprintf.h"
40 #include "irop.h"
41 #include "dbginfo.h"
42 #include "iropt_t.h"
43 #include "debug.h"
44 #include "error.h"
45
46 #include "../benode_t.h"
47 #include "../beabi.h"
48 #include "../besched.h"
49 #include "../besched_t.h"
50 #include "../beirg_t.h"
51 #include "../betranshlp.h"
52 #include "bearch_mips_t.h"
53
54 #include "mips_nodes_attr.h"
55 #include "archop.h"
56 #include "mips_transform.h"
57 #include "mips_new_nodes.h"
58 #include "mips_map_regs.h"
59 #include "mips_util.h"
60 #include "mips_emitter.h"
61
62 #include "gen_mips_regalloc_if.h"
63
64 /** hold the current code generator during transformation */
65 static mips_code_gen_t *env_cg = NULL;
66
67 /****************************************************************************************************
68  *                  _        _                        __                           _   _
69  *                 | |      | |                      / _|                         | | (_)
70  *  _ __   ___   __| | ___  | |_ _ __ __ _ _ __  ___| |_ ___  _ __ _ __ ___   __ _| |_ _  ___  _ __
71  * | '_ \ / _ \ / _` |/ _ \ | __| '__/ _` | '_ \/ __|  _/ _ \| '__| '_ ` _ \ / _` | __| |/ _ \| '_ \
72  * | | | | (_) | (_| |  __/ | |_| | | (_| | | | \__ \ || (_) | |  | | | | | | (_| | |_| | (_) | | | |
73  * |_| |_|\___/ \__,_|\___|  \__|_|  \__,_|_| |_|___/_| \___/|_|  |_| |_| |_|\__,_|\__|_|\___/|_| |_|
74  *
75  ****************************************************************************************************/
76
77 typedef ir_node *construct_binop_func(dbg_info *db, ir_graph *irg,
78         ir_node *block, ir_node *left, ir_node *right);
79
80 static INLINE int mode_needs_gp_reg(ir_mode *mode) {
81         return mode_is_int(mode) || mode_is_character(mode)
82                 || mode_is_reference(mode);
83 }
84
85 ir_node *mips_create_Immediate(long val)
86 {
87         ir_graph *irg   = current_ir_graph;
88         ir_node  *block = get_irg_start_block(irg);
89         const arch_register_t **slots;
90         ir_node  *res;
91
92         assert(val >=  -32768 && val <= 32767);
93         res      = new_rd_mips_Immediate(NULL, irg, block, MIPS_IMM_CONST, NULL,
94                                          val);
95         slots    = get_mips_slots(res);
96         slots[0] = &mips_gp_regs[REG_GP_NOREG];
97
98         return res;
99 }
100
101 ir_node* mips_create_zero(void)
102 {
103         ir_graph *irg   = current_ir_graph;
104         ir_node  *block = get_irg_start_block(irg);
105         ir_node  *zero  = new_rd_mips_zero(NULL, irg, block);
106         const arch_register_t **slots = get_mips_slots(zero);
107
108         slots[0] = &mips_gp_regs[REG_ZERO];
109
110         return zero;
111 }
112
113 static ir_node *try_create_Immediate(ir_node *node)
114 {
115         tarval   *tv;
116         long      val;
117         ir_mode  *mode;
118
119         if(!is_Const(node))
120                 return NULL;
121
122         mode = get_irn_mode(node);
123         if(!mode_needs_gp_reg(mode))
124                 return NULL;
125
126         tv = get_Const_tarval(node);
127         if(tarval_is_long(tv)) {
128                 val = get_tarval_long(tv);
129         } else if(tarval_is_null(tv)) {
130                 val = 0;
131         } else {
132                 ir_fprintf(stderr, "Optimisation Warning: tarval %+F is not a long?\n",
133                            node);
134                 return NULL;
135         }
136
137         if(val < -32768 || val > 32767)
138                 return NULL;
139
140         return mips_create_Immediate(val);
141 }
142
143 static void create_binop_operands(ir_node **new_left, ir_node **new_right,
144                                   ir_node *left, ir_node *right,
145                                   int is_commutative)
146 {
147         *new_right = try_create_Immediate(right);
148         if(*new_right != NULL) {
149                 *new_left = be_transform_node(left);
150                 return;
151         }
152         if(is_commutative) {
153                 *new_right = try_create_Immediate(left);
154                 if(*new_right != NULL) {
155                         *new_left = be_transform_node(right);
156                         return;
157                 }
158         }
159
160         *new_left  = be_transform_node(left);
161         *new_right = be_transform_node(right);
162 }
163
164 static ir_node *gen_binop(ir_node *node, ir_node *left, ir_node *right,
165                           construct_binop_func func, int supports_immediate)
166 {
167         ir_graph *irg   = current_ir_graph;
168         dbg_info *dbgi  = get_irn_dbg_info(node);
169         ir_node  *block = be_transform_node(get_nodes_block(node));
170         ir_node  *res;
171         ir_node  *new_left, *new_right;
172
173         assert(mode_needs_gp_reg(get_irn_mode(node)));
174
175         if(supports_immediate) {
176                 int is_commutative = is_op_commutative(get_irn_op(node));
177                 create_binop_operands(&new_left, &new_right, left, right,
178                                       is_commutative);
179         } else {
180                 new_left  = be_transform_node(left);
181                 new_right = be_transform_node(right);
182         }
183
184         res = func(dbgi, irg, block, new_left, new_right);
185
186         return res;
187 }
188
189 static ir_node *gen_Add(ir_node *node)
190 {
191         /* TODO: match add(symconst, const) */
192         return gen_binop(node, get_Add_left(node), get_Add_right(node),
193                          new_rd_mips_addu, 1);
194 }
195
196 static ir_node *gen_Sub(ir_node *node)
197 {
198         return gen_binop(node, get_Sub_left(node), get_Sub_right(node),
199                          new_rd_mips_addu, 0);
200 }
201
202 static ir_node *gen_And(ir_node *node)
203 {
204         return gen_binop(node, get_Add_left(node), get_Add_right(node),
205                          new_rd_mips_and, 1);
206 }
207
208 static ir_node *gen_Or(ir_node *node)
209 {
210         return gen_binop(node, get_Add_left(node), get_Add_right(node),
211                          new_rd_mips_or, 1);
212 }
213
214 static ir_node *gen_Eor(ir_node *node)
215 {
216         return gen_binop(node, get_Add_left(node), get_Add_right(node),
217                          new_rd_mips_xor, 1);
218 }
219
220 static ir_node *gen_Shl(ir_node *node)
221 {
222         return gen_binop(node, get_Add_left(node), get_Add_right(node),
223                          new_rd_mips_sll, 1);
224 }
225
226 static ir_node *gen_Shr(ir_node *node)
227 {
228         return gen_binop(node, get_Add_left(node), get_Add_right(node),
229                          new_rd_mips_srl, 1);
230 }
231
232 static ir_node *gen_Shrs(ir_node *node)
233 {
234         return gen_binop(node, get_Add_left(node), get_Add_right(node),
235                          new_rd_mips_sra, 1);
236 }
237
238 static ir_node *gen_Not(ir_node *node)
239 {
240         ir_graph *irg   = current_ir_graph;
241         dbg_info *dbgi  = get_irn_dbg_info(node);
242         ir_node  *block = be_transform_node(get_nodes_block(node));
243         ir_node  *op    = get_Not_op(node);
244         ir_node  *new_op;
245         ir_node  *res;
246         ir_node  *one;
247
248         /* we can transform not->or to nor */
249         if(is_Or(op)) {
250                 return gen_binop(op, get_Or_left(op), get_Or_right(op),
251                                  new_rd_mips_nor, 1);
252         }
253
254         /* construct (op < 1) */
255         one    = mips_create_Immediate(1);
256         new_op = be_transform_node(op);
257         res    = new_rd_mips_sltu(dbgi, irg, block, new_op, one);
258
259         return res;
260 }
261
262 static ir_node *gen_Minus(ir_node *node)
263 {
264         ir_graph *irg    = current_ir_graph;
265         dbg_info *dbgi   = get_irn_dbg_info(node);
266         ir_node  *block  = be_transform_node(get_nodes_block(node));
267         ir_node  *op     = get_Minus_op(node);
268         ir_node  *new_op = be_transform_node(op);
269         ir_node  *res;
270         ir_node  *zero;
271
272         /* construct (0 - op) */
273         zero = mips_create_zero();
274         res  = new_rd_mips_subu(dbgi, irg, block, zero, new_op);
275
276         return res;
277 }
278
279 static ir_node *gen_Abs(ir_node *node)
280 {
281         ir_graph *irg    = current_ir_graph;
282         dbg_info *dbgi   = get_irn_dbg_info(node);
283         ir_node  *block  = be_transform_node(get_nodes_block(node));
284         ir_node  *op     = get_Abs_op(node);
285         ir_node  *new_op = be_transform_node(op);
286         ir_node  *sra_const, *sra, *add, *xor;
287
288         /* TODO: support other bit sizes... */
289         assert(get_mode_size_bits(get_irn_mode(node)) == 32);
290         sra_const = mips_create_Immediate(31);
291         sra       = new_rd_mips_sra(dbgi, irg, block, new_op, sra_const);
292         add       = new_rd_mips_addu(dbgi, irg, block, new_op, sra);
293         xor       = new_rd_mips_xor(dbgi, irg, block, sra, add);
294
295         return xor;
296 }
297
298 static ir_node* gen_Const(ir_node *node)
299 {
300         ir_graph *irg   = current_ir_graph;
301         dbg_info *dbgi  = get_irn_dbg_info(node);
302         ir_node  *block = be_transform_node(get_nodes_block(node));
303         tarval   *tv    = get_Const_tarval(node);
304         ir_node  *upper_node;
305         ir_node  *lower_node;
306         ir_node  *or_const;
307         unsigned long val, lower, upper;
308
309         if(tarval_is_long(tv)) {
310                 val = get_tarval_long(tv);
311         } else if(tarval_is_null(tv)) {
312                 val = 0;
313         } else {
314                 panic("Can't get value of tarval %+F\n", node);
315         }
316
317         val = get_tarval_long(tv);
318
319         lower = val & 0xffff;
320         upper = (val >> 16) & 0xffff;
321         if(upper == 0) {
322                 upper_node = mips_create_zero();
323         } else {
324                 upper_node = new_rd_mips_lui(dbgi, irg, block, MIPS_IMM_CONST, NULL,
325                                              upper);
326         }
327
328         if(lower == 0)
329                 return upper_node;
330
331         or_const   = mips_create_Immediate(lower);
332         lower_node = new_rd_mips_or(dbgi, irg, block, upper_node, or_const);
333
334         return lower_node;
335 }
336
337 static ir_node* gen_SymConst(ir_node *node)
338 {
339         ir_graph *irg   = current_ir_graph;
340         dbg_info *dbgi  = get_irn_dbg_info(node);
341         ir_node  *block = be_transform_node(get_nodes_block(node));
342         ir_entity *entity;
343         ir_node *lui, *or_const, *or;
344
345         if(get_SymConst_kind(node) != symconst_addr_ent) {
346                 panic("Only address entity symconsts supported in mips backend");
347         }
348
349         entity = get_SymConst_entity(node);
350
351         lui            = new_rd_mips_lui(dbgi, irg, block, MIPS_IMM_SYMCONST_HI,
352                                          entity, 0);
353         or_const       = new_rd_mips_Immediate(dbgi, irg, block,
354                                                MIPS_IMM_SYMCONST_LO, entity, 0);
355         or             = new_rd_mips_or(dbgi, irg, block, lui, or_const);
356
357         return or;
358 }
359
360 typedef ir_node* (*gen_load_func) (dbg_info *dbg, ir_graph *irg,
361                                    ir_node *block, ir_node *ptr, ir_node *mem,
362                                    ir_entity *entity, long offset);
363
364 /**
365  * Generates a mips node for a firm Load node
366  */
367 static ir_node *gen_Load(ir_node *node)
368 {
369         ir_graph *irg     = current_ir_graph;
370         dbg_info *dbgi    = get_irn_dbg_info(node);
371         ir_node  *block   = be_transform_node(get_nodes_block(node));
372         ir_node  *mem     = get_Load_mem(node);
373         ir_node  *new_mem = be_transform_node(mem);
374         ir_node  *ptr     = get_Load_ptr(node);
375         ir_node  *new_ptr = be_transform_node(ptr);
376         ir_mode  *mode    = get_Load_mode(node);
377         int       sign    = get_mode_sign(mode);
378         ir_node  *res;
379         gen_load_func func;
380
381         ASSERT_NO_FLOAT(mode);
382         assert(mode_needs_gp_reg(mode));
383
384         /* TODO: make use of offset in ptrs */
385
386         switch(get_mode_size_bits(mode)) {
387         case 32:
388                 func = new_rd_mips_lw;
389                 break;
390         case 16:
391                 func = sign ? new_rd_mips_lh : new_rd_mips_lhu;
392                 break;
393         case 8:
394                 func = sign ? new_rd_mips_lb : new_rd_mips_lbu;
395                 break;
396         default:
397                 panic("mips backend only support 32, 16, 8 bit loads");
398         }
399
400         res = func(dbgi, irg, block, new_ptr, new_mem, NULL, 0);
401         set_irn_pinned(res, get_irn_pinned(node));
402
403         return res;
404 }
405
406 typedef ir_node* (*gen_store_func) (dbg_info *dbg, ir_graph *irg,
407                                     ir_node *block, ir_node *ptr, ir_node *val,
408                                     ir_node *mem, ir_entity *ent, long offset);
409
410 /**
411  * Generates a mips node for a firm Store node
412  */
413 static ir_node *gen_Store(ir_node *node)
414 {
415         ir_graph    *irg     = current_ir_graph;
416         dbg_info    *dbgi    = get_irn_dbg_info(node);
417         ir_node     *block   = be_transform_node(get_nodes_block(node));
418         ir_node     *mem     = get_Store_mem(node);
419         ir_node     *new_mem = be_transform_node(mem);
420         ir_node     *ptr     = get_Store_ptr(node);
421         ir_node     *new_ptr = be_transform_node(ptr);
422         ir_node     *val     = get_Store_value(node);
423         ir_node     *new_val = be_transform_node(val);
424         ir_mode     *mode    = get_irn_mode(val);
425         gen_store_func func;
426         ir_node     *res;
427
428         assert(mode_needs_gp_reg(mode));
429
430         switch(get_mode_size_bits(mode)) {
431         case 32:
432                 func = new_rd_mips_sw;
433                 break;
434         case 16:
435                 func = new_rd_mips_sh;
436                 break;
437         case 8:
438                 func = new_rd_mips_sb;
439                 break;
440         default:
441                 panic("store only supported for 32, 16, 8 bit values in mips backend");
442         }
443
444         res = func(dbgi, irg, block, new_ptr, new_val, new_mem, NULL, 0);
445         set_irn_pinned(res, get_irn_pinned(node));
446
447         return res;
448 }
449
450 static ir_node *gen_Proj_DivMod(ir_node *node)
451 {
452         ir_graph *irg     = current_ir_graph;
453         dbg_info *dbgi    = get_irn_dbg_info(node);
454         ir_node  *block   = be_transform_node(get_nodes_block(node));
455         ir_node  *divmod  = get_Proj_pred(node);
456         ir_node  *new_div = be_transform_node(divmod);
457         long      pn      = get_Proj_proj(node);
458         ir_node  *proj;
459
460         assert(is_mips_div(new_div) || is_mips_divu(new_div));
461
462         switch(get_irn_opcode(divmod)) {
463         case iro_Div:
464                 switch(pn) {
465                 case pn_Div_M:
466                         return new_rd_Proj(dbgi, irg, block, new_div, mode_M,
467                                            pn_mips_div_M);
468                 case pn_Div_res:
469                         proj = new_rd_Proj(dbgi, irg, block, new_div, mode_M,
470                                            pn_mips_div_lohi);
471                         return new_rd_mips_mflo(dbgi, irg, block, proj);
472                 default:
473                         break;
474                 }
475         case iro_Mod:
476                 switch(pn) {
477                 case pn_Mod_M:
478                         return new_rd_Proj(dbgi, irg, block, new_div, mode_M,
479                                            pn_mips_div_M);
480                 case pn_Mod_res:
481                         proj = new_rd_Proj(dbgi, irg, block, new_div, mode_M,
482                                            pn_mips_div_lohi);
483                         return new_rd_mips_mfhi(dbgi, irg, block, proj);
484                 default:
485                         break;
486                 }
487
488         case iro_DivMod:
489                 switch(pn) {
490                 case pn_Div_M:
491                         return new_rd_Proj(dbgi, irg, block, new_div, mode_M,
492                                            pn_mips_div_M);
493                 case pn_DivMod_res_div:
494                         proj = new_rd_Proj(dbgi, irg, block, new_div, mode_M,
495                                            pn_mips_div_lohi);
496                         return new_rd_mips_mflo(dbgi, irg, block, proj);
497                 case pn_DivMod_res_mod:
498                         proj = new_rd_Proj(dbgi, irg, block, new_div, mode_M,
499                                            pn_mips_div_lohi);
500                         return new_rd_mips_mfhi(dbgi, irg, block, proj);
501                 default:
502                         break;
503                 }
504         default:
505                 break;
506         }
507
508         panic("invalid proj attached to %+F\n", divmod);
509 }
510
511 static ir_node *gen_Proj_Start(ir_node *node)
512 {
513         ir_graph *irg   = current_ir_graph;
514         dbg_info *dbgi  = get_irn_dbg_info(node);
515         ir_node  *block = be_transform_node(get_nodes_block(node));
516         long      pn    = get_Proj_proj(node);
517
518         if(pn == pn_Start_X_initial_exec) {
519                 /* we exchange the projx with a jump */
520                 ir_node *jump = new_rd_Jmp(dbgi, irg, block);
521                 return jump;
522         }
523         if(node == be_get_old_anchor(anchor_tls)) {
524                 /* TODO... */
525                 return be_duplicate_node(node);
526         }
527         return be_duplicate_node(node);
528 }
529
530 static ir_node *gen_Proj(ir_node *node)
531 {
532         ir_graph *irg  = current_ir_graph;
533         dbg_info *dbgi = get_irn_dbg_info(node);
534         ir_node  *pred = get_Proj_pred(node);
535
536         switch(get_irn_opcode(pred)) {
537         case iro_Load:
538                 break;
539         case iro_Store:
540                 break;
541         case iro_Div:
542         case iro_Mod:
543         case iro_DivMod:
544                 return gen_Proj_DivMod(node);
545
546         case iro_Start:
547                 return gen_Proj_Start(node);
548
549         default:
550                 assert(get_irn_mode(node) != mode_T);
551                 if(mode_needs_gp_reg(get_irn_mode(node))) {
552                         ir_node *new_pred = be_transform_node(pred);
553                         ir_node *block    = be_transform_node(get_nodes_block(node));
554                         long     pn       = get_Proj_proj(node);
555
556                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn);
557                 }
558                 break;
559         }
560
561         return be_duplicate_node(node);
562 }
563
564 static ir_node *gen_Phi(ir_node *node)
565 {
566         ir_graph *irg   = current_ir_graph;
567         dbg_info *dbgi  = get_irn_dbg_info(node);
568         ir_node  *block = be_transform_node(get_nodes_block(node));
569         ir_mode  *mode  = get_irn_mode(node);
570         ir_node  *phi;
571
572         if(mode_needs_gp_reg(mode)) {
573                 assert(get_mode_size_bits(mode) <= 32);
574                 mode = mode_Iu;
575         }
576
577         /* phi nodes allow loops, so we use the old arguments for now
578          * and fix this later */
579         phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
580                           get_irn_in(node) + 1);
581         copy_node_attr(node, phi);
582         be_duplicate_deps(node, phi);
583
584         be_set_transformed_node(node, phi);
585         be_enqueue_preds(node);
586
587         return phi;
588 }
589
590 #if 0
591 static
592 ir_node *gen_node_for_SwitchCond(mips_transform_env_t *env)
593 {
594         ir_node *selector = get_Cond_selector(env->irn);
595         ir_mode *selector_mode = get_irn_mode(selector);
596         ir_node *node = env->irn;
597         dbg_info *dbg = env->dbg;
598         ir_graph *irg = env->irg;
599         ir_node *block = env->block;
600         ir_node *sub, *sltu, *minval_const, *max_const, *switchjmp;
601         ir_node *defaultproj, *defaultproj_succ;
602         ir_node *beq, *sl;
603         long pn, minval, maxval, defaultprojn;
604         const ir_edge_t *edge;
605         ir_node *zero, *two_const, *add, *la, *load, *proj;
606         ir_mode *unsigned_mode;
607         mips_attr_t *attr;
608
609         // mode_b conds are handled by gen_node_for_Proj
610         if(get_mode_sort(selector_mode) != irms_int_number)
611                 return env->irn;
612
613         assert(get_mode_size_bits(selector_mode) == 32);
614
615         defaultproj = NULL;
616         defaultprojn = get_Cond_defaultProj(node);
617
618         // go over all projs to find min-&maxval of the switch
619         minval = INT_MAX;
620         maxval = INT_MIN;
621         foreach_out_edge(node, edge) {
622                 ir_node* proj = get_edge_src_irn(edge);
623                 assert(is_Proj(proj) && "Only proj allowed at SwitchJmp");
624
625                 pn = get_Proj_proj(proj);
626                 if(pn == defaultprojn) {
627                         defaultproj = proj;
628                         continue;
629                 }
630
631                 if(pn < minval)
632                         minval = pn;
633                 if(pn > maxval)
634                         maxval = pn;
635         }
636         assert(defaultproj != NULL);
637
638         // subtract minval from the switch value
639
640         if(minval != 0) {
641                 minval_const = new_rd_Const(dbg, irg, block, selector_mode, new_tarval_from_long(minval, selector_mode));
642                 minval_const = gen_node_for_Const(env, dbg, irg, block, minval_const);
643                 sub = new_rd_mips_sub(dbg, irg, block, selector, minval_const);
644         } else {
645                 sub = selector;
646         }
647
648         // compare if we're above maxval-minval or below zero.
649         // we can do this with 1 compare because we use unsigned mode
650         unsigned_mode = new_ir_mode(get_mode_name(selector_mode),
651                         get_mode_sort(selector_mode), get_mode_size_bits(selector_mode),
652                         0, get_mode_arithmetic(selector_mode), get_mode_modulo_shift(selector_mode));
653
654         max_const = new_rd_Const(dbg, irg, block, unsigned_mode, new_tarval_from_long(maxval - minval + 1, unsigned_mode));
655         max_const = gen_node_for_Const(env, dbg, irg, block, max_const);
656         sltu = new_rd_mips_slt(dbg, irg, block, sub, max_const);
657
658         zero = gen_zero_node(env, dbg, irg, block);
659         beq = new_rd_mips_beq(dbg, irg, block, sltu, zero, mode_T);
660
661         // attach defaultproj to beq now
662         set_irn_n(defaultproj, 0, beq);
663         set_Proj_proj(defaultproj, 1);
664
665         two_const = new_rd_Const(dbg, irg, block, unsigned_mode, new_tarval_from_long(2, unsigned_mode));
666         two_const = gen_node_for_Const(env, dbg, irg, block, two_const);
667         sl = new_rd_mips_sl(dbg, irg, block, sub, two_const);
668
669         la = new_rd_mips_la(dbg, irg, block);
670         add = new_rd_mips_addu(dbg, irg, block, sl, la);
671         load = new_rd_mips_load_r(dbg, irg, block, new_rd_NoMem(irg), add, mode_T);
672         attr = get_mips_attr(load);
673         attr->modes.load_store_mode = mode_Iu;
674         attr->tv = new_tarval_from_long(0, mode_Iu);
675
676         proj = new_rd_Proj(dbg, irg, block, load, mode_Iu, pn_Load_res);
677
678         switchjmp = new_rd_mips_SwitchJump(dbg, irg, block, proj, mode_T);
679         attr = get_mips_attr(switchjmp);
680         attr->switch_default_pn = defaultprojn;
681
682         edge = get_irn_out_edge_first(defaultproj);
683         defaultproj_succ = get_edge_src_irn(edge);
684         attr->symconst_id = new_id_from_str(mips_get_block_label(defaultproj_succ));
685
686         attr = get_mips_attr(la);
687         attr->symconst_id = new_id_from_str(mips_get_jumptbl_label(switchjmp));
688
689         return switchjmp;
690 }
691 #endif
692
693 static ir_node *gen_Cond(ir_node *node)
694 {
695         ir_graph *irg       = current_ir_graph;
696         dbg_info *dbgi      = get_irn_dbg_info(node);
697         ir_node  *block     = get_nodes_block(node);
698         ir_node  *sel_proj  = get_Cond_selector(node);
699         ir_node  *cmp       = get_Proj_pred(sel_proj);
700         ir_node  *left      = get_Cmp_left(cmp);
701         ir_node  *new_left  = be_transform_node(left);
702         ir_node  *right     = get_Cmp_right(cmp);
703         ir_node  *new_right = be_transform_node(right);
704         long      pnc       = get_Proj_proj(sel_proj);
705         ir_node  *res;
706         ir_node  *slt;
707         ir_node  *zero;
708
709         /* TODO: use blez & co. when possible */
710
711         switch(pnc) {
712         case pn_Cmp_False:
713         case pn_Cmp_True:
714         case pn_Cmp_Leg:
715                 panic("mips backend can't handle unoptimized constant Cond");
716
717         case pn_Cmp_Eq:
718                 res = new_rd_mips_beq(dbgi, irg, block, new_left, new_right);
719                 break;
720
721         case pn_Cmp_Lt:
722                 zero = mips_create_zero();
723                 slt  = new_rd_mips_slt(dbgi, irg, block, new_left, new_right);
724                 res  = new_rd_mips_bne(dbgi, irg, block, slt, zero);
725                 break;
726
727         case pn_Cmp_Le:
728                 zero = mips_create_zero();
729                 slt  = new_rd_mips_slt(dbgi, irg, block, new_right, new_left);
730                 res  = new_rd_mips_beq(dbgi, irg, block, slt, zero);
731                 break;
732
733         case pn_Cmp_Gt:
734                 zero = mips_create_zero();
735                 slt  = new_rd_mips_slt(dbgi, irg, block, new_right, new_left);
736                 res  = new_rd_mips_bne(dbgi, irg, block, slt, zero);
737                 break;
738
739         case pn_Cmp_Ge:
740                 zero = mips_create_zero();
741                 slt  = new_rd_mips_slt(dbgi, irg, block, new_right, new_left);
742                 res  = new_rd_mips_bne(dbgi, irg, block, slt, zero);
743                 break;
744
745         case pn_Cmp_Lg:
746                 res = new_rd_mips_bne(dbgi, irg, block, new_left, new_right);
747                 break;
748
749         default:
750                 panic("mips backend doesn't handle unordered compares yet");
751         }
752
753         return res;
754 }
755
756 static ir_node *gen_Conv(ir_node *node)
757 {
758         ir_graph *irg      = current_ir_graph;
759         dbg_info *dbgi     = get_irn_dbg_info(node);
760         ir_node  *block    = be_transform_node(get_nodes_block(node));
761         ir_node  *op       = get_Conv_op(node);
762         ir_node  *new_op   = be_transform_node(op);
763         ir_mode  *src_mode = get_irn_mode(op);
764         ir_mode  *dst_mode = get_irn_mode(node);
765         int       src_size = get_mode_size_bits(src_mode);
766         int       dst_size = get_mode_size_bits(dst_mode);
767         ir_node  *res;
768
769         assert(mode_needs_gp_reg(src_mode));
770         assert(mode_needs_gp_reg(dst_mode));
771
772         /* we only need to do something on upconvs */
773         if(src_size >= dst_size) {
774                 /* unnecessary conv */
775                 return new_op;
776         }
777
778         if(mode_is_signed(src_mode)) {
779                 if(src_size == 8) {
780                         res = new_rd_mips_seb(dbgi, irg, block, new_op);
781                 } else if(src_size == 16) {
782                         res = new_rd_mips_seh(dbgi, irg, block, new_op);
783                 } else {
784                         panic("invalid conv %+F\n", node);
785                 }
786         } else {
787                 ir_node *and_const;
788
789                 if(src_size == 8) {
790                         and_const = mips_create_Immediate(0xff);
791                 } else if(src_size == 16) {
792                         and_const = mips_create_Immediate(0xffff);
793                 } else {
794                         panic("invalid conv %+F\n", node);
795                 }
796                 res = new_rd_mips_and(dbgi, irg, block, new_op, and_const);
797         }
798
799         return res;
800 }
801
802 static ir_node *create_div(ir_node *node, ir_node *left, ir_node *right,
803                            ir_mode *mode)
804 {
805         ir_graph *irg       = current_ir_graph;
806         dbg_info *dbgi      = get_irn_dbg_info(node);
807         ir_node  *block     = be_transform_node(get_nodes_block(node));
808         ir_node  *new_left  = be_transform_node(left);
809         ir_node  *new_right = be_transform_node(right);
810         ir_node  *res;
811
812         if(mode_is_signed(mode)) {
813                 res = new_rd_mips_div(dbgi, irg, block, new_left, new_right);
814         } else {
815                 res = new_rd_mips_divu(dbgi, irg, block, new_left, new_right);
816         }
817
818         set_irn_pinned(res, get_irn_pinned(node));
819
820         return res;
821 }
822
823 static ir_node *gen_DivMod(ir_node *node)
824 {
825         return create_div(node, get_DivMod_left(node), get_DivMod_right(node),
826                           get_DivMod_resmode(node));
827 }
828
829 static ir_node *gen_Div(ir_node *node)
830 {
831         return create_div(node, get_Div_left(node), get_Div_right(node),
832                           get_Div_resmode(node));
833 }
834
835 static ir_node *gen_Mod(ir_node *node)
836 {
837         return create_div(node, get_Mod_left(node), get_Mod_right(node),
838                           get_Mod_resmode(node));
839 }
840
841 #if 0
842 static ir_node *gen_node_for_Mul(mips_transform_env_t *env) {
843         ir_node *node = env->irn;
844         ir_node *mul;
845         ir_node *mflo;
846         ir_node *op1, *op2;
847         ir_mode *mode = get_irn_mode(node);
848
849         op1 = get_Mul_left(node);
850         op2 = get_Mul_right(node);
851
852         assert(get_mode_size_bits(env->mode) == 32);
853         assert(get_mode_size_bits(get_irn_mode(op1)) == get_mode_size_bits(env->mode));
854         assert(get_mode_size_bits(get_irn_mode(op2)) == get_mode_size_bits(env->mode));
855
856         if(mode_is_signed(mode)) {
857                 mul = new_rd_mips_mult(env->dbg, env->irg, env->block, get_Mul_left(node), get_Mul_right(node));
858         } else {
859                 mul = new_rd_mips_multu(env->dbg, env->irg, env->block, get_Mul_left(node), get_Mul_right(node));
860         }
861         mflo = new_rd_mips_mflo(env->dbg, env->irg, env->block, mul);
862
863         return mflo;
864 }
865
866 static
867 ir_node *gen_node_for_IJmp(mips_transform_env_t *env) {
868         ir_graph *irg    = env->irg;
869         ir_node  *node   = env->irn;
870         dbg_info *dbg    = get_irn_dbg_info(node);
871         ir_node  *block  = get_nodes_block(node);
872         ir_node  *target = get_IJmp_target(node);
873
874         return new_rd_mips_jr(dbg, irg, block, target);
875 }
876
877 static
878 ir_node *gen_node_for_Rot(mips_transform_env_t *env) {
879         ir_node *node = env->irn;
880         ir_node *subu, *srlv, *sllv, *or;
881
882         subu = new_rd_mips_subuzero(env->dbg, env->irg, env->block, get_Rot_right(node));
883         srlv = new_rd_mips_srlv(env->dbg, env->irg, env->block, get_Rot_left(node), subu);
884         sllv = new_rd_mips_sllv(env->dbg, env->irg, env->block, get_Rot_left(node), get_Rot_right(node));
885         or = new_rd_mips_or(env->dbg, env->irg, env->block, sllv, srlv);
886
887         return or;
888 }
889 #endif
890
891 static ir_node *gen_Unknown(ir_node *node)
892 {
893         (void) node;
894         assert(mode_needs_gp_reg(get_irn_mode(node)));
895         return mips_create_zero();
896 }
897
898 #if 0
899 /*
900  * lower a copyB into standard Firm assembler :-)
901  */
902 ir_node *gen_code_for_CopyB(ir_node *block, ir_node *node) {
903         ir_node *cnt, *sub;
904         ir_node *dst = get_CopyB_dst(node);
905         ir_node *src = get_CopyB_src(node);
906         ir_type *type = get_CopyB_type(node);
907         ir_node *mem = get_CopyB_mem(node);
908         ir_node *mm[4];
909         ir_node *result = NULL;
910         int size = get_type_size_bytes(type);
911         dbg_info *dbg = get_irn_dbg_info(node);
912         ir_graph *irg = get_irn_irg(block);
913         mips_attr_t *attr;
914         int i, n;
915
916         if (size > 16) {
917                 ir_node     *phi, *projT, *projF, *cmp, *proj, *cond, *jmp, *in[2];
918                 ir_node     *new_bl, *src_phi, *dst_phi, *mem_phi, *add;
919                 ir_mode     *p_mode = get_irn_mode(src);
920                 ir_node     *ld[4];
921
922                 /* build the control loop */
923                 in[0] = in[1] = new_r_Unknown(irg, mode_X);
924
925                 new_bl = new_r_Block(irg, 2, in);
926
927                 in[0] = cnt = new_Const_long(mode_Is, (size >> 4));
928         in[1] = new_r_Unknown(irg, mode_Is);
929                 phi   = new_r_Phi(irg, new_bl, 2, in, mode_Is);
930
931                 sub = new_rd_Sub(dbg, irg, new_bl, phi, new_Const_long(mode_Is, -1), mode_Is);
932                 set_Phi_pred(phi, 1, sub);
933
934                 cmp = new_rd_Cmp(dbg, irg, new_bl, sub, new_Const_long(mode_Is, 0));
935                 proj = new_r_Proj(irg, new_bl, cmp, mode_b, pn_Cmp_Lg);
936                 cond = new_rd_Cond(dbg, irg, new_bl, proj);
937
938                 projT = new_r_Proj(irg, new_bl, cond, mode_X, pn_Cond_true);
939                 projF = new_r_Proj(irg, new_bl, cond, mode_X, pn_Cond_false);
940
941                 jmp = get_Block_cfgpred(block, 0);
942                 set_Block_cfgpred(block, 0, projF);
943
944                 set_Block_cfgpred(new_bl, 0, jmp);
945                 set_Block_cfgpred(new_bl, 1, projT);
946
947                 size &= 0xF;
948
949                 /* build the copy */
950                 in[0]   = src;
951         in[1]   = new_r_Unknown(irg, p_mode);
952                 src_phi = new_r_Phi(irg, new_bl, 2, in, p_mode);
953
954                 in[0]   = dst;
955                 dst_phi = new_r_Phi(irg, new_bl, 2, in, p_mode);
956
957                 add = new_rd_Add(dbg, irg, new_bl, src_phi, new_Const_long(mode_Is, 16), p_mode);
958                 set_Phi_pred(src_phi, 1, add);
959                 add = new_rd_Add(dbg, irg, new_bl, dst_phi, new_Const_long(mode_Is, 16), p_mode);
960                 set_Phi_pred(dst_phi, 1, add);
961
962                 in[0]   = mem;
963         in[1]   = new_r_Unknown(irg, mode_M);
964                 mem_phi = new_r_Phi(irg, new_bl, 2, in, mode_M);
965
966                 src = src_phi;
967                 dst = dst_phi;
968
969                 /* create 4 parallel loads */
970                 for (i = 0; i < 4; ++i) {
971                         ir_node *load;
972
973                         load = new_rd_mips_load_r(dbg, irg, new_bl, mem_phi, src, mode_T);
974                         attr = get_mips_attr(load);
975                         attr->modes.load_store_mode = mode_Iu;
976                         attr->tv = new_tarval_from_long(i * 4, mode_Iu);
977
978                         ld[i] = new_rd_Proj(dbg, irg, new_bl, load, mode_Iu, pn_Load_res);
979                 }
980
981                 /* create 4 parallel stores */
982                 for (i = 0; i < 4; ++i) {
983                         ir_node *store;
984
985                         store = new_rd_mips_store_r(dbg, irg, new_bl, mem_phi, dst, ld[i], mode_T);
986                         attr = get_mips_attr(store);
987                         attr->modes.load_store_mode = mode_Iu;
988                         attr->tv = new_tarval_from_long(i * 4, mode_Iu);
989
990                         mm[i] = new_rd_Proj(dbg, irg, new_bl, store, mode_M, pn_Store_M);
991                 }
992                 mem = new_r_Sync(irg, new_bl, 4, mm);
993                 result = mem;
994                 set_Phi_pred(mem_phi, 1, mem);
995         }
996
997         // output store/loads manually
998         n = 0;
999         for(i = size; i > 0; ) {
1000                 ir_mode *mode;
1001                 ir_node *load, *store, *projv;
1002                 int offset = size - i;
1003                 if(i >= 4) {
1004                         mode = mode_Iu;
1005                         i -= 4;
1006                 } else if(i >= 2) {
1007                         mode = mode_Hu;
1008                         i -= 2;
1009                 } else {
1010                         mode = mode_Bu;
1011                         i -= 1;
1012                 }
1013
1014                 load = new_rd_mips_load_r(dbg, irg, block, mem, src, mode_T);
1015                 attr = get_mips_attr(load);
1016                 attr->modes.load_store_mode = mode;
1017                 attr->tv = new_tarval_from_long(offset, mode_Iu);
1018
1019                 projv = new_rd_Proj(dbg, irg, block, load, mode, pn_Load_res);
1020
1021                 store = new_rd_mips_store_r(dbg, irg, block, mem, dst, projv, mode_T);
1022                 attr = get_mips_attr(store);
1023                 attr->modes.load_store_mode = mode;
1024                 attr->tv = new_tarval_from_long(offset, mode_Iu);
1025
1026                 mm[n] = new_rd_Proj(dbg, irg, block, store, mode_M, pn_Store_M);
1027                 n++;
1028         }
1029
1030         if(n > 0) {
1031                 result = new_r_Sync(irg, block, n, mm);
1032         } else if(n == 1) {
1033                 result = mm[0];
1034         }
1035
1036         return result;
1037 }
1038
1039 static void mips_fix_CopyB_Proj(mips_transform_env_t* env) {
1040         ir_node *node = env->irn;
1041         long n = get_Proj_proj(node);
1042
1043         if(n == pn_CopyB_M_except) {
1044                 assert(0);
1045         } else if(n == pn_CopyB_M_regular) {
1046                 set_Proj_proj(node, pn_Store_M);
1047         } else if(n == pn_CopyB_M_except) {
1048                 set_Proj_proj(node, pn_Store_X_except);
1049         }
1050 }
1051 #endif
1052
1053 static void mips_transform_Spill(mips_transform_env_t* env) {
1054         ir_node   *node = env->irn;
1055         ir_node   *sched_point = NULL;
1056         ir_node   *store;
1057         ir_node   *nomem = new_rd_NoMem(env->irg);
1058         ir_node   *ptr   = get_irn_n(node, 0);
1059         ir_node   *val   = get_irn_n(node, 1);
1060         ir_entity *ent   = be_get_frame_entity(node);
1061
1062         if(sched_is_scheduled(node)) {
1063                 sched_point = sched_prev(node);
1064         }
1065
1066         store = new_rd_mips_sw(env->dbg, env->irg, env->block, ptr, val, nomem,
1067                                ent, 0);
1068
1069         if (sched_point) {
1070                 sched_add_after(sched_point, store);
1071                 sched_remove(node);
1072         }
1073
1074         exchange(node, store);
1075 }
1076
1077 static void mips_transform_Reload(mips_transform_env_t* env) {
1078         ir_node   *node = env->irn;
1079         ir_node   *sched_point = NULL;
1080         ir_node   *load, *proj;
1081         ir_node   *ptr   = get_irn_n(node, 0);
1082         ir_node   *mem   = get_irn_n(node, 1);
1083         ir_entity *ent   = be_get_frame_entity(node);
1084         const arch_register_t* reg;
1085
1086         if(sched_is_scheduled(node)) {
1087                 sched_point = sched_prev(node);
1088         }
1089
1090         load = new_rd_mips_lw(env->dbg, env->irg, env->block, ptr, mem, ent, 0);
1091
1092         proj = new_rd_Proj(env->dbg, env->irg, env->block, load, mode_Iu, pn_mips_lw_res);
1093
1094         if (sched_point) {
1095                 sched_add_after(sched_point, load);
1096
1097                 sched_remove(node);
1098         }
1099
1100         /* copy the register from the old node to the new Load */
1101         reg = arch_get_irn_register(env->cg->arch_env, node);
1102         arch_set_irn_register(env->cg->arch_env, proj, reg);
1103
1104         exchange(node, proj);
1105 }
1106
1107 #if 0
1108 static ir_node *gen_node_for_StackParam(mips_transform_env_t *env)
1109 {
1110         ir_node *node = env->irn;
1111         ir_node *sp = get_irn_n(node, 0);
1112         ir_node *load;
1113         ir_node *nomem = new_rd_NoMem(env->irg);
1114         ir_node *proj;
1115         mips_attr_t *attr;
1116
1117         load = new_rd_mips_load_r(env->dbg, env->irg, env->block, nomem, sp, mode_T);
1118         attr = get_mips_attr(load);
1119         attr->stack_entity = be_get_frame_entity(node);
1120         attr->modes.load_store_mode = env->mode;
1121
1122         proj = new_rd_Proj(env->dbg, env->irg, env->block, load, env->mode, pn_Load_res);
1123
1124         return proj;
1125 }
1126 #endif
1127
1128 #if 0
1129 static ir_node *gen_AddSP(ir_node *node)
1130 {
1131         ir_node *node = env->irn;
1132         ir_node *op1, *op2;
1133         ir_node *add;
1134         const arch_register_t *reg;
1135
1136         op1 = get_irn_n(node, 0);
1137         op2 = get_irn_n(node, 1);
1138
1139         add = new_rd_mips_addu(env->dbg, env->irg, env->block, op1, op2);
1140
1141         /* copy the register requirements from the old node to the new node */
1142         reg = arch_get_irn_register(env->cg->arch_env, node);
1143         arch_set_irn_register(env->cg->arch_env, add, reg);
1144
1145         return add;
1146 }
1147 #endif
1148
1149 /*********************************************************
1150  *                  _             _      _
1151  *                 (_)           | |    (_)
1152  *  _ __ ___   __ _ _ _ __     __| |_ __ ___   _____ _ __
1153  * | '_ ` _ \ / _` | | '_ \   / _` | '__| \ \ / / _ \ '__|
1154  * | | | | | | (_| | | | | | | (_| | |  | |\ V /  __/ |
1155  * |_| |_| |_|\__,_|_|_| |_|  \__,_|_|  |_| \_/ \___|_|
1156  *
1157  *********************************************************/
1158
1159 static ir_node *gen_Bad(ir_node *node)
1160 {
1161         panic("Unexpected node %+F found in mips transform phase.\n", node);
1162         return NULL;
1163 }
1164
1165 static void register_transformers(void)
1166 {
1167         clear_irp_opcodes_generic_func();
1168
1169         op_Add->ops.generic      = (op_func) gen_Add;
1170         op_Sub->ops.generic      = (op_func) gen_Sub;
1171         op_And->ops.generic      = (op_func) gen_And;
1172         op_Or->ops.generic       = (op_func) gen_Or;
1173         op_Eor->ops.generic      = (op_func) gen_Eor;
1174         op_Shl->ops.generic      = (op_func) gen_Shl;
1175         op_Shr->ops.generic      = (op_func) gen_Shr;
1176         op_Shrs->ops.generic     = (op_func) gen_Shrs;
1177         op_Not->ops.generic      = (op_func) gen_Not;
1178         op_Minus->ops.generic    = (op_func) gen_Minus;
1179         op_Div->ops.generic      = (op_func) gen_Div;
1180         op_Mod->ops.generic      = (op_func) gen_Mod;
1181         op_DivMod->ops.generic   = (op_func) gen_DivMod;
1182         op_Abs->ops.generic      = (op_func) gen_Abs;
1183         op_Load->ops.generic     = (op_func) gen_Load;
1184         op_Store->ops.generic    = (op_func) gen_Store;
1185         op_Cond->ops.generic     = (op_func) gen_Cond;
1186         op_Conv->ops.generic     = (op_func) gen_Conv;
1187         op_Const->ops.generic    = (op_func) gen_Const;
1188         op_SymConst->ops.generic = (op_func) gen_SymConst;
1189         op_Unknown->ops.generic  = (op_func) gen_Unknown;
1190         op_Proj->ops.generic     = (op_func) gen_Proj;
1191         op_Phi->ops.generic      = (op_func) gen_Phi;
1192
1193         op_Raise->ops.generic     = (op_func) gen_Bad;
1194         op_Sel->ops.generic       = (op_func) gen_Bad;
1195         op_InstOf->ops.generic    = (op_func) gen_Bad;
1196         op_Cast->ops.generic      = (op_func) gen_Bad;
1197         op_Free->ops.generic      = (op_func) gen_Bad;
1198         op_Tuple->ops.generic     = (op_func) gen_Bad;
1199         op_Id->ops.generic        = (op_func) gen_Bad;
1200         op_Confirm->ops.generic   = (op_func) gen_Bad;
1201         op_Filter->ops.generic    = (op_func) gen_Bad;
1202         op_CallBegin->ops.generic = (op_func) gen_Bad;
1203         op_EndReg->ops.generic    = (op_func) gen_Bad;
1204         op_EndExcept->ops.generic = (op_func) gen_Bad;
1205 }
1206
1207 #if 0
1208 /**
1209  * Transforms the given firm node (and maybe some other related nodes)
1210  * into one or more assembler nodes.
1211  *
1212  * @param node    the firm node
1213  * @param env     the debug module
1214  */
1215 void mips_transform_node(ir_node *node, void *env) {
1216         mips_code_gen_t *cgenv = (mips_code_gen_t *)env;
1217         ir_opcode code         = get_irn_opcode(node);
1218         ir_node *asm_node      = node;
1219         mips_transform_env_t tenv;
1220
1221         if (is_Block(node))
1222                 return;
1223
1224         tenv.block    = get_nodes_block(node);
1225         tenv.dbg      = get_irn_dbg_info(node);
1226         tenv.irg      = current_ir_graph;
1227         tenv.irn      = node;
1228         tenv.mode     = get_irn_mode(node);
1229         tenv.cg           = cgenv;
1230
1231 #define UNOP(firm_opcode, mips_nodetype)        case iro_##firm_opcode: asm_node = mips_gen_##mips_nodetype(&tenv, get_##firm_opcode##_op(node)); break
1232 #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
1233 #define IGN(a)         case iro_##a: break
1234 #define BAD(a)         case iro_##a: goto bad
1235
1236         switch (code) {
1237                 BINOP(Add, addu);
1238                 BINOP(Sub, sub);
1239                 BINOP(And, and);
1240                 BINOP(Or, or);
1241                 BINOP(Eor, xor);
1242                 UNOP(Not, not);
1243                 BINOP(Shl, sl);
1244                 BINOP(Shr, sr);
1245                 BINOP(Shrs, sra);
1246
1247         case iro_Abs:
1248                 asm_node = gen_node_for_Abs(&tenv);
1249                 break;
1250
1251         case iro_Rot:
1252                 asm_node = gen_node_for_Rot(&tenv);
1253                 break;
1254
1255         case iro_Div:
1256                 asm_node = gen_node_for_Div(&tenv);
1257                 break;
1258
1259         case iro_Mod:
1260                 asm_node = gen_node_for_Mod(&tenv);
1261                 break;
1262
1263         case iro_Load:
1264                 asm_node = gen_node_for_Load(&tenv);
1265                 break;
1266
1267         case iro_Store:
1268                 asm_node = gen_node_for_Store(&tenv);
1269                 break;
1270
1271         case iro_Proj:
1272                 asm_node = gen_node_for_Proj(&tenv);
1273                 break;
1274
1275         case iro_Conv:
1276                 asm_node = gen_node_for_Conv(&tenv);
1277                 break;
1278
1279         case iro_DivMod:
1280                 asm_node = gen_node_for_DivMod(&tenv);
1281                 break;
1282
1283         case iro_Mul:
1284                 asm_node = gen_node_for_Mul(&tenv);
1285                 break;
1286
1287         case iro_Jmp:
1288                 asm_node = gen_node_for_Jmp(&tenv);
1289                 break;
1290
1291         case iro_IJmp:
1292                 asm_node = gen_node_for_IJmp(&tenv);
1293                 break;
1294
1295         case iro_Unknown:
1296                 asm_node = gen_node_for_Unknown(&tenv);
1297                 break;
1298
1299         case iro_Cond:
1300                 asm_node = gen_node_for_Cond(&tenv);
1301                 break;
1302
1303         case iro_Phi:
1304                 asm_node = gen_node_for_Phi(&tenv);
1305                 break;
1306
1307                 /* TODO: implement these nodes */
1308                 BAD(Mux);
1309
1310                 /* You probably don't need to handle the following nodes */
1311
1312                 // call is handled in the emit phase
1313                 IGN(Call);
1314                 // Cmp is handled together with Cond
1315                 IGN(Cmp);
1316                 IGN(Alloc);
1317
1318                 IGN(Block);
1319                 IGN(Start);
1320                 IGN(End);
1321                 IGN(NoMem);
1322                 IGN(Break);
1323                 IGN(Sync);
1324
1325                 IGN(Const);
1326                 IGN(SymConst);
1327
1328                 BAD(Raise);
1329                 BAD(Sel);
1330                 BAD(InstOf);
1331                 BAD(Cast);
1332                 BAD(Free);
1333                 BAD(Tuple);
1334                 BAD(Id);
1335                 BAD(Bad);
1336                 BAD(Confirm);
1337                 BAD(Filter);
1338                 BAD(CallBegin);
1339                 BAD(EndReg);
1340                 BAD(EndExcept);
1341
1342                 default:
1343                         if(be_is_StackParam(node)) {
1344                                 //asm_node = gen_node_for_StackParam(&tenv);
1345                         } else if(be_is_AddSP(node)) {
1346                                 asm_node = gen_node_for_AddSP(&tenv);
1347                         }
1348                         break;
1349
1350 bad:
1351                 fprintf(stderr, "Not implemented: %s\n", get_irn_opname(node));
1352                 assert(0);
1353         }
1354
1355         if (asm_node != node) {
1356                 exchange(node, asm_node);
1357         }
1358 }
1359 #endif
1360
1361 void mips_transform_graph(mips_code_gen_t *cg)
1362 {
1363         env_cg = cg;
1364         register_transformers();
1365         be_transform_graph(cg->birg, NULL, cg);
1366 }
1367
1368 /**
1369  * Calls the transform functions for Spill and Reload.
1370  */
1371 void mips_after_ra_walker(ir_node *node, void *env) {
1372         mips_code_gen_t *cg = env;
1373         mips_transform_env_t tenv;
1374
1375         if (is_Block(node))
1376                 return;
1377
1378         tenv.block = get_nodes_block(node);
1379         tenv.dbg   = get_irn_dbg_info(node);
1380         tenv.irg   = current_ir_graph;
1381         tenv.irn   = node;
1382         tenv.mode  = get_irn_mode(node);
1383         tenv.cg    = cg;
1384
1385         if (be_is_Reload(node)) {
1386                 mips_transform_Reload(&tenv);
1387         } else if (be_is_Spill(node)) {
1388                 mips_transform_Spill(&tenv);
1389         }
1390 }