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