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