backends can specify costs for spill and reload
[libfirm] / ir / be / ppc32 / ppc32_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 codegenerator (transform FIRM into ppc FIRM)
23  * @author  Moritz Kroll, Jens Mueller
24  * @version $Id$
25  */
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include "irnode_t.h"
31 #include "irgraph_t.h"
32 #include "irmode_t.h"
33 #include "irgmod.h"
34 #include "iredges.h"
35 #include "iredges_t.h"
36 #include "irvrfy.h"
37 #include "ircons.h"
38 #include "dbginfo.h"
39 #include "iropt_t.h"
40 #include "irprintf.h"
41 #include "debug.h"
42
43 #include "../benode_t.h"
44 #include "bearch_ppc32_t.h"
45
46 #include "ppc32_nodes_attr.h"
47 #include "../arch/archop.h"     /* we need this for Min and Max nodes */
48 #include "ppc32_transform.h"
49 #include "ppc32_new_nodes.h"
50 #include "ppc32_map_regs.h"
51
52 #include "gen_ppc32_regalloc_if.h"
53
54 extern ir_op *get_op_Mulh(void);
55
56 int is_direct_entity(ir_entity *ent);
57
58 ir_mode* ppc32_mode_Cond = NULL;
59
60 /**
61  * Returns the proj of a given node with the given proj number
62  */
63 static INLINE ir_node *get_succ_Proj(ir_node *node, long proj)
64 {
65         const ir_edge_t *edge;
66         foreach_out_edge(node, edge)
67         {
68                 if (is_Proj(edge->src) && get_Proj_proj(edge->src) == proj)
69                         return edge->src;
70         }
71         return NULL;
72 }
73
74 /**
75  * Returns a singleton condition mode
76  */
77 ir_mode *get_ppc32_mode_Cond(void) {
78         if (ppc32_mode_Cond)
79                 return ppc32_mode_Cond;
80         else {
81                 ppc32_mode_Cond = new_ir_mode("mode_Cond", irms_character, 4, 0, irma_none, 0);
82                 return ppc32_mode_Cond;
83         }
84 }
85
86 /**
87  * Calculates the modecode with size, sort and signed attributes
88  */
89 modecode get_nice_modecode(ir_mode *irmode)
90 {
91         modecode mode = irm_max;
92         int sign = mode_is_signed(irmode);
93         int bits = get_mode_size_bits(irmode);
94         if(mode_is_int(irmode))
95         {
96                 switch(bits)
97                 {
98                         case 8:
99                                 mode = sign ? irm_Bs : irm_Bu;
100                                 break;
101                         case 16:
102                                 mode = sign ? irm_Hs : irm_Hu;
103                                 break;
104                         case 32:
105                                 mode = sign ? irm_Is : irm_Iu;
106                                 break;
107                 }
108         }
109         else if(mode_is_float(irmode))
110         {
111                 switch(bits)
112                 {
113                         case 32:
114                                 mode = irm_F;
115                                 break;
116                         case 64:
117                                 mode = irm_D;
118                                 break;
119                 }
120         }
121         else if(mode_is_reference(irmode))
122         {
123                 switch(bits)
124                 {
125                         case 32:
126                                 mode = irm_P;
127                                 break;
128                 }
129         }
130         return mode;
131 }
132
133 /**
134  * Returns true, if the given node is a Const node and it's value fits into
135  * a signed 16-bit variable
136  */
137 int is_16bit_signed_const(ir_node *node)
138 {
139         tarval *tv_const;
140
141         if(!is_ppc32_Const(node)) return 0;
142
143         tv_const = get_ppc32_constant_tarval(node);
144
145         switch(get_nice_modecode(get_irn_mode(node)))
146         {
147                 case irm_Bu:
148                 case irm_Bs:
149                 case irm_Hs:
150                         return 1;
151                 case irm_Iu:
152                 case irm_P:
153                 {
154                         unsigned char val2 = get_tarval_sub_bits(tv_const, 2);
155                         unsigned char val3 = get_tarval_sub_bits(tv_const, 3);
156                         if(val2 || val3)
157                                 return 0;
158
159                         // fall through
160                 }
161                 case irm_Hu:
162                 {
163                         unsigned char val1 = get_tarval_sub_bits(tv_const, 1);
164                         if(val1&0x80)
165                                 return 0;
166                         return 1;
167                 }
168
169                 case irm_Is:
170                 {
171                         unsigned char val2 = get_tarval_sub_bits(tv_const, 2);
172                         unsigned char val3 = get_tarval_sub_bits(tv_const, 3);
173                         if(val2==0 && val3==0)
174                         {
175                                 unsigned char val1 = get_tarval_sub_bits(tv_const, 1);
176                                 if(val1&0x80)
177                                         return 0;
178                                 return 1;
179                         }
180                         if(!(val2==0xff && val3==0xff))
181                         {
182                                 unsigned char val1 = get_tarval_sub_bits(tv_const, 1);
183                                 if(!(val1&0x80))
184                                         return 0;
185                                 return 1;
186                         }
187                         return 0;
188                 }
189                 default:
190                         fprintf(stderr, "is_16bit_signed_const(): Mode not supported: %s\n", get_mode_name(get_irn_mode(node)));
191                         assert(0);
192                         return 0;
193         }
194 }
195
196 /**
197  * Returns true, if the given node is a Const node and it's value fits into
198  * a unsigned 16-bit variable
199  */
200 int is_16bit_unsigned_const(ir_node *node)
201 {
202         tarval *tv_const;
203
204         if(!is_ppc32_Const(node)) return 0;
205
206         tv_const = get_ppc32_constant_tarval(node);
207         switch(get_nice_modecode(get_irn_mode(node)))
208         {
209                 case irm_Bu:
210                 case irm_Bs:
211                 case irm_Hs:
212                 case irm_Hu:
213                         return 1;
214                 case irm_Iu:
215                 case irm_P:
216                 case irm_Is:
217                 {
218                         unsigned char val2 = get_tarval_sub_bits(tv_const, 2);
219                         unsigned char val3 = get_tarval_sub_bits(tv_const, 3);
220                         if(val2 || val3)
221                                 return 0;
222                         return 1;
223                 }
224                 default:
225                         fprintf(stderr, "is_16bit_unsigned_const(): Mode not supported: %s\n", get_mode_name(get_irn_mode(node)));
226                         assert(0);
227                         return 0;
228         }
229 }
230
231
232 /****************************************************************************************************
233  *                  _        _                        __                           _   _
234  *                 | |      | |                      / _|                         | | (_)
235  *  _ __   ___   __| | ___  | |_ _ __ __ _ _ __  ___| |_ ___  _ __ _ __ ___   __ _| |_ _  ___  _ __
236  * | '_ \ / _ \ / _` |/ _ \ | __| '__/ _` | '_ \/ __|  _/ _ \| '__| '_ ` _ \ / _` | __| |/ _ \| '_ \
237  * | | | | (_) | (_| |  __/ | |_| | | (_| | | | \__ \ || (_) | |  | | | | | | (_| | |_| | (_) | | | |
238  * |_| |_|\___/ \__,_|\___|  \__|_|  \__,_|_| |_|___/_| \___/|_|  |_| |_| |_|\__,_|\__|_|\___/|_| |_|
239  *
240  ****************************************************************************************************/
241
242 /**
243  * Creates an ppc Add.
244  *
245  * @param env   The transformation environment
246  * @return the created ppc Add node
247  */
248 static ir_node *gen_Add(ppc32_transform_env_t *env) {
249         ir_node *op1 = get_Add_left(env->irn);
250         ir_node *op2 = get_Add_right(env->irn);
251
252         switch(get_nice_modecode(env->mode)){
253                 case irm_D:
254                         return new_rd_ppc32_fAdd(env->dbg, env->irg, env->block, op1, op2, env->mode);
255                 case irm_F:
256                         return new_rd_ppc32_fAdds(env->dbg, env->irg, env->block, op1, op2, env->mode);
257                 case irm_Is:
258                 case irm_Iu:
259                 case irm_Hs:
260                 case irm_Hu:
261                 case irm_Bs:
262                 case irm_Bu:
263                 case irm_P:
264                         if(is_16bit_signed_const(op1))
265                         {
266                                 ir_node *addnode = new_rd_ppc32_Addi(env->dbg, env->irg, env->block, op2, env->mode);
267                                 set_ppc32_constant_tarval(addnode, get_ppc32_constant_tarval(op1));
268                                 set_ppc32_offset_mode(addnode, ppc32_ao_None);
269                                 return addnode;
270                         }
271                         if(is_16bit_signed_const(op2))
272                         {
273                                 ir_node *addnode = new_rd_ppc32_Addi(env->dbg, env->irg, env->block, op1, env->mode);
274                                 set_ppc32_constant_tarval(addnode, get_ppc32_constant_tarval(op2));
275                                 set_ppc32_offset_mode(addnode, ppc32_ao_None);
276                                 return addnode;
277                         }
278
279                         return new_rd_ppc32_Add(env->dbg, env->irg, env->block, op1, op2, env->mode);
280
281                 default:
282                         fprintf(stderr, "Mode for Add not supported: %s\n", get_mode_name(env->mode));
283                         assert(0);
284                         return NULL;
285         }
286 }
287
288 /**
289  * Creates an ppc Mul.
290  *
291  * @param env   The transformation environment
292  * @return the created ppc Mul node
293  */
294 static ir_node *gen_Mul(ppc32_transform_env_t *env) {
295         ir_node *op1 = get_Mul_left(env->irn);
296         ir_node *op2 = get_Mul_right(env->irn);
297
298         switch(get_nice_modecode(env->mode)){
299                 case irm_D:
300                         return new_rd_ppc32_fMul(env->dbg, env->irg, env->block, op1, op2, env->mode);
301                 case irm_F:
302                         return new_rd_ppc32_fMuls(env->dbg, env->irg, env->block, op1, op2, env->mode);
303                 case irm_Is:
304                 case irm_Iu:
305                 case irm_Hs:
306                 case irm_Hu:
307                 case irm_Bs:
308                 case irm_Bu:
309                         return new_rd_ppc32_Mullw(env->dbg, env->irg, env->block, op1, op2, env->mode);
310
311                 case irm_P:
312                 default:
313                         fprintf(stderr, "Mode for Mul not supported: %s\n", get_mode_name(env->mode));
314                         assert(0);
315                         return NULL;
316         }
317 }
318
319 /**
320  * Creates an ppc Mulh.
321  *
322  * @param env   The transformation environment
323  * @return the created ppc Mulh node
324  */
325 static ir_node *gen_Mulh(ppc32_transform_env_t *env) {
326         ir_node *op1 = get_irn_n(env->irn, 0);
327         ir_node *op2 = get_irn_n(env->irn, 1);
328
329         switch(get_nice_modecode(env->mode)){
330                 case irm_Is:
331                 case irm_Hs:
332                 case irm_Bs:
333                         return new_rd_ppc32_Mulhw(env->dbg, env->irg, env->block, op1, op2, env->mode);
334
335                 case irm_Iu:
336                 case irm_Hu:
337                 case irm_Bu:
338                         return new_rd_ppc32_Mulhwu(env->dbg, env->irg, env->block, op1, op2, env->mode);
339
340                 case irm_D:
341                 case irm_F:
342                 case irm_P:
343                 default:
344                         fprintf(stderr, "Mode for Mulh not supported: %s\n", get_mode_name(env->mode));
345                         assert(0);
346                         return NULL;
347         }
348 }
349
350 /**
351  * Creates an ppc And.
352  *
353  * @param env   The transformation environment
354  * @return the created ppc And node
355  */
356 static ir_node *gen_And(ppc32_transform_env_t *env) {
357         ir_node *op1 = get_And_left(env->irn);
358         ir_node *op2 = get_And_right(env->irn);
359
360         return new_rd_ppc32_And(env->dbg, env->irg, env->block, op1, op2, env->mode);
361 }
362
363 /**
364  * Creates an ppc Or.
365  *
366  * @param env   The transformation environment
367  * @return the created ppc Or node
368  */
369 static ir_node *gen_Or(ppc32_transform_env_t *env) {
370         ir_node *op1 = get_Or_left(env->irn);
371         ir_node *op2 = get_Or_right(env->irn);
372
373         return new_rd_ppc32_Or(env->dbg, env->irg, env->block, op1, op2, env->mode);
374 }
375
376 /**
377  * Creates an ppc Xor.
378  *
379  * @param env   The transformation environment
380  * @return the created ppc Xor node
381  */
382 static ir_node *gen_Eor(ppc32_transform_env_t *env) {
383         ir_node *op1 = get_Eor_left(env->irn);
384         ir_node *op2 = get_Eor_right(env->irn);
385
386         return new_rd_ppc32_Xor(env->dbg, env->irg, env->block, op1, op2, env->mode);
387 }
388
389 /**
390  * Creates an ppc Sub.
391  *
392  * @param env   The transformation environment
393  * @return the created ppc Sub node
394  */
395 static ir_node *gen_Sub(ppc32_transform_env_t *env) {
396         ir_node *op1 = get_Sub_left(env->irn);
397         ir_node *op2 = get_Sub_right(env->irn);
398
399         switch(get_nice_modecode(env->mode)){
400                 case irm_D:
401                         return new_rd_ppc32_fSub(env->dbg, env->irg, env->block, op1, op2, env->mode);
402                 case irm_F:
403                         return new_rd_ppc32_fSubs(env->dbg, env->irg, env->block, op1, op2, env->mode);
404                 case irm_Is:
405                 case irm_Iu:
406                 case irm_Hs:
407                 case irm_Hu:
408                 case irm_Bs:
409                 case irm_Bu:
410                 case irm_P:
411                         return new_rd_ppc32_Sub(env->dbg, env->irg, env->block, op1, op2, env->mode);
412
413                 default:
414                         fprintf(stderr, "Mode for Sub not supported: %s\n", get_mode_name(env->mode));
415                         assert(0);
416                         return NULL;
417         }
418 }
419
420 /**
421  * Creates an ppc floating Div.
422  *
423  * @param env   The transformation environment
424  * @return the created ppc fDiv node
425  */
426 static ir_node *gen_Quot(ppc32_transform_env_t *env) {
427         ir_node *op1 = get_Quot_left(env->irn);
428         ir_node *op2 = get_Quot_right(env->irn);
429
430         switch(get_nice_modecode(env->mode)){
431                 case irm_D:
432                         return new_rd_ppc32_fDiv(env->dbg, env->irg, env->block, op1, op2, env->mode);
433                 case irm_F:
434                         return new_rd_ppc32_fDivs(env->dbg, env->irg, env->block, op1, op2, env->mode);
435
436                 default:
437                         fprintf(stderr, "Mode for Quot not supported: %s\n", get_mode_name(env->mode));
438                         assert(0);
439                         return NULL;
440         }
441 }
442
443 /**
444  * Creates an ppc integer Div.
445  *
446  * @param env   The transformation environment
447  * @return the created ppc Div node
448  */
449 static ir_node *gen_Div(ppc32_transform_env_t *env) {
450         ir_node *op1 = get_Div_left(env->irn);
451         ir_node *op2 = get_Div_right(env->irn);
452
453         switch(get_nice_modecode(get_irn_mode(op1))){
454                 case irm_Is:
455                 case irm_Hs:
456                 case irm_Bs:
457                         return new_rd_ppc32_Divw(env->dbg, env->irg, env->block, op1, op2, mode_T);
458
459                 case irm_Iu:
460                 case irm_Hu:
461                 case irm_Bu:
462                         return new_rd_ppc32_Divwu(env->dbg, env->irg, env->block, op1, op2, mode_T);
463
464                 default:
465                         fprintf(stderr, "Mode for Div not supported: %s\n", get_mode_name(get_irn_mode(op1)));
466                         assert(0);
467                         return NULL;
468         }
469 }
470
471 /**
472  * Creates an ppc integer Div and Mod.
473  *
474  * @param env   The transformation environment
475  * @return the created ppc Div node
476  */
477 static ir_node *gen_DivMod(ppc32_transform_env_t *env) {
478         ir_node *op1 = get_DivMod_left(env->irn);
479         ir_node *op2 = get_DivMod_right(env->irn);
480         ir_node *proj_div = NULL, *proj_mod = NULL;
481         ir_node *div_result;
482         const ir_edge_t *edge;
483         ir_mode *res_mode;
484
485         foreach_out_edge(env->irn, edge)
486         {
487                 if (is_Proj(edge->src))
488                 {
489                         switch(get_Proj_proj(edge->src)){
490                                 case pn_DivMod_res_div:
491                                         proj_div = edge->src;
492                                         break;
493                                 case pn_DivMod_res_mod:
494                                         proj_mod = edge->src;
495                                         break;
496                                 default:
497                                         break;
498                         }
499                 }
500         }
501
502         assert(proj_div!=NULL || proj_mod!=NULL);
503
504         res_mode = get_irn_mode(proj_div);
505
506         switch(get_nice_modecode(res_mode))
507         {
508                 case irm_Is:
509                 case irm_Hs:
510                 case irm_Bs:
511                         div_result = new_rd_ppc32_Divw(env->dbg, env->irg, env->block, op1, op2, mode_T);
512                         break;
513
514                 case irm_Iu:
515                 case irm_Hu:
516                 case irm_Bu:
517                         div_result = new_rd_ppc32_Divwu(env->dbg, env->irg, env->block, op1, op2, mode_T);
518                         break;
519
520                 default:
521                         fprintf(stderr, "Mode for DivMod not supported: %s\n", get_mode_name(res_mode));
522                         assert(0);
523                         return 0;
524
525         }
526
527         if (proj_div == NULL)
528                 proj_div = new_rd_Proj(env->dbg, env->irg, env->block, div_result, get_irn_mode(proj_mod), pn_DivMod_res_div);
529
530         if (proj_mod!=NULL){
531                 ir_node *mul_result;
532                 ir_node *mod_result;
533
534                 mul_result = new_rd_ppc32_Mullw(env->dbg, env->irg, env->block, proj_div, op2, res_mode);
535                 mod_result = new_rd_ppc32_Sub(env->dbg, env->irg, env->block, op1, mul_result, res_mode);
536
537                 exchange(proj_mod, mod_result);
538         }
539
540         return div_result;
541 }
542
543 /**
544  * Creates an ppc integer Mod.
545  *
546  * @param env   The transformation environment
547  * @return the created ppc Mod result node
548  */
549 static ir_node *gen_Mod(ppc32_transform_env_t *env) {
550         ir_node *op1 = get_Mod_left(env->irn);
551         ir_node *op2 = get_Mod_right(env->irn);
552         ir_node *proj_div = NULL, *proj_mod = NULL;
553         ir_node *div_result;
554         ir_mode *res_mode;
555         ir_node *mul_result;
556         ir_node *mod_result;
557
558         proj_mod = get_succ_Proj(env->irn, pn_Mod_res);
559
560         assert(proj_mod != NULL);
561         res_mode = get_irn_mode(proj_mod);
562
563         switch(get_nice_modecode(res_mode))
564         {
565                 case irm_Is:
566                 case irm_Hs:
567                 case irm_Bs:
568                         div_result = new_rd_ppc32_Divw(env->dbg, env->irg, env->block, op1, op2, mode_T);
569                         break;
570
571                 case irm_Iu:
572                 case irm_Hu:
573                 case irm_Bu:
574                         div_result = new_rd_ppc32_Divwu(env->dbg, env->irg, env->block, op1, op2, mode_T);
575                         break;
576
577                 default:
578                         fprintf(stderr, "Mode for Mod not supported: %s\n", get_mode_name(res_mode));
579                         assert(0);
580                         return NULL;
581
582         }
583
584         proj_div = new_rd_Proj(env->dbg, env->irg, env->block, div_result, res_mode, pn_DivMod_res_div);
585
586         mul_result = new_rd_ppc32_Mullw(env->dbg, env->irg, env->block, proj_div, op2, res_mode);
587         mod_result = new_rd_ppc32_Sub(env->dbg, env->irg, env->block, op1, mul_result, res_mode);
588
589         exchange(proj_mod, mod_result);
590
591         return div_result;
592 }
593
594 /**
595  * Creates an ppc Shl.
596  *
597  * @param env   The transformation environment
598  * @return the created ppc Shl node
599  */
600 static ir_node *gen_Shl(ppc32_transform_env_t *env) {
601         ir_node *op1 = get_Shl_left(env->irn);
602         ir_node *op2 = get_Shl_right(env->irn);
603
604         if(is_ppc32_Const(op2))
605         {
606                 ir_node *shift = new_rd_ppc32_Rlwinm(env->dbg, env->irg, env->block, op1, env->mode);
607                 tarval *tv_const = get_ppc32_constant_tarval(op2);
608                 int sh = get_tarval_long(tv_const);
609                 assert(0<=sh && sh<=31);
610                 set_ppc32_rlwimi_const(shift, sh, 0, 31-sh);
611                 return shift;
612         }
613         return new_rd_ppc32_Slw(env->dbg, env->irg, env->block, op1, op2, env->mode);
614 }
615
616 /**
617  * Creates an ppc Srw.
618  *
619  * @param env   The transformation environment
620  * @return the created ppc Shr node
621  */
622 static ir_node *gen_Shr(ppc32_transform_env_t *env) {
623         ir_node *op1 = get_Shr_left(env->irn);
624         ir_node *op2 = get_Shr_right(env->irn);
625
626         if(is_ppc32_Const(op2))
627         {
628                 ir_node *shift = new_rd_ppc32_Rlwinm(env->dbg, env->irg, env->block, op1, env->mode);
629                 tarval *tv_const = get_ppc32_constant_tarval(op2);
630                 int sh = get_tarval_long(tv_const);
631                 assert(0<=sh && sh<=31);
632                 set_ppc32_rlwimi_const(shift, 32-sh, sh, 31);
633                 return shift;
634         }
635         return new_rd_ppc32_Srw(env->dbg, env->irg, env->block, op1, op2, env->mode);
636 }
637
638 /**
639  * Creates an ppc Sraw.
640  *
641  * @param env   The transformation environment
642  * @return the created ppc Sraw node
643  */
644 static ir_node *gen_Shrs(ppc32_transform_env_t *env) {
645         ir_node *op1 = get_Shrs_left(env->irn);
646         ir_node *op2 = get_Shrs_right(env->irn);
647
648         if(is_ppc32_Const(op2))
649         {
650                 ir_node *shift = new_rd_ppc32_Srawi(env->dbg, env->irg, env->block, op1, env->mode);
651                 tarval *tv_const = get_ppc32_constant_tarval(op2);
652                 int sh = get_tarval_long(tv_const);
653                 assert(0<=sh && sh<=31);
654                 set_ppc32_constant_tarval(shift, tv_const);
655                 set_ppc32_offset_mode(shift, ppc32_ao_None);
656                 return shift;
657         }
658         return new_rd_ppc32_Sraw(env->dbg, env->irg, env->block, op1, op2, env->mode);
659 }
660
661 /**
662  * Creates an ppc RotL.
663  *
664  * @param env   The transformation environment
665  * @return the created ppc RotL node
666  */
667 static ir_node *gen_Rot(ppc32_transform_env_t *env) {
668         ir_node *op1 = get_Rot_left(env->irn);
669         ir_node *op2 = get_Rot_right(env->irn);
670
671         if(is_ppc32_Const(op2))
672         {
673                 ir_node *rot = new_rd_ppc32_Rlwinm(env->dbg, env->irg, env->block, op1, env->mode);
674                 tarval *tv_const = get_ppc32_constant_tarval(op2);
675                 int sh = get_tarval_long(tv_const);
676                 assert(0<=sh && sh<=31);
677                 set_ppc32_rlwimi_const(rot, sh, 0, 31);
678                 return rot;
679         }
680         return new_rd_ppc32_Rlwnm(env->dbg, env->irg, env->block, op1, op2, env->mode);
681 }
682
683 /**
684  * Creates an ppc Cmp.
685  *
686  * @param env   The transformation environment
687  * @return the created ppc Cmp node
688  */
689 static ir_node *gen_Cmp(ppc32_transform_env_t *env) {
690         ir_node *op1 = get_Cmp_left(env->irn);
691         ir_node *op2 = get_Cmp_right(env->irn);
692
693         const ir_edge_t *edge;
694         foreach_out_edge(env->irn, edge)
695         {
696                 if (is_Proj(edge->src))
697                         set_irn_mode(edge->src, get_ppc32_mode_Cond());
698         }
699
700         if(mode_is_float(env->mode))
701                 return new_rd_ppc32_fCmpu(env->dbg, env->irg, env->block, op1, op2, env->mode);
702         else if(mode_is_signed(env->mode))
703         {
704                 if(is_16bit_signed_const(op2))
705                 {
706                         ir_node *cmp = new_rd_ppc32_Cmpi(env->dbg, env->irg, env->block, op1, env->mode);
707                         tarval *tv_const = get_ppc32_constant_tarval(op2);
708                         set_ppc32_constant_tarval(cmp, tv_const);
709                         set_ppc32_offset_mode(cmp, ppc32_ao_None);
710                         return cmp;
711                 }
712                 else
713                 {
714                         return new_rd_ppc32_Cmp(env->dbg, env->irg, env->block, op1, op2, env->mode);
715                 }
716         }
717         else
718         {
719                 if(is_16bit_unsigned_const(op2))
720                 {
721                         ir_node *cmp = new_rd_ppc32_Cmpli(env->dbg, env->irg, env->block, op1, env->mode);
722                         tarval *tv_const = get_ppc32_constant_tarval(op2);
723                         set_ppc32_constant_tarval(cmp, tv_const);
724                         set_ppc32_offset_mode(cmp, ppc32_ao_None);
725
726                         return cmp;
727                 }
728                 else
729                 {
730                         return new_rd_ppc32_Cmpl(env->dbg, env->irg, env->block, op1, op2, env->mode);
731                 }
732         }
733 }
734
735 /**
736  * Transforms a Minus node.
737  *
738  * @param env   The transformation environment
739  * @return the created ppc Minus node
740  */
741 static ir_node *gen_Minus(ppc32_transform_env_t *env) {
742         ir_node *op = get_Minus_op(env->irn);
743
744         switch(get_nice_modecode(env->mode)){
745                 case irm_D:
746                 case irm_F:
747                         return new_rd_ppc32_fNeg(env->dbg, env->irg, env->block, op, env->mode);
748                 case irm_Is:
749                 case irm_Iu:
750                 case irm_Hs:
751                 case irm_Hu:
752                 case irm_Bs:
753                 case irm_Bu:
754                 case irm_P:
755                         return new_rd_ppc32_Neg(env->dbg, env->irg, env->block, op, env->mode);
756
757                 default:
758                         fprintf(stderr, "Mode for Neg not supported: %s\n", get_mode_name(env->mode));
759                         assert(0);
760                         return NULL;
761         }
762 }
763
764 /**
765  * Transforms a Not node.
766  *
767  * @param env   The transformation environment
768  * @return the created ppc Not node
769  */
770 static ir_node *gen_Not(ppc32_transform_env_t *env) {
771         return new_rd_ppc32_Not(env->dbg, env->irg, env->block, get_Not_op(env->irn), env->mode);
772 }
773
774
775 static ir_node *own_gen_Andi_dot_lo16(ppc32_transform_env_t *env, ir_node *op, int mask)
776 {
777         ir_node *andi = new_rd_ppc32_Andi_dot(env->dbg, env->irg, env->block, op, mode_T);
778         ir_node* in[1];
779         set_ppc32_offset_mode(andi, ppc32_ao_Lo16);
780         set_ppc32_constant_tarval(andi, new_tarval_from_long(mask, mode_Is));
781         in[0] = new_rd_Proj(env->dbg, env->irg, env->block, andi, env->mode,1);
782         be_new_Keep(&ppc32_reg_classes[CLASS_ppc32_condition], env->irg, env->block, 1, in);
783         return new_rd_Proj(env->dbg, env->irg, env->block, andi, env->mode,0);
784 }
785
786 /**
787  * Transforms a Conv node.
788  *
789  * @param env   The transformation environment
790  * @return the created ppc Conv node
791  */
792 static ir_node *gen_Conv(ppc32_transform_env_t *env) {
793         ir_node *op = get_Conv_op(env->irn);
794         modecode from_mode=get_nice_modecode(get_irn_mode(op));
795         modecode to_mode=get_nice_modecode(env->mode);
796
797 #define SKIP return op
798
799         if(from_mode == to_mode) SKIP;
800
801         switch(from_mode){
802                 case irm_F:
803                         switch(to_mode)
804                         {
805                                 case irm_D: SKIP;
806                                 default:
807                                         break;
808                         }
809                         break;
810
811                 case irm_D:
812                         switch(to_mode)
813                         {
814                                 case irm_F:
815                                         return new_rd_ppc32_fRsp(env->dbg, env->irg, env->block, op, env->mode);
816                                 default:
817                                         break;
818                         }
819                         break;
820
821                 case irm_Is:
822                 case irm_Iu:
823                         switch(to_mode)
824                         {
825                                 case irm_Hs:
826                                         return new_rd_ppc32_Extsh(env->dbg, env->irg, env->block, op, env->mode);
827                                 case irm_Hu:
828                                         return own_gen_Andi_dot_lo16(env, op, 0xffff);
829                                 case irm_Bs:
830                                         return new_rd_ppc32_Extsb(env->dbg, env->irg, env->block, op, env->mode);
831                                 case irm_Bu:
832                                         return own_gen_Andi_dot_lo16(env, op, 0xff);
833                                 case irm_Is:
834                                 case irm_Iu:
835                                         SKIP;
836                                 default:
837                                         break;
838                         }
839                         break;
840
841                 case irm_Hs:
842                 case irm_Hu:
843                         switch(to_mode)
844                         {
845                                 case irm_Iu:
846                                         if(from_mode==irm_Hu)
847                                 case irm_Hu:
848                                                 return own_gen_Andi_dot_lo16(env, op, 0xffff);
849                                 case irm_Is:
850                                         SKIP;
851                                 case irm_Bs:
852                                         return new_rd_ppc32_Extsb(env->dbg, env->irg, env->block, op, env->mode);
853                                 case irm_Bu:
854                                         return own_gen_Andi_dot_lo16(env, op, 0xff);
855                                 case irm_Hs:
856                                         return new_rd_ppc32_Extsh(env->dbg, env->irg, env->block, op, env->mode);
857                                 default:
858                                         break;
859                         }
860                         break;
861
862                 case irm_Bs:
863                 case irm_Bu:
864                         switch(to_mode)
865                         {
866                                 case irm_Iu:
867                                 case irm_Hu:
868                                         if(from_mode==irm_Bs)
869                                 case irm_Bu:
870                                                 return own_gen_Andi_dot_lo16(env, op, 0xff);
871                                 case irm_Is:
872                                 case irm_Hs:
873                                         SKIP;
874                                 case irm_Bs:
875                                         return new_rd_ppc32_Extsb(env->dbg, env->irg, env->block, op, env->mode);
876                                 default:
877                                         break;
878                         }
879                         break;
880                 case irm_P:
881                         if(to_mode==irm_Is || to_mode==irm_Iu) SKIP;
882                         break;
883                 default:
884                         break;
885         }
886
887         fprintf(stderr, "Mode for Conv not supported: %s -> %s\n",
888                 get_mode_name(get_irn_mode(get_irn_n(env->irn,0))),get_mode_name(env->mode));
889         assert(0);
890         return NULL;
891
892 #undef SKIP
893 }
894
895 /**
896  * Transforms an Abs node.
897  *
898  * @param env   The transformation environment
899  * @return the ppc node generating the absolute value
900  */
901 static ir_node *gen_Abs(ppc32_transform_env_t *env) {
902         ir_node *op = get_Abs_op(env->irn);
903         int shift = 7;
904         ir_node *n1,*n2;
905
906         switch(get_nice_modecode(env->mode))
907         {
908                 case irm_F:
909                 case irm_D:
910                         return new_rd_ppc32_fAbs(env->dbg, env->irg, env->block, op, env->mode);
911                 case irm_Is:
912                         shift += 16;
913                 case irm_Hs:
914                         shift += 8;
915                 case irm_Bs:
916                         n1 = new_rd_ppc32_Srawi(env->dbg, env->irg, env->block, op, env->mode);
917                         set_ppc32_constant_tarval(n1, new_tarval_from_long(shift, mode_Is));
918                         set_ppc32_offset_mode(n1, ppc32_ao_None);
919                         n2 = new_rd_ppc32_Add(env->dbg, env->irg, env->block, op, n1, env->mode);
920                         return new_rd_ppc32_Xor(env->dbg, env->irg, env->block, n2, n1, env->mode);
921                 default:
922                         break;
923         }
924         fprintf(stderr, "Mode for Abs not supported: %s\n", get_mode_name(env->mode));
925         assert(0);
926         return NULL;
927 }
928
929 /**
930  * Transforms an Cond node.
931  *
932  * @param env   The transformation environment
933  * @return a ppc branch node
934  */
935 static ir_node *gen_Cond(ppc32_transform_env_t *env) {
936         ir_node *selector = get_Cond_selector(env->irn);
937         ir_mode *projmode = get_irn_mode(selector);
938         if(is_Proj(selector) && projmode==get_ppc32_mode_Cond())
939         {
940                 int projnum = get_Proj_proj(selector);
941                 ir_node *branch = new_rd_ppc32_Branch(env->dbg, env->irg, env->block, selector, env->mode);
942                 set_ppc32_proj_nr(branch, projnum);
943                 return branch;
944         }
945         else
946         {
947                 ir_node *unknown_gpr = new_rd_ppc32_Unknown(env->dbg, env->irg, env->block, mode_Is);
948                 ir_node *unknown_cond = new_rd_ppc32_cUnknown(env->dbg, env->irg, env->block, get_ppc32_mode_Cond());
949
950                 ir_node *switch_node = new_rd_ppc32_Switch(env->dbg, env->irg, env->block, selector,
951                         unknown_gpr, unknown_cond, env->mode);
952                 set_ppc32_proj_nr(switch_node, get_Cond_defaultProj(env->irn));
953
954                 return switch_node;
955         }
956 }
957
958 /**
959  * Transforms an Unknown node.
960  *
961  * @param env   The transformation environment
962  * @return a ppc Unknown node
963  */
964 static ir_node *gen_Unknown(ppc32_transform_env_t *env) {
965         if(mode_is_float(env->mode))
966                 return new_rd_ppc32_fUnknown(env->dbg, env->irg, env->block, env->mode);
967         else if (mode_is_int(env->mode))
968                 return new_rd_ppc32_Unknown(env->dbg, env->irg, env->block, env->mode);
969         else
970         {
971                 fprintf(stderr, "Mode %s for unknown value not supported.\n", get_mode_name(env->mode));
972                 assert(0);
973                 return 0;
974         }
975 }
976
977 static ir_node *ldst_insert_const(ir_node *ptr, tarval **ptv, ident **pid, ppc32_transform_env_t *env) {
978         tarval *tv_const = NULL;
979         ident *id_symconst = NULL;
980
981         if(is_ppc32_Const(ptr))
982         {
983                 tv_const = get_ppc32_constant_tarval(ptr);
984                 ptr = new_rd_ppc32_Addis_zero(env->dbg, env->irg, env->block, mode_P, ppc32_ao_Ha16, tv_const, NULL);
985         }
986         else if(is_ppc32_SymConst(ptr))
987         {
988                 ir_entity *ent = get_ppc32_frame_entity(ptr);
989                 if(is_direct_entity(ent))
990                 {
991                         id_symconst = get_entity_ident(ent);
992                         ptr = new_rd_ppc32_Addis_zero(env->dbg, env->irg, env->block, mode_P, ppc32_ao_Ha16, NULL, id_symconst);
993                 }
994         }
995         *ptv = tv_const;
996         *pid = id_symconst;
997         return ptr;
998 }
999
1000 /**
1001  * Transforms a Load.
1002  *
1003  * @param env   The transformation environment
1004  * @return the created ppc Load node
1005  */
1006 static ir_node *gen_Load(ppc32_transform_env_t *env) {
1007         ir_node *node = env->irn;
1008         ir_node *loadptr = get_Load_ptr(node);
1009         ir_node *load;
1010         ir_mode *mode = get_Load_mode(node);
1011         tarval *tv_const = NULL;
1012         ident *id_symconst = NULL;
1013
1014         loadptr = ldst_insert_const(loadptr, &tv_const, &id_symconst, env);
1015         switch(get_nice_modecode(mode)){
1016                 case irm_Bu:
1017                         load = new_rd_ppc32_Lbz(env->dbg, env->irg, env->block, loadptr, get_Load_mem(node));
1018                         break;
1019
1020                 case irm_Bs:
1021                 {
1022                         ir_node *proj_load, *extsb_node;
1023                         load =  new_rd_ppc32_Lbz(env->dbg, env->irg, env->block, loadptr, get_Load_mem(node));
1024                         proj_load = new_rd_Proj(env->dbg, env->irg, env->block, load, mode, pn_Load_res);
1025                         extsb_node = new_rd_ppc32_Extsb(env->dbg, env->irg, env->block, proj_load, mode);
1026                         exchange(get_succ_Proj(env->irn, pn_Load_res), extsb_node);
1027                         break;
1028                 }
1029
1030
1031                 case irm_Hu:
1032                         load = new_rd_ppc32_Lhz(env->dbg, env->irg, env->block, loadptr, get_Load_mem(node));
1033                         break;
1034                 case irm_Hs:
1035                         load =new_rd_ppc32_Lha(env->dbg, env->irg, env->block, loadptr, get_Load_mem(node));
1036                         break;
1037                 case irm_Is:
1038                 case irm_Iu:
1039                 case irm_P:
1040                         load = new_rd_ppc32_Lwz(env->dbg, env->irg, env->block, loadptr, get_Load_mem(node));
1041                         break;
1042
1043                 case irm_D:
1044                         load = new_rd_ppc32_Lfd(env->dbg, env->irg, env->block, loadptr, get_Load_mem(node));
1045                         break;
1046                 case irm_F:
1047                         load = new_rd_ppc32_Lfs(env->dbg, env->irg, env->block, loadptr, get_Load_mem(node));
1048                         break;
1049
1050                 default:
1051                         fprintf(stderr, "Mode for Load not supported: %s\n", get_mode_name(env->mode));
1052                         assert(0);
1053                         return 0;
1054         }
1055
1056         if(tv_const)
1057         {
1058                 set_ppc32_offset_mode(load, ppc32_ao_Lo16);
1059                 set_ppc32_constant_tarval(load, tv_const);
1060         }
1061         else if(id_symconst)
1062         {
1063                 set_ppc32_offset_mode(load, ppc32_ao_Lo16);
1064                 set_ppc32_symconst_ident(load, id_symconst);
1065         }
1066         return load;
1067 }
1068
1069
1070
1071 /**
1072  * Transforms a Store.
1073  *
1074  * @param env   The transformation environment
1075  * @return the created ppc Store node
1076  */
1077 static ir_node *gen_Store(ppc32_transform_env_t *env) {
1078         ir_node *node = env->irn;
1079         ir_node *storeptr = get_Store_ptr(node);
1080         ir_node *valuenode = get_Store_value(node);
1081         ir_mode *mode = get_irn_mode(valuenode);
1082         ir_node *store;
1083         tarval *tv_const = NULL;
1084         ident *id_symconst = NULL;
1085
1086         storeptr = ldst_insert_const(storeptr, &tv_const, &id_symconst, env);
1087
1088         switch(get_nice_modecode(mode)){
1089                 case irm_Bu:
1090                 case irm_Bs:
1091                         store = new_rd_ppc32_Stb(env->dbg, env->irg, env->block, storeptr, get_Store_value(node), get_Store_mem(node));
1092                         break;
1093
1094                 case irm_Hu:
1095                 case irm_Hs:
1096                         store = new_rd_ppc32_Sth(env->dbg, env->irg, env->block, storeptr, get_Store_value(node), get_Store_mem(node));
1097                         break;
1098                 case irm_Is:
1099                 case irm_Iu:
1100                 case irm_P:
1101                         store = new_rd_ppc32_Stw(env->dbg, env->irg, env->block, storeptr, get_Store_value(node), get_Store_mem(node));
1102                         break;
1103
1104                 case irm_D:
1105                         store = new_rd_ppc32_Stfd(env->dbg, env->irg, env->block, storeptr, get_Store_value(node), get_Store_mem(node));
1106                         break;
1107                 case irm_F:
1108                         store = new_rd_ppc32_Stfs(env->dbg, env->irg, env->block, storeptr, get_Store_value(node), get_Store_mem(node));
1109                         break;
1110
1111                 default:
1112                         fprintf(stderr, "Mode for Store not supported: %s\n", get_mode_name(env->mode));
1113                         assert(0);
1114                         return 0;
1115         }
1116         if(tv_const)
1117         {
1118                 set_ppc32_offset_mode(store, ppc32_ao_Lo16);
1119                 set_ppc32_constant_tarval(store, tv_const);
1120         }
1121         else if(id_symconst)
1122         {
1123                 set_ppc32_offset_mode(store, ppc32_ao_Lo16);
1124                 set_ppc32_symconst_ident(store, id_symconst);
1125         }
1126         return store;
1127 }
1128
1129 /**
1130  * Transforms a CopyB.
1131  *
1132  * @param env   The transformation environment
1133  * @return the created ppc CopyB node
1134  */
1135 static ir_node *gen_CopyB(ppc32_transform_env_t *env) {
1136         ir_node *mem = get_CopyB_mem(env->irn);
1137         ir_node *src = get_CopyB_src(env->irn);
1138         ir_node *dest = get_CopyB_dst(env->irn);
1139         ir_type *type = get_CopyB_type(env->irn);
1140         int size = get_type_size_bytes(type);
1141         int offset = 0;
1142
1143         ir_node *load, *store = NULL;
1144
1145         if(size/4 >= 1)
1146         {
1147                 ir_node *res;
1148                 tarval *offset0 = new_tarval_from_long(0, mode_Is);
1149                 tarval *offset4 = new_tarval_from_long(4, mode_Is);
1150
1151                 load = new_rd_ppc32_Lwz(env->dbg, env->irg, env->block, src, mem);
1152                 set_ppc32_constant_tarval(load, offset0);
1153                 set_ppc32_offset_mode(load, ppc32_ao_None);
1154                 mem = new_rd_Proj(env->dbg, env->irg, env->block, load, mode_M, pn_Load_M);
1155                 res = new_rd_Proj(env->dbg, env->irg, env->block, load, mode_Is, pn_Load_res);
1156
1157                 store = new_rd_ppc32_Stw(env->dbg, env->irg, env->block, dest, res, mem);
1158                 set_ppc32_constant_tarval(store, offset0);
1159                 set_ppc32_offset_mode(store, ppc32_ao_None);
1160                 mem = new_rd_Proj(env->dbg, env->irg, env->block, store, mode_M, pn_Store_M);
1161
1162                 if(size/4==2)
1163                 {
1164                         load = new_rd_ppc32_Lwz(env->dbg, env->irg, env->block, src, mem);
1165                         set_ppc32_constant_tarval(load, offset4);
1166                         set_ppc32_offset_mode(load, ppc32_ao_None);
1167                         mem = new_rd_Proj(env->dbg, env->irg, env->block, load, mode_M, pn_Load_M);
1168                         res = new_rd_Proj(env->dbg, env->irg, env->block, load, mode_Is, pn_Load_res);
1169
1170                         store = new_rd_ppc32_Stw(env->dbg, env->irg, env->block, dest, res, mem);
1171                         set_ppc32_constant_tarval(store, offset4);
1172                         set_ppc32_offset_mode(store, ppc32_ao_None);
1173                         mem = new_rd_Proj(env->dbg, env->irg, env->block, store, mode_M, pn_Store_M);
1174
1175                         offset = 8;
1176                 }
1177                 else
1178                 {
1179                         ir_node *ornode, *mtctrnode;
1180                         ir_node* in[3];
1181                         assert(size/4-1<=0xffff);
1182                         if(size/4-1<0x8000)
1183                         {
1184                                 ornode = new_rd_ppc32_Addi_zero(env->dbg, env->irg, env->block, mode_Is);
1185                                 set_ppc32_offset_mode(ornode, ppc32_ao_None);
1186                         }
1187                         else
1188                         {
1189                                 ir_node *zeroreg = new_rd_ppc32_Addi_zero(env->dbg, env->irg, env->block, mode_Is);
1190                                 set_ppc32_offset_mode(zeroreg, ppc32_ao_None);
1191                                 set_ppc32_constant_tarval(zeroreg, new_tarval_from_long(0, mode_Is));
1192                                 ornode = new_rd_ppc32_Ori(env->dbg, env->irg, env->block, zeroreg, mode_Is);
1193                                 set_ppc32_offset_mode(ornode, ppc32_ao_Lo16);
1194                         }
1195
1196                         set_ppc32_constant_tarval(ornode, new_tarval_from_long(size/4-1, mode_Is));
1197                         mtctrnode = new_rd_ppc32_Mtctr(env->dbg, env->irg, env->block, ornode, mode_Is);
1198                         store = new_rd_ppc32_LoopCopy(env->dbg, env->irg, env->block, src, dest, mtctrnode, mem, mode_T);
1199
1200                         in[0] = new_rd_Proj(env->dbg, env->irg, env->block, store, mode_Is, 1); // src
1201                         in[1] = new_rd_Proj(env->dbg, env->irg, env->block, store, mode_Is, 2); // dest
1202                         in[2] = new_rd_Proj(env->dbg, env->irg, env->block, store, mode_Is, 4); // temp
1203                         be_new_Keep(&ppc32_reg_classes[CLASS_ppc32_gp], env->irg, env->block, 3, in);
1204                         in[0] = new_rd_Proj(env->dbg, env->irg, env->block, store, mode_Is, 3); // ctr
1205                         be_new_Keep(&ppc32_reg_classes[CLASS_ppc32_count], env->irg, env->block, 1, in);
1206
1207                         mem = new_rd_Proj(env->dbg, env->irg, env->block, store, mode_M, 0);
1208
1209                         offset = 4;
1210                 }
1211         }
1212
1213         if(size & 2)
1214         {
1215                 ir_node *res;
1216                 tarval* offset_tarval = new_tarval_from_long(offset, mode_Is);
1217                 load = new_rd_ppc32_Lhz(env->dbg, env->irg, env->block, src, mem);
1218                 set_ppc32_constant_tarval(load, offset_tarval);
1219                 set_ppc32_offset_mode(load, ppc32_ao_None);
1220                 mem = new_rd_Proj(env->dbg, env->irg, env->block, load, mode_M, pn_Load_M);
1221                 res = new_rd_Proj(env->dbg, env->irg, env->block, load, mode_Is, pn_Load_res);
1222
1223                 store = new_rd_ppc32_Sth(env->dbg, env->irg, env->block, dest, res, mem);
1224                 set_ppc32_constant_tarval(store, offset_tarval);
1225                 set_ppc32_offset_mode(store, ppc32_ao_None);
1226                 mem = new_rd_Proj(env->dbg, env->irg, env->block, store, mode_M, pn_Store_M);
1227
1228                 offset += 2;
1229         }
1230
1231         if(size & 1)
1232         {
1233                 ir_node *res;
1234                 tarval* offset_tarval = new_tarval_from_long(offset, mode_Is);
1235                 load = new_rd_ppc32_Lbz(env->dbg, env->irg, env->block, src, mem);
1236                 set_ppc32_constant_tarval(load, offset_tarval);
1237                 set_ppc32_offset_mode(load, ppc32_ao_None);
1238                 mem = new_rd_Proj(env->dbg, env->irg, env->block, load, mode_M, pn_Load_M);
1239                 res = new_rd_Proj(env->dbg, env->irg, env->block, load, mode_Is, pn_Load_res);
1240
1241                 store = new_rd_ppc32_Stb(env->dbg, env->irg, env->block, dest, res, mem);
1242                 set_ppc32_constant_tarval(store, offset_tarval);
1243                 set_ppc32_offset_mode(store, ppc32_ao_None);
1244                 // mem = new_rd_Proj(env->dbg, env->irg, env->block, store, mode_M, pn_Store_M);
1245         }
1246
1247         return store;
1248 }
1249
1250 /**
1251  * Transforms a FrameAddr into a ppc Add.
1252  *
1253  * @param env   The transformation environment
1254  */
1255 static ir_node *gen_be_FrameAddr(ppc32_transform_env_t *env) {
1256         ir_node *op = get_irn_n(env->irn, 0);
1257         ir_node *add = new_rd_ppc32_Addi(env->dbg, env->irg, env->block, op, mode_P);
1258         set_ppc32_frame_entity(add, be_get_frame_entity(env->irn));
1259         return add;
1260 }
1261
1262 /**
1263  * Transforms a StackParam into a ppc Load
1264  *
1265  * @param env   The transformation environment
1266  */
1267 static ir_node *gen_be_StackParam(ppc32_transform_env_t *env) {
1268         ir_node *load = new_rd_ppc32_Lwz(env->dbg, env->irg, env->block, get_irn_n(env->irn, 0), new_NoMem());
1269         ir_node *proj = new_rd_Proj(env->dbg, env->irg, env->block, load, env->mode, pn_Load_res);
1270         set_ppc32_frame_entity(load, be_get_frame_entity(env->irn));
1271         return proj;
1272 }
1273
1274
1275 /*********************************************************
1276  *                  _             _      _
1277  *                 (_)           | |    (_)
1278  *  _ __ ___   __ _ _ _ __     __| |_ __ ___   _____ _ __
1279  * | '_ ` _ \ / _` | | '_ \   / _` | '__| \ \ / / _ \ '__|
1280  * | | | | | | (_| | | | | | | (_| | |  | |\ V /  __/ |
1281  * |_| |_| |_|\__,_|_|_| |_|  \__,_|_|  |_| \_/ \___|_|
1282  *
1283  *********************************************************/
1284
1285 /**
1286  * the BAD transformer.
1287  */
1288 static ir_node *bad_transform(ppc32_transform_env_t *env) {
1289         ir_fprintf(stderr, "Not implemented: %+F\n", env->irn);
1290         assert(0);
1291         return NULL;
1292 }
1293
1294 /**
1295  * Enters all transform functions into the generic pointer
1296  */
1297 void ppc32_register_transformers(void) {
1298         ir_op *op_Max, *op_Min, *op_Mulh;
1299
1300         /* first clear the generic function pointer for all ops */
1301         clear_irp_opcodes_generic_func();
1302
1303 #define FIRM_OP(a)     op_##a->ops.generic = (op_func)gen_##a
1304 #define BAD(a)         op_##a->ops.generic = (op_func)bad_transform
1305 #define IGN(a)
1306
1307         FIRM_OP(Add);
1308         FIRM_OP(Mul);
1309         FIRM_OP(And);
1310         FIRM_OP(Or);
1311         FIRM_OP(Eor);
1312
1313         FIRM_OP(Sub);
1314         FIRM_OP(Shl);
1315         FIRM_OP(Shr);
1316         FIRM_OP(Shrs);
1317         FIRM_OP(Rot);
1318         FIRM_OP(Quot);
1319         FIRM_OP(Div);
1320         FIRM_OP(DivMod);
1321         FIRM_OP(Mod);
1322         FIRM_OP(Cmp);
1323
1324         FIRM_OP(Minus);
1325         FIRM_OP(Not);
1326         FIRM_OP(Conv);
1327         FIRM_OP(Abs);
1328
1329         FIRM_OP(Load);
1330         FIRM_OP(Store);
1331         FIRM_OP(Cond);
1332         FIRM_OP(Unknown);
1333         FIRM_OP(CopyB);
1334
1335         /* TODO: implement these nodes */
1336         BAD(Mux);
1337
1338         /* You probably don't need to handle the following nodes */
1339
1340         IGN(Call);
1341         IGN(Proj);
1342         IGN(Alloc);
1343
1344         IGN(Block);
1345         IGN(Start);
1346         IGN(End);
1347         IGN(NoMem);
1348         IGN(Phi);
1349         IGN(IJmp);
1350         IGN(Jmp);
1351         IGN(Break);
1352         IGN(Sync);
1353
1354         BAD(Raise);
1355         BAD(Sel);
1356         BAD(InstOf);
1357         BAD(Cast);
1358         BAD(Free);
1359         BAD(Tuple);
1360         BAD(Id);
1361         BAD(Bad);
1362         BAD(Confirm);
1363         BAD(Filter);
1364         BAD(CallBegin);
1365         BAD(EndReg);
1366         BAD(EndExcept);
1367
1368         FIRM_OP(be_FrameAddr);
1369         FIRM_OP(be_StackParam);
1370         op_Mulh = get_op_Mulh();
1371         if (op_Mulh)
1372                 FIRM_OP(Mulh);
1373         op_Max = get_op_Max();
1374         if (op_Max)
1375                 BAD(Max);
1376         op_Min = get_op_Min();
1377         if (op_Min)
1378                 BAD(Min);
1379 }
1380
1381 typedef ir_node *(transform_func)(ppc32_transform_env_t *env);
1382
1383 /**
1384  * Transforms the given firm node (and maybe some other related nodes)
1385  * into one or more assembler nodes.
1386  *
1387  * @param node    the firm node
1388  * @param env     the debug module
1389  */
1390 void ppc32_transform_node(ir_node *node, void *env) {
1391         ppc32_code_gen_t *cg = (ppc32_code_gen_t *)env;
1392         ir_op *op            = get_irn_op(node);
1393         ir_node *asm_node    = NULL;
1394
1395         if (op == op_Block)
1396                 return;
1397
1398         DBG((cg->mod, LEVEL_1, "check %+F ... ", node));
1399
1400         if (op->ops.generic) {
1401                 ppc32_transform_env_t tenv;
1402                 transform_func *transform = (transform_func *)op->ops.generic;
1403
1404                 tenv.block    = get_nodes_block(node);
1405                 tenv.dbg      = get_irn_dbg_info(node);
1406                 tenv.irg      = current_ir_graph;
1407                 tenv.irn      = node;
1408                 tenv.mode     = get_irn_mode(node);
1409                 DEBUG_ONLY(tenv.mod = cg->mod;)
1410
1411                 asm_node = (*transform)(&tenv);
1412         }
1413
1414         if (asm_node) {
1415                 exchange(node, asm_node);
1416                 DB((cg->mod, LEVEL_1, "created node %+F[%p]\n", asm_node, asm_node));
1417         }
1418         else {
1419                 DB((cg->mod, LEVEL_1, "ignored\n"));
1420         }
1421 }
1422
1423 /**
1424  * Constant generating code
1425  */
1426
1427 struct tv_ent {
1428         ir_entity *ent;
1429         tarval *tv;
1430 };
1431
1432 /** Compares two (entity, tarval) combinations */
1433 static int cmp_tv_ent(const void *a, const void *b, size_t len) {
1434         const struct tv_ent *e1 = a;
1435         const struct tv_ent *e2 = b;
1436
1437         return !(e1->tv == e2->tv);
1438 }
1439
1440 /** Generates a SymConst node for a known FP const */
1441 static ir_node *gen_fp_known_symconst(ppc32_transform_env_t *env, tarval *known_const) {
1442         static set    *const_set = NULL;
1443         static ir_type *tp = NULL;
1444         struct tv_ent  key;
1445         struct tv_ent *entry;
1446         ir_node       *cnst,*symcnst;
1447         ir_graph      *rem;
1448         ir_entity     *ent = NULL;
1449
1450         if(!const_set)
1451                 const_set = new_set(cmp_tv_ent, 10);
1452         if(!tp)
1453                 tp = new_type_primitive(new_id_from_str("const_double_t"), env->mode);
1454
1455         key.tv  = known_const;
1456         key.ent = NULL;
1457
1458         entry = set_insert(const_set, &key, sizeof(key), HASH_PTR(key.tv));
1459
1460         if(!entry->ent) {
1461                 char buf[80];
1462                 sprintf(buf, "const_%ld", get_irn_node_nr(env->irn));
1463                 ent = new_entity(get_glob_type(), new_id_from_str(buf), tp);
1464
1465                 set_entity_ld_ident(ent, get_entity_ident(ent));
1466                 set_entity_visibility(ent, visibility_local);
1467                 set_entity_variability(ent, variability_constant);
1468                 set_entity_allocation(ent, allocation_static);
1469
1470                 /* we create a new entity here: It's initialization must resist on the
1471                     const code irg */
1472                 rem = current_ir_graph;
1473                 current_ir_graph = get_const_code_irg();
1474                 cnst = new_Const(env->mode, key.tv);
1475                 current_ir_graph = rem;
1476
1477                 set_atomic_ent_value(ent, cnst);
1478
1479                 /* set the entry for hashmap */
1480                 entry->ent = ent;
1481         }                                // TODO: Wird nicht richtig in global type gesteckt, ppc32_gen_decls.c findet ihn nicht
1482
1483         symcnst = new_rd_ppc32_SymConst(env->dbg, env->irg, env->block, env->mode);
1484         set_ppc32_frame_entity(symcnst, ent);
1485         return symcnst;
1486 }
1487
1488 static ir_node *gen_ppc32_SymConst(ppc32_transform_env_t *env);
1489
1490 /**
1491  * Transforms a Const.
1492  *
1493  * @param mod     the debug module
1494  * @param block   the block the new node should belong to
1495  * @param node    the ir Const node
1496  * @param mode    node mode
1497  * @return the created ppc Load immediate node
1498  */
1499 static ir_node *gen_ppc32_Const(ppc32_transform_env_t *env) {
1500         tarval *tv_const = get_ppc32_constant_tarval(env->irn);
1501         ir_node *node;
1502
1503         switch(get_nice_modecode(env->mode)){
1504                 case irm_Hu:
1505                 {
1506                         unsigned char val1 = get_tarval_sub_bits(tv_const, 1);
1507                         if(val1&0x80)
1508                         {
1509                                 ir_node *zeroreg = new_rd_ppc32_Addi_zero(env->dbg, env->irg, env->block, mode_Is);
1510                                 set_ppc32_constant_tarval(zeroreg, new_tarval_from_long(0, mode_Is));
1511                                 set_ppc32_offset_mode(zeroreg, ppc32_ao_None);
1512                                 node = new_rd_ppc32_Ori(env->dbg, env->irg, env->block, zeroreg, mode_Is);
1513                                 set_ppc32_offset_mode(node, ppc32_ao_Lo16);
1514                                 break;
1515                         }
1516                 }
1517                 case irm_Bu:
1518                 case irm_Bs:
1519                 case irm_Hs:
1520                         node = new_rd_ppc32_Addi_zero(env->dbg, env->irg, env->block, env->mode);
1521                         set_ppc32_offset_mode(node, ppc32_ao_None);
1522                         break;
1523                 case irm_Is:
1524                 case irm_Iu:
1525                 case irm_P:
1526                 {
1527                         unsigned char val2 = get_tarval_sub_bits(tv_const,2);
1528                         unsigned char val3 = get_tarval_sub_bits(tv_const,3);
1529                         if(!val2 && !val3)
1530                         {
1531                                 unsigned char val1 = get_tarval_sub_bits(tv_const, 1);
1532                                 if(val1&0x80)
1533                                 {
1534                                         ir_node *zeroreg = new_rd_ppc32_Addi_zero(env->dbg, env->irg, env->block, mode_Is);
1535                                         set_ppc32_constant_tarval(zeroreg, new_tarval_from_long(0, mode_Is));
1536                                         set_ppc32_offset_mode(zeroreg, ppc32_ao_None);
1537                                         node = new_rd_ppc32_Ori(env->dbg, env->irg, env->block, zeroreg, mode_Is);
1538                                         set_ppc32_offset_mode(node, ppc32_ao_Lo16);
1539                                 }
1540                                 else
1541                                 {
1542                                         node = new_rd_ppc32_Addi_zero(env->dbg, env->irg, env->block, env->mode);
1543                                         set_ppc32_offset_mode(node, ppc32_ao_None);
1544                                 }
1545                         }
1546                         else
1547                         {
1548                                 unsigned char val0 = get_tarval_sub_bits(tv_const,0);
1549                                 unsigned char val1 = get_tarval_sub_bits(tv_const,1);
1550                                 node = new_rd_ppc32_Addis_zero(env->dbg, env->irg, env->block, env->mode, ppc32_ao_Hi16, tv_const, NULL);
1551                                 if(val0 || val1)
1552                                 {
1553                                         set_ppc32_constant_tarval(node, tv_const);
1554                                         node = new_rd_ppc32_Ori(env->dbg, env->irg, env->block, node, env->mode);
1555                                         set_ppc32_offset_mode(node, ppc32_ao_Lo16);
1556                                 }
1557                         }
1558                         break;
1559                 }
1560
1561                 default:
1562                         fprintf(stderr, "Mode for Const not supported: %s\n", get_mode_name(env->mode));
1563                         assert(0);
1564                         return 0;
1565         }
1566         set_ppc32_constant_tarval(node, tv_const);
1567         return node;
1568 }
1569
1570 /**
1571  * Transforms a fConst.
1572  *
1573  * @param mod     the debug module
1574  * @param block   the block the new node should belong to
1575  * @param node    the ir Const node
1576  * @param mode    node mode
1577  * @return the created ppc float Load node
1578  */
1579 static ir_node *gen_ppc32_fConst(ppc32_transform_env_t *env) {
1580         tarval *tv_const = get_ppc32_constant_tarval(env->irn);
1581
1582         switch(get_nice_modecode(env->mode)){
1583                 case irm_D:
1584                 case irm_F:
1585                 {
1586                         ir_node *addr, *load;
1587                         ir_mode *mode = env->mode;
1588                         ir_entity *ent;
1589                         env->irn = gen_fp_known_symconst(env, tv_const);
1590                         env->mode = mode_P;
1591                         ent = get_ppc32_frame_entity(env->irn);
1592                         if(is_direct_entity(ent))
1593                         {
1594                                 ident *id_symconst = get_entity_ident(ent);
1595                                 ir_node *node_addis = new_rd_ppc32_Addis_zero(env->dbg, env->irg, env->block, env->mode, ppc32_ao_Ha16, NULL, id_symconst);
1596
1597                                 if(mode==mode_D)
1598                                         load = new_rd_ppc32_Lfd(env->dbg, env->irg, env->block, node_addis, new_NoMem());
1599                                 else // mode_F
1600                                         load = new_rd_ppc32_Lfs(env->dbg, env->irg, env->block, node_addis, new_NoMem());
1601
1602                                 set_ppc32_symconst_ident(load, id_symconst);
1603                                 set_ppc32_offset_mode(load, ppc32_ao_Lo16);
1604                         }
1605                         else
1606                         {
1607                                 addr = gen_ppc32_SymConst (env);
1608                                 if(mode==mode_D)
1609                                         load = new_rd_ppc32_Lfd(env->dbg, env->irg, env->block, addr, new_NoMem());
1610                                 else // mode_F
1611                                         load = new_rd_ppc32_Lfs(env->dbg, env->irg, env->block, addr, new_NoMem());
1612                         }
1613                         return new_rd_Proj(env->dbg, env->irg, env->block, load, mode, pn_Load_res);
1614                 }
1615
1616                 default:
1617                         fprintf(stderr, "Mode for fConst not supported: %s\n", get_mode_name(env->mode));
1618                         assert(0);
1619                         return 0;
1620         }
1621         assert(0 && "Dead end!");
1622 }
1623
1624
1625 /**
1626  * Returns true, if the entity can be accessed directly,
1627  * or false, if the address must be loaded first
1628  */
1629 int is_direct_entity(ir_entity *ent) {
1630         return get_entity_visibility(ent) != visibility_external_allocated;
1631 /*      visibility vis = get_entity_visibility(ent);
1632         if(is_Method_type(get_entity_type(ent)))
1633         {
1634                 return (vis!=visibility_external_allocated);
1635         }
1636         else
1637         {
1638                 return (vis==visibility_local);
1639         }*/
1640 }
1641
1642 /**
1643  * Transforms a SymConst.
1644  *
1645  * @param mod     the debug module
1646  * @param block   the block the new node should belong to
1647  * @param node    the ir Const node
1648  * @param mode    node mode
1649  * @return the created ppc Load immediate node
1650  */
1651 static ir_node *gen_ppc32_SymConst(ppc32_transform_env_t *env) {
1652         ir_entity *ent = get_ppc32_frame_entity(env->irn);
1653         ident *id_symconst = get_entity_ident(ent);
1654         ir_node *node;
1655         switch(get_nice_modecode(env->mode)){
1656                 case irm_P:
1657                 {
1658                         if (is_direct_entity(ent))
1659                         {
1660                                 ir_node *node_addis = new_rd_ppc32_Addis_zero(env->dbg, env->irg, env->block, env->mode, ppc32_ao_Hi16, NULL, id_symconst);
1661                                 node = new_rd_ppc32_Ori(env->dbg, env->irg, env->block, node_addis, env->mode);
1662                                 set_ppc32_symconst_ident(node, id_symconst);
1663                                 set_ppc32_offset_mode(node, ppc32_ao_Lo16);
1664                         }
1665                         else
1666                         {
1667                                 ir_node *node_addis = new_rd_ppc32_Addis_zero(env->dbg, env->irg, env->block, env->mode, ppc32_ao_Ha16, NULL, id_symconst);
1668                                 node = new_rd_ppc32_Lwz(env->dbg, env->irg, env->block, node_addis, new_NoMem());
1669                                 set_ppc32_symconst_ident(node, id_symconst);
1670                                 set_ppc32_offset_mode(node, ppc32_ao_Lo16);
1671                                 node = new_rd_Proj(env->dbg, env->irg, env->block, node, env->mode, pn_Load_res);
1672                         }
1673                         break;
1674                 }
1675
1676                 default:
1677                         fprintf(stderr, "Mode for SymConst not supported: %s\n", get_mode_name(env->mode));
1678                         assert(0);
1679                         return 0;
1680         }
1681         return node;
1682 }
1683
1684 /**
1685  * Transforms the given firm node (and maybe some other related nodes)
1686  * into one or more assembler nodes.
1687  *
1688  * @param node    the firm node
1689  * @param env     the debug module
1690  */
1691 void ppc32_transform_const(ir_node *node, void *env) {
1692         ppc32_code_gen_t *cgenv    = (ppc32_code_gen_t *)env;
1693         ir_node          *asm_node = NULL;
1694         ppc32_transform_env_t tenv;
1695
1696         if (is_Block(node))
1697                 return;
1698
1699         tenv.block = get_nodes_block(node);
1700         tenv.dbg   = get_irn_dbg_info(node);
1701         tenv.irg   = current_ir_graph;
1702         tenv.irn   = node;
1703         DEBUG_ONLY(tenv.mod   = cgenv->mod;)
1704         tenv.mode  = get_irn_mode(node);
1705
1706 #define OTHER_GEN(a)                        \
1707         if (get_irn_op(node) == get_op_##a()) { \
1708                 asm_node = gen_##a(&tenv);          \
1709         }
1710
1711         DBG((tenv.mod, LEVEL_1, "check %+F ... ", node));
1712
1713         OTHER_GEN(ppc32_Const)
1714         else OTHER_GEN(ppc32_fConst)
1715         else OTHER_GEN(ppc32_SymConst)
1716
1717         if (asm_node) {
1718                 exchange(node, asm_node);
1719                 DB((tenv.mod, LEVEL_1, "created node %+F[%p]\n", asm_node, asm_node));
1720         }
1721         else {
1722                 DB((tenv.mod, LEVEL_1, "ignored\n"));
1723         }
1724 #undef OTHER_GEN
1725 }