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